chore: sync GovOPlaN module split state

This commit is contained in:
2026-07-10 12:51:22 +02:00
parent 41528f1947
commit 63ff9a3366
20 changed files with 1151 additions and 0 deletions
@@ -0,0 +1,54 @@
import { useEffect, useState } from "react";
import {
DismissibleAlert,
LoadingFrame,
MetricCard,
StatusBadge,
adminErrorMessage,
type ApiSettings
} from "@govoplan/core-webui";
import { fetchOpsStatus, type OpsStatus } from "../../api/ops";
export default function OpsHealthWidget({ settings, refreshKey }: { settings: ApiSettings; refreshKey: number }) {
const [status, setStatus] = useState<OpsStatus | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState("");
useEffect(() => {
let cancelled = false;
setLoading(true);
setError("");
fetchOpsStatus(settings).
then((next) => {if (!cancelled) setStatus(next);}).
catch((err) => {if (!cancelled) setError(adminErrorMessage(err));}).
finally(() => {if (!cancelled) setLoading(false);});
return () => {cancelled = true;};
}, [settings.apiBaseUrl, settings.apiKey, settings.accessToken, refreshKey]);
const checks = status?.checks ?? [];
const warningCount = checks.filter((item) => item.state === "warning").length;
const errorCount = checks.filter((item) => item.state === "error").length;
const ready = status?.readiness.ready ?? false;
return (
<LoadingFrame loading={loading} label="Loading operations status">
{error && <DismissibleAlert tone="warning" resetKey={error}>{error}</DismissibleAlert>}
<div className="metric-grid inside dashboard-widget-metrics">
<MetricCard label="Readiness" value={ready ? "ready" : "blocked"} tone={ready ? "good" : "danger"} detail={status?.readiness.profile ?? "-"} />
<MetricCard label="Workers" value={status?.summary.celery_enabled ? "split" : "off"} tone={status?.summary.celery_enabled ? "good" : "warning"} detail={status?.summary.celery_queues?.length ? status.summary.celery_queues.join(", ") : "single-process"} />
<MetricCard label="Warnings" value={warningCount + errorCount} tone={errorCount ? "danger" : warningCount ? "warning" : "good"} detail="Current health checks" />
</div>
{status?.readiness.blockers.length ?
<dl className="detail-list dashboard-compact-list below-grid">
{status.readiness.blockers.slice(0, 3).map((blocker) =>
<div key={blocker.id}>
<dt><StatusBadge status={blocker.state === "error" ? "error" : "warning"} label={blocker.state} /></dt>
<dd><strong>{blocker.label}</strong><span className="muted"> · {blocker.detail}</span></dd>
</div>
)}
</dl> :
<p className="muted below-grid">No readiness blockers reported.</p>
}
</LoadingFrame>);
}