feat(dashboard): add code refactors
This commit is contained in:
3 files changed
+44
-22
No files matched your search
@@ -2,6 +2,10 @@ import { createSlice, type PayloadAction } from "@reduxjs/toolkit";
|
||||
|
||||
type ThemeMode = "light" | "dark";
|
||||
type ChartType = "histogram" | "line";
|
||||
|
||||
export const dashboardCardKeys = ["monitorStatus", "monitorsByType"] as const;
|
||||
export type DashboardCardKey = (typeof dashboardCardKeys)[number];
|
||||
|
||||
type TableName =
|
||||
| "monitors"
|
||||
| "team"
|
||||
@@ -35,6 +39,7 @@ interface UIState {
|
||||
language: string;
|
||||
starPromptOpen: boolean;
|
||||
chartType: ChartType;
|
||||
dashboardVisibleCards: DashboardCardKey[];
|
||||
}
|
||||
|
||||
const initialMode: ThemeMode = window?.matchMedia?.("(prefers-color-scheme: dark)")
|
||||
@@ -74,6 +79,7 @@ const initialState: UIState = {
|
||||
language: "en",
|
||||
starPromptOpen: true,
|
||||
chartType: "histogram",
|
||||
dashboardVisibleCards: [...dashboardCardKeys],
|
||||
};
|
||||
|
||||
const uiSlice = createSlice({
|
||||
@@ -117,6 +123,9 @@ const uiSlice = createSlice({
|
||||
setChartType: (state, action: PayloadAction<ChartType>) => {
|
||||
state.chartType = action.payload;
|
||||
},
|
||||
setDashboardVisibleCards: (state, action: PayloadAction<DashboardCardKey[]>) => {
|
||||
state.dashboardVisibleCards = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -133,4 +142,5 @@ export const {
|
||||
setLanguage,
|
||||
setStarPromptOpen,
|
||||
setChartType,
|
||||
setDashboardVisibleCards,
|
||||
} = uiSlice.actions;
|
||||
@@ -1,10 +1,11 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { useState } from "react";
|
||||
import Stack from "@mui/material/Stack";
|
||||
import FormControlLabel from "@mui/material/FormControlLabel";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Checkbox, Dialog } from "@/Components/inputs";
|
||||
import { type DashboardCardKey, dashboardCardKeys } from "@/Features/UI/uiSlice";
|
||||
|
||||
export type DashboardCardKey = "monitorStatus" | "monitorsByType";
|
||||
export type { DashboardCardKey };
|
||||
|
||||
interface EditCardsModalProps {
|
||||
open: boolean;
|
||||
@@ -13,8 +14,6 @@ interface EditCardsModalProps {
|
||||
onSave: (visibleCards: Set<DashboardCardKey>) => void;
|
||||
}
|
||||
|
||||
const allCards: DashboardCardKey[] = ["monitorStatus", "monitorsByType"];
|
||||
|
||||
export const EditCardsModal = ({
|
||||
open,
|
||||
visibleCards,
|
||||
@@ -24,9 +23,10 @@ export const EditCardsModal = ({
|
||||
const { t } = useTranslation();
|
||||
const [draft, setDraft] = useState<Set<DashboardCardKey>>(new Set(visibleCards));
|
||||
|
||||
useEffect(() => {
|
||||
if (open) setDraft(new Set(visibleCards));
|
||||
}, [open, visibleCards]);
|
||||
const handleClose = () => {
|
||||
setDraft(new Set(visibleCards));
|
||||
onClose();
|
||||
};
|
||||
|
||||
const handleToggle = (key: DashboardCardKey) => {
|
||||
setDraft((prev) => {
|
||||
@@ -45,14 +45,14 @@ export const EditCardsModal = ({
|
||||
open={open}
|
||||
title={t("pages.dashboard.editCardsModal.title")}
|
||||
content={t("pages.dashboard.editCardsModal.description")}
|
||||
onCancel={onClose}
|
||||
onCancel={handleClose}
|
||||
onConfirm={() => onSave(draft)}
|
||||
confirmText={t("pages.dashboard.editCardsModal.done")}
|
||||
maxWidth="xs"
|
||||
fullWidth
|
||||
>
|
||||
<Stack>
|
||||
{allCards.map((key) => (
|
||||
{dashboardCardKeys.map((key) => (
|
||||
<FormControlLabel
|
||||
key={key}
|
||||
label={t(`pages.dashboard.cards.${key}`)}
|
||||
|
||||
@@ -1,29 +1,35 @@
|
||||
import { useMemo, useState } from "react";
|
||||
import { useMemo, useState, type ReactNode } from "react";
|
||||
import Box from "@mui/material/Box";
|
||||
import Stack from "@mui/material/Stack";
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
|
||||
import { BasePage } from "@/Components/design-elements/BasePage";
|
||||
import { Button } from "@/Components/inputs";
|
||||
import { LAYOUT } from "@/Utils/Theme/constants";
|
||||
import { useMonitorListController } from "@/Hooks/useMonitorListController";
|
||||
import { MonitorTypes, type MonitorTypeCount } from "@/Types/Monitor";
|
||||
import {
|
||||
setDashboardVisibleCards,
|
||||
dashboardCardKeys,
|
||||
type DashboardCardKey,
|
||||
} from "@/Features/UI/uiSlice";
|
||||
import type { RootState, AppDispatch } from "@/store";
|
||||
|
||||
import { MonitorStatusCard } from "@/Pages/Dashboard/components/cards/MonitorStatusCard";
|
||||
import { MonitorsByTypeCard } from "@/Pages/Dashboard/components/cards/MonitorsByTypeCard";
|
||||
import {
|
||||
EditCardsModal,
|
||||
type DashboardCardKey,
|
||||
} from "@/Pages/Dashboard/components/EditCardsModal";
|
||||
|
||||
const allCards = new Set<DashboardCardKey>(["monitorStatus", "monitorsByType"]);
|
||||
import { EditCardsModal } from "@/Pages/Dashboard/components/EditCardsModal";
|
||||
|
||||
const Dashboard = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useDispatch<AppDispatch>();
|
||||
const [editOpen, setEditOpen] = useState(false);
|
||||
const [visibleCards, setVisibleCards] = useState<Set<DashboardCardKey>>(allCards);
|
||||
const visibleCardsList = useSelector(
|
||||
(state: RootState) => state.ui.dashboardVisibleCards
|
||||
);
|
||||
const visibleCards = useMemo(() => new Set(visibleCardsList), [visibleCardsList]);
|
||||
|
||||
const { monitors, summary } = useMonitorListController({
|
||||
types: [...MonitorTypes],
|
||||
@@ -43,6 +49,11 @@ const Dashboard = () => {
|
||||
.sort((a, b) => b.count - a.count);
|
||||
}, [monitors]);
|
||||
|
||||
const cardComponents: Record<DashboardCardKey, ReactNode> = {
|
||||
monitorStatus: <MonitorStatusCard summary={summary} />,
|
||||
monitorsByType: <MonitorsByTypeCard monitorsByType={monitorsByType} />,
|
||||
};
|
||||
|
||||
return (
|
||||
<BasePage headerKey="dashboard">
|
||||
<Stack gap={theme.spacing(LAYOUT.SM)}>
|
||||
@@ -64,10 +75,11 @@ const Dashboard = () => {
|
||||
gridTemplateColumns={{ xs: "1fr", md: "1fr 1fr" }}
|
||||
gap={theme.spacing(LAYOUT.MD)}
|
||||
>
|
||||
{visibleCards.has("monitorStatus") && <MonitorStatusCard summary={summary} />}
|
||||
{visibleCards.has("monitorsByType") && (
|
||||
<MonitorsByTypeCard monitorsByType={monitorsByType} />
|
||||
)}
|
||||
{dashboardCardKeys
|
||||
.filter((key) => visibleCards.has(key))
|
||||
.map((key) => (
|
||||
<div key={key}>{cardComponents[key]}</div>
|
||||
))}
|
||||
</Box>
|
||||
</Stack>
|
||||
|
||||
@@ -76,7 +88,7 @@ const Dashboard = () => {
|
||||
visibleCards={visibleCards}
|
||||
onClose={() => setEditOpen(false)}
|
||||
onSave={(next) => {
|
||||
setVisibleCards(next);
|
||||
dispatch(setDashboardVisibleCards([...next]));
|
||||
setEditOpen(false);
|
||||
}}
|
||||
/>
|
||||
|
||||
Reference in new issue
Block a user