diff --git a/package.json b/package.json
index 5acccfb9..3ad4baa9 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,7 @@
"@mantine/hooks": "^7.8.1",
"@mantine/notifications": "^7.8.1",
"@monaco-editor/react": "^4.5.1",
+ "@reduxjs/toolkit": "^2.5.0",
"@tabler/icons-react": "^3.3.0",
"@types/js-cookie": "^3.0.3",
"axios": "^1.4.0",
@@ -52,6 +53,7 @@
"react-grid-layout": "^1.4.4",
"react-query": "^3.39.3",
"react-querybuilder": "^6.5.5",
+ "react-redux": "^9.2.0",
"react-resizable": "^3.0.5",
"react-resizable-panels": "^0.0.53",
"react-router-dom": "^6.14.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index de73e0f8..6d99ddf1 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -41,6 +41,9 @@ importers:
'@monaco-editor/react':
specifier: ^4.5.1
version: 4.5.1(monaco-editor@0.48.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ '@reduxjs/toolkit':
+ specifier: ^2.5.0
+ version: 2.5.0(react-redux@9.2.0(@types/react@18.2.14)(react@18.2.0)(redux@5.0.1))(react@18.2.0)
'@tabler/icons-react':
specifier: ^3.3.0
version: 3.3.0(react@18.2.0)
@@ -119,6 +122,9 @@ importers:
react-querybuilder:
specifier: ^6.5.5
version: 6.5.5(react@18.2.0)
+ react-redux:
+ specifier: ^9.2.0
+ version: 9.2.0(@types/react@18.2.14)(react@18.2.0)(redux@5.0.1)
react-resizable:
specifier: ^3.0.5
version: 3.0.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
@@ -598,6 +604,17 @@ packages:
'@protobufjs/utf8@1.1.0':
resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==}
+ '@reduxjs/toolkit@2.5.0':
+ resolution: {integrity: sha512-awNe2oTodsZ6LmRqmkFhtb/KH03hUhxOamEQy411m3Njj3BbFvoBovxo4Q1cBWnV1ErprVj9MlF0UPXkng0eyg==}
+ peerDependencies:
+ react: ^16.9.0 || ^17.0.0 || ^18 || ^19
+ react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0
+ peerDependenciesMeta:
+ react:
+ optional: true
+ react-redux:
+ optional: true
+
'@remix-run/router@1.7.0':
resolution: {integrity: sha512-Eu1V3kz3mV0wUpVTiFHuaT8UD1gj/0VnoFHQYX35xlslQUpe8CuYoKFn9d4WZFHm3yDywz6ALZuGdnUPKrNeAw==}
engines: {node: '>=14'}
@@ -799,6 +816,9 @@ packages:
'@types/semver@7.5.0':
resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==}
+ '@types/use-sync-external-store@0.0.6':
+ resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==}
+
'@typescript-eslint/eslint-plugin@5.60.1':
resolution: {integrity: sha512-KSWsVvsJsLJv3c4e73y/Bzt7OpqMCADUO846bHcuWYSYM19bldbAeDv7dYyV0jwkbMfJ2XdlzwjhXtuD7OY6bw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -2077,6 +2097,18 @@ packages:
react-native:
optional: true
+ react-redux@9.2.0:
+ resolution: {integrity: sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==}
+ peerDependencies:
+ '@types/react': ^18.2.25 || ^19
+ react: ^18.0 || ^19
+ redux: ^5.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ redux:
+ optional: true
+
react-remove-scroll-bar@2.3.4:
resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==}
engines: {node: '>=10'}
@@ -2170,9 +2202,17 @@ packages:
react: ^16.0.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0
+ redux-thunk@3.1.0:
+ resolution: {integrity: sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==}
+ peerDependencies:
+ redux: ^5.0.0
+
redux@4.2.1:
resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==}
+ redux@5.0.1:
+ resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==}
+
regenerator-runtime@0.13.11:
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
@@ -2190,6 +2230,9 @@ packages:
resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==}
engines: {node: '>=0.10'}
+ reselect@5.1.1:
+ resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==}
+
resize-observer-polyfill@1.5.1:
resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==}
@@ -2450,6 +2493,11 @@ packages:
'@types/react':
optional: true
+ use-sync-external-store@1.4.0:
+ resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
@@ -2886,6 +2934,16 @@ snapshots:
'@protobufjs/utf8@1.1.0': {}
+ '@reduxjs/toolkit@2.5.0(react-redux@9.2.0(@types/react@18.2.14)(react@18.2.0)(redux@5.0.1))(react@18.2.0)':
+ dependencies:
+ immer: 10.0.3
+ redux: 5.0.1
+ redux-thunk: 3.1.0(redux@5.0.1)
+ reselect: 5.1.1
+ optionalDependencies:
+ react: 18.2.0
+ react-redux: 9.2.0(@types/react@18.2.14)(react@18.2.0)(redux@5.0.1)
+
'@remix-run/router@1.7.0': {}
'@swc/core-darwin-arm64@1.3.67':
@@ -3050,6 +3108,8 @@ snapshots:
'@types/semver@7.5.0': {}
+ '@types/use-sync-external-store@0.0.6': {}
+
'@typescript-eslint/eslint-plugin@5.60.1(@typescript-eslint/parser@5.60.1(eslint@8.43.0)(typescript@5.1.6))(eslint@8.43.0)(typescript@5.1.6)':
dependencies:
'@eslint-community/regexpp': 4.5.1
@@ -4446,6 +4506,15 @@ snapshots:
optionalDependencies:
react-dom: 18.2.0(react@18.2.0)
+ react-redux@9.2.0(@types/react@18.2.14)(react@18.2.0)(redux@5.0.1):
+ dependencies:
+ '@types/use-sync-external-store': 0.0.6
+ react: 18.2.0
+ use-sync-external-store: 1.4.0(react@18.2.0)
+ optionalDependencies:
+ '@types/react': 18.2.14
+ redux: 5.0.1
+
react-remove-scroll-bar@2.3.4(@types/react@18.2.14)(react@18.2.0):
dependencies:
react: 18.2.0
@@ -4553,10 +4622,16 @@ snapshots:
tiny-invariant: 1.3.3
victory-vendor: 36.9.2
+ redux-thunk@3.1.0(redux@5.0.1):
+ dependencies:
+ redux: 5.0.1
+
redux@4.2.1:
dependencies:
'@babel/runtime': 7.21.5
+ redux@5.0.1: {}
+
regenerator-runtime@0.13.11: {}
regexp.prototype.flags@1.5.0:
@@ -4571,6 +4646,8 @@ snapshots:
repeat-string@1.6.1: {}
+ reselect@5.1.1: {}
+
resize-observer-polyfill@1.5.1: {}
resolve-from@4.0.0: {}
@@ -4814,6 +4891,10 @@ snapshots:
optionalDependencies:
'@types/react': 18.2.14
+ use-sync-external-store@1.4.0(react@18.2.0):
+ dependencies:
+ react: 18.2.0
+
util-deprecate@1.0.2: {}
utrie@1.0.2:
diff --git a/src/main.tsx b/src/main.tsx
index f6191e65..b63d724e 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -13,6 +13,8 @@ import Mantine from '@/components/Mantine';
import { BrowserRouter } from 'react-router-dom';
import ErrorBoundary from './components/ErrorBoundary';
import { QueryClient, QueryClientProvider } from 'react-query';
+import { Provider } from 'react-redux';
+import { store } from './store';
const queryClient = new QueryClient();
@@ -21,7 +23,9 @@ ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
-
+
+
+
diff --git a/src/store/alertsSlice.ts b/src/store/alertsSlice.ts
new file mode 100644
index 00000000..0ada7073
--- /dev/null
+++ b/src/store/alertsSlice.ts
@@ -0,0 +1,16 @@
+import { createSlice } from '@reduxjs/toolkit';
+
+const alertsSlice = createSlice({
+ name: 'alerts',
+ initialState: {
+ alertsList: [{}],
+ },
+ reducers: {
+ pushAlert(state, action) {
+ state.alertsList.push(action.payload);
+ },
+ },
+});
+
+export const { pushAlert } = alertsSlice.actions;
+export const alertsReducer = alertsSlice.reducer;
diff --git a/src/store/index.ts b/src/store/index.ts
new file mode 100644
index 00000000..f3cb316a
--- /dev/null
+++ b/src/store/index.ts
@@ -0,0 +1,13 @@
+import { configureStore } from '@reduxjs/toolkit';
+import { alertsReducer, pushAlert } from './alertsSlice';
+
+export const store = configureStore({
+ reducer: {
+ alerts: alertsReducer,
+ },
+});
+
+export { pushAlert };
+
+export type RootState = ReturnType;
+export type AppDispatch = typeof store.dispatch;