Files
Checkmate/client/src/Pages/Logs/TabQueue.tsx
T
gorkem-bwl 319f667028 feat(client): unify section headers on /logs and group titles with their tables
- Apply the eyebrow variant to "Runtime stats" and "Memory & CPU" so /logs sections share the same uppercase header style as Job queue
- Pair each section's heading + explainer with its table in a tighter sub-stack so the big gap only sits between sections, not under the explainer
- Restore the missing useTheme() call inside TableFailedJobs and TableLogs so the monospace token resolves
2026-04-26 01:55:33 -04:00

117 lines
2.9 KiB
TypeScript

import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography";
import Box from "@mui/material/Box";
import { TableJobs, TableFailedJobs } from "./components/TableJobs";
import { useTheme } from "@mui/material";
import { useTranslation, Trans } from "react-i18next";
import { useGet, usePost } from "@/Hooks/UseApi";
import type { QueueData } from "@/Types/Queue";
import { Metrics } from "@/Pages/Logs/components/Metrics";
import { Button } from "@/Components/inputs";
import { EmptyState } from "@/Components/design-elements";
export const TabQueue = () => {
const theme = useTheme();
const { t } = useTranslation();
const {
data: queueData,
isLoading,
// error,
refetch,
} = useGet<QueueData>("/queue/all-metrics", {}, { refreshInterval: 5000 });
const { post, loading: isFlushing } = usePost();
const jobs = queueData?.jobs ?? [];
const metrics = queueData?.metrics ?? null;
const hasNeverRun = !isLoading && metrics !== null && (metrics.totalRuns ?? 0) === 0;
const noQueueData = !isLoading && metrics === null && jobs.length === 0;
if (hasNeverRun || noQueueData) {
return (
<EmptyState
fullscreen
title={t("pages.logs.queueFallback.title")}
description={t("pages.logs.queueFallback.description")}
/>
);
}
const handleFlushQueue = async () => {
await post("/queue/flush", {});
refetch();
};
return (
<Stack gap={theme.spacing(16)}>
<Metrics metrics={metrics} />
<Stack gap={theme.spacing(3)}>
<Stack gap={theme.spacing(1)}>
<Typography
variant="eyebrow"
color="text.secondary"
>
{t("pages.logs.jobQueue")}
</Typography>
<Typography
sx={{
fontSize: 13,
color: theme.palette.text.secondary,
}}
>
<Trans
i18nKey="pages.logs.jobQueueExplainer"
components={{
highlight: (
<Box
component="span"
sx={{
backgroundColor:
theme.palette.mode === "dark"
? "rgba(19, 113, 91, 0.18)"
: "#ECF7F2",
color: theme.palette.text.primary,
px: 1,
py: 0.25,
borderRadius: 0.5,
}}
/>
),
}}
/>
</Typography>
</Stack>
<TableJobs jobs={jobs} />
</Stack>
<Stack gap={theme.spacing(3)}>
<Stack gap={theme.spacing(1)}>
<Typography
variant="eyebrow"
color="text.secondary"
>
{t("pages.logs.failedJobs")}
</Typography>
<Typography
sx={{
fontSize: 13,
color: theme.palette.text.secondary,
}}
>
{t("pages.logs.failedJobsExplainer")}
</Typography>
</Stack>
<TableFailedJobs metrics={metrics} />
</Stack>
<Stack alignItems={"flex-end"}>
<Button
variant="contained"
onClick={handleFlushQueue}
loading={isFlushing}
>
{t("common.buttons.flushQueue")}
</Button>
</Stack>
</Stack>
);
};