Fix ops dashboard rollout status rendering
This commit is contained in:
@@ -19,12 +19,16 @@ type ProbabilityRollout = {
|
|||||||
|
|
||||||
type SystemStatusPayload = {
|
type SystemStatusPayload = {
|
||||||
state_storage_mode?: string;
|
state_storage_mode?: string;
|
||||||
sqlite?: { ok?: boolean; path?: string };
|
db?: { ok?: boolean; db_path?: string };
|
||||||
features?: Record<string, unknown>;
|
features?: Record<string, unknown>;
|
||||||
metrics?: Record<string, unknown>;
|
metrics?: Record<string, unknown>;
|
||||||
probability?: {
|
probability?: {
|
||||||
mode?: string;
|
engine_mode?: string;
|
||||||
rollout?: ProbabilityRollout;
|
rollout?: {
|
||||||
|
decision?: ProbabilityRollout;
|
||||||
|
evaluation_report_exists?: boolean;
|
||||||
|
shadow_report_exists?: boolean;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
integrations?: Record<string, unknown>;
|
integrations?: Record<string, unknown>;
|
||||||
};
|
};
|
||||||
@@ -184,12 +188,14 @@ export function OpsDashboard() {
|
|||||||
void loadLeaderboard();
|
void loadLeaderboard();
|
||||||
}, [loadLeaderboard, loadUsers]);
|
}, [loadLeaderboard, loadUsers]);
|
||||||
|
|
||||||
|
const rolloutDecision = status?.probability?.rollout?.decision;
|
||||||
|
|
||||||
const rolloutVariant = useMemo(() => {
|
const rolloutVariant = useMemo(() => {
|
||||||
const decision = status?.probability?.rollout?.decision;
|
const decision = rolloutDecision?.decision;
|
||||||
if (decision === "promote") return "success" as const;
|
if (decision === "promote") return "success" as const;
|
||||||
if (decision === "observe") return "warning" as const;
|
if (decision === "observe") return "warning" as const;
|
||||||
return "danger" as const;
|
return "danger" as const;
|
||||||
}, [status?.probability?.rollout?.decision]);
|
}, [rolloutDecision?.decision]);
|
||||||
|
|
||||||
const submitGrant = useCallback(async () => {
|
const submitGrant = useCallback(async () => {
|
||||||
setGrantLoading(true);
|
setGrantLoading(true);
|
||||||
@@ -238,11 +244,11 @@ export function OpsDashboard() {
|
|||||||
<Badge variant={health?.status === "ok" ? "success" : "danger"}>
|
<Badge variant={health?.status === "ok" ? "success" : "danger"}>
|
||||||
Health {health?.status || "unknown"}
|
Health {health?.status || "unknown"}
|
||||||
</Badge>
|
</Badge>
|
||||||
<Badge variant={status?.sqlite?.ok ? "success" : "danger"}>
|
<Badge variant={status?.db?.ok ? "success" : "danger"}>
|
||||||
SQLite {status?.sqlite?.ok ? "ok" : "error"}
|
SQLite {status?.db?.ok ? "ok" : "error"}
|
||||||
</Badge>
|
</Badge>
|
||||||
<Badge variant={rolloutVariant}>
|
<Badge variant={rolloutVariant}>
|
||||||
EMOS {status?.probability?.rollout?.decision || "hold"}
|
EMOS {rolloutDecision?.decision || "hold"}
|
||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -294,10 +300,10 @@ export function OpsDashboard() {
|
|||||||
<CardDescription>SQLite 是否正常,以及 rollout 当前状态。</CardDescription>
|
<CardDescription>SQLite 是否正常,以及 rollout 当前状态。</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-2 text-sm text-slate-300">
|
<CardContent className="space-y-2 text-sm text-slate-300">
|
||||||
<div className="flex justify-between gap-3"><span>SQLite</span><span>{status?.sqlite?.ok ? "ok" : "error"}</span></div>
|
<div className="flex justify-between gap-3"><span>SQLite</span><span>{status?.db?.ok ? "ok" : "error"}</span></div>
|
||||||
<div className="flex justify-between gap-3"><span>EMOS 模式</span><span>{status?.probability?.mode || "-"}</span></div>
|
<div className="flex justify-between gap-3"><span>EMOS 模式</span><span>{status?.probability?.engine_mode || "-"}</span></div>
|
||||||
<div className="flex justify-between gap-3"><span>上线门禁</span><span>{status?.probability?.rollout?.decision || "-"}</span></div>
|
<div className="flex justify-between gap-3"><span>上线门禁</span><span>{rolloutDecision?.decision || "-"}</span></div>
|
||||||
<div className="flex justify-between gap-3"><span>ready_for_primary</span><span>{status?.probability?.rollout?.ready_for_primary ? "true" : "false"}</span></div>
|
<div className="flex justify-between gap-3"><span>ready_for_primary</span><span>{rolloutDecision?.ready_for_primary ? "true" : "false"}</span></div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
@@ -340,16 +346,16 @@ export function OpsDashboard() {
|
|||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-4 text-sm text-slate-300">
|
<CardContent className="space-y-4 text-sm text-slate-300">
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-2">
|
||||||
<Badge variant={rolloutVariant}>{status?.probability?.rollout?.decision || "hold"}</Badge>
|
<Badge variant={rolloutVariant}>{rolloutDecision?.decision || "hold"}</Badge>
|
||||||
<Badge variant={status?.probability?.rollout?.ready_for_primary ? "success" : "warning"}>
|
<Badge variant={rolloutDecision?.ready_for_primary ? "success" : "warning"}>
|
||||||
ready={status?.probability?.rollout?.ready_for_primary ? "true" : "false"}
|
ready={rolloutDecision?.ready_for_primary ? "true" : "false"}
|
||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div className="mb-2 text-xs font-bold uppercase tracking-[0.16em] text-slate-500">阻塞原因</div>
|
<div className="mb-2 text-xs font-bold uppercase tracking-[0.16em] text-slate-500">阻塞原因</div>
|
||||||
<ul className="space-y-2">
|
<ul className="space-y-2">
|
||||||
{(status?.probability?.rollout?.blocking_reasons || []).length ? (
|
{(rolloutDecision?.blocking_reasons || []).length ? (
|
||||||
(status?.probability?.rollout?.blocking_reasons || []).map((reason) => (
|
(rolloutDecision?.blocking_reasons || []).map((reason) => (
|
||||||
<li key={reason} className="rounded-2xl border border-slate-800 bg-slate-950/70 px-3 py-2">
|
<li key={reason} className="rounded-2xl border border-slate-800 bg-slate-950/70 px-3 py-2">
|
||||||
{reason}
|
{reason}
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
Reference in New Issue
Block a user