diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..7f80b8533 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +* text=auto +* text eol=lf \ No newline at end of file diff --git a/client/src/Pages/StatusPage/Status/Components/StatusBar.tsx b/client/src/Pages/StatusPage/Status/Components/StatusBar.tsx index b5c52b32b..d2043a7f3 100644 --- a/client/src/Pages/StatusPage/Status/Components/StatusBar.tsx +++ b/client/src/Pages/StatusPage/Status/Components/StatusBar.tsx @@ -1,35 +1,115 @@ -import { AlertTriangle, CircleCheck } from "lucide-react"; +import { + AlertTriangle, + CircleCheck, + CircleX, + Loader, + PauseCircle, + ShieldAlert, + Wrench, +} from "lucide-react"; import Stack from "@mui/material/Stack"; import Typography from "@mui/material/Typography"; import { useTranslation } from "react-i18next"; -import type { Theme } from "@mui/material"; import { useTheme } from "@mui/material"; -import type { Monitor } from "@/Types/Monitor"; +import type { Theme } from "@mui/material"; +import type { Monitor, MonitorStatus } from "@/Types/Monitor"; + +interface StatusDisplay { + icon: JSX.Element; + msg?: string; + color?: string; +} const getMonitorStatus = (monitors: Monitor[], theme: Theme, t: Function) => { - const monitorsStatus: Record = { + const monitorsStatus: StatusDisplay = { icon: , }; - if (monitors.every((monitor) => monitor.status === "up")) { + // Handle empty monitors array + if (monitors.length === 0) { + monitorsStatus.msg = t("pages.statusPages.statusBar.noMonitors"); + monitorsStatus.color = theme.palette.warning.main; + monitorsStatus.icon = ; + return monitorsStatus; + } + + const allOf = (...statuses: MonitorStatus[]) => + monitors.every((m) => statuses.includes(m.status)); + const someOf = (...statuses: MonitorStatus[]) => + monitors.some((m) => statuses.includes(m.status)); + const noneOf = (...statuses: MonitorStatus[]) => + monitors.every((m) => !statuses.includes(m.status)); + + // All monitors in a single state + if (allOf("up")) { monitorsStatus.msg = t("pages.statusPages.statusBar.allUp"); monitorsStatus.color = theme.palette.success.main; monitorsStatus.icon = ; - return monitorsStatus; - } else if (monitors.every((monitor) => monitor.status === "down")) { + } else if (allOf("breached")) { + monitorsStatus.msg = t("pages.statusPages.statusBar.allBreached"); + monitorsStatus.color = theme.palette.error.main; + monitorsStatus.icon = ; + } else if (allOf("maintenance")) { + monitorsStatus.msg = t("pages.statusPages.statusBar.allMaintenance"); + monitorsStatus.color = theme.palette.warning.main; + monitorsStatus.icon = ; + } else if (allOf("down")) { monitorsStatus.msg = t("pages.statusPages.statusBar.allDown"); monitorsStatus.color = theme.palette.error.main; - return monitorsStatus; - } else if (monitors.some((monitor) => monitor.status === "down")) { + monitorsStatus.icon = ; + } else if (allOf("paused")) { + monitorsStatus.msg = t("pages.statusPages.statusBar.allPaused"); + monitorsStatus.color = theme.palette.warning.main; + monitorsStatus.icon = ; + } else if (allOf("initializing")) { + monitorsStatus.msg = t("pages.statusPages.statusBar.allInitializing"); + monitorsStatus.color = theme.palette.warning.main; + monitorsStatus.icon = ; + + // Breached takes highest priority in mixed states + } else if (someOf("breached") && someOf("down")) { + monitorsStatus.msg = t("pages.statusPages.statusBar.breachedAndDown"); + monitorsStatus.color = theme.palette.error.main; + monitorsStatus.icon = ; + } else if (someOf("breached")) { + monitorsStatus.msg = t("pages.statusPages.statusBar.breached"); + monitorsStatus.color = theme.palette.error.main; + monitorsStatus.icon = ; + + // Maintenance combinations + } else if (someOf("maintenance") && someOf("down")) { + monitorsStatus.msg = t("pages.statusPages.statusBar.maintenanceAndDown"); + monitorsStatus.color = theme.palette.error.main; + monitorsStatus.icon = ; + } else if (someOf("maintenance") && noneOf("down")) { + monitorsStatus.msg = t("pages.statusPages.statusBar.maintenance"); + monitorsStatus.color = theme.palette.warning.main; + monitorsStatus.icon = ; + + // Degraded (some down, no maintenance/breached) + } else if (someOf("down")) { monitorsStatus.msg = t("pages.statusPages.statusBar.degraded"); monitorsStatus.color = theme.palette.warning.main; - return monitorsStatus; + monitorsStatus.icon = ; + + // Some Paused + } else if (someOf("paused")) { + monitorsStatus.msg = t("pages.statusPages.statusBar.partiallyPaused"); + monitorsStatus.color = theme.palette.warning.main; + monitorsStatus.icon = ; + + // Initializing + } else if (someOf("initializing")) { + monitorsStatus.msg = t("pages.statusPages.statusBar.initializing"); + monitorsStatus.color = theme.palette.info.main; + monitorsStatus.icon = ; } else { monitorsStatus.msg = t("pages.statusPages.statusBar.unknown"); monitorsStatus.color = theme.palette.warning.main; - return monitorsStatus; } + + return monitorsStatus; }; interface StatusBarProps { diff --git a/client/src/locales/en.json b/client/src/locales/en.json index 83ca4fa33..863e54f2c 100644 --- a/client/src/locales/en.json +++ b/client/src/locales/en.json @@ -1208,9 +1208,20 @@ } }, "statusBar": { - "allDown": "All systems are down", "allUp": "All systems operational", + "allBreached": "All systems have exceeded thresholds", + "allMaintenance": "All systems are under maintenance", + "allDown": "All systems are down", + "allPaused": "All systems are paused", + "allInitializing": "All systems are initializing", + "breachedAndDown": "Some systems have exceeded thresholds and are down", + "breached": "Some systems have exceeded thresholds", "degraded": "Some systems are experiencing issues", + "maintenanceAndDown": "Some systems are down during maintenance", + "maintenance": "Some systems are under maintenance", + "partiallyPaused": "Some systems are paused", + "initializing": "Some systems are initializing", + "noMonitors": "No monitors have been configured", "unknown": "Unable to determine system status" }, "table": {