@tduniec/plugin-template-designer-foundation 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"DesignerFlow.esm.js","sources":["../../src/designerFlow/DesignerFlow.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n ComponentType,\n createElement,\n} from \"react\";\nimport type { MouseEvent as ReactMouseEvent } from \"react\";\nimport {\n ReactFlow,\n applyNodeChanges,\n applyEdgeChanges,\n addEdge,\n Node,\n Edge,\n NodeChange,\n EdgeChange,\n useNodesState,\n ReactFlowInstance,\n NodeProps,\n NodeTypes,\n Viewport,\n OnMoveEnd,\n OnMove,\n} from \"@xyflow/react\";\nimport \"@xyflow/react/dist/style.css\";\nimport type {\n ScaffolderTaskOutput,\n TaskStep,\n} from \"@backstage/plugin-scaffolder-common\";\nimport type {\n ActionNodeData,\n OutputNodeData,\n ParametersNodeData,\n TemplateParametersValue,\n} from \"../types/flowNodes\";\nimport {\n buildNodesFromModel,\n collectParameterReferences,\n collectStepOutputReferences,\n stableStringify,\n extractStepsFromNodes,\n extractParametersFromNodes,\n extractOutputFromNodes,\n} from \"./model\";\nimport { createSequentialEdges } from \"../utils/createSequentialEdges\";\nimport {\n buildEdgeHashMap,\n buildNodeHashMap,\n mergeEdgesWithStability,\n mergeNodesWithStability,\n} from \"./utils/stableComparators\";\nimport {\n createHandleAddNode,\n createHandleRemoveNode,\n createHandleRemoveInputKey,\n createHandleReorderAndAlignNodes,\n createHandleUpdateField,\n createHandleUpdateInput,\n createHandleUpdateOutput,\n createHandleUpdateSections,\n} from \"./handlers\";\nimport { alignNodes, resolveNodeHeightForTracking } from \"./nodeLayout\";\nimport {\n FLOW_LAYOUT,\n nodeDefaults as baseNodeDefaults,\n} from \"../components/designerFlowConfig\";\nimport { useScaffolderActions } from \"../api/useScaffolderActions\";\n\nconst EMPTY_EDGES: Edge[] = [];\nconst EMIT_DEBOUNCE_MS = 1200; // Emit only after user pauses typing for a bit (more relaxed UX).\nconst VIEWPORT_TUNING = {\n alignDebounceMs: 120, // Debounce view/align updates so typing isn't interrupted by layout thrash.\n centerDurationMs: 280,\n fitFallbackDelayMs: 50,\n};\n\n// Prevent benign ResizeObserver loop errors from bubbling to the dev overlay.\nif (\n typeof window !== \"undefined\" &&\n !(window as any).__rfResizeObserverPatched\n) {\n (window as any).__rfResizeObserverPatched = true;\n // Wrap ResizeObserver callbacks in rAF to avoid sync measurement loops that trigger the warning.\n if (typeof window.ResizeObserver === \"function\") {\n const OriginalResizeObserver = window.ResizeObserver;\n window.ResizeObserver = class extends OriginalResizeObserver {\n constructor(callback: ResizeObserverCallback) {\n super((entries, observer) => {\n window.requestAnimationFrame(() => callback(entries, observer));\n });\n }\n } as typeof ResizeObserver;\n }\n const shouldSwallow = (message: unknown) =>\n typeof message === \"string\" &&\n message.includes(\"ResizeObserver loop completed with undelivered\");\n const swallowResizeObserverError = (event: ErrorEvent) => {\n const message =\n event?.message || (event as any)?.error?.message || String(event);\n if (shouldSwallow(message)) {\n event.preventDefault();\n event.stopImmediatePropagation();\n return true;\n }\n return undefined;\n };\n const swallowResizeObserverRejection = (event: PromiseRejectionEvent) => {\n const message = (event.reason as any)?.message ?? String(event.reason);\n if (shouldSwallow(message)) {\n event.preventDefault();\n event.stopImmediatePropagation();\n return true;\n }\n return undefined;\n };\n const swallowLoopEvent = (event: Event) => {\n event.preventDefault();\n event.stopImmediatePropagation();\n };\n const originalOnError = window.onerror;\n window.onerror = function handleResizeObserverOnError(\n message,\n source,\n lineno,\n colno,\n error\n ): boolean | void {\n if (\n shouldSwallow(\n typeof message === \"string\"\n ? message\n : (error as any)?.message ?? String(message)\n )\n ) {\n return true;\n }\n if (typeof originalOnError === \"function\") {\n return originalOnError(message, source, lineno, colno, error);\n }\n return undefined;\n };\n const originalOnUnhandledRejection = window.onunhandledrejection;\n window.onunhandledrejection = function handleResizeObserverOnUnhandled(\n event\n ) {\n const reason = (event as any)?.reason;\n const message =\n (reason as any)?.message ?? (typeof reason === \"string\" ? reason : \"\");\n if (shouldSwallow(message)) {\n return true;\n }\n if (typeof originalOnUnhandledRejection === \"function\") {\n return (originalOnUnhandledRejection as any)(event);\n }\n return undefined;\n };\n window.addEventListener(\"error\", swallowResizeObserverError, true);\n window.addEventListener(\n \"unhandledrejection\",\n swallowResizeObserverRejection,\n true\n );\n window.addEventListener(\n \"resizeobserverlooperror\" as any,\n swallowLoopEvent,\n true\n );\n}\n\nconst shallowArrayEqual = (a?: string[], b?: string[]) => {\n if (a === b) {\n return true;\n }\n if (!a || !b || a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i += 1) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n};\n\n// Main orchestration component that renders and synchronizes the Designer flow.\n\nconst FIXED_X_POSITION = FLOW_LAYOUT.fixedXPosition;\nconst VERTICAL_SPACING = FLOW_LAYOUT.verticalSpacing;\n\nexport type DesignerFlowProps = {\n steps?: TaskStep[];\n parameters?: TemplateParametersValue;\n output?: ScaffolderTaskOutput | null;\n onStepsChange?: (steps: TaskStep[]) => void;\n onParametersChange?: (parameters: TemplateParametersValue) => void;\n onOutputChange?: (output: ScaffolderTaskOutput | undefined) => void;\n actionNodeComponent: ComponentType<{ data: ActionNodeData }>;\n parametersNodeComponent: ComponentType<{ data: ParametersNodeData }>;\n outputNodeComponent: ComponentType<{ data: OutputNodeData }>;\n decorateNodes?: (nodes: Node[]) => Node[];\n decorateEdges?: (edges: Edge[], nodes: Node[]) => Edge[];\n nodeDefaults?: Partial<Node>;\n};\n\nexport default function DesignerFlow({\n steps = [],\n parameters,\n output,\n onStepsChange,\n onParametersChange,\n onOutputChange,\n actionNodeComponent,\n parametersNodeComponent,\n outputNodeComponent,\n decorateNodes,\n decorateEdges,\n nodeDefaults = baseNodeDefaults,\n}: DesignerFlowProps) {\n const nodeDataHashRef = useRef<Record<string, string>>({});\n const edgeDataHashRef = useRef<Record<string, string>>({});\n const scaffolderActionsCache = useScaffolderActions();\n\n const {\n ids: scaffolderActionIds,\n inputsById: scaffolderActionInputsById,\n outputsById: scaffolderActionOutputsById,\n inputRequiredById: scaffolderActionInputRequiredById,\n } = scaffolderActionsCache;\n\n const normalizedParametersProp = parameters ?? undefined;\n const normalizedOutputProp = output ?? null;\n const pendingFocusNodeIdRef = useRef<string | null>(null);\n const hasMountedRef = useRef(false);\n const lastNodeCountRef = useRef(0);\n\n const initialNodes = useMemo(() => {\n const built = buildNodesFromModel(\n steps,\n normalizedParametersProp,\n normalizedOutputProp,\n {\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n }\n );\n const nodes = decorateNodes ? decorateNodes(built) : built;\n nodeDataHashRef.current = buildNodeHashMap(nodes);\n return nodes;\n }, [\n steps,\n normalizedParametersProp,\n normalizedOutputProp,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n decorateNodes,\n ]);\n\n const [nodes, setNodes] = useNodesState(initialNodes);\n const initialEdges = useMemo(() => {\n const edges = decorateEdges\n ? decorateEdges(createSequentialEdges(initialNodes), initialNodes)\n : createSequentialEdges(initialNodes);\n edgeDataHashRef.current = buildEdgeHashMap(edges);\n lastNodeCountRef.current = initialNodes.length;\n return edges;\n }, [decorateEdges, initialNodes]);\n\n const [edges, setEdges] = useState<Edge[]>(initialEdges);\n\n const modelHash = useMemo(\n () =>\n stableStringify({\n steps,\n parameters: normalizedParametersProp,\n output: normalizedOutputProp,\n }),\n [steps, normalizedParametersProp, normalizedOutputProp]\n );\n\n const cacheFingerprint = useMemo(\n () =>\n stableStringify({\n ids: scaffolderActionIds,\n inputs: scaffolderActionInputsById,\n outputs: scaffolderActionOutputsById,\n inputRequired: scaffolderActionInputRequiredById,\n }),\n [\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n ]\n );\n\n const lastAppliedModelHashRef = useRef<string | null>(null);\n const lastEmittedModelHashRef = useRef<string | null>(null);\n const lastCacheFingerprintRef = useRef<string | null>(null);\n const nodeHeightsRef = useRef<Record<string, number>>({});\n const lastViewportRef = useRef<Viewport | null>(null);\n const emitDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isDraggingRef = useRef(false);\n const [isDragging, setIsDragging] = useState(false);\n const emitAfterDragRef = useRef(false);\n const pendingInitialFitRef = useRef(true);\n const userMovedViewportRef = useRef(false);\n const layoutInitializedRef = useRef(false);\n const [viewport, setViewport] = useState<Viewport | null>(() => {\n const existing = lastViewportRef.current;\n if (existing) {\n return existing;\n }\n const fallback = { x: 0, y: 0, zoom: 1 };\n lastViewportRef.current = fallback;\n return fallback;\n });\n const fitViewRafRef = useRef<number | null>(null);\n const fitViewTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const alignDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const setViewportIfChanged = useCallback((next: Viewport | null) => {\n if (!next) {\n return;\n }\n const prev = lastViewportRef.current;\n if (\n prev &&\n prev.x === next.x &&\n prev.y === next.y &&\n prev.zoom === next.zoom\n ) {\n return;\n }\n lastViewportRef.current = next;\n setViewport(next);\n }, []);\n useEffect(() => {\n const isCacheChanged = cacheFingerprint !== lastCacheFingerprintRef.current;\n const prevAppliedModelHash = lastAppliedModelHashRef.current;\n\n if (modelHash === lastAppliedModelHashRef.current && !isCacheChanged) {\n return;\n }\n\n const builtNodes = buildNodesFromModel(\n steps,\n normalizedParametersProp,\n normalizedOutputProp,\n {\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n }\n );\n\n const nextNodes = decorateNodes ? decorateNodes(builtNodes) : builtNodes;\n const isInitialMount = !hasMountedRef.current;\n const shouldReplaceNodes =\n prevAppliedModelHash !== modelHash || isInitialMount;\n\n lastAppliedModelHashRef.current = modelHash;\n lastCacheFingerprintRef.current = cacheFingerprint;\n lastEmittedModelHashRef.current = modelHash;\n\n setNodes((currentNodes) => {\n if (shouldReplaceNodes) {\n nodeDataHashRef.current = buildNodeHashMap(nextNodes);\n nodeHeightsRef.current = {};\n return nextNodes;\n }\n return mergeNodesWithStability(currentNodes, nextNodes, nodeDataHashRef);\n });\n setEdges((currentEdges) => {\n const newEdges = decorateEdges\n ? decorateEdges(createSequentialEdges(nextNodes), nextNodes)\n : createSequentialEdges(nextNodes);\n if (shouldReplaceNodes) {\n edgeDataHashRef.current = buildEdgeHashMap(newEdges);\n return newEdges;\n }\n return mergeEdgesWithStability(currentEdges, newEdges, edgeDataHashRef);\n });\n hasMountedRef.current = true;\n lastNodeCountRef.current = nextNodes.length;\n if (isInitialMount) {\n pendingInitialFitRef.current = true;\n }\n }, [\n steps,\n normalizedParametersProp,\n normalizedOutputProp,\n modelHash,\n cacheFingerprint,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n decorateNodes,\n decorateEdges,\n setNodes,\n setEdges,\n ]);\n\n const lastParameterResizeRef = useRef<{\n id: string;\n prevHeight: number;\n nextHeight: number;\n } | null>(null);\n\n useEffect(() => {\n if (!nodes.length) {\n return;\n }\n\n if (nodes.some((node) => node.dragging)) {\n return;\n }\n\n const activeNodeIds = new Set<string>();\n let hasMeasuredChange = false;\n let parameterResize: {\n id: string;\n prevHeight: number;\n nextHeight: number;\n } | null = null;\n\n nodes.forEach((node) => {\n activeNodeIds.add(node.id);\n const measuredHeight = resolveNodeHeightForTracking(node);\n if (typeof measuredHeight !== \"number\") {\n return;\n }\n const previousHeight = nodeHeightsRef.current[node.id];\n const heightDelta =\n previousHeight === undefined\n ? Number.POSITIVE_INFINITY\n : Math.abs(previousHeight - measuredHeight);\n if (heightDelta >= 1) {\n if (node.type === \"parametersNode\") {\n parameterResize = {\n id: node.id,\n prevHeight: previousHeight ?? measuredHeight,\n nextHeight: measuredHeight,\n };\n }\n nodeHeightsRef.current[node.id] = measuredHeight;\n hasMeasuredChange = true;\n } else if (previousHeight === undefined) {\n // Initialize tracking even if we consider the change too small to react to layout.\n nodeHeightsRef.current[node.id] = measuredHeight;\n }\n });\n\n Object.keys(nodeHeightsRef.current).forEach((id) => {\n if (!activeNodeIds.has(id)) {\n delete nodeHeightsRef.current[id];\n }\n });\n\n if (!hasMeasuredChange) {\n return;\n }\n\n if (!layoutInitializedRef.current) {\n // Skip the first post-measure align to avoid initial jump; positions are already close to target.\n layoutInitializedRef.current = true;\n return;\n }\n\n lastParameterResizeRef.current = parameterResize;\n\n if (alignDebounceRef.current) {\n clearTimeout(alignDebounceRef.current);\n }\n alignDebounceRef.current = setTimeout(() => {\n alignDebounceRef.current = null;\n setNodes((currentNodes) => {\n const resize = lastParameterResizeRef.current;\n const updated = currentNodes.map((node) => {\n if (node.type !== \"parametersNode\") {\n return node;\n }\n if (!resize || resize.id !== node.id) {\n // Keep x locked even if there was no measured change.\n return {\n ...node,\n position: { ...node.position, x: FIXED_X_POSITION },\n };\n }\n const prevBottom = node.position.y + resize.prevHeight;\n const nextY = Math.max(0, prevBottom - resize.nextHeight);\n if (node.position.y === nextY) {\n return {\n ...node,\n position: { ...node.position, x: FIXED_X_POSITION },\n };\n }\n return {\n ...node,\n position: { x: FIXED_X_POSITION, y: nextY },\n };\n });\n\n const alignedNodes = alignNodes(\n updated,\n FIXED_X_POSITION,\n VERTICAL_SPACING\n );\n const positionsChanged = alignedNodes.some((node, index) => {\n const previousNode = currentNodes[index];\n if (!previousNode) {\n return true;\n }\n return (\n node.position.x !== previousNode.position.x ||\n node.position.y !== previousNode.position.y\n );\n });\n\n return positionsChanged ? alignedNodes : currentNodes;\n });\n }, VIEWPORT_TUNING.alignDebounceMs);\n }, [nodes, setNodes]);\n\n const parameterReferences = useMemo(\n () => collectParameterReferences(normalizedParametersProp),\n [normalizedParametersProp]\n );\n\n const stepOutputReferencesByNode = useMemo(\n () => collectStepOutputReferences(nodes, parameterReferences),\n [nodes, parameterReferences]\n );\n\n const onNodesChange = useCallback(\n (changes: NodeChange<Node>[]) =>\n setNodes((ns) => {\n if (\n changes.some(\n (change) => change.type === \"position\" && change.dragging\n )\n ) {\n isDraggingRef.current = true;\n setIsDragging(true);\n } else if (\n changes.some(\n (change) => change.type === \"position\" && change.dragging === false\n )\n ) {\n const stillDragging = ns.some((node) => node.dragging);\n isDraggingRef.current = stillDragging;\n setIsDragging(stillDragging);\n }\n return applyNodeChanges(changes, ns);\n }),\n [setNodes]\n );\n\n const onEdgesChange = useCallback(\n (changes: EdgeChange<Edge>[]) =>\n setEdges((es) => applyEdgeChanges(changes, es)),\n [setEdges]\n );\n\n const resolvedNodeTypes = useMemo<NodeTypes>(\n () => ({\n parametersNode: ((props: NodeProps) =>\n createElement(parametersNodeComponent, {\n data: props.data as ParametersNodeData,\n })) as ComponentType<NodeProps>,\n actionNode: ((props: NodeProps) =>\n createElement(actionNodeComponent, {\n data: props.data as ActionNodeData,\n })) as ComponentType<NodeProps>,\n outputNode: ((props: NodeProps) =>\n createElement(outputNodeComponent, {\n data: props.data as OutputNodeData,\n })) as ComponentType<NodeProps>,\n }),\n [actionNodeComponent, outputNodeComponent, parametersNodeComponent]\n );\n\n const onConnect = useCallback(\n (params: any) => setEdges((es) => addEdge(params, es)),\n [setEdges]\n );\n\n const reorderAndAlignNodes = useMemo(\n () =>\n createHandleReorderAndAlignNodes(setNodes, setEdges, {\n fixedXPosition: FIXED_X_POSITION,\n verticalSpacing: VERTICAL_SPACING,\n }),\n [setNodes, setEdges]\n );\n\n const onNodeDragStop = useCallback(\n (_: ReactMouseEvent, node: Node) => {\n isDraggingRef.current = false;\n setIsDragging(false);\n reorderAndAlignNodes(node);\n },\n [reorderAndAlignNodes]\n );\n\n const onUpdateField = useMemo(\n () => createHandleUpdateField(setNodes),\n [setNodes]\n );\n\n const onUpdateInput = useMemo(\n () => createHandleUpdateInput(setNodes),\n [setNodes]\n );\n\n const onRemoveInputKey = useMemo(\n () => createHandleRemoveInputKey(setNodes),\n [setNodes]\n );\n\n const onUpdateOutput = useMemo(\n () => createHandleUpdateOutput(setNodes),\n [setNodes]\n );\n\n const onUpdateSections = useMemo(\n () => createHandleUpdateSections(setNodes),\n [setNodes]\n );\n\n const handleAddNode = useMemo(\n () =>\n createHandleAddNode(setNodes, setEdges, {\n fixedXPosition: FIXED_X_POSITION,\n verticalSpacing: VERTICAL_SPACING,\n nodeDefaults,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionInputRequiredById,\n scaffolderActionOutputsById,\n onNodeAdded: (rfId: string) => {\n pendingFocusNodeIdRef.current = rfId;\n // Keep current zoom/viewport; focus will center on the new node.\n pendingInitialFitRef.current = false;\n },\n }),\n [\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n nodeDefaults,\n setNodes,\n setEdges,\n ]\n );\n\n const handleRemoveNode = useMemo(\n () =>\n createHandleRemoveNode(setNodes, setEdges, {\n fixedXPosition: FIXED_X_POSITION,\n verticalSpacing: VERTICAL_SPACING,\n }),\n [setNodes, setEdges]\n );\n\n const emitChanges = useCallback(() => {\n if (!onStepsChange && !onParametersChange && !onOutputChange) {\n return;\n }\n const stepsFromNodes = extractStepsFromNodes(nodes);\n const parametersFromNodes = extractParametersFromNodes(nodes);\n const outputFromNodes = extractOutputFromNodes(nodes);\n\n const nextHash = stableStringify({\n steps: stepsFromNodes,\n parameters: parametersFromNodes,\n output: outputFromNodes,\n });\n\n if (nextHash === lastEmittedModelHashRef.current) {\n return;\n }\n\n lastEmittedModelHashRef.current = nextHash;\n onStepsChange?.(stepsFromNodes);\n onParametersChange?.(parametersFromNodes);\n onOutputChange?.(outputFromNodes);\n }, [\n nodes,\n onOutputChange,\n onParametersChange,\n onStepsChange,\n lastEmittedModelHashRef,\n ]);\n\n const emitChangesDeferred = useCallback(() => {\n if (emitDebounceRef.current) {\n clearTimeout(emitDebounceRef.current);\n }\n emitDebounceRef.current = setTimeout(() => {\n emitChanges();\n emitDebounceRef.current = null;\n }, EMIT_DEBOUNCE_MS);\n }, [emitChanges]);\n\n const flushPendingEmit = useCallback(() => {\n if (emitDebounceRef.current) {\n clearTimeout(emitDebounceRef.current);\n emitDebounceRef.current = null;\n }\n emitChanges();\n }, [emitChanges]);\n\n // Hoist handler/data refs into state so ReactFlow sees unchanged node objects when nothing relevant changed.\n const ensureNodeDataStability = useCallback(\n (node: Node): Node => {\n if (node.type === \"actionNode\") {\n const data = node.data as ActionNodeData;\n const nextRefs =\n stepOutputReferencesByNode[node.id] ?? data.stepOutputReferences;\n const refsUnchanged = shallowArrayEqual(\n data.stepOutputReferences,\n nextRefs\n );\n\n const hasSameHandlers =\n data.onAddNode === handleAddNode &&\n data.onRemoveNode === handleRemoveNode &&\n data.onUpdateField === onUpdateField &&\n data.onUpdateInput === onUpdateInput &&\n data.onRemoveInputKey === onRemoveInputKey;\n const hasSameCaches =\n data.scaffolderActionIds === scaffolderActionIds &&\n data.scaffolderActionInputsById === scaffolderActionInputsById &&\n data.scaffolderActionOutputsById === scaffolderActionOutputsById &&\n data.scaffolderActionInputRequiredById ===\n scaffolderActionInputRequiredById;\n\n if (hasSameHandlers && hasSameCaches && refsUnchanged) {\n return node;\n }\n\n return {\n ...node,\n data: {\n ...data,\n onAddNode: handleAddNode,\n onRemoveNode: handleRemoveNode,\n onUpdateField,\n onUpdateInput,\n onRemoveInputKey,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n stepOutputReferences: refsUnchanged\n ? data.stepOutputReferences\n : nextRefs,\n },\n };\n }\n\n if (node.type === \"outputNode\") {\n const data = node.data as OutputNodeData;\n const nextRefs =\n stepOutputReferencesByNode[node.id] ?? data.stepOutputReferences;\n const refsUnchanged = shallowArrayEqual(\n data.stepOutputReferences,\n nextRefs\n );\n const hasSameHandlers =\n data.onUpdateOutput === onUpdateOutput &&\n data.onRemoveNode === handleRemoveNode &&\n data.onAddNode === handleAddNode;\n\n const hasSameCaches =\n data.scaffolderActionIds === scaffolderActionIds &&\n data.scaffolderActionInputsById === scaffolderActionInputsById &&\n data.scaffolderActionOutputsById === scaffolderActionOutputsById &&\n data.scaffolderActionInputRequiredById ===\n scaffolderActionInputRequiredById;\n\n if (hasSameHandlers && hasSameCaches && refsUnchanged) {\n return node;\n }\n\n return {\n ...node,\n data: {\n ...data,\n onUpdateOutput,\n onRemoveNode: handleRemoveNode,\n onAddNode: handleAddNode,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n stepOutputReferences: refsUnchanged\n ? data.stepOutputReferences\n : nextRefs,\n },\n };\n }\n\n if (node.type === \"parametersNode\") {\n const data = node.data as ParametersNodeData;\n const hasSameHandlers =\n data.onUpdateSections === onUpdateSections &&\n data.onRemoveNode === handleRemoveNode &&\n data.onAddNode === handleAddNode;\n const hasSameCaches =\n data.scaffolderActionIds === scaffolderActionIds &&\n data.scaffolderActionInputsById === scaffolderActionInputsById &&\n data.scaffolderActionOutputsById === scaffolderActionOutputsById &&\n data.scaffolderActionInputRequiredById ===\n scaffolderActionInputRequiredById;\n\n if (hasSameHandlers && hasSameCaches) {\n return node;\n }\n\n return {\n ...node,\n data: {\n ...data,\n onUpdateSections,\n onRemoveNode: handleRemoveNode,\n onAddNode: handleAddNode,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n },\n };\n }\n\n return node;\n },\n [\n handleAddNode,\n handleRemoveNode,\n onUpdateField,\n onUpdateInput,\n onRemoveInputKey,\n onUpdateOutput,\n onUpdateSections,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n stepOutputReferencesByNode,\n ]\n );\n\n useEffect(() => {\n setNodes((currentNodes) => {\n let changed = false;\n const nextNodes = currentNodes.map((node) => {\n const updated = ensureNodeDataStability(node);\n if (updated !== node) {\n changed = true;\n }\n return updated;\n });\n\n // Returning the same array keeps ReactFlow nodes prop stable unless something truly changed.\n return changed ? nextNodes : currentNodes;\n });\n }, [ensureNodeDataStability, setNodes]);\n\n useEffect(() => {\n emitChangesDeferred();\n }, [nodes, emitChangesDeferred]);\n\n useEffect(() => {\n // Force next emit to run even if hash matches, so input edits flush to YAML.\n lastEmittedModelHashRef.current = null;\n }, [nodes]);\n\n useEffect(() => {\n if (!nodes.length) {\n return;\n }\n emitChangesDeferred();\n }, [emitChangesDeferred, modelHash, nodes]);\n\n useEffect(() => {\n return () => {\n if (emitDebounceRef.current) {\n clearTimeout(emitDebounceRef.current);\n }\n if (fitViewRafRef.current !== null) {\n cancelAnimationFrame(fitViewRafRef.current);\n fitViewRafRef.current = null;\n }\n if (fitViewTimeoutRef.current) {\n clearTimeout(fitViewTimeoutRef.current);\n fitViewTimeoutRef.current = null;\n }\n if (alignDebounceRef.current) {\n clearTimeout(alignDebounceRef.current);\n }\n flushPendingEmit();\n };\n }, [flushPendingEmit]);\n\n const [reactFlowInstance, setReactFlowInstance] =\n useState<ReactFlowInstance | null>(null);\n const fitFlowToView = useCallback(() => {\n if (!reactFlowInstance || !nodes.length) {\n return;\n }\n if (fitViewRafRef.current !== null) {\n return;\n }\n if (userMovedViewportRef.current && !pendingInitialFitRef.current) {\n // Respect user navigation; don't snap back after they moved the camera.\n return;\n }\n const nodeWithWidth = nodes.find((node) => node.width);\n const nodeWidth = nodeWithWidth?.width ?? 760;\n const padding = Math.max((window.innerWidth - nodeWidth) / 2 - 24, 60);\n const viewOptions = {\n padding,\n minZoom: 0.2,\n };\n // Delay fitView to the next frame to avoid ResizeObserver loops while nodes mount/measure.\n fitViewRafRef.current = window.requestAnimationFrame(() => {\n fitViewRafRef.current = null;\n try {\n reactFlowInstance.fitView(viewOptions);\n setViewportIfChanged(reactFlowInstance.getViewport());\n } catch {\n // Swallow rare layout timing errors; the next change will try again.\n }\n });\n // Fallback in case RAF is skipped (tab in background).\n if (fitViewTimeoutRef.current) {\n clearTimeout(fitViewTimeoutRef.current);\n }\n fitViewTimeoutRef.current = setTimeout(() => {\n fitViewTimeoutRef.current = null;\n try {\n reactFlowInstance.fitView(viewOptions);\n setViewportIfChanged(reactFlowInstance.getViewport());\n } catch {\n // Ignore; typically triggered only during tab throttling.\n }\n }, VIEWPORT_TUNING.fitFallbackDelayMs);\n }, [nodes, reactFlowInstance, setViewportIfChanged]);\n\n useEffect(() => {\n if (!reactFlowInstance) {\n return;\n }\n if (viewport === null) {\n setViewportIfChanged(viewport);\n }\n if (!pendingInitialFitRef.current) {\n return;\n }\n pendingInitialFitRef.current = false;\n fitFlowToView();\n }, [\n fitFlowToView,\n nodes,\n edges,\n reactFlowInstance,\n viewport,\n setViewportIfChanged,\n ]);\n\n useEffect(() => {\n const swallowResizeObserverError = (event: ErrorEvent) => {\n const message =\n event?.message || (event as any)?.error?.message || String(event);\n if (\n typeof message === \"string\" &&\n message.includes(\"ResizeObserver loop\")\n ) {\n // Prevent dev overlay noise for benign ResizeObserver timing loops that appear after fitView/layout.\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n };\n const swallowResizeObserverRejection = (event: PromiseRejectionEvent) => {\n const message = (event.reason as any)?.message ?? String(event.reason);\n if (\n typeof message === \"string\" &&\n message.includes(\"ResizeObserver loop\")\n ) {\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n };\n window.addEventListener(\"error\", swallowResizeObserverError, true);\n window.addEventListener(\n \"unhandledrejection\",\n swallowResizeObserverRejection,\n true\n );\n // Chrome/FF dispatch a dedicated event for this condition; capture it to prevent overlay noise.\n const swallowLoopErrorEvent = (event: Event) => {\n event.preventDefault();\n event.stopImmediatePropagation();\n };\n window.addEventListener(\n \"resizeobserverlooperror\" as any,\n swallowLoopErrorEvent,\n true\n );\n return () => {\n window.removeEventListener(\"error\", swallowResizeObserverError, true);\n window.removeEventListener(\n \"unhandledrejection\",\n swallowResizeObserverRejection,\n true\n );\n window.removeEventListener(\n \"resizeobserverlooperror\" as any,\n swallowLoopErrorEvent,\n true\n );\n };\n }, []);\n\n useEffect(() => {\n if (!reactFlowInstance) {\n return undefined;\n }\n window.addEventListener(\"resize\", fitFlowToView);\n return () => {\n window.removeEventListener(\"resize\", fitFlowToView);\n };\n }, [fitFlowToView, reactFlowInstance]);\n\n useEffect(() => {\n if (!isDragging) {\n if (emitAfterDragRef.current) {\n emitAfterDragRef.current = false;\n lastEmittedModelHashRef.current = null;\n }\n // Trigger emit cycle after drag ends so external state is up to date.\n lastEmittedModelHashRef.current = null;\n }\n }, [isDragging]);\n\n const handleMoveEnd: OnMoveEnd = useCallback(\n (_event, nextViewport: Viewport) => {\n // Keep zoom stable to optionally cull edges when zoomed out.\n setViewportIfChanged(nextViewport);\n },\n [setViewportIfChanged]\n );\n\n const handleMove: OnMove = useCallback(\n (_, nextViewport) => {\n userMovedViewportRef.current = true;\n setViewportIfChanged(nextViewport);\n },\n [setViewportIfChanged]\n );\n\n const shouldCullEdges =\n edges.length > 300 && (viewport?.zoom ?? 1) < 0.3 && !isDragging;\n const renderedEdges = useMemo(\n () =>\n shouldCullEdges\n ? EMPTY_EDGES // Dropping edges when zoomed out keeps canvas responsive with huge graphs.\n : edges,\n [edges, shouldCullEdges]\n );\n\n useEffect(() => {\n if (!reactFlowInstance) {\n return;\n }\n const pendingId = pendingFocusNodeIdRef.current;\n if (!pendingId) {\n return;\n }\n const target = nodes.find((node) => node.id === pendingId);\n if (!target) {\n return;\n }\n pendingFocusNodeIdRef.current = null;\n const nodeCenterX = target.position.x + (target.width ?? 0) / 2;\n const nodeCenterY = target.position.y + (target.height ?? 0) / 2;\n const zoom = viewport?.zoom ?? lastViewportRef.current?.zoom ?? undefined;\n try {\n reactFlowInstance.setCenter(nodeCenterX, nodeCenterY, {\n zoom,\n duration: VIEWPORT_TUNING.centerDurationMs,\n });\n window.requestAnimationFrame(() => {\n setViewportIfChanged(reactFlowInstance.getViewport());\n });\n } catch {\n // ignore\n }\n }, [nodes, reactFlowInstance, viewport, setViewportIfChanged]);\n\n return (\n <div style={{ width: \"100%\", height: \"100%\", minHeight: \"100%\" }}>\n <ReactFlow\n nodes={nodes}\n edges={renderedEdges}\n nodeTypes={resolvedNodeTypes}\n defaultViewport={\n viewport ?? {\n x: 0,\n y: 0,\n zoom: 1,\n }\n }\n viewport={viewport ?? undefined}\n onNodesChange={onNodesChange}\n onEdgesChange={onEdgesChange}\n onNodeDragStop={onNodeDragStop}\n onConnect={onConnect}\n onMove={handleMove}\n onlyRenderVisibleElements\n onInit={setReactFlowInstance}\n onMoveEnd={handleMoveEnd}\n />\n </div>\n );\n}\n"],"names":["nodeDefaults","baseNodeDefaults","nodes","edges"],"mappings":"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"}
1
+ {"version":3,"file":"DesignerFlow.esm.js","sources":["../../src/designerFlow/DesignerFlow.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n ComponentType,\n createElement,\n useLayoutEffect,\n} from \"react\";\nimport type { MouseEvent as ReactMouseEvent } from \"react\";\nimport {\n ReactFlow,\n applyNodeChanges,\n applyEdgeChanges,\n addEdge,\n Node,\n Edge,\n NodeChange,\n EdgeChange,\n useNodesState,\n ReactFlowInstance,\n NodeProps,\n NodeTypes,\n Viewport,\n OnMoveEnd,\n OnMove,\n MiniMap,\n ReactFlowProvider,\n} from \"@xyflow/react\";\nimport { Box, Button } from \"@material-ui/core\";\nimport \"@xyflow/react/dist/style.css\";\nimport type {\n ScaffolderTaskOutput,\n TaskStep,\n} from \"@backstage/plugin-scaffolder-common\";\nimport type {\n ActionNodeData,\n OutputNodeData,\n ParametersNodeData,\n TemplateParametersValue,\n} from \"../types/flowNodes\";\nimport {\n buildNodesFromModel,\n collectParameterReferences,\n collectStepOutputReferences,\n stableStringify,\n extractStepsFromNodes,\n extractParametersFromNodes,\n extractOutputFromNodes,\n} from \"./model\";\nimport { createSequentialEdges } from \"../utils/createSequentialEdges\";\nimport {\n buildEdgeHashMap,\n buildNodeHashMap,\n mergeEdgesWithStability,\n mergeNodesWithStability,\n} from \"./utils/stableComparators\";\nimport {\n createHandleAddNode,\n createHandleRemoveNode,\n createHandleRemoveInputKey,\n createHandleReorderAndAlignNodes,\n createHandleUpdateField,\n createHandleUpdateInput,\n createHandleUpdateOutput,\n createHandleUpdateSections,\n} from \"./handlers\";\nimport { alignNodes, resolveNodeHeightForTracking } from \"./nodeLayout\";\nimport {\n FLOW_LAYOUT,\n nodeDefaults as baseNodeDefaults,\n} from \"../components/designerFlowConfig\";\nimport { useScaffolderActions } from \"../api/useScaffolderActions\";\n\nconst EMPTY_EDGES: Edge[] = [];\nconst EMIT_DEBOUNCE_MS = 1200; // Emit only after user pauses typing for a bit (more relaxed UX).\nconst VIEWPORT_TUNING = {\n alignDebounceMs: 120, // Debounce view/align updates so typing isn't interrupted by layout thrash.\n centerDurationMs: 420,\n fitFallbackDelayMs: 50,\n};\n\n// Prevent benign ResizeObserver loop errors from bubbling to the dev overlay.\nif (\n typeof window !== \"undefined\" &&\n !(window as any).__rfResizeObserverPatched\n) {\n (window as any).__rfResizeObserverPatched = true;\n // Wrap ResizeObserver callbacks in rAF to avoid sync measurement loops that trigger the warning.\n if (typeof window.ResizeObserver === \"function\") {\n const OriginalResizeObserver = window.ResizeObserver;\n window.ResizeObserver = class extends OriginalResizeObserver {\n constructor(callback: ResizeObserverCallback) {\n super((entries, observer) => {\n window.requestAnimationFrame(() => callback(entries, observer));\n });\n }\n } as typeof ResizeObserver;\n }\n const shouldSwallow = (message: unknown) =>\n typeof message === \"string\" &&\n message.includes(\"ResizeObserver loop completed with undelivered\");\n const swallowResizeObserverError = (event: ErrorEvent) => {\n const message =\n event?.message || (event as any)?.error?.message || String(event);\n if (shouldSwallow(message)) {\n event.preventDefault();\n event.stopImmediatePropagation();\n return true;\n }\n return undefined;\n };\n const swallowResizeObserverRejection = (event: PromiseRejectionEvent) => {\n const message = (event.reason as any)?.message ?? String(event.reason);\n if (shouldSwallow(message)) {\n event.preventDefault();\n event.stopImmediatePropagation();\n return true;\n }\n return undefined;\n };\n const swallowLoopEvent = (event: Event) => {\n event.preventDefault();\n event.stopImmediatePropagation();\n };\n const originalOnError = window.onerror;\n window.onerror = function handleResizeObserverOnError(\n message,\n source,\n lineno,\n colno,\n error\n ): boolean | void {\n if (\n shouldSwallow(\n typeof message === \"string\"\n ? message\n : (error as any)?.message ?? String(message)\n )\n ) {\n return true;\n }\n if (typeof originalOnError === \"function\") {\n return originalOnError(message, source, lineno, colno, error);\n }\n return undefined;\n };\n const originalOnUnhandledRejection = window.onunhandledrejection;\n window.onunhandledrejection = function handleResizeObserverOnUnhandled(\n event\n ) {\n const reason = (event as any)?.reason;\n const message =\n (reason as any)?.message ?? (typeof reason === \"string\" ? reason : \"\");\n if (shouldSwallow(message)) {\n return true;\n }\n if (typeof originalOnUnhandledRejection === \"function\") {\n return (originalOnUnhandledRejection as any)(event);\n }\n return undefined;\n };\n window.addEventListener(\"error\", swallowResizeObserverError, true);\n window.addEventListener(\n \"unhandledrejection\",\n swallowResizeObserverRejection,\n true\n );\n window.addEventListener(\n \"resizeobserverlooperror\" as any,\n swallowLoopEvent,\n true\n );\n}\n\nconst shallowArrayEqual = (a?: string[], b?: string[]) => {\n if (a === b) {\n return true;\n }\n if (!a || !b || a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i += 1) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n};\n\n// Main orchestration component that renders and synchronizes the Designer flow.\n\nconst FIXED_X_POSITION = FLOW_LAYOUT.fixedXPosition;\nconst VERTICAL_SPACING = FLOW_LAYOUT.verticalSpacing;\nconst HORIZONTAL_PAN_RANGE = 5000; // limit horizontal pan; graph is vertical so we keep it near the fixed X\n\nexport type DesignerFlowProps = {\n steps?: TaskStep[];\n parameters?: TemplateParametersValue;\n output?: ScaffolderTaskOutput | null;\n onStepsChange?: (steps: TaskStep[]) => void;\n onParametersChange?: (parameters: TemplateParametersValue) => void;\n onOutputChange?: (output: ScaffolderTaskOutput | undefined) => void;\n actionNodeComponent: ComponentType<{ data: ActionNodeData }>;\n parametersNodeComponent: ComponentType<{ data: ParametersNodeData }>;\n outputNodeComponent: ComponentType<{ data: OutputNodeData }>;\n showMiniMap?: boolean;\n decorateNodes?: (nodes: Node[]) => Node[];\n decorateEdges?: (edges: Edge[], nodes: Node[]) => Edge[];\n nodeDefaults?: Partial<Node>;\n};\n\nexport default function DesignerFlow({\n steps = [],\n parameters,\n output,\n onStepsChange,\n onParametersChange,\n onOutputChange,\n actionNodeComponent,\n parametersNodeComponent,\n outputNodeComponent,\n showMiniMap = false,\n decorateNodes,\n decorateEdges,\n nodeDefaults = baseNodeDefaults,\n}: DesignerFlowProps) {\n const nodeDataHashRef = useRef<Record<string, string>>({});\n const edgeDataHashRef = useRef<Record<string, string>>({});\n const scaffolderActionsCache = useScaffolderActions();\n\n const {\n ids: scaffolderActionIds,\n inputsById: scaffolderActionInputsById,\n outputsById: scaffolderActionOutputsById,\n inputRequiredById: scaffolderActionInputRequiredById,\n } = scaffolderActionsCache;\n\n const normalizedParametersProp = parameters ?? undefined;\n const normalizedOutputProp = output ?? null;\n const pendingFocusNodeIdRef = useRef<string | null>(null);\n const hasMountedRef = useRef(false);\n const lastNodeCountRef = useRef(0);\n\n const initialNodes = useMemo(() => {\n const built = buildNodesFromModel(\n steps,\n normalizedParametersProp,\n normalizedOutputProp,\n {\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n }\n );\n const nodes = decorateNodes ? decorateNodes(built) : built;\n nodeDataHashRef.current = buildNodeHashMap(nodes);\n return nodes;\n }, [\n steps,\n normalizedParametersProp,\n normalizedOutputProp,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n decorateNodes,\n ]);\n\n const [nodes, setNodes] = useNodesState(initialNodes);\n const initialEdges = useMemo(() => {\n const edges = decorateEdges\n ? decorateEdges(createSequentialEdges(initialNodes), initialNodes)\n : createSequentialEdges(initialNodes);\n edgeDataHashRef.current = buildEdgeHashMap(edges);\n lastNodeCountRef.current = initialNodes.length;\n return edges;\n }, [decorateEdges, initialNodes]);\n\n const [edges, setEdges] = useState<Edge[]>(initialEdges);\n\n const modelHash = useMemo(\n () =>\n stableStringify({\n steps,\n parameters: normalizedParametersProp,\n output: normalizedOutputProp,\n }),\n [steps, normalizedParametersProp, normalizedOutputProp]\n );\n\n const cacheFingerprint = useMemo(\n () =>\n stableStringify({\n ids: scaffolderActionIds,\n inputs: scaffolderActionInputsById,\n outputs: scaffolderActionOutputsById,\n inputRequired: scaffolderActionInputRequiredById,\n }),\n [\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n ]\n );\n\n const lastAppliedModelHashRef = useRef<string | null>(null);\n const lastEmittedModelHashRef = useRef<string | null>(null);\n const lastCacheFingerprintRef = useRef<string | null>(null);\n const nodeHeightsRef = useRef<Record<string, number>>({});\n const lastViewportRef = useRef<Viewport | null>(null);\n const emitDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isDraggingRef = useRef(false);\n const [isDragging, setIsDragging] = useState(false);\n const emitAfterDragRef = useRef(false);\n const pendingInitialFitRef = useRef(true);\n const userMovedViewportRef = useRef(false);\n const layoutInitializedRef = useRef(false);\n const [viewport, setViewport] = useState<Viewport | null>(() => {\n const existing = lastViewportRef.current;\n if (existing) {\n return existing;\n }\n const fallback = { x: 0, y: 0, zoom: 1 };\n lastViewportRef.current = fallback;\n return fallback;\n });\n const [miniMapVisible, setMiniMapVisible] = useState(showMiniMap);\n const fitViewRafRef = useRef<number | null>(null);\n const fitViewTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const alignDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const setViewportIfChanged = useCallback((next: Viewport | null) => {\n if (!next) {\n return;\n }\n const prev = lastViewportRef.current;\n if (\n prev &&\n prev.x === next.x &&\n prev.y === next.y &&\n prev.zoom === next.zoom\n ) {\n return;\n }\n lastViewportRef.current = next;\n setViewport(next);\n }, []);\n useEffect(() => {\n const isCacheChanged = cacheFingerprint !== lastCacheFingerprintRef.current;\n const prevAppliedModelHash = lastAppliedModelHashRef.current;\n\n if (modelHash === lastAppliedModelHashRef.current && !isCacheChanged) {\n return;\n }\n\n const builtNodes = buildNodesFromModel(\n steps,\n normalizedParametersProp,\n normalizedOutputProp,\n {\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n }\n );\n\n const nextNodes = decorateNodes ? decorateNodes(builtNodes) : builtNodes;\n const isInitialMount = !hasMountedRef.current;\n const shouldReplaceNodes =\n prevAppliedModelHash !== modelHash || isInitialMount;\n\n lastAppliedModelHashRef.current = modelHash;\n lastCacheFingerprintRef.current = cacheFingerprint;\n lastEmittedModelHashRef.current = modelHash;\n\n setNodes((currentNodes) => {\n if (shouldReplaceNodes) {\n nodeDataHashRef.current = buildNodeHashMap(nextNodes);\n nodeHeightsRef.current = {};\n return nextNodes;\n }\n return mergeNodesWithStability(currentNodes, nextNodes, nodeDataHashRef);\n });\n setEdges((currentEdges) => {\n const newEdges = decorateEdges\n ? decorateEdges(createSequentialEdges(nextNodes), nextNodes)\n : createSequentialEdges(nextNodes);\n if (shouldReplaceNodes) {\n edgeDataHashRef.current = buildEdgeHashMap(newEdges);\n return newEdges;\n }\n return mergeEdgesWithStability(currentEdges, newEdges, edgeDataHashRef);\n });\n hasMountedRef.current = true;\n lastNodeCountRef.current = nextNodes.length;\n if (isInitialMount) {\n pendingInitialFitRef.current = true;\n }\n }, [\n steps,\n normalizedParametersProp,\n normalizedOutputProp,\n modelHash,\n cacheFingerprint,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n decorateNodes,\n decorateEdges,\n setNodes,\n setEdges,\n ]);\n\n const lastParameterResizeRef = useRef<{\n id: string;\n prevHeight: number;\n nextHeight: number;\n } | null>(null);\n\n useLayoutEffect(() => {\n if (!nodes.length) {\n return;\n }\n\n if (nodes.some((node) => node.dragging)) {\n return;\n }\n\n const activeNodeIds = new Set<string>();\n let hasMeasuredChange = false;\n let parameterResize: {\n id: string;\n prevHeight: number;\n nextHeight: number;\n } | null = null;\n\n nodes.forEach((node) => {\n activeNodeIds.add(node.id);\n const measuredHeight = resolveNodeHeightForTracking(node);\n if (typeof measuredHeight !== \"number\") {\n return;\n }\n const previousHeight = nodeHeightsRef.current[node.id];\n const heightDelta =\n previousHeight === undefined\n ? Number.POSITIVE_INFINITY\n : Math.abs(previousHeight - measuredHeight);\n if (heightDelta >= 1) {\n if (node.type === \"parametersNode\") {\n parameterResize = {\n id: node.id,\n prevHeight: previousHeight ?? measuredHeight,\n nextHeight: measuredHeight,\n };\n }\n nodeHeightsRef.current[node.id] = measuredHeight;\n hasMeasuredChange = true;\n } else if (previousHeight === undefined) {\n // Initialize tracking even if we consider the change too small to react to layout.\n nodeHeightsRef.current[node.id] = measuredHeight;\n }\n });\n\n Object.keys(nodeHeightsRef.current).forEach((id) => {\n if (!activeNodeIds.has(id)) {\n delete nodeHeightsRef.current[id];\n }\n });\n\n if (!hasMeasuredChange) {\n return;\n }\n\n lastParameterResizeRef.current = parameterResize;\n\n setNodes((currentNodes) => {\n const resize = lastParameterResizeRef.current;\n const updated = currentNodes.map((node) => {\n if (node.type !== \"parametersNode\") {\n return node;\n }\n if (!resize || resize.id !== node.id) {\n // Keep x locked even if there was no measured change.\n return {\n ...node,\n position: { ...node.position, x: FIXED_X_POSITION },\n };\n }\n const prevBottom = node.position.y + resize.prevHeight;\n const nextY = Math.max(0, prevBottom - resize.nextHeight);\n if (node.position.y === nextY) {\n return {\n ...node,\n position: { ...node.position, x: FIXED_X_POSITION },\n };\n }\n return {\n ...node,\n position: { x: FIXED_X_POSITION, y: nextY },\n };\n });\n\n const alignedNodes = alignNodes(\n updated,\n FIXED_X_POSITION,\n VERTICAL_SPACING\n );\n const positionsChanged = alignedNodes.some((node, index) => {\n const previousNode = currentNodes[index];\n if (!previousNode) {\n return true;\n }\n return (\n node.position.x !== previousNode.position.x ||\n node.position.y !== previousNode.position.y\n );\n });\n\n return positionsChanged ? alignedNodes : currentNodes;\n });\n layoutInitializedRef.current = true;\n }, [nodes, setNodes]);\n\n const parameterReferences = useMemo(\n () => collectParameterReferences(normalizedParametersProp),\n [normalizedParametersProp]\n );\n\n const stepOutputReferencesByNode = useMemo(\n () => collectStepOutputReferences(nodes, parameterReferences),\n [nodes, parameterReferences]\n );\n\n const onNodesChange = useCallback(\n (changes: NodeChange<Node>[]) =>\n setNodes((ns) => {\n if (\n changes.some(\n (change) => change.type === \"position\" && change.dragging\n )\n ) {\n isDraggingRef.current = true;\n setIsDragging(true);\n } else if (\n changes.some(\n (change) => change.type === \"position\" && change.dragging === false\n )\n ) {\n const stillDragging = ns.some((node) => node.dragging);\n isDraggingRef.current = stillDragging;\n setIsDragging(stillDragging);\n }\n return applyNodeChanges(changes, ns);\n }),\n [setNodes]\n );\n\n const onEdgesChange = useCallback(\n (changes: EdgeChange<Edge>[]) =>\n setEdges((es) => applyEdgeChanges(changes, es)),\n [setEdges]\n );\n\n const resolvedNodeTypes = useMemo<NodeTypes>(\n () => ({\n parametersNode: ((props: NodeProps) =>\n createElement(parametersNodeComponent, {\n data: props.data as ParametersNodeData,\n })) as ComponentType<NodeProps>,\n actionNode: ((props: NodeProps) =>\n createElement(actionNodeComponent, {\n data: props.data as ActionNodeData,\n })) as ComponentType<NodeProps>,\n outputNode: ((props: NodeProps) =>\n createElement(outputNodeComponent, {\n data: props.data as OutputNodeData,\n })) as ComponentType<NodeProps>,\n }),\n [actionNodeComponent, outputNodeComponent, parametersNodeComponent]\n );\n\n const onConnect = useCallback(\n (params: any) => setEdges((es) => addEdge(params, es)),\n [setEdges]\n );\n\n const reorderAndAlignNodes = useMemo(\n () =>\n createHandleReorderAndAlignNodes(setNodes, setEdges, {\n fixedXPosition: FIXED_X_POSITION,\n verticalSpacing: VERTICAL_SPACING,\n }),\n [setNodes, setEdges]\n );\n\n const onNodeDragStop = useCallback(\n (_: ReactMouseEvent, node: Node) => {\n isDraggingRef.current = false;\n setIsDragging(false);\n reorderAndAlignNodes(node);\n },\n [reorderAndAlignNodes]\n );\n\n const onUpdateField = useMemo(\n () => createHandleUpdateField(setNodes),\n [setNodes]\n );\n\n const onUpdateInput = useMemo(\n () => createHandleUpdateInput(setNodes),\n [setNodes]\n );\n\n const onRemoveInputKey = useMemo(\n () => createHandleRemoveInputKey(setNodes),\n [setNodes]\n );\n\n const onUpdateOutput = useMemo(\n () => createHandleUpdateOutput(setNodes),\n [setNodes]\n );\n\n const onUpdateSections = useMemo(\n () => createHandleUpdateSections(setNodes),\n [setNodes]\n );\n\n const handleAddNode = useMemo(\n () =>\n createHandleAddNode(setNodes, setEdges, {\n fixedXPosition: FIXED_X_POSITION,\n verticalSpacing: VERTICAL_SPACING,\n nodeDefaults,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionInputRequiredById,\n scaffolderActionOutputsById,\n onNodeAdded: (rfId: string) => {\n pendingFocusNodeIdRef.current = rfId;\n // Keep current zoom/viewport; focus will center on the new node.\n pendingInitialFitRef.current = false;\n },\n }),\n [\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n nodeDefaults,\n setNodes,\n setEdges,\n ]\n );\n\n const handleRemoveNode = useMemo(\n () =>\n createHandleRemoveNode(setNodes, setEdges, {\n fixedXPosition: FIXED_X_POSITION,\n verticalSpacing: VERTICAL_SPACING,\n }),\n [setNodes, setEdges]\n );\n\n const emitChanges = useCallback(() => {\n if (!onStepsChange && !onParametersChange && !onOutputChange) {\n return;\n }\n const stepsFromNodes = extractStepsFromNodes(nodes);\n const parametersFromNodes = extractParametersFromNodes(nodes);\n const outputFromNodes = extractOutputFromNodes(nodes);\n\n const nextHash = stableStringify({\n steps: stepsFromNodes,\n parameters: parametersFromNodes,\n output: outputFromNodes,\n });\n\n if (nextHash === lastEmittedModelHashRef.current) {\n return;\n }\n\n lastEmittedModelHashRef.current = nextHash;\n onStepsChange?.(stepsFromNodes);\n onParametersChange?.(parametersFromNodes);\n onOutputChange?.(outputFromNodes);\n }, [\n nodes,\n onOutputChange,\n onParametersChange,\n onStepsChange,\n lastEmittedModelHashRef,\n ]);\n\n const emitChangesDeferred = useCallback(() => {\n if (emitDebounceRef.current) {\n clearTimeout(emitDebounceRef.current);\n }\n emitDebounceRef.current = setTimeout(() => {\n emitChanges();\n emitDebounceRef.current = null;\n }, EMIT_DEBOUNCE_MS);\n }, [emitChanges]);\n\n const flushPendingEmit = useCallback(() => {\n if (emitDebounceRef.current) {\n clearTimeout(emitDebounceRef.current);\n emitDebounceRef.current = null;\n }\n emitChanges();\n }, [emitChanges]);\n\n // Hoist handler/data refs into state so ReactFlow sees unchanged node objects when nothing relevant changed.\n const ensureNodeDataStability = useCallback(\n (node: Node): Node => {\n if (node.type === \"actionNode\") {\n const data = node.data as ActionNodeData;\n const nextRefs =\n stepOutputReferencesByNode[node.id] ?? data.stepOutputReferences;\n const refsUnchanged = shallowArrayEqual(\n data.stepOutputReferences,\n nextRefs\n );\n\n const hasSameHandlers =\n data.onAddNode === handleAddNode &&\n data.onRemoveNode === handleRemoveNode &&\n data.onUpdateField === onUpdateField &&\n data.onUpdateInput === onUpdateInput &&\n data.onRemoveInputKey === onRemoveInputKey;\n const hasSameCaches =\n data.scaffolderActionIds === scaffolderActionIds &&\n data.scaffolderActionInputsById === scaffolderActionInputsById &&\n data.scaffolderActionOutputsById === scaffolderActionOutputsById &&\n data.scaffolderActionInputRequiredById ===\n scaffolderActionInputRequiredById;\n\n if (hasSameHandlers && hasSameCaches && refsUnchanged) {\n return node;\n }\n\n return {\n ...node,\n data: {\n ...data,\n onAddNode: handleAddNode,\n onRemoveNode: handleRemoveNode,\n onUpdateField,\n onUpdateInput,\n onRemoveInputKey,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n stepOutputReferences: refsUnchanged\n ? data.stepOutputReferences\n : nextRefs,\n },\n };\n }\n\n if (node.type === \"outputNode\") {\n const data = node.data as OutputNodeData;\n const nextRefs =\n stepOutputReferencesByNode[node.id] ?? data.stepOutputReferences;\n const refsUnchanged = shallowArrayEqual(\n data.stepOutputReferences,\n nextRefs\n );\n const hasSameHandlers =\n data.onUpdateOutput === onUpdateOutput &&\n data.onRemoveNode === handleRemoveNode &&\n data.onAddNode === handleAddNode;\n\n const hasSameCaches =\n data.scaffolderActionIds === scaffolderActionIds &&\n data.scaffolderActionInputsById === scaffolderActionInputsById &&\n data.scaffolderActionOutputsById === scaffolderActionOutputsById &&\n data.scaffolderActionInputRequiredById ===\n scaffolderActionInputRequiredById;\n\n if (hasSameHandlers && hasSameCaches && refsUnchanged) {\n return node;\n }\n\n return {\n ...node,\n data: {\n ...data,\n onUpdateOutput,\n onRemoveNode: handleRemoveNode,\n onAddNode: handleAddNode,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n stepOutputReferences: refsUnchanged\n ? data.stepOutputReferences\n : nextRefs,\n },\n };\n }\n\n if (node.type === \"parametersNode\") {\n const data = node.data as ParametersNodeData;\n const hasSameHandlers =\n data.onUpdateSections === onUpdateSections &&\n data.onRemoveNode === handleRemoveNode &&\n data.onAddNode === handleAddNode;\n const hasSameCaches =\n data.scaffolderActionIds === scaffolderActionIds &&\n data.scaffolderActionInputsById === scaffolderActionInputsById &&\n data.scaffolderActionOutputsById === scaffolderActionOutputsById &&\n data.scaffolderActionInputRequiredById ===\n scaffolderActionInputRequiredById;\n\n if (hasSameHandlers && hasSameCaches) {\n return node;\n }\n\n return {\n ...node,\n data: {\n ...data,\n onUpdateSections,\n onRemoveNode: handleRemoveNode,\n onAddNode: handleAddNode,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n },\n };\n }\n\n return node;\n },\n [\n handleAddNode,\n handleRemoveNode,\n onUpdateField,\n onUpdateInput,\n onRemoveInputKey,\n onUpdateOutput,\n onUpdateSections,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n stepOutputReferencesByNode,\n ]\n );\n\n useEffect(() => {\n setNodes((currentNodes) => {\n let changed = false;\n const nextNodes = currentNodes.map((node) => {\n const updated = ensureNodeDataStability(node);\n if (updated !== node) {\n changed = true;\n }\n return updated;\n });\n\n // Returning the same array keeps ReactFlow nodes prop stable unless something truly changed.\n return changed ? nextNodes : currentNodes;\n });\n }, [ensureNodeDataStability, setNodes]);\n\n useEffect(() => {\n emitChangesDeferred();\n }, [nodes, emitChangesDeferred]);\n\n useEffect(() => {\n // Force next emit to run even if hash matches, so input edits flush to YAML.\n lastEmittedModelHashRef.current = null;\n }, [nodes]);\n\n useEffect(() => {\n if (!nodes.length) {\n return;\n }\n emitChangesDeferred();\n }, [emitChangesDeferred, modelHash, nodes]);\n\n useEffect(() => {\n const alignTimeout = alignDebounceRef.current;\n return () => {\n if (emitDebounceRef.current) {\n clearTimeout(emitDebounceRef.current);\n }\n if (fitViewRafRef.current !== null) {\n cancelAnimationFrame(fitViewRafRef.current);\n fitViewRafRef.current = null;\n }\n if (fitViewTimeoutRef.current) {\n clearTimeout(fitViewTimeoutRef.current);\n fitViewTimeoutRef.current = null;\n }\n if (alignTimeout) {\n clearTimeout(alignTimeout);\n }\n flushPendingEmit();\n };\n }, [flushPendingEmit]);\n\n const [reactFlowInstance, setReactFlowInstance] =\n useState<ReactFlowInstance | null>(null);\n const fitFlowToView = useCallback(() => {\n if (!reactFlowInstance || !nodes.length) {\n return;\n }\n if (fitViewRafRef.current !== null) {\n return;\n }\n if (userMovedViewportRef.current && !pendingInitialFitRef.current) {\n // Respect user navigation; don't snap back after they moved the camera.\n return;\n }\n const nodeWithWidth = nodes.find((node) => node.width);\n const nodeWidth = nodeWithWidth?.width ?? 760;\n // tighter horizontal padding; graph is vertical so we don't need wide gutters\n const padding = Math.max((window.innerWidth - nodeWidth) / 2 - 24, 24);\n const viewOptions = {\n padding,\n minZoom: 0.2,\n };\n // Delay fitView to the next frame to avoid ResizeObserver loops while nodes mount/measure.\n fitViewRafRef.current = window.requestAnimationFrame(() => {\n fitViewRafRef.current = null;\n try {\n reactFlowInstance.fitView(viewOptions);\n setViewportIfChanged(reactFlowInstance.getViewport());\n } catch {\n // Swallow rare layout timing errors; the next change will try again.\n }\n });\n // Fallback in case RAF is skipped (tab in background).\n if (fitViewTimeoutRef.current) {\n clearTimeout(fitViewTimeoutRef.current);\n }\n fitViewTimeoutRef.current = setTimeout(() => {\n fitViewTimeoutRef.current = null;\n try {\n reactFlowInstance.fitView(viewOptions);\n setViewportIfChanged(reactFlowInstance.getViewport());\n } catch {\n // Ignore; typically triggered only during tab throttling.\n }\n }, VIEWPORT_TUNING.fitFallbackDelayMs);\n }, [nodes, reactFlowInstance, setViewportIfChanged]);\n\n useEffect(() => {\n if (!reactFlowInstance) {\n return;\n }\n if (viewport === null) {\n setViewportIfChanged(viewport);\n }\n if (!pendingInitialFitRef.current) {\n return;\n }\n pendingInitialFitRef.current = false;\n fitFlowToView();\n }, [\n fitFlowToView,\n nodes,\n edges,\n reactFlowInstance,\n viewport,\n setViewportIfChanged,\n ]);\n\n useEffect(() => {\n const swallowResizeObserverError = (event: ErrorEvent) => {\n const message =\n event?.message || (event as any)?.error?.message || String(event);\n if (\n typeof message === \"string\" &&\n message.includes(\"ResizeObserver loop\")\n ) {\n // Prevent dev overlay noise for benign ResizeObserver timing loops that appear after fitView/layout.\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n };\n const swallowResizeObserverRejection = (event: PromiseRejectionEvent) => {\n const message = (event.reason as any)?.message ?? String(event.reason);\n if (\n typeof message === \"string\" &&\n message.includes(\"ResizeObserver loop\")\n ) {\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n };\n window.addEventListener(\"error\", swallowResizeObserverError, true);\n window.addEventListener(\n \"unhandledrejection\",\n swallowResizeObserverRejection,\n true\n );\n // Chrome/FF dispatch a dedicated event for this condition; capture it to prevent overlay noise.\n const swallowLoopErrorEvent = (event: Event) => {\n event.preventDefault();\n event.stopImmediatePropagation();\n };\n window.addEventListener(\n \"resizeobserverlooperror\" as any,\n swallowLoopErrorEvent,\n true\n );\n return () => {\n window.removeEventListener(\"error\", swallowResizeObserverError, true);\n window.removeEventListener(\n \"unhandledrejection\",\n swallowResizeObserverRejection,\n true\n );\n window.removeEventListener(\n \"resizeobserverlooperror\" as any,\n swallowLoopErrorEvent,\n true\n );\n };\n }, []);\n\n useEffect(() => {\n if (!reactFlowInstance) {\n return undefined;\n }\n window.addEventListener(\"resize\", fitFlowToView);\n return () => {\n window.removeEventListener(\"resize\", fitFlowToView);\n };\n }, [fitFlowToView, reactFlowInstance]);\n\n useEffect(() => {\n if (!isDragging) {\n if (emitAfterDragRef.current) {\n emitAfterDragRef.current = false;\n lastEmittedModelHashRef.current = null;\n }\n // Trigger emit cycle after drag ends so external state is up to date.\n lastEmittedModelHashRef.current = null;\n }\n }, [isDragging]);\n\n const handleMoveEnd: OnMoveEnd = useCallback(\n (_event, nextViewport: Viewport) => {\n // Keep zoom stable to optionally cull edges when zoomed out.\n setViewportIfChanged(nextViewport);\n },\n [setViewportIfChanged]\n );\n\n const handleMove: OnMove = useCallback(\n (_, nextViewport) => {\n userMovedViewportRef.current = true;\n setViewportIfChanged(nextViewport);\n },\n [setViewportIfChanged]\n );\n\n const shouldCullEdges =\n edges.length > 300 && (viewport?.zoom ?? 1) < 0.3 && !isDragging;\n const renderedEdges = useMemo(\n () =>\n shouldCullEdges\n ? EMPTY_EDGES // Dropping edges when zoomed out keeps canvas responsive with huge graphs.\n : edges,\n [edges, shouldCullEdges]\n );\n\n useEffect(() => {\n if (!reactFlowInstance) {\n return;\n }\n const pendingId = pendingFocusNodeIdRef.current;\n if (!pendingId) {\n return;\n }\n const target = nodes.find((node) => node.id === pendingId);\n if (!target) {\n return;\n }\n pendingFocusNodeIdRef.current = null;\n const nodeCenterX = target.position.x + (target.width ?? 0) / 2;\n const nodeCenterY = target.position.y + (target.height ?? 0) / 2;\n const zoom = viewport?.zoom ?? lastViewportRef.current?.zoom ?? undefined;\n try {\n reactFlowInstance.setCenter(nodeCenterX, nodeCenterY, {\n zoom,\n duration: VIEWPORT_TUNING.centerDurationMs,\n });\n window.requestAnimationFrame(() => {\n setViewportIfChanged(reactFlowInstance.getViewport());\n });\n } catch {\n // ignore\n }\n }, [nodes, reactFlowInstance, viewport, setViewportIfChanged]);\n\n return (\n <ReactFlowProvider>\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n minHeight: \"100%\",\n position: \"relative\",\n }}\n >\n <ReactFlow\n nodes={nodes}\n edges={renderedEdges}\n nodeTypes={resolvedNodeTypes}\n defaultViewport={\n viewport ?? {\n x: 0,\n y: 0,\n zoom: 0.5,\n }\n }\n viewport={viewport ?? undefined}\n onNodesChange={onNodesChange}\n onEdgesChange={onEdgesChange}\n onNodeDragStop={onNodeDragStop}\n onConnect={onConnect}\n onMove={handleMove}\n translateExtent={[\n [FIXED_X_POSITION - HORIZONTAL_PAN_RANGE, -10000],\n [FIXED_X_POSITION + HORIZONTAL_PAN_RANGE, 10000000],\n ]}\n onlyRenderVisibleElements\n onInit={setReactFlowInstance}\n onMoveEnd={handleMoveEnd}\n minZoom={0.1}\n />\n <Box\n position=\"absolute\"\n right={0}\n bottom={0}\n display=\"flex\"\n flexDirection=\"column\"\n alignItems=\"flex-end\"\n >\n <Button\n size=\"small\"\n variant=\"contained\"\n color=\"primary\"\n onClick={() => setMiniMapVisible((prev) => !prev)}\n style={{ padding: \"2px 8px\", minWidth: 0, width: \"60px\" }}\n >\n {miniMapVisible ? \"Hide\" : \"Map\"}\n </Button>\n {miniMapVisible ? (\n <MiniMap\n pannable\n zoomable\n style={{\n background: \"rgba(255,255,255,0.9)\",\n width: 140,\n height: 96,\n border: \"1px solid rgba(0,0,0,0.12)\",\n boxShadow: \"0 2px 6px rgba(0,0,0,0.08)\",\n marginTop: 4,\n right: \"-15px\",\n bottom: \"20px\",\n }}\n maskColor=\"rgba(0,0,0,0.06)\"\n />\n ) : null}\n </Box>\n </div>\n </ReactFlowProvider>\n );\n}\n"],"names":["nodeDefaults","baseNodeDefaults","nodes","edges"],"mappings":"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"}
@@ -81,11 +81,27 @@ const buildNodesFromModel = (steps, parameters, output, options) => {
81
81
  FLOW_LAYOUT.verticalSpacing
82
82
  );
