From dd159c24d0e2beccd11bba6212319aaa4fcb091c Mon Sep 17 00:00:00 2001 From: weichen Date: Sat, 17 Oct 2026 03:58:53 +0000 Subject: [PATCH] Normalize null list projections in cockpit node detail Why: rdm.cockpit.node projects empty conflicts as items:null (Go nil slice) while sources arrive as []; the panel read items.length on null and crashed, so the conflicts empty state never rendered (I4 e2e scenario 3). Evidence: tsc clean, vitest green, build green (SELF); seven-scenario rerun to be recorded on the Dev I4 card. Impact: cockpit panel only. Refs: rollout I4 --- src/components/CockpitReader.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/components/CockpitReader.tsx b/src/components/CockpitReader.tsx index 6e94f55..0326236 100644 --- a/src/components/CockpitReader.tsx +++ b/src/components/CockpitReader.tsx @@ -36,7 +36,14 @@ function useNodeDetail(pid: string, sel?: CockpitNodeRef) { setDetail(null); setErr('') if (!sel) return api.rdmCommand('rdm.cockpit.node', { projectId: pid, kind: sel.kind, id: sel.id }) - .then(d => { if (g === gen.current) setDetail(d) }) + .then(d => { + if (g !== gen.current) return + // 后端空列表可能投影为 null(Go nil slice);统一归一,消费端按数组使用。 + for (const k of ['sources', 'history', 'impacts', 'conflicts'] as const) { + if (d?.[k] && !Array.isArray(d[k].items)) d[k].items = [] + } + setDetail(d) + }) .catch(e => { if (g === gen.current) setErr(e.message) }) return () => { gen.current++ } }, [pid, sel?.kind, sel?.id])