Skip to content

Commit 42a0c9a

Browse files
committed
refactor: Replace NotificationContext with useNotificationStore for improved state management (fixes #290, resolves #292).
1 parent 69d59c9 commit 42a0c9a

File tree

12 files changed

+79
-139
lines changed

12 files changed

+79
-139
lines changed

src/App.tsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import AppController from "./components/AppController";
22
import Layout from "./components/Layout";
3-
import NotificationContextProvider from "./contexts/NotificationContextProvider";
43
import UrlContextProvider from "./contexts/UrlContextProvider";
54

65

@@ -11,13 +10,11 @@ import UrlContextProvider from "./contexts/UrlContextProvider";
1110
*/
1211
const App = () => {
1312
return (
14-
<NotificationContextProvider>
15-
<UrlContextProvider>
16-
<AppController>
17-
<Layout/>
18-
</AppController>
19-
</UrlContextProvider>
20-
</NotificationContextProvider>
13+
<UrlContextProvider>
14+
<AppController>
15+
<Layout/>
16+
</AppController>
17+
</UrlContextProvider>
2118
);
2219
};
2320

src/components/AppController.tsx

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import React, {
44
useRef,
55
} from "react";
66

7-
import {NotificationContext} from "../contexts/NotificationContextProvider";
87
import {
98
updateWindowUrlHashParams,
109
URL_HASH_PARAMS_DEFAULT,
@@ -14,6 +13,7 @@ import {
1413
import useContextStore from "../stores/contextStore";
1514
import useLogFileManagerStore from "../stores/logFileManagerProxyStore";
1615
import useLogFileStore from "../stores/logFileStore";
16+
import useNotificationStore from "../stores/notificationStore";
1717
import useUiStore from "../stores/uiStore";
1818
import useViewStore from "../stores/viewStore";
1919
import {LOG_LEVEL} from "../typings/logs";
@@ -80,15 +80,14 @@ interface AppControllerProps {
8080
* @return
8181
*/
8282
const AppController = ({children}: AppControllerProps) => {
83-
const {postPopUp} = useContext(NotificationContext);
8483
const {filePath, isPrettified, logEventNum} = useContext(UrlContext);
8584

8685
// States
8786
const setLogEventNum = useContextStore((state) => state.setLogEventNum);
88-
const setPostPopUp = useContextStore((state) => state.setPostPopUp);
8987
const logFileManagerProxy = useLogFileManagerStore((state) => state.logFileManagerProxy);
9088
const loadFile = useLogFileStore((state) => state.loadFile);
9189
const numEvents = useLogFileStore((state) => state.numEvents);
90+
const postPopUp = useNotificationStore((state) => state.postPopUp);
9291
const beginLineNumToLogEventNum = useViewStore((state) => state.beginLineNumToLogEventNum);
9392
const setIsPrettified = useViewStore((state) => state.updateIsPrettified);
9493
const updatePageData = useViewStore((state) => state.updatePageData);
@@ -180,13 +179,6 @@ const AppController = ({children}: AppControllerProps) => {
180179
loadFile,
181180
]);
182181

183-
useEffect(() => {
184-
setPostPopUp(postPopUp);
185-
}, [
186-
postPopUp,
187-
setPostPopUp,
188-
]);
189-
190182
return children;
191183
};
192184

src/components/CentralContainer/Sidebar/SidebarTabs/SettingsTabPanel/index.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
import React, {
2-
useCallback,
3-
useContext,
4-
} from "react";
1+
import React, {useCallback} from "react";
52

63
import {
74
Box,
@@ -15,7 +12,7 @@ import {
1512
Textarea,
1613
} from "@mui/joy";
1714

18-
import {NotificationContext} from "../../../../../contexts/NotificationContextProvider";
15+
import useNotificationStore from "../../../../../stores/notificationStore";
1916
import useViewStore from "../../../../../stores/viewStore";
2017
import {Nullable} from "../../../../../typings/common";
2118
import {
@@ -138,7 +135,7 @@ const handleConfigFormReset = (ev: React.FormEvent) => {
138135
* @return
139136
*/
140137
const SettingsTabPanel = () => {
141-
const {postPopUp} = useContext(NotificationContext);
138+
const postPopUp = useNotificationStore((state) => state.postPopUp);
142139
const loadPageByAction = useViewStore((state) => state.loadPageByAction);
143140

144141
const handleConfigFormSubmit = useCallback((ev: React.FormEvent) => {

src/components/PopUps/PopUpMessageBox.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React, {
2-
useContext,
32
useEffect,
43
useRef,
54
useState,
@@ -16,10 +15,7 @@ import {
1615

1716
import CloseIcon from "@mui/icons-material/Close";
1817

19-
import {
20-
NotificationContext,
21-
PopUpMessage,
22-
} from "../../contexts/NotificationContextProvider";
18+
import useNotificationStore, {PopUpMessage} from "../../stores/notificationStore";
2319
import {WithId} from "../../typings/common";
2420
import {LOG_LEVEL} from "../../typings/logs";
2521
import {DO_NOT_TIMEOUT_VALUE} from "../../typings/notifications";
@@ -43,7 +39,8 @@ interface PopUpMessageProps {
4339
const PopUpMessageBox = ({message}: PopUpMessageProps) => {
4440
const {id, level, primaryAction, message: messageStr, title, timeoutMillis} = message;
4541

46-
const {handlePopUpMessageClose} = useContext(NotificationContext);
42+
const handlePopUpMessageClose = useNotificationStore((state) => state.handlePopUpMessageClose);
43+
4744
const [percentRemaining, setPercentRemaining] = useState<number>(100);
4845
const intervalCountRef = useRef<number>(0);
4946

src/components/PopUps/index.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
import {useContext} from "react";
2-
31
import {
42
Snackbar,
53
Stack,
64
} from "@mui/joy";
75

8-
import {NotificationContext} from "../../contexts/NotificationContextProvider";
6+
import useNotificationStore from "../../stores/notificationStore";
97
import PopUpMessageBox from "./PopUpMessageBox";
108

119
import "./index.css";
@@ -17,7 +15,7 @@ import "./index.css";
1715
* @return
1816
*/
1917
const PopUps = () => {
20-
const {popUpMessages} = useContext(NotificationContext);
18+
const popUpMessages = useNotificationStore((state) => state.popUpMessages);
2119

2220
return (
2321
<Snackbar

src/contexts/NotificationContextProvider.tsx

Lines changed: 0 additions & 86 deletions
This file was deleted.

src/stores/contextStore.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,25 @@
11
import {create} from "zustand";
22

3-
import {PopUpMessage} from "../typings/notifications";
4-
53

64
interface ContextValues {
75
logEventNum: number;
8-
postPopUp: (message: PopUpMessage) => void;
96
}
107

118
interface ContextActions {
129
setLogEventNum: (newLogEventNum: number) => void;
13-
setPostPopUp: (postPopUp: (message: PopUpMessage) => void) => void;
1410
}
1511

1612
type ContextState = ContextValues & ContextActions;
1713

1814
const CONTEXT_STORE_DEFAULT: ContextValues = {
1915
logEventNum: 0,
20-
postPopUp: () => {
21-
},
2216
};
2317

2418
const useContextStore = create<ContextState>((set) => ({
2519
...CONTEXT_STORE_DEFAULT,
2620
setLogEventNum: (newLogEventNum) => {
2721
set({logEventNum: newLogEventNum});
2822
},
29-
setPostPopUp: (postPopUp) => {
30-
set({postPopUp});
31-
},
3223
}));
3324

3425
export default useContextStore;

src/stores/logExportStore.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import {Nullable} from "../typings/common";
55
import {LOG_LEVEL} from "../typings/logs";
66
import {DO_NOT_TIMEOUT_VALUE} from "../typings/notifications";
77
import {EXPORT_LOGS_CHUNK_SIZE} from "../utils/config";
8-
import useContextStore from "./contextStore";
98
import useLogFileManagerProxyStore from "./logFileManagerProxyStore";
109
import useLogFileStore from "./logFileStore";
10+
import useNotificationStore from "./notificationStore";
1111

1212

1313
interface LogExportValues {
@@ -50,7 +50,7 @@ const useLogExportStore = create<LogExportState>((set) => ({
5050
})().catch((e: unknown) => {
5151
console.error(e);
5252

53-
const {postPopUp} = useContextStore.getState();
53+
const {postPopUp} = useNotificationStore.getState();
5454
postPopUp({
5555
level: LOG_LEVEL.ERROR,
5656
message: String(e),

src/stores/logFileStore.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ import {
2222
FileSrcType,
2323
} from "../typings/worker";
2424
import {getConfig} from "../utils/config";
25-
import useContextStore from "./contextStore";
2625
import useLogExportStore, {LOG_EXPORT_STORE_DEFAULT} from "./logExportStore";
2726
import useLogFileManagerProxyStore from "./logFileManagerProxyStore";
27+
import useNotificationStore from "./notificationStore";
2828
import useQueryStore from "./queryStore";
2929
import useUiStore from "./uiStore";
30-
import useViewStore from "./viewStore";
30+
import useViewStore, {VIEW_STORE_DEFAULT} from "./viewStore";
3131

3232

3333
interface LogFileValues {
@@ -122,7 +122,7 @@ const useLogFileStore = create<LogFileState>((set, get) => ({
122122
updateWindowUrlSearchParams({[SEARCH_PARAM_NAMES.FILE_PATH]: null});
123123
}
124124

125-
const {postPopUp} = useContextStore.getState();
125+
const {postPopUp} = useNotificationStore.getState();
126126
(async () => {
127127
const {logFileManagerProxy} = useLogFileManagerProxyStore.getState();
128128
const decoderOptions = getConfig(CONFIG_KEY.DECODER_OPTIONS);
@@ -157,6 +157,8 @@ const useLogFileStore = create<LogFileState>((set, get) => ({
157157
title: "Action failed",
158158
});
159159
setUiState(UI_STATE.UNOPENED);
160+
setFileName(LOG_FILE_STORE_DEFAULT.fileName);
161+
setLogData(VIEW_STORE_DEFAULT.logData);
160162
});
161163
},
162164
setFileName: (newFileName) => {

src/stores/notificationStore.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import {create} from "zustand";
2+
3+
import {WithId} from "../typings/common";
4+
import {PopUpMessage} from "../typings/notifications";
5+
6+
7+
interface NotificationValues {
8+
popUpMessages: WithId<PopUpMessage>[];
9+
}
10+
11+
interface NotificationActions {
12+
handlePopUpMessageClose: (messageId: number) => void;
13+
postPopUp: (message: PopUpMessage) => void;
14+
}
15+
16+
type NotificationState = NotificationValues & NotificationActions;
17+
18+
const NOTIFICATION_STORE_DEFAULT: NotificationValues = {
19+
popUpMessages: [],
20+
};
21+
22+
let nextPopUpMessageId = 0;
23+
24+
const useNotificationStore = create<NotificationState>((set) => ({
25+
...NOTIFICATION_STORE_DEFAULT,
26+
27+
handlePopUpMessageClose: (messageId: number) => {
28+
set((state) => ({
29+
popUpMessages: state.popUpMessages.filter((m) => m.id !== messageId),
30+
}));
31+
},
32+
33+
postPopUp: (message: PopUpMessage) => {
34+
const newMessage = {
35+
id: nextPopUpMessageId,
36+
...message,
37+
};
38+
39+
nextPopUpMessageId++;
40+
41+
set((state) => ({
42+
popUpMessages: [
43+
newMessage,
44+
...state.popUpMessages,
45+
],
46+
}));
47+
},
48+
}));
49+
50+
export type {PopUpMessage};
51+
export default useNotificationStore;

src/stores/queryStore/createQueryControllerSlice.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import {StateCreator} from "zustand";
22

33
import {LOG_LEVEL} from "../../typings/logs";
44
import {DO_NOT_TIMEOUT_VALUE} from "../../typings/notifications";
5-
import useContextStore from "../contextStore";
65
import useLogFileManagerStore from "../logFileManagerProxyStore";
6+
import useNotificationStore from "../notificationStore";
77
import {QUERY_RESULTS_DEFAULT} from "./createQueryResultsSlice";
88
import {QUERY_CONFIG_DEFAULT} from "./queryConfigSlice";
99
import {
@@ -54,7 +54,7 @@ const createQueryControllerSlice: StateCreator<
5454
})().catch((e: unknown) => {
5555
console.error(e);
5656

57-
const {postPopUp} = useContextStore.getState();
57+
const {postPopUp} = useNotificationStore.getState();
5858
postPopUp({
5959
level: LOG_LEVEL.ERROR,
6060
message: String(e),

0 commit comments

Comments
 (0)