extract strings

This commit is contained in:
Alex Holliday
2026-01-28 18:45:11 +00:00
parent 7a66b5310b
commit 975d134dd8
5 changed files with 101 additions and 99 deletions
@@ -3,6 +3,7 @@ import Typography from "@mui/material/Typography";
import { ToggleButtonGroup, ToggleButton } from "@/Components/v2/inputs";
import { useTheme } from "@mui/material/styles";
import CircularProgress from "@mui/material/CircularProgress";
import { useTranslation } from "react-i18next";
import Box from "@mui/material/Box";
interface MonitorTimeFrameHeaderProps {
@@ -19,7 +20,7 @@ export const HeaderTimeRange = ({
setDateRange,
}: MonitorTimeFrameHeaderProps) => {
const theme = useTheme();
const { t } = useTranslation();
const handleChange = (
_event: React.MouseEvent<HTMLElement>,
newValue: string | null
@@ -39,29 +40,17 @@ export const HeaderTimeRange = ({
onChange={handleChange}
size="small"
>
<ToggleButton
disabled={isLoading}
value="recent"
>
Recent
<ToggleButton value="recent">
{t("components.headerTimeRange.labels.recent")}
</ToggleButton>
<ToggleButton
disabled={isLoading}
value="day"
>
Day
<ToggleButton value="day">
{t("components.headerTimeRange.labels.day")}
</ToggleButton>
<ToggleButton
disabled={isLoading}
value="week"
>
Week
<ToggleButton value="week">
{t("components.headerTimeRange.labels.week")}
</ToggleButton>
<ToggleButton
disabled={isLoading}
value="month"
>
Month
<ToggleButton value="month">
{t("components.headerTimeRange.labels.month")}
</ToggleButton>
</ToggleButtonGroup>
);
@@ -74,19 +63,9 @@ export const HeaderTimeRange = ({
alignItems="center"
gap={theme.spacing(4)}
>
<Box sx={{ width: 20, height: 20, display: "flex", alignItems: "center", justifyContent: "center" }}>
{isLoading && <CircularProgress size={16} />}
</Box>
{isLoading && <CircularProgress size={16} />}
<Typography variant="body2">
Showing statistics for past{" "}
{dateRange === "recent"
? "2 hours"
: dateRange === "day"
? "24 hours"
: dateRange === "week"
? "7 days"
: "30 days"}
.
{t(`components.headerTimeRange.description.${dateRange}`)}
</Typography>
{timeFramePicker}
</Stack>
@@ -113,9 +113,6 @@ export const TotalChecksBox = ({ n }: { n: number }) => {
label={t("pages.common.monitors.status.total")}
n={n}
color={theme.palette.primary.light}
sx={{
maxWidth: "300px",
}}
/>
);
};
@@ -127,9 +124,6 @@ export const DownChecksBox = ({ n }: { n: number }) => {
label={t("pages.common.monitors.status.down")}
n={n}
color={theme.palette.error.light}
sx={{
maxWidth: "300px",
}}
/>
);
};
@@ -141,9 +135,6 @@ export const UpChecksBox = ({ n }: { n: number }) => {
label={t("pages.common.monitors.status.up")}
n={n}
color={theme.palette.success.light}
sx={{
maxWidth: "300px",
}}
/>
);
};
@@ -9,28 +9,24 @@ import type { Header } from "@/Components/v2/design-elements/Table";
import type { Monitor, MonitorStatus } from "@/Types/Monitor";
import { useTranslation } from "react-i18next";
import { useMemo } from "react";
import { formatDateWithTz } from "@/Utils/TimeUtils";
import { useNavigate } from "react-router";
import type { Check, ChecksResponse } from "@/Types/Check";
import type { Check } from "@/Types/Check";
import type { RootState } from "@/Types/state";
import { useSelector } from "react-redux";
import { useGet } from "@/Hooks/UseApi";
export const ChecksTable = ({
monitors,
selectedMonitorId,
statusFilter,
dateRange,
checks,
checksCount,
page,
setPage,
rowsPerPage,
setRowsPerPage,
}: {
monitors: Monitor[] | null;
selectedMonitorId: string;
statusFilter: string;
dateRange: string;
checks: Check[];
checksCount: number;
page: number;
setPage: (page: number) => void;
rowsPerPage: number;
@@ -40,44 +36,6 @@ export const ChecksTable = ({
const uiTimezone = useSelector((state: RootState) => state.ui.timezone);
const navigate = useNavigate();
const selectedMonitorType = monitors?.find((m) => m.id === selectedMonitorId)?.type;
const teamChecksUrl = useMemo(() => {
if (selectedMonitorId !== "0") return null;
const params = new URLSearchParams();
params.append("sortOrder", "desc");
if (dateRange) params.append("dateRange", dateRange);
if (statusFilter) params.append("filter", statusFilter);
params.append("page", String(page));
params.append("rowsPerPage", String(rowsPerPage));
return `/checks/team?${params.toString()}`;
}, [selectedMonitorId, dateRange, statusFilter, page, rowsPerPage]);
const monitorChecksUrl = useMemo(() => {
if (selectedMonitorId === "0" || !selectedMonitorType) return null;
const params = new URLSearchParams();
params.append("type", selectedMonitorType);
params.append("sortOrder", "desc");
if (statusFilter) params.append("filter", statusFilter);
if (dateRange) params.append("dateRange", dateRange);
params.append("page", String(page));
params.append("rowsPerPage", String(rowsPerPage));
return `/checks/${selectedMonitorId}?${params.toString()}`;
}, [selectedMonitorId, selectedMonitorType, dateRange, statusFilter, page, rowsPerPage]);
const { data: teamData, isLoading: isLoadingTeam } =
useGet<ChecksResponse>(teamChecksUrl);
const { data: monitorData, isLoading: isLoadingMonitor } =
useGet<ChecksResponse>(monitorChecksUrl);
const checks =
selectedMonitorId === "0" ? (teamData?.checks ?? []) : (monitorData?.checks ?? []);
const checksCount =
selectedMonitorId === "0"
? (teamData?.checksCount ?? 0)
: (monitorData?.checksCount ?? 0);
const isLoading = isLoadingTeam || isLoadingMonitor;
const getHeaders = (t: Function, uiTimezone: string) => {
const headers: Header<Check>[] = [
{
+68 -10
View File
@@ -11,24 +11,22 @@ import { ChecksTable } from "./Components/ChecksTable";
import { MenuItem, useTheme } from "@mui/material";
import { useTranslation } from "react-i18next";
import { useState } from "react";
import { useState, useMemo } from "react";
import { useParams } from "react-router-dom";
import { useGet } from "@/Hooks/UseApi";
import type { Monitor } from "@/Types/Monitor";
import type { ChecksSummary } from "@/Types/Check";
import type { ChecksSummary, ChecksResponse } from "@/Types/Check";
const Checks = () => {
const { t } = useTranslation();
const { monitorId } = useParams<{ monitorId?: string }>();
// Local state
const [selectedMonitor, setSelectedMonitor] = useState<string>(monitorId || "0");
const [dateRange, setDateRange] = useState<string>("recent");
const [statusFilter, setStatusFilter] = useState<string>("down");
const [page, setPage] = useState<number>(0);
const [rowsPerPage, setRowsPerPage] = useState<number>(10);
// Data fetching with SWR
const monitorsUrl = "/monitors/team";
const summaryUrl = `/checks/team/summary?dateRange=${dateRange}`;
@@ -38,7 +36,68 @@ const Checks = () => {
const { data: summaryResponse, isLoading: isLoadingSummary } =
useGet<ChecksSummary>(summaryUrl);
const isLoading = isLoadingMonitors || isLoadingSummary;
const selectedMonitorType = monitorsResponse?.find(
(m) => m.id === selectedMonitor
)?.type;
const teamChecksUrl = useMemo(() => {
if (selectedMonitor !== "0") return null;
const params = new URLSearchParams();
params.append("sortOrder", "desc");
if (dateRange) params.append("dateRange", dateRange);
if (statusFilter) params.append("filter", statusFilter);
params.append("page", String(page));
params.append("rowsPerPage", String(rowsPerPage));
return `/checks/team?${params.toString()}`;
}, [selectedMonitor, dateRange, statusFilter, page, rowsPerPage]);
const monitorChecksUrl = useMemo(() => {
if (selectedMonitor === "0" || !selectedMonitorType) return null;
const params = new URLSearchParams();
params.append("type", selectedMonitorType);
params.append("sortOrder", "desc");
if (statusFilter) params.append("filter", statusFilter);
if (dateRange) params.append("dateRange", dateRange);
params.append("page", String(page));
params.append("rowsPerPage", String(rowsPerPage));
return `/checks/${selectedMonitor}?${params.toString()}`;
}, [selectedMonitor, selectedMonitorType, dateRange, statusFilter, page, rowsPerPage]);
const {
data: teamChecksData,
isLoading: isLoadingTeamChecks,
isValidating: isValidatingTeamChecks,
} = useGet<ChecksResponse>(
teamChecksUrl,
{},
{ keepPreviousData: true, refreshInterval: 30000 }
);
const {
data: monitorChecksData,
isLoading: isLoadingMonitorChecks,
isValidating: isValidatingMonitorChecks,
} = useGet<ChecksResponse>(
monitorChecksUrl,
{},
{ keepPreviousData: true, refreshInterval: 30000 }
);
const checks =
selectedMonitor === "0"
? (teamChecksData?.checks ?? [])
: (monitorChecksData?.checks ?? []);
const checksCount =
selectedMonitor === "0"
? (teamChecksData?.checksCount ?? 0)
: (monitorChecksData?.checksCount ?? 0);
const isLoadingChecks =
isLoadingTeamChecks ||
isLoadingMonitorChecks ||
isValidatingTeamChecks ||
isValidatingMonitorChecks;
const isLoading = isLoadingMonitors || isLoadingSummary || isLoadingChecks;
const totalChecks = summaryResponse?.totalChecks || 0;
const downChecks = summaryResponse?.downChecks || 0;
const upChecks = totalChecks - (summaryResponse?.downChecks || 0);
@@ -61,7 +120,7 @@ const Checks = () => {
gap={2}
>
<Stack
direction="row"
direction={{ xs: "column", md: "row" }}
gap={2}
>
<Select
@@ -94,7 +153,7 @@ const Checks = () => {
</Select>
</Stack>
<HeaderTimeRange
isLoading={isLoading}
isLoading={isLoading || isLoadingChecks}
dateRange={dateRange}
setDateRange={setDateRange}
/>
@@ -102,9 +161,8 @@ const Checks = () => {
<ChecksTable
monitors={monitorsResponse ?? null}
selectedMonitorId={selectedMonitor}
statusFilter={statusFilter}
dateRange={dateRange}
checks={checks}
checksCount={checksCount}
page={page}
setPage={setPage}
rowsPerPage={rowsPerPage}
+16
View File
@@ -171,6 +171,22 @@
},
"add": "Add",
"monitors": "monitors",
"components": {
"headerTimeRange": {
"labels": {
"recent": "Recent",
"day": "Day",
"week": "Week",
"month": "Month"
},
"description": {
"recent": "Showing statistics for past 2 hours.",
"day": "Showing statistics for past 24 hours.",
"week": "Showing statistics for past 7 days.",
"month": "Showing statistics for past 30 days."
}
}
},
"pages": {
"common": {
"monitors": {