diff --git a/client/src/Components/WalletProvider/index.css b/client/src/Components/WalletProvider/index.css
deleted file mode 100644
index f3da31efc..000000000
--- a/client/src/Components/WalletProvider/index.css
+++ /dev/null
@@ -1,53 +0,0 @@
-.wallet-adapter-dropdown {
- width: 100%;
- display: flex;
- flex-wrap: wrap;
- justify-content: center;
- align-items: center;
- gap: var(--env-var-spacing-1);
-}
-
-.wallet-adapter-button {
- display: flex;
- align-items: center;
- justify-content: center;
- width: auto;
- height: var(--env-var-height-2) !important;
- font-size: var(--env-var-font-size-medium-plus) !important;
- font-weight: 500 !important;
- margin: 0;
- padding: calc(
- (var(--env-var-height-2) - var(--env-var-font-size-medium-plus) * 1.2) / 2
- )
- var(--env-var-spacing-1);
- white-space: nowrap;
-}
-
-.wallet-adapter-modal-title {
- font-size: var(--font-size-h5) !important;
-}
-
-/* Separator styling */
-.wallet-adapter-modal-divider {
- background-color: var(--border-color) !important;
- margin: var(--spacing-md) 0 !important;
-}
-
-/* Responsive fixes */
-@media (max-width: 1200px) {
- .wallet-adapter-button {
- font-size: var(--env-var-font-size-medium) !important;
- padding: calc((var(--env-var-height-2) - var(--env-var-font-size-medium) * 1.2) / 2)
- var(--env-var-spacing-1-minus) !important;
- }
-}
-
-@media (max-width: 900px) {
- .wallet-adapter-modal-wrapper {
- flex-direction: column !important;
- }
-
- .wallet-adapter-modal-divider {
- margin: var(--spacing-sm) 0 !important;
- }
-}
diff --git a/client/src/Components/WalletProvider/index.jsx b/client/src/Components/WalletProvider/index.jsx
deleted file mode 100644
index 13cc83b07..000000000
--- a/client/src/Components/WalletProvider/index.jsx
+++ /dev/null
@@ -1,50 +0,0 @@
-// import { useMemo } from "react";
-// import { ConnectionProvider, WalletProvider } from "@solana/wallet-adapter-react";
-// import { WalletAdapterNetwork } from "@solana/wallet-adapter-base";
-// import {
-// UnsafeBurnerWalletAdapter,
-// PhantomWalletAdapter,
-// } from "@solana/wallet-adapter-wallets";
-
-// import { WalletModalProvider } from "@solana/wallet-adapter-react-ui";
-// import { clusterApiUrl } from "@solana/web3.js";
-// import PropTypes from "prop-types";
-// import "./index.css";
-
-// // Default styles that can be overridden by your app
-// import "@solana/wallet-adapter-react-ui/styles.css";
-
-// export const Wallet = ({ children }) => {
-// // The network can be set to 'devnet', 'testnet', or 'mainnet-beta'.
-// const network = WalletAdapterNetwork.Mainnet;
-
-// // You can also provide a custom RPC endpoint.
-// const endpoint = useMemo(() => clusterApiUrl(network), [network]);
-
-// const wallets = useMemo(
-// () => [new PhantomWalletAdapter()],
-// // eslint-disable-next-line react-hooks/exhaustive-deps
-// [network]
-// );
-
-// return (
-//
-//
-// {children}
-//
-//
-// );
-// };
-
-// Wallet.propTypes = {
-// children: PropTypes.node,
-// };
-
-const Wallet = ({ children }) => {
- return children;
-};
-
-export default Wallet;
diff --git a/client/src/Components/v1/Breadcrumbs/index.css b/client/src/Components/v1/Breadcrumbs/index.css
index abb3c0a28..022db9a83 100644
--- a/client/src/Components/v1/Breadcrumbs/index.css
+++ b/client/src/Components/v1/Breadcrumbs/index.css
@@ -6,7 +6,6 @@
min-height: 16px;
}
.MuiBreadcrumbs-root .MuiBreadcrumbs-li a {
- font-size: var(--env-var-font-size-medium);
font-weight: 400;
}
.MuiBreadcrumbs-root .MuiBreadcrumbs-li:not(:last-child) {
diff --git a/client/src/Components/v1/Inputs/Select/index.jsx b/client/src/Components/v1/Inputs/Select/index.jsx
index 0f96a2ff6..ec2522d17 100644
--- a/client/src/Components/v1/Inputs/Select/index.jsx
+++ b/client/src/Components/v1/Inputs/Select/index.jsx
@@ -64,7 +64,6 @@ const Select = ({
const theme = useTheme();
const getItemValue = (item) => item?._id ?? item?.id;
const itemStyles = {
- fontSize: "var(--env-var-font-size-medium)",
color: theme.palette.primary.contrastTextTertiary,
borderRadius: theme.shape.borderRadius,
margin: theme.spacing(2),
diff --git a/client/src/Components/v1/Inputs/TextInput/Adornments/index.jsx b/client/src/Components/v1/Inputs/TextInput/Adornments/index.jsx
index 078684405..2b3abab0f 100644
--- a/client/src/Components/v1/Inputs/TextInput/Adornments/index.jsx
+++ b/client/src/Components/v1/Inputs/TextInput/Adornments/index.jsx
@@ -18,7 +18,6 @@ export const HttpAdornment = ({ https }) => {
>
diff --git a/client/src/Components/v2/design-elements/MonitorStatus.tsx b/client/src/Components/v2/design-elements/MonitorStatus.tsx
index 3d5e81845..09cd95f0f 100644
--- a/client/src/Components/v2/design-elements/MonitorStatus.tsx
+++ b/client/src/Components/v2/design-elements/MonitorStatus.tsx
@@ -23,7 +23,6 @@ export const MonitorStatus = ({ monitor }: { monitor: Monitor }) => {
overflow={"hidden"}
textOverflow={"ellipsis"}
whiteSpace={"nowrap"}
- maxWidth={isSmall ? "100%" : "calc((100vw - var(--env-var-width-2)) / 2)"}
>
{monitor.name}
@@ -40,7 +39,6 @@ export const MonitorStatus = ({ monitor }: { monitor: Monitor }) => {
overflow={"hidden"}
textOverflow={"ellipsis"}
whiteSpace={"nowrap"}
- maxWidth={isSmall ? "100%" : "calc((100vw - var(--env-var-width-2)) / 2)"}
>
{formatUrl(monitor?.url)}
diff --git a/client/src/Components/v2/design-elements/PulseDot.tsx b/client/src/Components/v2/design-elements/PulseDot.tsx
index ab792b628..1f5b3401e 100644
--- a/client/src/Components/v2/design-elements/PulseDot.tsx
+++ b/client/src/Components/v2/design-elements/PulseDot.tsx
@@ -1,4 +1,17 @@
-import { Box, Stack, useTheme } from "@mui/material";
+import Box from "@mui/material/Box";
+import Stack from "@mui/material/Stack";
+import { useTheme, keyframes } from "@mui/material";
+
+const ripple = keyframes`
+ from {
+ opacity: 1;
+ transform: scale(0);
+ }
+ to {
+ opacity: 0;
+ transform: scale(2);
+ }
+`;
interface PulseDotProps {
color: string;
@@ -28,7 +41,7 @@ export const PulseDot = ({ color }: PulseDotProps) => {
height: "100%",
backgroundColor: "inherit",
borderRadius: "50%",
- animation: "ripple 1.8s ease-out infinite",
+ animation: `${ripple} 1.8s ease-out infinite`,
},
"&::after": {
content: `""`,
diff --git a/client/src/Features/UI/uiSlice.js b/client/src/Features/UI/uiSlice.js
deleted file mode 100644
index 0e8ca8608..000000000
--- a/client/src/Features/UI/uiSlice.js
+++ /dev/null
@@ -1,98 +0,0 @@
-import { createSlice } from "@reduxjs/toolkit";
-
-const initialMode = window?.matchMedia?.("(prefers-color-scheme: dark)")?.matches
- ? "dark"
- : "light";
-
-const initialState = {
- monitors: {
- rowsPerPage: 10,
- },
- team: {
- rowsPerPage: 5,
- },
- maintenance: {
- rowsPerPage: 5,
- },
- infrastructure: {
- rowsPerPage: 5,
- },
- logs: {
- rowsPerPage: 15,
- },
- sidebar: {
- collapsed: false,
- },
- mode: initialMode,
- showURL: false,
- greeting: { index: 0, lastUpdate: null },
- timezone: "America/Toronto",
- distributedUptimeEnabled: false,
- language: "en",
- starPromptOpen: true,
- chartType: "histogram",
-};
-
-const uiSlice = createSlice({
- name: "ui",
- initialState,
- reducers: {
- setDistributedUptimeEnabled: (state, action) => {
- state.distributedUptimeEnabled = action.payload;
- },
- setRowsPerPage: (state, action) => {
- const { table, value } = action.payload;
- if (!state[table]) {
- state[table] = {};
- }
- state[table].rowsPerPage = value;
- },
- toggleSidebar: (state) => {
- state.sidebar.collapsed = !state.sidebar.collapsed;
- },
- setCollapsed: (state, action) => {
- const { collapsed } = action.payload;
- state.sidebar.collapsed = collapsed;
- },
- setMode: (state, action) => {
- state.mode = action.payload;
- },
- setShowURL: (state, action) => {
- state.showURL = action.payload;
- },
- setGreeting(state, action) {
- if (!state.greeting) {
- state.greeting = { index: 0, lastUpdate: null };
- }
- state.greeting.index = action.payload.index;
- state.greeting.lastUpdate = action.payload.lastUpdate;
- },
- setTimezone(state, action) {
- state.timezone = action.payload.timezone;
- },
- setLanguage: (state, action) => {
- state.language = action.payload;
- },
- setStarPromptOpen: (state, action) => {
- state.starPromptOpen = action.payload;
- },
- setChartType: (state, action) => {
- state.chartType = action.payload;
- },
- },
-});
-
-export default uiSlice.reducer;
-export const {
- setRowsPerPage,
- toggleSidebar,
- setCollapsed,
- setMode,
- setShowURL,
- setGreeting,
- setTimezone,
- setDistributedUptimeEnabled,
- setLanguage,
- setStarPromptOpen,
- setChartType,
-} = uiSlice.actions;
diff --git a/client/src/Features/UI/uiSlice.ts b/client/src/Features/UI/uiSlice.ts
new file mode 100644
index 000000000..0675784b9
--- /dev/null
+++ b/client/src/Features/UI/uiSlice.ts
@@ -0,0 +1,133 @@
+import { createSlice, type PayloadAction } from "@reduxjs/toolkit";
+
+type ThemeMode = "light" | "dark";
+type ChartType = "histogram" | "line";
+type TableName = "monitors" | "team" | "maintenance" | "infrastructure" | "logs";
+
+interface TableState {
+ rowsPerPage: number;
+}
+
+interface SidebarState {
+ collapsed: boolean;
+}
+
+interface GreetingState {
+ index: number;
+ lastUpdate: string | null;
+}
+
+interface UIState {
+ monitors: TableState;
+ team: TableState;
+ maintenance: TableState;
+ infrastructure: TableState;
+ logs: TableState;
+ sidebar: SidebarState;
+ mode: ThemeMode;
+ showURL: boolean;
+ greeting: GreetingState;
+ timezone: string;
+ distributedUptimeEnabled: boolean;
+ language: string;
+ starPromptOpen: boolean;
+ chartType: ChartType;
+}
+
+const initialMode: ThemeMode = window?.matchMedia?.("(prefers-color-scheme: dark)")
+ ?.matches
+ ? "dark"
+ : "light";
+
+const initialState: UIState = {
+ monitors: {
+ rowsPerPage: 10,
+ },
+ team: {
+ rowsPerPage: 5,
+ },
+ maintenance: {
+ rowsPerPage: 5,
+ },
+ infrastructure: {
+ rowsPerPage: 5,
+ },
+ logs: {
+ rowsPerPage: 15,
+ },
+ sidebar: {
+ collapsed: false,
+ },
+ mode: initialMode,
+ showURL: false,
+ greeting: { index: 0, lastUpdate: null },
+ timezone: "America/Toronto",
+ distributedUptimeEnabled: false,
+ language: "en",
+ starPromptOpen: true,
+ chartType: "histogram",
+};
+
+const uiSlice = createSlice({
+ name: "ui",
+ initialState,
+ reducers: {
+ setDistributedUptimeEnabled: (state, action: PayloadAction) => {
+ state.distributedUptimeEnabled = action.payload;
+ },
+ setRowsPerPage: (
+ state,
+ action: PayloadAction<{ table: TableName; value: number }>
+ ) => {
+ const { table, value } = action.payload;
+ state[table].rowsPerPage = value;
+ },
+ toggleSidebar: (state) => {
+ state.sidebar.collapsed = !state.sidebar.collapsed;
+ },
+ setCollapsed: (state, action: PayloadAction<{ collapsed: boolean }>) => {
+ state.sidebar.collapsed = action.payload.collapsed;
+ },
+ setMode: (state, action: PayloadAction) => {
+ state.mode = action.payload;
+ },
+ setShowURL: (state, action: PayloadAction) => {
+ state.showURL = action.payload;
+ },
+ setGreeting: (
+ state,
+ action: PayloadAction<{ index: number; lastUpdate: string | null }>
+ ) => {
+ state.greeting.index = action.payload.index;
+ state.greeting.lastUpdate = action.payload.lastUpdate;
+ },
+ setTimezone: (state, action: PayloadAction<{ timezone: string }>) => {
+ state.timezone = action.payload.timezone;
+ },
+ setLanguage: (state, action: PayloadAction) => {
+ state.language = action.payload;
+ },
+ setStarPromptOpen: (state, action: PayloadAction) => {
+ state.starPromptOpen = action.payload;
+ },
+ setChartType: (state, action: PayloadAction) => {
+ state.chartType = action.payload;
+ },
+ },
+});
+
+export type { UIState, ThemeMode, ChartType, TableName };
+export default uiSlice.reducer;
+export const {
+ setRowsPerPage,
+ toggleSidebar,
+ setCollapsed,
+ setMode,
+ setShowURL,
+ setGreeting,
+ setTimezone,
+ setDistributedUptimeEnabled,
+ setLanguage,
+ setStarPromptOpen,
+ setChartType,
+} = uiSlice.actions;
diff --git a/client/src/Pages/Integrations/index.css b/client/src/Pages/Integrations/index.css
deleted file mode 100644
index 29969577a..000000000
--- a/client/src/Pages/Integrations/index.css
+++ /dev/null
@@ -1,10 +0,0 @@
-.integrations h1.MuiTypography-root {
- font-size: var(--env-var-font-size-large);
- font-weight: 600;
-}
-.integrations p.MuiTypography-root {
- font-size: var(--env-var-font-size-medium);
-}
-.integrations button {
- height: var(--env-var-height-2);
-}
diff --git a/client/src/Pages/Integrations/index.jsx b/client/src/Pages/Integrations/index.jsx
deleted file mode 100644
index dde6b52ee..000000000
--- a/client/src/Pages/Integrations/index.jsx
+++ /dev/null
@@ -1,156 +0,0 @@
-import PropTypes from "prop-types";
-import { Stack, Typography, Grid, Button } from "@mui/material";
-import { useTheme } from "@emotion/react";
-import Discord from "../../../assets/icons/discord-icon.svg?react";
-import Slack from "../../../assets/icons/slack-icon.svg?react";
-import Zapier from "../../../assets/icons/zapier-icon.svg?react";
-import { useTranslation } from "react-i18next";
-
-import "./index.css";
-
-/**
- * Integrations component
- * @param {Object} props - Props for the IntegrationsComponent.
- * @param {string} props.icon - The icon for the integration image.
- * @param {string} props.header - The header for the integration.
- * @param {string} props.info - Information about the integration.
- * @param {Function} props.onClick - The onClick handler for the integration button.
- * @returns {JSX.Element} The JSX representation of the IntegrationsComponent.
- */
-const IntegrationsComponent = ({ icon, header, info, onClick }) => {
- const theme = useTheme();
- const { t } = useTranslation();
-
- return (
-
-
- {icon}
-
- {header}
-
- {info}
-
-
-
-
-
- );
-};
-
-// PropTypes for IntegrationsComponent
-IntegrationsComponent.propTypes = {
- icon: PropTypes.object.isRequired,
- header: PropTypes.string.isRequired,
- info: PropTypes.string.isRequired,
- onClick: PropTypes.func.isRequired,
-};
-
-/**
- * Integrations Page Component
- * @returns {JSX.Element} The JSX representation of the Integrations page.
- */
-
-const Integrations = () => {
- const theme = useTheme();
- const { t } = useTranslation();
-
- const integrations = [
- {
- icon: (
-
- ),
- header: t("integrationsSlack"),
- info: t("integrationsSlackInfo"),
- onClick: () => {},
- },
- {
- icon: (
-
- ),
- header: t("integrationsDiscord"),
- info: t("integrationsDiscordInfo"),
- onClick: () => {},
- },
- {
- icon: (
-
- ),
- header: t("integrationsZapier"),
- info: t("integrationsZapierInfo"),
- onClick: () => {},
- },
- // Add more integrations as needed
- ];
-
- return (
-
- {t("integrations")}
- {t("integrationsPrism")}
-
- {integrations.map((integration, index) => (
-
- ))}
-
-
- );
-};
-
-export default Integrations;
diff --git a/client/src/Pages/Settings/index.jsx b/client/src/Pages/Settings/index.jsx
index fb6185784..6e6574963 100644
--- a/client/src/Pages/Settings/index.jsx
+++ b/client/src/Pages/Settings/index.jsx
@@ -27,7 +27,7 @@ import {
import SettingsStats from "./SettingsStats.jsx";
import { useIsAdmin } from "@/Hooks/useIsAdmin.js";
-import { useGet, usePost, useDelete, useLazyGet, usePut } from "@/Hooks/UseApi";
+import { useGet, usePost, useDelete, useLazyGet, usePatch } from "@/Hooks/UseApi";
// Constants
const BREADCRUMBS = [{ name: `Settings`, path: "/settings" }];
@@ -62,10 +62,10 @@ const Settings = () => {
}
}, [fetchedSettings]);
- const { put: saveSettingsFn, loading: isSaving } = usePut();
+ const { patch: saveSettingsFn, loading: isSaving } = usePatch();
const saveSettings = async (settings) => {
- const response = await saveSettingsFn("/settings", { settings });
+ const response = await saveSettingsFn("/settings", settings);
if (response?.data) {
const data = response.data;
setIsApiKeySet(data.pagespeedKeySet);
diff --git a/client/src/Utils/Theme/globalTheme.js b/client/src/Utils/Theme/globalTheme.js
index 37143d730..98f3479be 100644
--- a/client/src/Utils/Theme/globalTheme.js
+++ b/client/src/Utils/Theme/globalTheme.js
@@ -38,7 +38,6 @@ const baseTheme = (palette) => ({
fontWeight: 400,
},
label: {
- fontSize: "var(--env-var-font-size-medium)",
color: palette.primary.contrastTextSecondary,
fontWeight: 500,
},
@@ -332,8 +331,6 @@ const baseTheme = (palette) => ({
"& .MuiInputBase-input": {
padding: ".75em",
- minHeight: "var(--env-var-height-2)",
- fontSize: "var(--env-var-font-size-medium)",
fontWeight: 400,
color: palette.primary.contrastTextSecondary,
"&.Mui-disabled": {
@@ -368,13 +365,12 @@ const baseTheme = (palette) => ({
"& .MuiFormHelperText-root": {
color: palette.error.main,
opacity: 0.8,
- fontSize: "var(--env-var-font-size-medium)",
+ fontSize: "var()",
marginLeft: 0,
},
"& .MuiFormHelperText-root.Mui-error": {
opacity: 0.8,
- fontSize: "var(--env-var-font-size-medium)",
color: palette.error.main,
whiteSpace: "nowrap",
},
@@ -762,7 +758,6 @@ const baseTheme = (palette) => ({
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
- maxWidth: "calc((100vw - var(--env-var-width-2)) / 2)",
},
},
{
@@ -775,7 +770,6 @@ const baseTheme = (palette) => ({
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
- maxWidth: "calc((100vw - var(--env-var-width-2)) / 2)",
},
},
],
diff --git a/client/src/Utils/Theme/v2Theme.ts b/client/src/Utils/Theme/v2Theme.ts
index 57ca76669..39ede6c7e 100644
--- a/client/src/Utils/Theme/v2Theme.ts
+++ b/client/src/Utils/Theme/v2Theme.ts
@@ -49,6 +49,13 @@ export const theme = (mode: string, palette: any) =>
},
components: {
+ MuiTouchRipple: {
+ styleOverrides: {
+ root: {
+ display: "none",
+ },
+ },
+ },
MuiButtonBase: {
defaultProps: {
disableRipple: true,
diff --git a/client/src/index.css b/client/src/index.css
index 48737d4bb..a662ef475 100644
--- a/client/src/index.css
+++ b/client/src/index.css
@@ -18,70 +18,4 @@ html {
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-
- /* Generalized Stylings */
- --env-var-radius-2: 8px;
-
- --env-var-width-2: 360px;
- --env-var-width-4: 100px;
-
- --env-var-height-2: 34px;
-
- --env-var-nav-bar-height: 70px;
- --env-var-side-bar-width: 250px;
- --env-var-side-bar-collapsed-width: 64px;
- --env-var-side-bar-auth-footer-height: 50px;
-
- --env-var-spacing-1: 12px;
- --env-var-spacing-1-plus: 16px;
- --env-var-spacing-1-minus: 10px;
- --env-var-spacing-2: 24px;
-
- --env-var-font-size-small: 11px;
- --env-var-font-size-small-plus: 12px;
- --env-var-font-size-medium: 13px;
- --env-var-font-size-medium-plus: 14px;
- --env-var-font-size-large: 16px;
- --env-var-font-size-large-plus: 22px;
- --env-var-font-size-xlarge: 30px;
-}
-
-.MuiInputBase-root.Mui-disabled input {
- cursor: not-allowed;
-}
-
-/* .Toastify__toast-container {
- min-width: 300px;
- width: auto;
-}
-.Toastify__toast-body .alert {
- min-width: 150px;
- padding: 5px 10px;
- align-items: center;
-}
-.Toastify [class^="Toastify__toast"] {
- padding: 0;
- margin: 0;
-}
-.Toastify__toast {
- min-height: 0;
- border-radius: 4px;
-}
-.Toastify [class*="Toastify__toast-theme"] {
- background-color: transparent;
-} */
-
-.MuiTouchRipple-root {
- display: none;
-}
-
-@keyframes ripple {
- from {
- opacity: 1;
- transform: scale(0);
- }
- to {
- opacity: 0;
- transform: scale(2);
- }
}
diff --git a/client/src/main.tsx b/client/src/main.tsx
index 813a839bd..1e339f87b 100644
--- a/client/src/main.tsx
+++ b/client/src/main.tsx
@@ -3,7 +3,7 @@ import App from "./App.jsx";
import "./index.css";
import { BrowserRouter as Router } from "react-router-dom";
import { Provider } from "react-redux";
-import { persistor, store } from "./store.js";
+import { persistor, store } from "@/store.js";
import { PersistGate } from "redux-persist/integration/react";
import I18nLoader from "./Components/v1/I18nLoader/index.jsx";
import { initApiClient } from "./Utils/ApiClient.js";
diff --git a/client/src/store.js b/client/src/store.ts
similarity index 59%
rename from client/src/store.js
rename to client/src/store.ts
index 69aa3d50b..9e064b55f 100644
--- a/client/src/store.js
+++ b/client/src/store.ts
@@ -1,18 +1,21 @@
import { configureStore, combineReducers } from "@reduxjs/toolkit";
-
-import authReducer from "./Features/Auth/authSlice";
-import uiReducer from "./Features/UI/uiSlice";
+import authReducer from "@/Features/Auth/authSlice";
+import uiReducer from "@/Features/UI/uiSlice";
import storage from "redux-persist/lib/storage";
-import { persistReducer, persistStore, createTransform } from "redux-persist";
+import {
+ persistReducer,
+ persistStore,
+ createTransform,
+ PERSIST,
+ REHYDRATE,
+} from "redux-persist";
const authTransform = createTransform(
- (inboundState) => {
+ (inboundState: Record) => {
const { profileImage, ...rest } = inboundState;
return rest;
},
- // No transformation on rehydration
- null,
- // Only applies to auth
+ undefined,
{ whitelist: ["auth"] }
);
@@ -28,6 +31,7 @@ const rootReducer = combineReducers({
ui: uiReducer,
});
+// @ts-expect-error - redux-persist types don't align perfectly with redux-toolkit
const persistedReducer = persistReducer(persistConfig, rootReducer);
export const store = configureStore({
@@ -35,10 +39,13 @@ export const store = configureStore({
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
- ignoredActions: ["persist/PERSIST", "persist/REHYDRATE", "persist/REGISTER"],
+ ignoredActions: [PERSIST, REHYDRATE, "persist/REGISTER"],
},
}),
});
+export type RootState = ReturnType;
+export type AppDispatch = typeof store.dispatch;
+
export const persistor = persistStore(store);
export default store;
diff --git a/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts b/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts
index d5d275e59..6cd1a7675 100644
--- a/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts
+++ b/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts
@@ -89,7 +89,6 @@ class SuperSimpleQueueHelper {
// Step 4 Add check to buffer
this.buffer.addToBuffer({ check });
-
// Step 4. Update monitor status
const statusChangeResult = await this.statusService.updateMonitorStatus(status, check);
diff --git a/server/src/service/infrastructure/statusService.ts b/server/src/service/infrastructure/statusService.ts
index 506ad5396..284fd3ff7 100755
--- a/server/src/service/infrastructure/statusService.ts
+++ b/server/src/service/infrastructure/statusService.ts
@@ -3,6 +3,7 @@ import MonitorStats from "../../db/models/MonitorStats.js";
import { CheckModel } from "@/db/models/index.js";
import type {
Monitor,
+ MonitorStatus,
MonitorStatusResponse,
StatusChangeResult,
Check,
@@ -200,14 +201,13 @@ export class StatusService implements IStatusService {
monitor.recentChecks.shift();
}
- monitor.status = status === true ? "up" : "down";
-
const prevStatus = monitor.status;
- let newStatus = monitor.status;
+ let newStatus: MonitorStatus = status === true ? "up" : "down";
let statusChanged = false;
// Return early if not enough data points
if (monitor.statusWindow.length < monitor.statusWindowSize) {
+ monitor.status = newStatus;
const updated = await this.monitorsRepository.updateById(monitor.id, monitor.teamId, monitor);
return {
monitor: updated,