From d6d74d4c6bddc767de00b9d1bb75a425aa63d9bf Mon Sep 17 00:00:00 2001 From: JGerla Date: Thu, 22 Jan 2026 11:26:48 +0100 Subject: [PATCH] feat: made warnings undo redo safe and added warnings to phase nodes ref: N25B-450 --- .../visualProgrammingUI/EditorUndoRedo.ts | 18 ++++- .../components/EditorWarnings.tsx | 7 +- .../components/WarningSidebar.tsx | 5 +- .../visualProgrammingUI/nodes/PhaseNode.tsx | 77 +++++++++++++++++-- .../EditorUndoRedo.test.ts | 41 ++++++++-- 5 files changed, 128 insertions(+), 20 deletions(-) diff --git a/src/pages/VisProgPage/visualProgrammingUI/EditorUndoRedo.ts b/src/pages/VisProgPage/visualProgrammingUI/EditorUndoRedo.ts index 6ad705d..4e45148 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/EditorUndoRedo.ts +++ b/src/pages/VisProgPage/visualProgrammingUI/EditorUndoRedo.ts @@ -1,10 +1,18 @@ import type {Edge, Node} from "@xyflow/react"; import type {StateCreator, StoreApi } from 'zustand/vanilla'; +import type { + SeverityIndex, + WarningRegistry +} from "./components/EditorWarnings.tsx"; import type {FlowState} from "./VisProgTypes.tsx"; export type FlowSnapshot = { nodes: Node[]; edges: Edge[]; + warnings: { + warningRegistry: WarningRegistry; + severityIndex: SeverityIndex; + } } /** @@ -41,7 +49,11 @@ export const UndoRedo = ( */ const getSnapshot = (state : BaseFlowState) : FlowSnapshot => (structuredClone({ nodes: state.nodes, - edges: state.edges + edges: state.edges, + warnings: { + warningRegistry: state.editorWarningRegistry, + severityIndex: state.severityIndex, + } })); const initialState = config(set, get, api); @@ -78,6 +90,8 @@ export const UndoRedo = ( set({ nodes: snapshot.nodes, edges: snapshot.edges, + editorWarningRegistry: snapshot.warnings.warningRegistry, + severityIndex: snapshot.warnings.severityIndex, }); state.future.push(currentSnapshot); // push current to redo @@ -97,6 +111,8 @@ export const UndoRedo = ( set({ nodes: snapshot.nodes, edges: snapshot.edges, + editorWarningRegistry: snapshot.warnings.warningRegistry, + severityIndex: snapshot.warnings.severityIndex, }); state.past.push(currentSnapshot); // push current to undo diff --git a/src/pages/VisProgPage/visualProgrammingUI/components/EditorWarnings.tsx b/src/pages/VisProgPage/visualProgrammingUI/components/EditorWarnings.tsx index eb5a0f6..c8c3a27 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/components/EditorWarnings.tsx +++ b/src/pages/VisProgPage/visualProgrammingUI/components/EditorWarnings.tsx @@ -19,6 +19,7 @@ export type WarningType = | 'MISSING_OUTPUT' | 'PLAN_IS_UNDEFINED' | 'INCOMPLETE_PROGRAM' + | 'NOT_CONNECTED_TO_PROGRAM' | string export type WarningSeverity = @@ -87,7 +88,7 @@ export type EditorWarningRegistry = { /** * unregisters warnings from the warningRegistry and the SeverityIndex - * @param {EditorWarning} warning + * @param {WarningId} warning */ unregisterWarningsForId: (id: WarningId) => void; } @@ -187,13 +188,15 @@ export function editorWarningRegistry(get: ZustandGet, set: ZustandSet) : Editor // remove from severity index if (nodeWarnings) { - nodeWarnings.forEach((warning, warningKey) => { + nodeWarnings.forEach((warning) => { + const warningKey = `${warning.type}:${warning.scope.handleId}`; sIndex.get(warning.severity)?.delete(`${id}|${warningKey}`); }); } // remove from warning registry wRegistry.delete(id); + console.log(wRegistry.get(id)); set({ editorWarningRegistry: wRegistry, diff --git a/src/pages/VisProgPage/visualProgrammingUI/components/WarningSidebar.tsx b/src/pages/VisProgPage/visualProgrammingUI/components/WarningSidebar.tsx index eb2efee..867a027 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/components/WarningSidebar.tsx +++ b/src/pages/VisProgPage/visualProgrammingUI/components/WarningSidebar.tsx @@ -19,9 +19,6 @@ export function WarningsSidebar() { ? warnings : warnings.filter(w => w.severity === severityFilter); - - - return (