Skip to content

Commit 2d54b83

Browse files
Add load state in <StateContextProvider/> and disable UI elements based on the state. (#88)
Co-authored-by: davemarco <[email protected]>
1 parent 76f70bc commit 2d54b83

File tree

15 files changed

+324
-63
lines changed

15 files changed

+324
-63
lines changed

new-log-viewer/src/components/DropFileContainer/index.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,7 @@
2828

2929
background-color: #f3f3f3;
3030
}
31+
32+
.hover-message-disabled {
33+
background-color: #fce4e4;
34+
}

new-log-viewer/src/components/DropFileContainer/index.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import React, {
44
} from "react";
55

66
import {StateContext} from "../../contexts/StateContextProvider";
7+
import {UI_ELEMENT} from "../../typings/states";
78
import {CURSOR_CODE} from "../../typings/worker";
9+
import {isDisabled} from "../../utils/states";
810

911
import "./index.css";
1012

@@ -21,8 +23,9 @@ interface DropFileContextProviderProps {
2123
* @return
2224
*/
2325
const DropFileContainer = ({children}: DropFileContextProviderProps) => {
24-
const {loadFile} = useContext(StateContext);
26+
const {loadFile, uiState} = useContext(StateContext);
2527
const [isFileHovering, setIsFileHovering] = useState(false);
28+
const disabled = isDisabled(uiState, UI_ELEMENT.DRAG_AND_DROP);
2629

2730
const handleDrag = (ev: React.DragEvent<HTMLDivElement>) => {
2831
ev.preventDefault();
@@ -52,6 +55,9 @@ const DropFileContainer = ({children}: DropFileContextProviderProps) => {
5255
ev.stopPropagation();
5356

5457
setIsFileHovering(false);
58+
if (disabled) {
59+
return;
60+
}
5561

5662
const [file] = ev.dataTransfer.files;
5763
if ("undefined" === typeof file) {
@@ -78,10 +84,14 @@ const DropFileContainer = ({children}: DropFileContextProviderProps) => {
7884
onDrop={handleDrop}
7985
>
8086
<div
81-
className={"hover-message"}
87+
className={`hover-message ${disabled ?
88+
"hover-message-disabled" :
89+
""}`}
8290
onDrop={handleDrop}
8391
>
84-
Drop file to view
92+
{disabled ?
93+
"Drop is disabled during loading" :
94+
"Drop file to view"}
8595
</div>
8696
</div>
8797
)}

new-log-viewer/src/components/MenuBar/ExportLogsButton.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ import {
1212
EXPORT_LOG_PROGRESS_VALUE_MAX,
1313
EXPORT_LOG_PROGRESS_VALUE_MIN,
1414
} from "../../services/LogExportManager";
15+
import {UI_ELEMENT} from "../../typings/states";
16+
import {
17+
ignorePointerIfFastLoading,
18+
isDisabled,
19+
} from "../../utils/states";
1520
import SmallIconButton from "./SmallIconButton";
1621

1722

@@ -21,16 +26,14 @@ import SmallIconButton from "./SmallIconButton";
2126
* @return
2227
*/
2328
const ExportLogsButton = () => {
24-
const {exportLogs, exportProgress, fileName} = useContext(StateContext);
29+
const {exportLogs, exportProgress, uiState} = useContext(StateContext);
2530

2631
return (
2732
<SmallIconButton
33+
className={ignorePointerIfFastLoading(uiState)}
2834
disabled={
29-
// eslint-disable-next-line no-warning-comments
30-
// TODO: Replace `"" === fileName` with a more specific context variable that
31-
// indicates whether the file has been loaded.
3235
(null !== exportProgress && EXPORT_LOG_PROGRESS_VALUE_MAX !== exportProgress) ||
33-
"" === fileName
36+
isDisabled(uiState, UI_ELEMENT.EXPORT_LOGS_BUTTON)
3437
}
3538
onClick={exportLogs}
3639
>

new-log-viewer/src/components/MenuBar/NavigationBar.tsx

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
11
import React, {useContext} from "react";
22

3+
import {
4+
ButtonGroup,
5+
IconButton,
6+
} from "@mui/joy";
7+
38
import NavigateBefore from "@mui/icons-material/NavigateBefore";
49
import NavigateNext from "@mui/icons-material/NavigateNext";
510
import SkipNext from "@mui/icons-material/SkipNext";
611
import SkipPrevious from "@mui/icons-material/SkipPrevious";
712

813
import {StateContext} from "../../contexts/StateContextProvider";
14+
import {UI_ELEMENT} from "../../typings/states";
915
import {ACTION_NAME} from "../../utils/actions";
16+
import {
17+
ignorePointerIfFastLoading,
18+
isDisabled,
19+
} from "../../utils/states";
1020
import PageNumInput from "./PageNumInput";
11-
import SmallIconButton from "./SmallIconButton";
1221

1322

1423
/**
@@ -17,7 +26,7 @@ import SmallIconButton from "./SmallIconButton";
1726
* @return
1827
*/
1928
const NavigationBar = () => {
20-
const {loadPageByAction} = useContext(StateContext);
29+
const {uiState, loadPageByAction} = useContext(StateContext);
2130

2231
const handleNavButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
2332
const {actionName} = event.currentTarget.dataset;
@@ -34,35 +43,41 @@ const NavigationBar = () => {
3443
};
3544

3645
return (
37-
<>
38-
<SmallIconButton
46+
<ButtonGroup
47+
className={ignorePointerIfFastLoading(uiState)}
48+
disabled={isDisabled(uiState, UI_ELEMENT.NAVIGATION_BAR)}
49+
size={"sm"}
50+
spacing={0.01}
51+
variant={"plain"}
52+
>
53+
<IconButton
3954
data-action-name={ACTION_NAME.FIRST_PAGE}
4055
onClick={handleNavButtonClick}
4156
>
4257
<SkipPrevious/>
43-
</SmallIconButton>
44-
<SmallIconButton
58+
</IconButton>
59+
<IconButton
4560
data-action-name={ACTION_NAME.PREV_PAGE}
4661
onClick={handleNavButtonClick}
4762
>
4863
<NavigateBefore/>
49-
</SmallIconButton>
64+
</IconButton>
5065

5166
<PageNumInput/>
5267

53-
<SmallIconButton
68+
<IconButton
5469
data-action-name={ACTION_NAME.NEXT_PAGE}
5570
onClick={handleNavButtonClick}
5671
>
5772
<NavigateNext/>
58-
</SmallIconButton>
59-
<SmallIconButton
73+
</IconButton>
74+
<IconButton
6075
data-action-name={ACTION_NAME.LAST_PAGE}
6176
onClick={handleNavButtonClick}
6277
>
6378
<SkipNext/>
64-
</SmallIconButton>
65-
</>
79+
</IconButton>
80+
</ButtonGroup>
6681
);
6782
};
6883

new-log-viewer/src/components/MenuBar/PageNumInput.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,8 @@
1313
.page-num-input-num-pages-text {
1414
font-size: inherit !important;
1515
}
16+
17+
.page-num-input-num-pages-text-disabled {
18+
/* stylelint-disable-next-line custom-property-pattern */
19+
color: var(--joy-palette-neutral-plainDisabledColor) !important;
20+
}

new-log-viewer/src/components/MenuBar/PageNumInput.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ import {
1111
} from "@mui/joy";
1212

1313
import {StateContext} from "../../contexts/StateContextProvider";
14+
import {UI_ELEMENT} from "../../typings/states";
1415
import {ACTION_NAME} from "../../utils/actions";
16+
import {
17+
ignorePointerIfFastLoading,
18+
isDisabled,
19+
} from "../../utils/states";
1520

1621
import "./PageNumInput.css";
1722

@@ -25,11 +30,13 @@ const PAGE_NUM_INPUT_FIT_EXTRA_WIDTH = 2;
2530
* @return
2631
*/
2732
const PageNumInput = () => {
28-
const {loadPageByAction, numPages, pageNum} = useContext(StateContext);
33+
const {loadPageByAction, numPages, pageNum, uiState} = useContext(StateContext);
2934

3035
const [isEditing, setIsEditing] = useState<boolean>(false);
3136
const inputRef = useRef<HTMLInputElement>(null);
3237

38+
const disabled = isDisabled(uiState, UI_ELEMENT.NAVIGATION_BAR);
39+
3340
const handleSubmit = (ev?: React.FormEvent<HTMLFormElement>) => {
3441
if ("undefined" !== typeof ev) {
3542
ev.preventDefault();
@@ -80,14 +87,17 @@ const PageNumInput = () => {
8087
onSubmit={handleSubmit}
8188
>
8289
<Input
83-
className={"page-num-input"}
90+
className={`page-num-input ${ignorePointerIfFastLoading(uiState)}`}
91+
disabled={disabled}
8492
size={"sm"}
8593
slotProps={{input: {ref: inputRef}}}
8694
type={"number"}
8795
endDecorator={
8896
<Typography
89-
className={"page-num-input-num-pages-text"}
9097
level={"body-md"}
98+
className={`page-num-input-num-pages-text ${disabled ?
99+
"page-num-input-num-pages-text-disabled" :
100+
""}`}
91101
>
92102
{"/ "}
93103
{numPages}

new-log-viewer/src/components/MenuBar/index.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,8 @@
3939
display: flex !important;
4040
justify-content: flex-end;
4141
}
42+
43+
.menu-bar-loading-progress {
44+
z-index: var(--ylv-loading-progress-z-index);
45+
margin-bottom: -2px;
46+
}

new-log-viewer/src/components/MenuBar/index.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
Box,
55
Divider,
66
IconButton,
7+
LinearProgress,
78
Sheet,
89
Tooltip,
910
Typography,
@@ -12,8 +13,10 @@ import {
1213
import FolderOpenIcon from "@mui/icons-material/FolderOpen";
1314

1415
import {StateContext} from "../../contexts/StateContextProvider";
16+
import {UI_ELEMENT} from "../../typings/states";
1517
import {CURSOR_CODE} from "../../typings/worker";
1618
import {openFile} from "../../utils/file";
19+
import {isDisabled} from "../../utils/states";
1720
import ExportLogsButton from "./ExportLogsButton";
1821
import NavigationBar from "./NavigationBar";
1922

@@ -26,7 +29,7 @@ import "./index.css";
2629
* @return
2730
*/
2831
const MenuBar = () => {
29-
const {fileName, loadFile} = useContext(StateContext);
32+
const {fileName, loadFile, uiState} = useContext(StateContext);
3033

3134
const handleOpenFile = () => {
3235
openFile((file) => {
@@ -52,6 +55,7 @@ const MenuBar = () => {
5255
variant={"outlined"}
5356
>
5457
<IconButton
58+
disabled={isDisabled(uiState, UI_ELEMENT.OPEN_FILE_BUTTON)}
5559
size={"sm"}
5660
onClick={handleOpenFile}
5761
>
@@ -84,6 +88,11 @@ const MenuBar = () => {
8488

8589
<ExportLogsButton/>
8690
</Sheet>
91+
{(false === isDisabled(uiState, UI_ELEMENT.PROGRESS_BAR)) &&
92+
<LinearProgress
93+
className={"menu-bar-loading-progress"}
94+
size={"sm"}
95+
thickness={2}/>}
8796
</>
8897
);
8998
};

new-log-viewer/src/components/StatusBar/LogLevelSelect/index.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515
background-color: initial !important;
1616
}
1717

18+
.log-level-select-render-value-box-label-disabled {
19+
/* stylelint-disable-next-line custom-property-pattern */
20+
color: var(--joy-palette-neutral-plainDisabledColor) !important;
21+
}
22+
1823
.log-level-select-listbox {
1924
/* Disallow width auto-resizing with the `Select` button. */
2025
max-width: 0;

new-log-viewer/src/components/StatusBar/LogLevelSelect/index.tsx

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,12 @@ import {
3232
LOG_LEVEL_NAMES,
3333
MAX_LOG_LEVEL,
3434
} from "../../../typings/logs";
35+
import {UI_ELEMENT} from "../../../typings/states";
3536
import {range} from "../../../utils/data";
37+
import {
38+
ignorePointerIfFastLoading,
39+
isDisabled,
40+
} from "../../../utils/states";
3641
import LogLevelChip from "./LogLevelChip";
3742

3843
import "./index.css";
@@ -126,26 +131,29 @@ interface ClearFiltersOptionProps {
126131
* @param props.onClick
127132
* @return
128133
*/
129-
const ClearFiltersOption = ({onClick}: ClearFiltersOptionProps) => (
130-
<Option
131-
value={INVALID_LOG_LEVEL_VALUE}
132-
onClick={onClick}
133-
>
134-
<ListItemDecorator>
135-
<CloseIcon/>
136-
</ListItemDecorator>
137-
Clear filters
138-
</Option>
139-
);
134+
const ClearFiltersOption = ({onClick}: ClearFiltersOptionProps) => {
135+
return (
136+
<Option
137+
value={INVALID_LOG_LEVEL_VALUE}
138+
onClick={onClick}
139+
>
140+
<ListItemDecorator>
141+
<CloseIcon/>
142+
</ListItemDecorator>
143+
Clear filters
144+
</Option>
145+
);
146+
};
140147

141148
/**
142149
* Renders a dropdown box for selecting log levels.
143150
*
144151
* @return
145152
*/
146153
const LogLevelSelect = () => {
154+
const {uiState, setLogLevelFilter} = useContext(StateContext);
147155
const [selectedLogLevels, setSelectedLogLevels] = useState<LOG_LEVEL[]>([]);
148-
const {setLogLevelFilter} = useContext(StateContext);
156+
const disabled = isDisabled(uiState, UI_ELEMENT.LOG_LEVEL_FILTER);
149157

150158
const handleRenderValue = (selected: SelectValue<SelectOption<LOG_LEVEL>, true>) => (
151159
<Box className={"log-level-select-render-value-box"}>
@@ -206,7 +214,8 @@ const LogLevelSelect = () => {
206214

207215
return (
208216
<Select
209-
className={"log-level-select"}
217+
className={`log-level-select ${ignorePointerIfFastLoading(uiState)}`}
218+
disabled={disabled}
210219
multiple={true}
211220
renderValue={handleRenderValue}
212221
size={"sm"}
@@ -223,7 +232,11 @@ const LogLevelSelect = () => {
223232
</IconButton>
224233
</Tooltip>}
225234
placeholder={
226-
<Chip className={"log-level-select-render-value-box-label"}>
235+
<Chip
236+
className={`log-level-select-render-value-box-label ${disabled ?
237+
"log-level-select-render-value-box-label-disabled" :
238+
""}`}
239+
>
227240
Log Level
228241
</Chip>
229242
}

0 commit comments

Comments
 (0)