Merge pull request #3275 from bluewave-labs/fix/ts

Fix/ts
This commit is contained in:
Alexander Holliday
2026-02-12 10:32:22 -08:00
committed by GitHub
4 changed files with 150 additions and 108 deletions
-98
View File
@@ -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;
+133
View File
@@ -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<boolean>) => {
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<ThemeMode>) => {
state.mode = action.payload;
},
setShowURL: (state, action: PayloadAction<boolean>) => {
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<string>) => {
state.language = action.payload;
},
setStarPromptOpen: (state, action: PayloadAction<boolean>) => {
state.starPromptOpen = action.payload;
},
setChartType: (state, action: PayloadAction<ChartType>) => {
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;
+1 -1
View File
@@ -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";
+16 -9
View File
@@ -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<string, unknown>) => {
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<typeof rootReducer>;
export type AppDispatch = typeof store.dispatch;
export const persistor = persistStore(store);
export default store;