83
83
  };
84
+ const normalizeStepOrder = (step) => {
85
+ const { if: stepIf, each: stepEach, ...rest } = step;
86
+ const ordered = {};
87
+ if (stepIf !== void 0) {
88
+ ordered.if = stepIf;
89
+ }
90
+ if (stepEach !== void 0) {
91
+ ordered.each = stepEach;
92
+ }
93
+ Object.keys(rest).forEach((key) => {
94
+ ordered[key] = rest[key];
95
+ });
96
+ return ordered;
97
+ };
84
98
  const extractStepsFromNodes = (nodes) => {
85
99
  const actionNodes = nodes.filter(
86
100
  (node) => node.type === "actionNode"
87
101
  );
88
- return actionNodes.map((node) => cloneStep(node.data.step));
102
+ return actionNodes.map(
103
+ (node) => normalizeStepOrder(cloneStep(node.data.step))
104
+ );
89
105
  };
90
106
  const extractParametersFromNodes = (nodes) => {
91
107
  const parametersNode = nodes.find(
@@ -1 +1 @@
1
- {"version":3,"file":"model.esm.js","sources":["../../src/designerFlow/model.ts"],"sourcesContent":["import type { Node } from \"@xyflow/react\";\nimport type {\n TaskStep,\n ScaffolderTaskOutput,\n} from \"@backstage/plugin-scaffolder-common\";\nimport type {\n ActionNodeData,\n OutputNodeData,\n ParametersNodeData,\n TemplateParametersValue,\n} from \"../types/flowNodes\";\nimport { alignNodes } from \"./nodeLayout\";\nimport { normalizeParametersToSections } from \"./parameterTransforms\";\nimport { FLOW_LAYOUT, nodeDefaults } from \"../components/designerFlowConfig\";\n\nconst sanitizeForRfId = (value: string) =>\n value.replace(/[^a-zA-Z0-9-_.:]/g, \"_\");\n\nconst buildRfId = (step: TaskStep | undefined, index: number) => {\n if (step && typeof step.id === \"string\" && step.id.trim().length > 0) {\n return `rf-${sanitizeForRfId(step.id)}-${index}`;\n }\n return `rf-${index + 1}`;\n};\n\nexport const cloneStep = (step: TaskStep): TaskStep =>\n JSON.parse(JSON.stringify(step ?? {})) as TaskStep;\n\nexport const cloneOutput = (\n output: ScaffolderTaskOutput | undefined | null\n): ScaffolderTaskOutput =>\n JSON.parse(JSON.stringify(output ?? {})) as ScaffolderTaskOutput;\n\nexport const cloneParameters = (\n parameters: TemplateParametersValue\n): TemplateParametersValue =>\n parameters === undefined\n ? undefined\n : (JSON.parse(JSON.stringify(parameters)) as TemplateParametersValue);\n\nexport type BuildNodesFromModelOptions = {\n scaffolderActionIds: string[];\n scaffolderActionInputsById: Record<string, Record<string, unknown>>;\n scaffolderActionOutputsById: Record<string, Record<string, unknown>>;\n scaffolderActionInputRequiredById: Record<string, string[]>;\n};\n\nexport const buildNodesFromModel = (\n steps: TaskStep[],\n parameters: TemplateParametersValue,\n output: ScaffolderTaskOutput | undefined | null,\n options: BuildNodesFromModelOptions\n) => {\n const {\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n } = options;\n\n const parameterSections = normalizeParametersToSections(parameters);\n const nodes: Node[] = [];\n\n const rfParametersId = \"rf-parameters\";\n nodes.push({\n id: rfParametersId,\n type: \"parametersNode\",\n position: { x: FLOW_LAYOUT.fixedXPosition, y: 0 },\n data: {\n rfId: rfParametersId,\n parameters: cloneParameters(parameters),\n sections: parameterSections,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionInputRequiredById,\n scaffolderActionOutputsById,\n },\n ...nodeDefaults,\n });\n\n const rfOutputId = \"rf-output\";\n nodes.push({\n id: rfOutputId,\n type: \"outputNode\",\n position: {\n x: FLOW_LAYOUT.fixedXPosition,\n y: FLOW_LAYOUT.verticalSpacing * (steps.length + 1),\n },\n data: {\n rfId: rfOutputId,\n output: cloneOutput(output),\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionInputRequiredById,\n scaffolderActionOutputsById,\n } satisfies OutputNodeData,\n ...nodeDefaults,\n });\n\n steps.forEach((step, index) => {\n const rfId = buildRfId(step, index);\n nodes.splice(index + 1, 0, {\n id: rfId,\n type: \"actionNode\",\n position: {\n x: FLOW_LAYOUT.fixedXPosition,\n y: FLOW_LAYOUT.verticalSpacing * (index + 1),\n },\n data: {\n rfId,\n step: cloneStep(step),\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionInputRequiredById,\n scaffolderActionOutputsById,\n } satisfies ActionNodeData,\n ...nodeDefaults,\n });\n });\n\n return alignNodes(\n nodes,\n FLOW_LAYOUT.fixedXPosition,\n FLOW_LAYOUT.verticalSpacing\n );\n};\n\nexport const extractStepsFromNodes = (nodes: Node[]): TaskStep[] => {\n const actionNodes = nodes.filter(\n (node) => node.type === \"actionNode\"\n ) as Node<ActionNodeData>[];\n return actionNodes.map((node) => cloneStep(node.data.step));\n};\n\nexport const extractParametersFromNodes = (\n nodes: Node[]\n): TemplateParametersValue => {\n const parametersNode = nodes.find(\n (node) => node.type === \"parametersNode\"\n ) as Node<ParametersNodeData> | undefined;\n if (!parametersNode) {\n return [];\n }\n return cloneParameters(parametersNode.data.parameters);\n};\n\nexport const extractOutputFromNodes = (\n nodes: Node[]\n): ScaffolderTaskOutput | undefined => {\n const outputNode = nodes.find((node) => node.type === \"outputNode\") as\n | Node<OutputNodeData>\n | undefined;\n if (!outputNode) {\n return undefined;\n }\n return cloneOutput(outputNode.data.output);\n};\n\nexport const collectParameterReferences = (\n parameters: TemplateParametersValue | undefined\n): string[] => {\n if (!parameters || !Array.isArray(parameters)) {\n return [];\n }\n return parameters.flatMap((param) =>\n Object.keys((param as any)?.properties ?? {}).map(\n (propKey) => `\\${{ parameters.${propKey} }}`\n )\n );\n};\n\nexport const collectStepOutputReferences = (\n nodes: Node[],\n parameterReferences: string[]\n): Record<string, string[]> => {\n const formatStepOutputProp = (stepId: string, prop: string) =>\n `\\${{ steps['${stepId}'].output.${prop} }}`;\n\n const referencesByNode: Record<string, string[]> = {};\n const sortedNodes = [...nodes].sort((a, b) => a.position.y - b.position.y);\n const accumulatedReferences: string[] = [...parameterReferences];\n const accumulatedSet = new Set<string>(parameterReferences);\n const outputKeysByStepId: Record<string, string[]> = {};\n\n sortedNodes.forEach((node) => {\n referencesByNode[node.id] = [...accumulatedReferences];\n\n const data = node.data as Partial<ActionNodeData> | undefined;\n if (!data || !data.step) {\n return;\n }\n\n const { step, scaffolderActionOutputsById } = data;\n const stepId =\n step && typeof step.id === \"string\" && step.id.trim().length > 0\n ? step.id\n : null;\n const actionId =\n step && typeof step.action === \"string\" && step.action.trim().length > 0\n ? step.action\n : null;\n\n if (!stepId || !actionId) {\n return;\n }\n\n const outputKeys = new Set<string>();\n const schemaOutputs = scaffolderActionOutputsById?.[actionId];\n if (schemaOutputs && typeof schemaOutputs === \"object\") {\n // Prefer nested properties if present; otherwise use top-level keys.\n const props =\n (schemaOutputs as { properties?: Record<string, unknown> })\n .properties ?? schemaOutputs;\n Object.keys(props ?? {}).forEach((key) => {\n if (key) {\n outputKeys.add(key);\n }\n });\n }\n\n const stepOutput = (step as { output?: Record<string, unknown> }).output;\n if (stepOutput && typeof stepOutput === \"object\") {\n Object.keys(stepOutput).forEach((key) => {\n if (key) {\n outputKeys.add(key);\n }\n });\n }\n\n if (outputKeys.size === 0) {\n return;\n }\n\n outputKeysByStepId[stepId] = Array.from(outputKeys);\n\n // Add per-key references from schema/output values (omit whole output object to avoid unusable suggestion).\n outputKeys.forEach((outputKey) => {\n const reference = formatStepOutputProp(stepId, outputKey);\n if (!accumulatedSet.has(reference)) {\n accumulatedSet.add(reference);\n accumulatedReferences.push(reference);\n }\n });\n });\n\n return referencesByNode;\n};\n\nexport const stableStringify = (value: unknown) =>\n JSON.stringify(value, (_key, v) => {\n if (Array.isArray(v)) {\n return v;\n }\n if (v && typeof v === \"object\") {\n return Object.keys(v as Record<string, unknown>)\n .sort()\n .reduce<Record<string, unknown>>((acc, k) => {\n acc[k] = (v as Record<string, unknown>)[k];\n return acc;\n }, {});\n }\n return v;\n });\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model.esm.js","sources":["../../src/designerFlow/model.ts"],"sourcesContent":["import type { Node } from \"@xyflow/react\";\nimport type {\n TaskStep,\n ScaffolderTaskOutput,\n} from \"@backstage/plugin-scaffolder-common\";\nimport type {\n ActionNodeData,\n OutputNodeData,\n ParametersNodeData,\n TemplateParametersValue,\n} from \"../types/flowNodes\";\nimport { alignNodes } from \"./nodeLayout\";\nimport { normalizeParametersToSections } from \"./parameterTransforms\";\nimport { FLOW_LAYOUT, nodeDefaults } from \"../components/designerFlowConfig\";\n\nconst sanitizeForRfId = (value: string) =>\n value.replace(/[^a-zA-Z0-9-_.:]/g, \"_\");\n\nconst buildRfId = (step: TaskStep | undefined, index: number) => {\n if (step && typeof step.id === \"string\" && step.id.trim().length > 0) {\n return `rf-${sanitizeForRfId(step.id)}-${index}`;\n }\n return `rf-${index + 1}`;\n};\n\nexport const cloneStep = (step: TaskStep): TaskStep =>\n JSON.parse(JSON.stringify(step ?? {})) as TaskStep;\n\nexport const cloneOutput = (\n output: ScaffolderTaskOutput | undefined | null\n): ScaffolderTaskOutput =>\n JSON.parse(JSON.stringify(output ?? {})) as ScaffolderTaskOutput;\n\nexport const cloneParameters = (\n parameters: TemplateParametersValue\n): TemplateParametersValue =>\n parameters === undefined\n ? undefined\n : (JSON.parse(JSON.stringify(parameters)) as TemplateParametersValue);\n\nexport type BuildNodesFromModelOptions = {\n scaffolderActionIds: string[];\n scaffolderActionInputsById: Record<string, Record<string, unknown>>;\n scaffolderActionOutputsById: Record<string, Record<string, unknown>>;\n scaffolderActionInputRequiredById: Record<string, string[]>;\n};\n\nexport const buildNodesFromModel = (\n steps: TaskStep[],\n parameters: TemplateParametersValue,\n output: ScaffolderTaskOutput | undefined | null,\n options: BuildNodesFromModelOptions\n) => {\n const {\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n } = options;\n\n const parameterSections = normalizeParametersToSections(parameters);\n const nodes: Node[] = [];\n\n const rfParametersId = \"rf-parameters\";\n nodes.push({\n id: rfParametersId,\n type: \"parametersNode\",\n position: { x: FLOW_LAYOUT.fixedXPosition, y: 0 },\n data: {\n rfId: rfParametersId,\n parameters: cloneParameters(parameters),\n sections: parameterSections,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionInputRequiredById,\n scaffolderActionOutputsById,\n },\n ...nodeDefaults,\n });\n\n const rfOutputId = \"rf-output\";\n nodes.push({\n id: rfOutputId,\n type: \"outputNode\",\n position: {\n x: FLOW_LAYOUT.fixedXPosition,\n y: FLOW_LAYOUT.verticalSpacing * (steps.length + 1),\n },\n data: {\n rfId: rfOutputId,\n output: cloneOutput(output),\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionInputRequiredById,\n scaffolderActionOutputsById,\n } satisfies OutputNodeData,\n ...nodeDefaults,\n });\n\n steps.forEach((step, index) => {\n const rfId = buildRfId(step, index);\n nodes.splice(index + 1, 0, {\n id: rfId,\n type: \"actionNode\",\n position: {\n x: FLOW_LAYOUT.fixedXPosition,\n y: FLOW_LAYOUT.verticalSpacing * (index + 1),\n },\n data: {\n rfId,\n step: cloneStep(step),\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionInputRequiredById,\n scaffolderActionOutputsById,\n } satisfies ActionNodeData,\n ...nodeDefaults,\n });\n });\n\n return alignNodes(\n nodes,\n FLOW_LAYOUT.fixedXPosition,\n FLOW_LAYOUT.verticalSpacing\n );\n};\n\nconst normalizeStepOrder = (step: TaskStep): TaskStep => {\n // Keep existing values intact; only adjusts insertion order for export.\n const { if: stepIf, each: stepEach, ...rest } = step as Record<string, any>;\n const ordered: Record<string, any> = {};\n if (stepIf !== undefined) {\n ordered.if = stepIf;\n }\n if (stepEach !== undefined) {\n ordered.each = stepEach;\n }\n // Preserve all other fields in their existing relative order.\n Object.keys(rest).forEach((key) => {\n ordered[key] = rest[key];\n });\n return ordered as TaskStep;\n};\n\nexport const extractStepsFromNodes = (nodes: Node[]): TaskStep[] => {\n const actionNodes = nodes.filter(\n (node) => node.type === \"actionNode\"\n ) as Node<ActionNodeData>[];\n return actionNodes.map((node) =>\n normalizeStepOrder(cloneStep(node.data.step))\n );\n};\n\nexport const extractParametersFromNodes = (\n nodes: Node[]\n): TemplateParametersValue => {\n const parametersNode = nodes.find(\n (node) => node.type === \"parametersNode\"\n ) as Node<ParametersNodeData> | undefined;\n if (!parametersNode) {\n return [];\n }\n return cloneParameters(parametersNode.data.parameters);\n};\n\nexport const extractOutputFromNodes = (\n nodes: Node[]\n): ScaffolderTaskOutput | undefined => {\n const outputNode = nodes.find((node) => node.type === \"outputNode\") as\n | Node<OutputNodeData>\n | undefined;\n if (!outputNode) {\n return undefined;\n }\n return cloneOutput(outputNode.data.output);\n};\n\nexport const collectParameterReferences = (\n parameters: TemplateParametersValue | undefined\n): string[] => {\n if (!parameters || !Array.isArray(parameters)) {\n return [];\n }\n return parameters.flatMap((param) =>\n Object.keys((param as any)?.properties ?? {}).map(\n (propKey) => `\\${{ parameters.${propKey} }}`\n )\n );\n};\n\nexport const collectStepOutputReferences = (\n nodes: Node[],\n parameterReferences: string[]\n): Record<string, string[]> => {\n const formatStepOutputProp = (stepId: string, prop: string) =>\n `\\${{ steps['${stepId}'].output.${prop} }}`;\n\n const referencesByNode: Record<string, string[]> = {};\n const sortedNodes = [...nodes].sort((a, b) => a.position.y - b.position.y);\n const accumulatedReferences: string[] = [...parameterReferences];\n const accumulatedSet = new Set<string>(parameterReferences);\n const outputKeysByStepId: Record<string, string[]> = {};\n\n sortedNodes.forEach((node) => {\n referencesByNode[node.id] = [...accumulatedReferences];\n\n const data = node.data as Partial<ActionNodeData> | undefined;\n if (!data || !data.step) {\n return;\n }\n\n const { step, scaffolderActionOutputsById } = data;\n const stepId =\n step && typeof step.id === \"string\" && step.id.trim().length > 0\n ? step.id\n : null;\n const actionId =\n step && typeof step.action === \"string\" && step.action.trim().length > 0\n ? step.action\n : null;\n\n if (!stepId || !actionId) {\n return;\n }\n\n const outputKeys = new Set<string>();\n const schemaOutputs = scaffolderActionOutputsById?.[actionId];\n if (schemaOutputs && typeof schemaOutputs === \"object\") {\n // Prefer nested properties if present; otherwise use top-level keys.\n const props =\n (schemaOutputs as { properties?: Record<string, unknown> })\n .properties ?? schemaOutputs;\n Object.keys(props ?? {}).forEach((key) => {\n if (key) {\n outputKeys.add(key);\n }\n });\n }\n\n const stepOutput = (step as { output?: Record<string, unknown> }).output;\n if (stepOutput && typeof stepOutput === \"object\") {\n Object.keys(stepOutput).forEach((key) => {\n if (key) {\n outputKeys.add(key);\n }\n });\n }\n\n if (outputKeys.size === 0) {\n return;\n }\n\n outputKeysByStepId[stepId] = Array.from(outputKeys);\n\n // Add per-key references from schema/output values (omit whole output object to avoid unusable suggestion).\n outputKeys.forEach((outputKey) => {\n const reference = formatStepOutputProp(stepId, outputKey);\n if (!accumulatedSet.has(reference)) {\n accumulatedSet.add(reference);\n accumulatedReferences.push(reference);\n }\n });\n });\n\n return referencesByNode;\n};\n\nexport const stableStringify = (value: unknown) =>\n JSON.stringify(value, (_key, v) => {\n if (Array.isArray(v)) {\n return v;\n }\n if (v && typeof v === \"object\") {\n return Object.keys(v as Record<string, unknown>)\n .sort()\n .reduce<Record<string, unknown>>((acc, k) => {\n acc[k] = (v as Record<string, unknown>)[k];\n return acc;\n }, {});\n }\n return v;\n });\n"],"names":[],"mappings":"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"}
@@ -83,10 +83,14 @@ const alignNodes = (nodes, fixedXPosition, verticalSpacing) => {
83
83
  const outputNode = nodes.find((node) => node.type === "outputNode");
84
84
  let nextY = parametersNode?.position?.y ?? 0;
85
85
  const aligned = [];
86
+ const animatedStyle = {
87
+ transition: "transform 260ms ease-out"
88
+ };
86
89
  if (parametersNode) {
87
90
  aligned.push({
88
91
  ...parametersNode,
89
- position: { x: fixedXPosition, y: nextY }
92
+ position: { x: fixedXPosition, y: nextY },
93
+ style: { ...parametersNode.style ?? {}, ...animatedStyle }
90
94
  });
91
95
  const height = resolveNodeHeightForTracking(parametersNode) ?? NODE_VERTICAL_SPACING.parametersNode ?? DEFAULT_NODE_HEIGHT;
92
96
  nextY += height + verticalSpacing + MIN_VERTICAL_GAP;
@@ -94,7 +98,8 @@ const alignNodes = (nodes, fixedXPosition, verticalSpacing) => {
94
98
  actionNodes.forEach((node, _index) => {
95
99
  aligned.push({
96
100
  ...node,
97
- position: { x: fixedXPosition, y: nextY }
101
+ position: { x: fixedXPosition, y: nextY },
102
+ style: { ...node.style ?? {}, ...animatedStyle }
98
103
  });
99
104
  const height = resolveNodeHeightForTracking(node) ?? NODE_VERTICAL_SPACING.actionNode ?? DEFAULT_NODE_HEIGHT;
100
105
  nextY += height + verticalSpacing + MIN_VERTICAL_GAP;
@@ -102,7 +107,8 @@ const alignNodes = (nodes, fixedXPosition, verticalSpacing) => {
102
107
  if (outputNode) {
103
108
  aligned.push({
104
109
  ...outputNode,
105
- position: { x: fixedXPosition, y: nextY }
110
+ position: { x: fixedXPosition, y: nextY },
111
+ style: { ...outputNode.style ?? {}, ...animatedStyle }
106
112
  });
107
113
  }
108
114
  return aligned;
@@ -1 +1 @@
1
- {"version":3,"file":"nodeLayout.esm.js","sources":["../../src/designerFlow/nodeLayout.ts"],"sourcesContent":["import type { Node } from \"@xyflow/react\";\nimport type {\n ActionNodeData,\n OutputNodeData,\n ParametersNodeData,\n} from \"../types/flowNodes\";\nimport { NODE_VERTICAL_SPACING } from \"../types/flowNodes\";\n\n// Shared helpers for computing consistent node alignment/spacing in the flow.\n\nconst DEFAULT_NODE_HEIGHT = 320;\nconst MIN_VERTICAL_GAP = 16;\n\nconst parseNumericHeight = (value: unknown): number | null => {\n if (typeof value === \"number\" && Number.isFinite(value) && value > 0) {\n return value;\n }\n if (typeof value === \"string\") {\n const parsed = Number.parseFloat(value);\n if (!Number.isNaN(parsed) && parsed > 0) {\n return parsed;\n }\n }\n return null;\n};\n\nconst estimateParametersNodeHeight = (node: Node): number | null => {\n if (node.type !== \"parametersNode\") {\n return null;\n }\n const data = node.data as ParametersNodeData | undefined;\n if (!data) {\n return null;\n }\n\n const sections = data.sections ?? [];\n const PARAMETER_SHELL_HEIGHT = 300;\n const PARAMETER_CARD_BASE = 220;\n const SECTION_BASE = 180;\n const FIELD_HEIGHT = 86;\n\n if (!sections.length) {\n return PARAMETER_SHELL_HEIGHT + PARAMETER_CARD_BASE + SECTION_BASE;\n }\n\n const sectionsHeight = sections.reduce((total, section) => {\n const fieldCount = section.fields?.length ?? 0;\n return total + SECTION_BASE + Math.max(fieldCount, 1) * FIELD_HEIGHT;\n }, 0);\n\n return PARAMETER_SHELL_HEIGHT + PARAMETER_CARD_BASE + sectionsHeight;\n};\n\nconst estimateActionNodeHeight = (node: Node): number | null => {\n if (node.type !== \"actionNode\") {\n return null;\n }\n const data = node.data as ActionNodeData | undefined;\n if (!data) {\n return null;\n }\n const inputsLength = Object.keys(data.step?.input ?? {}).length || 0;\n const INPUT_ROW_HEIGHT = 56;\n const BASE_HEIGHT = 420;\n return BASE_HEIGHT + inputsLength * INPUT_ROW_HEIGHT;\n};\n\nconst estimateOutputNodeHeight = (node: Node): number | null => {\n if (node.type !== \"outputNode\") {\n return null;\n }\n const data = node.data as OutputNodeData | undefined;\n if (!data) {\n return null;\n }\n const linksLength = Array.isArray(data.output?.links)\n ? data.output.links.length\n : 0;\n const textLength = Array.isArray((data.output as any)?.text)\n ? (data.output as any).text.length\n : 0;\n const ITEM_HEIGHT = 56;\n const BASE_HEIGHT = 320;\n return BASE_HEIGHT + Math.max(linksLength + textLength, 1) * ITEM_HEIGHT;\n};\n\nconst estimateHeightByType = (node: Node): number | null => {\n return (\n estimateParametersNodeHeight(node) ??\n estimateActionNodeHeight(node) ??\n estimateOutputNodeHeight(node)\n );\n};\n\nexport const resolveNodeHeightForTracking = (node: Node): number | null => {\n const dataHeight = parseNumericHeight((node.data as any)?.measuredHeight);\n if (dataHeight !== null) {\n return dataHeight;\n }\n const explicit = parseNumericHeight(node?.measured?.height);\n if (explicit !== null) {\n return explicit;\n }\n return estimateHeightByType(node);\n};\n\nexport const alignNodes = (\n nodes: Node[],\n fixedXPosition: number,\n verticalSpacing: number\n) => {\n const parametersNode = nodes.find((node) => node.type === \"parametersNode\");\n const actionNodes = nodes.filter((node) => node.type === \"actionNode\");\n const outputNode = nodes.find((node) => node.type === \"outputNode\");\n\n let nextY = parametersNode?.position?.y ?? 0;\n const aligned: Node[] = [];\n\n if (parametersNode) {\n aligned.push({\n ...parametersNode,\n position: { x: fixedXPosition, y: nextY },\n });\n const height =\n resolveNodeHeightForTracking(parametersNode) ??\n NODE_VERTICAL_SPACING.parametersNode ??\n DEFAULT_NODE_HEIGHT;\n nextY += height + verticalSpacing + MIN_VERTICAL_GAP;\n }\n\n actionNodes.forEach((node, _index) => {\n aligned.push({\n ...node,\n position: { x: fixedXPosition, y: nextY },\n });\n const height =\n resolveNodeHeightForTracking(node) ??\n NODE_VERTICAL_SPACING.actionNode ??\n DEFAULT_NODE_HEIGHT;\n nextY += height + verticalSpacing + MIN_VERTICAL_GAP;\n });\n\n if (outputNode) {\n aligned.push({\n ...outputNode,\n position: { x: fixedXPosition, y: nextY },\n });\n }\n\n return aligned;\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"nodeLayout.esm.js","sources":["../../src/designerFlow/nodeLayout.ts"],"sourcesContent":["import type { Node } from \"@xyflow/react\";\nimport type {\n ActionNodeData,\n OutputNodeData,\n ParametersNodeData,\n} from \"../types/flowNodes\";\nimport { NODE_VERTICAL_SPACING } from \"../types/flowNodes\";\n\n// Shared helpers for computing consistent node alignment/spacing in the flow.\n\nconst DEFAULT_NODE_HEIGHT = 320;\nconst MIN_VERTICAL_GAP = 16;\n\nconst parseNumericHeight = (value: unknown): number | null => {\n if (typeof value === \"number\" && Number.isFinite(value) && value > 0) {\n return value;\n }\n if (typeof value === \"string\") {\n const parsed = Number.parseFloat(value);\n if (!Number.isNaN(parsed) && parsed > 0) {\n return parsed;\n }\n }\n return null;\n};\n\nconst estimateParametersNodeHeight = (node: Node): number | null => {\n if (node.type !== \"parametersNode\") {\n return null;\n }\n const data = node.data as ParametersNodeData | undefined;\n if (!data) {\n return null;\n }\n\n const sections = data.sections ?? [];\n const PARAMETER_SHELL_HEIGHT = 300;\n const PARAMETER_CARD_BASE = 220;\n const SECTION_BASE = 180;\n const FIELD_HEIGHT = 86;\n\n if (!sections.length) {\n return PARAMETER_SHELL_HEIGHT + PARAMETER_CARD_BASE + SECTION_BASE;\n }\n\n const sectionsHeight = sections.reduce((total, section) => {\n const fieldCount = section.fields?.length ?? 0;\n return total + SECTION_BASE + Math.max(fieldCount, 1) * FIELD_HEIGHT;\n }, 0);\n\n return PARAMETER_SHELL_HEIGHT + PARAMETER_CARD_BASE + sectionsHeight;\n};\n\nconst estimateActionNodeHeight = (node: Node): number | null => {\n if (node.type !== \"actionNode\") {\n return null;\n }\n const data = node.data as ActionNodeData | undefined;\n if (!data) {\n return null;\n }\n const inputsLength = Object.keys(data.step?.input ?? {}).length || 0;\n const INPUT_ROW_HEIGHT = 56;\n const BASE_HEIGHT = 420;\n return BASE_HEIGHT + inputsLength * INPUT_ROW_HEIGHT;\n};\n\nconst estimateOutputNodeHeight = (node: Node): number | null => {\n if (node.type !== \"outputNode\") {\n return null;\n }\n const data = node.data as OutputNodeData | undefined;\n if (!data) {\n return null;\n }\n const linksLength = Array.isArray(data.output?.links)\n ? data.output.links.length\n : 0;\n const textLength = Array.isArray((data.output as any)?.text)\n ? (data.output as any).text.length\n : 0;\n const ITEM_HEIGHT = 56;\n const BASE_HEIGHT = 320;\n return BASE_HEIGHT + Math.max(linksLength + textLength, 1) * ITEM_HEIGHT;\n};\n\nconst estimateHeightByType = (node: Node): number | null => {\n return (\n estimateParametersNodeHeight(node) ??\n estimateActionNodeHeight(node) ??\n estimateOutputNodeHeight(node)\n );\n};\n\nexport const resolveNodeHeightForTracking = (node: Node): number | null => {\n const dataHeight = parseNumericHeight((node.data as any)?.measuredHeight);\n if (dataHeight !== null) {\n return dataHeight;\n }\n const explicit = parseNumericHeight(node?.measured?.height);\n if (explicit !== null) {\n return explicit;\n }\n return estimateHeightByType(node);\n};\n\nexport const alignNodes = (\n nodes: Node[],\n fixedXPosition: number,\n verticalSpacing: number\n) => {\n const parametersNode = nodes.find((node) => node.type === \"parametersNode\");\n const actionNodes = nodes.filter((node) => node.type === \"actionNode\");\n const outputNode = nodes.find((node) => node.type === \"outputNode\");\n\n let nextY = parametersNode?.position?.y ?? 0;\n const aligned: Node[] = [];\n const animatedStyle = {\n transition: \"transform 260ms ease-out\",\n };\n\n if (parametersNode) {\n aligned.push({\n ...parametersNode,\n position: { x: fixedXPosition, y: nextY },\n style: { ...(parametersNode.style ?? {}), ...animatedStyle },\n });\n const height =\n resolveNodeHeightForTracking(parametersNode) ??\n NODE_VERTICAL_SPACING.parametersNode ??\n DEFAULT_NODE_HEIGHT;\n nextY += height + verticalSpacing + MIN_VERTICAL_GAP;\n }\n\n actionNodes.forEach((node, _index) => {\n aligned.push({\n ...node,\n position: { x: fixedXPosition, y: nextY },\n style: { ...(node.style ?? {}), ...animatedStyle },\n });\n const height =\n resolveNodeHeightForTracking(node) ??\n NODE_VERTICAL_SPACING.actionNode ??\n DEFAULT_NODE_HEIGHT;\n nextY += height + verticalSpacing + MIN_VERTICAL_GAP;\n });\n\n if (outputNode) {\n aligned.push({\n ...outputNode,\n position: { x: fixedXPosition, y: nextY },\n style: { ...(outputNode.style ?? {}), ...animatedStyle },\n });\n }\n\n return aligned;\n};\n"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -198,6 +198,10 @@ type ActionNodeData = BaseNodeData & {
198
198
  onUpdateField?: (rfId: string, field: keyof TaskStep, value: string) => void;
199
199
  onUpdateInput?: (rfId: string, key: string, value: unknown) => void;
200
200
  onRemoveInputKey?: (rfId: string, key: string) => void;
201
+ /** Optional slot to inject additional icons/actions into the header. */
202
+ headerActionsSlot?: ReactNode;
203
+ /** Optional slot to render custom UI above the key/value input grid. */
204
+ inputsLeadingSlot?: ReactNode;
201
205
  };
202
206
  type OutputNodeData = BaseNodeData & {
203
207
  output: ScaffolderTaskOutput;
@@ -287,11 +291,12 @@ type DesignerFlowProps = {
287
291
  outputNodeComponent: ComponentType<{
288
292
  data: OutputNodeData;
289
293
  }>;
294
+ showMiniMap?: boolean;
290
295
  decorateNodes?: (nodes: Node[]) => Node[];
291
296
  decorateEdges?: (edges: Edge[], nodes: Node[]) => Edge[];
292
297
  nodeDefaults?: Partial<Node>;
293
298
  };
294
- declare function DesignerFlow({ steps, parameters, output, onStepsChange, onParametersChange, onOutputChange, actionNodeComponent, parametersNodeComponent, outputNodeComponent, decorateNodes, decorateEdges, nodeDefaults, }: DesignerFlowProps): react_jsx_runtime.JSX.Element;
299
+ declare function DesignerFlow({ steps, parameters, output, onStepsChange, onParametersChange, onOutputChange, actionNodeComponent, parametersNodeComponent, outputNodeComponent, showMiniMap, decorateNodes, decorateEdges, nodeDefaults, }: DesignerFlowProps): react_jsx_runtime.JSX.Element;
295
300
 
296
301
  type TemplateWorkspaceProps = {
297
302
  templateSteps: TaskStep[];
@@ -319,10 +324,11 @@ type TemplateWorkspaceProps = {
319
324
  actionNodeComponent?: DesignerFlowProps["actionNodeComponent"];
320
325
  outputNodeComponent?: DesignerFlowProps["outputNodeComponent"];
321
326
  headerActionsSlot?: ReactNode;
327
+ primaryActionsSlot?: ReactNode;
322
328
  flowTopSlot?: ReactNode;
323
329
  rightPanelSlot?: ReactNode;
324
330
  };
325
- declare const TemplateWorkspace: ({ templateSteps, templateParameters, templateOutput, templateYaml, yamlError, loadError, showYaml, onToggleYaml, onYamlChange, onStepsChange, onParametersChange, onOutputChange, onReload, onSave, onOpenTemplatePicker, activeTemplateLabel, reloadButtonLabel, saveButtonLabel, isReloading, isSaving, isSyncing, parametersNodeComponent, actionNodeComponent, outputNodeComponent, headerActionsSlot, flowTopSlot, rightPanelSlot, }: TemplateWorkspaceProps) => react_jsx_runtime.JSX.Element;
331
+ declare const TemplateWorkspace: ({ templateSteps, templateParameters, templateOutput, templateYaml, yamlError, loadError, showYaml, onToggleYaml, onYamlChange, onStepsChange, onParametersChange, onOutputChange, onReload, onSave, onOpenTemplatePicker, activeTemplateLabel, reloadButtonLabel, saveButtonLabel, isReloading, isSaving, isSyncing, parametersNodeComponent, actionNodeComponent, outputNodeComponent, headerActionsSlot, primaryActionsSlot, flowTopSlot, rightPanelSlot, }: TemplateWorkspaceProps) => react_jsx_runtime.JSX.Element;
326
332
 
327
333
  type EditorState = null | {
328
334
  target: HTMLInputElement | HTMLTextAreaElement;
@@ -1 +1 @@
1
- {"version":3,"file":"flowNodes.esm.js","sources":["../../src/types/flowNodes.ts"],"sourcesContent":["import type {\n ScaffolderTaskOutput,\n TaskStep,\n} from \"@backstage/plugin-scaffolder-common\";\nimport type { TemplateParametersValue } from \"./templateParameters\";\n\nexport type DesignerNodeType = \"parametersNode\" | \"actionNode\" | \"outputNode\";\n\nexport type AddNodeConfig = {\n afterRfId: string;\n type?: DesignerNodeType;\n stepTemplate?: Partial<TaskStep>;\n outputTemplate?: ScaffolderTaskOutput;\n parametersTemplate?: TemplateParametersValue;\n};\n\ntype BaseNodeData = {\n /** Stable ReactFlow node id */\n rfId: string;\n /** Cached scaffolder action ids for dropdown options */\n scaffolderActionIds?: string[];\n /** Cached action input schemas keyed by action id */\n scaffolderActionInputsById?: Record<string, Record<string, unknown>>;\n /** Cached action required input keys keyed by action id */\n scaffolderActionInputRequiredById?: Record<string, string[]>;\n /** Cached action output schemas keyed by action id */\n scaffolderActionOutputsById?: Record<string, Record<string, unknown>>;\n /** Suggestions for referencing previous step outputs */\n stepOutputReferences?: string[];\n onAddNode?: (config: AddNodeConfig) => void;\n onRemoveNode?: (rfId: string) => void;\n /** DOM-measured height used to stabilize layout */\n measuredHeight?: number;\n};\n\nexport type ActionNodeData = BaseNodeData & {\n /** User payload; id is editable string (reserved by your template) */\n step: TaskStep & { input?: Record<string, unknown> };\n onUpdateField?: (rfId: string, field: keyof TaskStep, value: string) => void;\n onUpdateInput?: (rfId: string, key: string, value: unknown) => void;\n onRemoveInputKey?: (rfId: string, key: string) => void;\n};\n\nexport type OutputNodeData = BaseNodeData & {\n output: ScaffolderTaskOutput;\n onUpdateOutput?: (\n rfId: string,\n updater: (prev: ScaffolderTaskOutput) => ScaffolderTaskOutput\n ) => void;\n};\n\nexport type ParameterFieldDisplay = {\n id: string;\n fieldName: string;\n sectionId: string;\n sectionTitle?: string;\n required: boolean;\n schema?: Record<string, unknown>;\n};\n\nexport type ParameterSectionDisplay = {\n id: string;\n title?: string;\n description?: string;\n required?: string[];\n properties?: Record<string, Record<string, unknown>>;\n fields: ParameterFieldDisplay[];\n};\n\nexport type ParametersNodeData = BaseNodeData & {\n parameters: TemplateParametersValue;\n sections?: ParameterSectionDisplay[];\n onUpdateSections?: (\n rfId: string,\n updater: (prev: ParameterSectionDisplay[]) => ParameterSectionDisplay[]\n ) => void;\n};\n\nexport const NODE_VERTICAL_SPACING: Record<DesignerNodeType, number> = {\n parametersNode: 120,\n actionNode: 120,\n outputNode: 120,\n};\n\nexport type { TemplateParametersValue };\n"],"names":[],"mappings":"AA8EO,MAAM,qBAAA,GAA0D;AAAA,EACrE,cAAA,EAAgB,GAAA;AAAA,EAChB,UAAA,EAAY,GAAA;AAAA,EACZ,UAAA,EAAY;AACd;;;;"}
1
+ {"version":3,"file":"flowNodes.esm.js","sources":["../../src/types/flowNodes.ts"],"sourcesContent":["import type {\n ScaffolderTaskOutput,\n TaskStep,\n} from \"@backstage/plugin-scaffolder-common\";\nimport type { ReactNode } from \"react\";\nimport type { TemplateParametersValue } from \"./templateParameters\";\n\nexport type DesignerNodeType = \"parametersNode\" | \"actionNode\" | \"outputNode\";\n\nexport type AddNodeConfig = {\n afterRfId: string;\n type?: DesignerNodeType;\n stepTemplate?: Partial<TaskStep>;\n outputTemplate?: ScaffolderTaskOutput;\n parametersTemplate?: TemplateParametersValue;\n};\n\ntype BaseNodeData = {\n /** Stable ReactFlow node id */\n rfId: string;\n /** Cached scaffolder action ids for dropdown options */\n scaffolderActionIds?: string[];\n /** Cached action input schemas keyed by action id */\n scaffolderActionInputsById?: Record<string, Record<string, unknown>>;\n /** Cached action required input keys keyed by action id */\n scaffolderActionInputRequiredById?: Record<string, string[]>;\n /** Cached action output schemas keyed by action id */\n scaffolderActionOutputsById?: Record<string, Record<string, unknown>>;\n /** Suggestions for referencing previous step outputs */\n stepOutputReferences?: string[];\n onAddNode?: (config: AddNodeConfig) => void;\n onRemoveNode?: (rfId: string) => void;\n /** DOM-measured height used to stabilize layout */\n measuredHeight?: number;\n};\n\nexport type ActionNodeData = BaseNodeData & {\n /** User payload; id is editable string (reserved by your template) */\n step: TaskStep & { input?: Record<string, unknown> };\n onUpdateField?: (rfId: string, field: keyof TaskStep, value: string) => void;\n onUpdateInput?: (rfId: string, key: string, value: unknown) => void;\n onRemoveInputKey?: (rfId: string, key: string) => void;\n /** Optional slot to inject additional icons/actions into the header. */\n headerActionsSlot?: ReactNode;\n /** Optional slot to render custom UI above the key/value input grid. */\n inputsLeadingSlot?: ReactNode;\n};\n\nexport type OutputNodeData = BaseNodeData & {\n output: ScaffolderTaskOutput;\n onUpdateOutput?: (\n rfId: string,\n updater: (prev: ScaffolderTaskOutput) => ScaffolderTaskOutput\n ) => void;\n};\n\nexport type ParameterFieldDisplay = {\n id: string;\n fieldName: string;\n sectionId: string;\n sectionTitle?: string;\n required: boolean;\n schema?: Record<string, unknown>;\n};\n\nexport type ParameterSectionDisplay = {\n id: string;\n title?: string;\n description?: string;\n required?: string[];\n properties?: Record<string, Record<string, unknown>>;\n fields: ParameterFieldDisplay[];\n};\n\nexport type ParametersNodeData = BaseNodeData & {\n parameters: TemplateParametersValue;\n sections?: ParameterSectionDisplay[];\n onUpdateSections?: (\n rfId: string,\n updater: (prev: ParameterSectionDisplay[]) => ParameterSectionDisplay[]\n ) => void;\n};\n\nexport const NODE_VERTICAL_SPACING: Record<DesignerNodeType, number> = {\n parametersNode: 120,\n actionNode: 120,\n outputNode: 120,\n};\n\nexport type { TemplateParametersValue };\n"],"names":[],"mappings":"AAmFO,MAAM,qBAAA,GAA0D;AAAA,EACrE,cAAA,EAAgB,GAAA;AAAA,EAChB,UAAA,EAAY,GAAA;AAAA,EACZ,UAAA,EAAY;AACd;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tduniec/plugin-template-designer-foundation",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/index.esm.js",
6
6
  "types": "./dist/index.d.ts",