|
|
|
@@ -167,11 +167,12 @@ type SystemStatus = {
|
|
|
|
|
ai: AiServiceMetrics;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function formatBytes(bytes?: number | null) {
|
|
|
|
|
function formatBytes(bytes: number | null | undefined, locale: string) {
|
|
|
|
|
if (bytes == null) return "-";
|
|
|
|
|
if (bytes < 1024) return `${bytes} B`;
|
|
|
|
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
|
|
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
|
|
|
if (bytes < 1024) return `${bytes.toLocaleString(locale)} B`;
|
|
|
|
|
const options = { minimumFractionDigits: 1, maximumFractionDigits: 1 };
|
|
|
|
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toLocaleString(locale, options)} KB`;
|
|
|
|
|
return `${(bytes / (1024 * 1024)).toLocaleString(locale, options)} MB`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function displayMetadata(value?: string | null) {
|
|
|
|
@@ -182,8 +183,8 @@ function formatDate(value?: string | null, locale?: string) {
|
|
|
|
|
return value ? new Date(value).toLocaleString(locale) : "-";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function formatPercent(value?: number | null) {
|
|
|
|
|
return typeof value === "number" ? `${Math.round(value * 100)}%` : "-";
|
|
|
|
|
function formatPercent(value: number | null | undefined, locale: string) {
|
|
|
|
|
return typeof value === "number" ? value.toLocaleString(locale, { style: "percent", maximumFractionDigits: 0 }) : "-";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function parseBenchmarkIndex(indexJson?: string | null): CvBenchmarkIndex | null {
|
|
|
|
@@ -225,6 +226,7 @@ const actionErrorKeys: Record<ActionKind, TranslationKey> = { save: "adminSystem
|
|
|
|
|
|
|
|
|
|
export default function AdminSystemPage() {
|
|
|
|
|
const { language, t } = useI18n();
|
|
|
|
|
const locale = language === "nb" ? "nb-NO" : "en";
|
|
|
|
|
const [tab, setTab] = useState(0);
|
|
|
|
|
const [status, setStatus] = useState<SystemStatus | null>(null);
|
|
|
|
|
const [emailSettings, setEmailSettings] = useState<EditableEmailSettings | null>(null);
|
|
|
|
@@ -495,7 +497,7 @@ export default function AdminSystemPage() {
|
|
|
|
|
<DetailRow label={t("adminSystemDataRoot")} value={status?.storage.dataRoot || "-"} />
|
|
|
|
|
<DetailRow label={t("adminSystemDbPath")} value={status?.storage.dbPath || "-"} />
|
|
|
|
|
<DetailRow label={t("adminSystemDbFileExists")} value={status?.storage.dbExists ? t("yes") : t("noWord")} />
|
|
|
|
|
<DetailRow label={t("adminSystemDbSize")} value={formatBytes(status?.storage.dbSizeBytes)} />
|
|
|
|
|
<DetailRow label={t("adminSystemDbSize")} value={formatBytes(status?.storage.dbSizeBytes, locale)} />
|
|
|
|
|
<DetailRow label={t("companies")} value={status?.storage.companyCount ?? 0} />
|
|
|
|
|
<DetailRow label={t("adminSystemJobs")} value={status?.storage.jobCount ?? 0} />
|
|
|
|
|
<DetailRow label={t("adminSystemDeletedJobs")} value={status?.storage.deletedCount ?? 0} />
|
|
|
|
@@ -612,9 +614,9 @@ export default function AdminSystemPage() {
|
|
|
|
|
<>
|
|
|
|
|
<Box sx={{ mt: 2, display: "grid", gridTemplateColumns: { xs: "1fr 1fr", md: "repeat(5, 1fr)" }, gap: 1.25 }}>
|
|
|
|
|
<SummaryCard title={t("adminBenchmarkFiles")} value={String(benchmarkIndex.TotalFiles)} subtitle={t("adminBenchmarkCorpusInputs")} />
|
|
|
|
|
<SummaryCard title={t("adminBenchmarkCoverage")} value={formatPercent(benchmarkIndex.AverageCoverage)} subtitle={t("adminBenchmarkCoverageHelp")} tone={benchmarkTone(benchmarkIndex.AverageCoverage)} />
|
|
|
|
|
<SummaryCard title={t("adminBenchmarkConfidence")} value={formatPercent(benchmarkIndex.AverageConfidence)} subtitle={t("adminBenchmarkConfidenceHelp")} tone={benchmarkTone(benchmarkIndex.AverageConfidence)} />
|
|
|
|
|
<SummaryCard title={t("adminBenchmarkConsistency")} value={formatPercent(benchmarkIndex.AverageConsistency)} subtitle={t("adminBenchmarkConsistencyHelp")} tone={benchmarkTone(benchmarkIndex.AverageConsistency)} />
|
|
|
|
|
<SummaryCard title={t("adminBenchmarkCoverage")} value={formatPercent(benchmarkIndex.AverageCoverage, locale)} subtitle={t("adminBenchmarkCoverageHelp")} tone={benchmarkTone(benchmarkIndex.AverageCoverage)} />
|
|
|
|
|
<SummaryCard title={t("adminBenchmarkConfidence")} value={formatPercent(benchmarkIndex.AverageConfidence, locale)} subtitle={t("adminBenchmarkConfidenceHelp")} tone={benchmarkTone(benchmarkIndex.AverageConfidence)} />
|
|
|
|
|
<SummaryCard title={t("adminBenchmarkConsistency")} value={formatPercent(benchmarkIndex.AverageConsistency, locale)} subtitle={t("adminBenchmarkConsistencyHelp")} tone={benchmarkTone(benchmarkIndex.AverageConsistency)} />
|
|
|
|
|
<SummaryCard title={t("adminBenchmarkMissingApproved")} value={String(benchmarkIndex.MissingApprovedFixtures)} subtitle={t("adminBenchmarkNeedsReview")} tone={benchmarkIndex.MissingApprovedFixtures > 0 ? "warning" : "success"} />
|
|
|
|
|
</Box>
|
|
|
|
|
|
|
|
|
@@ -638,9 +640,9 @@ export default function AdminSystemPage() {
|
|
|
|
|
<Box key={entry.Slug} sx={{ p: 1.25, borderRadius: 2, backgroundColor: "background.default", border: "none", boxShadow: "0px 1px 2px 0px rgba(15,23,42,0.04), 0px 8px 24px -12px rgba(15,23,42,0.12)" }}>
|
|
|
|
|
<Typography variant="body2" sx={{ fontWeight: 800 }}>{entry.FileName}</Typography>
|
|
|
|
|
<Box sx={{ display: "flex", gap: 0.75, flexWrap: "wrap", mt: 0.75 }}>
|
|
|
|
|
<Chip size="small" label={t("adminBenchmarkCoverageValue", { value: formatPercent(entry.CoverageScore) })} color={benchmarkTone(entry.CoverageScore)} />
|
|
|
|
|
<Chip size="small" label={t("adminBenchmarkConfidenceValue", { value: formatPercent(entry.ConfidenceScore) })} color={benchmarkTone(entry.ConfidenceScore)} />
|
|
|
|
|
<Chip size="small" label={t("adminBenchmarkConsistencyValue", { value: formatPercent(entry.ConsistencyScore) })} color={benchmarkTone(entry.ConsistencyScore)} />
|
|
|
|
|
<Chip size="small" label={t("adminBenchmarkCoverageValue", { value: formatPercent(entry.CoverageScore, locale) })} color={benchmarkTone(entry.CoverageScore)} />
|
|
|
|
|
<Chip size="small" label={t("adminBenchmarkConfidenceValue", { value: formatPercent(entry.ConfidenceScore, locale) })} color={benchmarkTone(entry.ConfidenceScore)} />
|
|
|
|
|
<Chip size="small" label={t("adminBenchmarkConsistencyValue", { value: formatPercent(entry.ConsistencyScore, locale) })} color={benchmarkTone(entry.ConsistencyScore)} />
|
|
|
|
|
</Box>
|
|
|
|
|
<Typography variant="caption" sx={{ display: "block", color: "text.secondary", mt: 0.75 }}>{entry.DiffSummary || "-"}</Typography>
|
|
|
|
|
</Box>
|
|
|
|
|