mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-30 08:16:49 +00:00
fix(frontend): remove debug wrapper nodes from flow graph
Remove WrapperInfo type, SHOW_DEBUG_WRAPPERS flag, buildDebugWrapperNodes helper, DebugWrapperNode component, and all related plumbing in FlowGraphV2. The bbox computation now uses groupLayouts directly, keeping layout correctness without any debug wrapper overhead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
78371e97a2
commit
5a3efd7d84
@@ -70,8 +70,7 @@
|
||||
import type { MoveManager } from './moveManager.svelte'
|
||||
import DragCoordinator from './DragCoordinator.svelte'
|
||||
import type { ModulesTestStates } from '../modulesTest.svelte'
|
||||
import { compoundLayout, buildDebugWrapperNodes, type WrapperInfo } from './compoundLayout'
|
||||
import DebugWrapperNode from './renderers/nodes/DebugWrapperNode.svelte'
|
||||
import { compoundLayout } from './compoundLayout'
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import type { AssetWithAltAccessType } from '../assets/lib'
|
||||
import type { ModuleActionInfo } from '$lib/components/flows/flowDiff'
|
||||
@@ -324,7 +323,6 @@
|
||||
}
|
||||
type NodePos = { position: { x: number; y: number } }
|
||||
let lastNodes: [NodeDep[], (NodeDep & NodePos)[]] | undefined = undefined
|
||||
let lastWrappers: WrapperInfo[] = []
|
||||
let lastXCenter = 0
|
||||
|
||||
function layoutNodes(nodes: NodeDep[]): (NodeDep & NodePos)[] {
|
||||
@@ -348,15 +346,13 @@
|
||||
)
|
||||
|
||||
// Run recursive compound layout
|
||||
const { positions, bbox, wrappers } = compoundLayout(nodes, edges, {
|
||||
const { positions, bbox } = compoundLayout(nodes, edges, {
|
||||
nodeWidth: NODE.width,
|
||||
nodeHeight: NODE.height,
|
||||
gapH: NODE.gap.horizontal,
|
||||
gapV: NODE.gap.vertical
|
||||
})
|
||||
|
||||
lastWrappers = wrappers
|
||||
|
||||
// Center horizontally
|
||||
const xCenter =
|
||||
(fullSize ? fullWidth : width) / 2 - bbox.width / 2 - (width - fullWidth) / 2
|
||||
@@ -618,11 +614,7 @@
|
||||
}
|
||||
|
||||
// update nodes
|
||||
nodes = [
|
||||
...finalNodes,
|
||||
...buildDebugWrapperNodes(lastWrappers, lastXCenter),
|
||||
...(noteNodesResult?.noteNodes ?? [])
|
||||
]
|
||||
nodes = [...finalNodes, ...(noteNodesResult?.noteNodes ?? [])]
|
||||
|
||||
edges = [
|
||||
...(assetNodesResult?.newAssetEdges ?? []),
|
||||
@@ -668,8 +660,7 @@
|
||||
assetsOverflowed: AssetsOverflowedNode,
|
||||
aiTool: AiToolNode,
|
||||
newAiTool: NewAiToolNode,
|
||||
note: NoteNode,
|
||||
debugWrapper: DebugWrapperNode
|
||||
note: NoteNode
|
||||
} as any
|
||||
|
||||
const edgeTypes = {
|
||||
@@ -971,7 +962,7 @@
|
||||
{@render leftHeader()}
|
||||
</div>
|
||||
{:else}
|
||||
<Controls position="top-right" orientation="horizontal" showLock={false} fitViewOptions={{ nodes: nodes.filter((n) => n.type !== 'debugWrapper' && n.type !== 'note') }}>
|
||||
<Controls position="top-right" orientation="horizontal" showLock={false} fitViewOptions={{ nodes: nodes.filter((n) => n.type !== 'note') }}>
|
||||
{#if multiSelectEnabled}
|
||||
<div class="flex items-center gap-2">
|
||||
<Tooltip>
|
||||
|
||||
@@ -23,33 +23,12 @@ type CompoundGroup = {
|
||||
}[]
|
||||
}
|
||||
|
||||
export type WrapperInfo = {
|
||||
id: string
|
||||
headId: string
|
||||
type: CompoundGroup['type']
|
||||
level: 'group' | 'branch' | 'loop-body'
|
||||
label: string
|
||||
x: number
|
||||
y: number
|
||||
width: number
|
||||
height: number
|
||||
}
|
||||
|
||||
type LayoutResult = {
|
||||
positions: Map<string, { x: number; y: number }>
|
||||
bbox: { width: number; height: number }
|
||||
wrappers: WrapperInfo[]
|
||||
contentMinX: number
|
||||
}
|
||||
|
||||
/**
|
||||
* ----- DEBUG -----
|
||||
* Flip to `true` to compute and visualize compound-layout wrapper boxes.
|
||||
* When enabled, the layout returns WrapperInfo[] objects that FlowGraphV2
|
||||
* renders as colored dashed/dotted rectangles around groups and branches.
|
||||
*/
|
||||
export const SHOW_DEBUG_WRAPPERS = false
|
||||
|
||||
const LOOP_INDENT = 25
|
||||
|
||||
/**
|
||||
@@ -301,7 +280,6 @@ function layoutLevel(
|
||||
return {
|
||||
positions,
|
||||
bbox: { width: constants.nodeWidth, height: 0 },
|
||||
wrappers: [],
|
||||
contentMinX: 0
|
||||
}
|
||||
}
|
||||
@@ -543,89 +521,6 @@ function layoutLevel(
|
||||
}
|
||||
}
|
||||
|
||||
// ----- DEBUG: wrapper visualization data -----
|
||||
const wrappers: WrapperInfo[] = []
|
||||
if (SHOW_DEBUG_WRAPPERS) {
|
||||
for (const [headId, gl] of groupLayouts) {
|
||||
const wrapperPos = sugResult.positions.get(headId)
|
||||
if (!wrapperPos) continue
|
||||
|
||||
// Overall group wrapper
|
||||
wrappers.push({
|
||||
id: `__wrapper__${headId}`,
|
||||
headId,
|
||||
type: gl.group.type,
|
||||
level: 'group',
|
||||
label: `${gl.group.type} (${headId})`,
|
||||
x: wrapperPos.x,
|
||||
y: wrapperPos.y,
|
||||
width: gl.wrapperWidth,
|
||||
height: gl.wrapperHeight
|
||||
})
|
||||
|
||||
const rowHeight = constants.nodeHeight + constants.gapV
|
||||
const isBranch = gl.group.type === 'branchall' || gl.group.type === 'branchone'
|
||||
if (isBranch) {
|
||||
const branchWidths = gl.branchLayouts.map((bl) =>
|
||||
Math.max(bl.bbox.width, constants.nodeWidth)
|
||||
)
|
||||
const totalWidth =
|
||||
branchWidths.reduce((s, w) => s + w, 0) +
|
||||
Math.max(0, branchWidths.length - 1) * constants.gapH
|
||||
let cx = wrapperPos.x - totalWidth / 2
|
||||
for (let bi = 0; bi < gl.branchLayouts.length; bi++) {
|
||||
const bl = gl.branchLayouts[bi]
|
||||
const bw = branchWidths[bi]
|
||||
const branchCenterX = cx + bw / 2
|
||||
|
||||
// Per-branch wrapper
|
||||
wrappers.push({
|
||||
id: `__wrapper__${headId}__branch_${bi}`,
|
||||
headId,
|
||||
type: gl.group.type,
|
||||
level: 'branch',
|
||||
label: `branch ${bi} (${bl.labelId})`,
|
||||
x: branchCenterX,
|
||||
y: wrapperPos.y + rowHeight,
|
||||
width: bw,
|
||||
height: bl.bbox.height
|
||||
})
|
||||
|
||||
// Child wrappers from recursive layout
|
||||
for (const cw of bl.result.wrappers) {
|
||||
wrappers.push({ ...cw, x: branchCenterX + cw.x, y: wrapperPos.y + rowHeight + cw.y })
|
||||
}
|
||||
cx += bw + constants.gapH
|
||||
}
|
||||
} else {
|
||||
const bl = gl.branchLayouts[0]
|
||||
if (bl) {
|
||||
// Loop body wrapper
|
||||
wrappers.push({
|
||||
id: `__wrapper__${headId}__body`,
|
||||
headId,
|
||||
type: gl.group.type,
|
||||
level: 'loop-body',
|
||||
label: `loop body (${bl.labelId})`,
|
||||
x: wrapperPos.x + LOOP_INDENT,
|
||||
y: wrapperPos.y + rowHeight,
|
||||
width: bl.bbox.width,
|
||||
height: bl.bbox.height
|
||||
})
|
||||
|
||||
// Child wrappers from recursive layout
|
||||
for (const cw of bl.result.wrappers) {
|
||||
wrappers.push({
|
||||
...cw,
|
||||
x: wrapperPos.x + LOOP_INDENT + cw.x,
|
||||
y: wrapperPos.y + rowHeight + cw.y
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compute overall bbox (nodes + group wrapper extents)
|
||||
let minX = Infinity
|
||||
let maxX = -Infinity
|
||||
@@ -654,7 +549,7 @@ function layoutLevel(
|
||||
width: Math.max(bboxWidth, constants.nodeWidth),
|
||||
height: Math.max(bboxHeight, 0)
|
||||
}
|
||||
return { positions, bbox: finalBbox, wrappers, contentMinX }
|
||||
return { positions, bbox: finalBbox, contentMinX }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -693,11 +588,6 @@ export function compoundLayout(
|
||||
for (const pos of result.positions.values()) {
|
||||
pos.x -= minX
|
||||
}
|
||||
if (SHOW_DEBUG_WRAPPERS) {
|
||||
for (const w of result.wrappers) {
|
||||
w.x -= minX
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -712,37 +602,3 @@ export function compoundLayout(
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/** Build SvelteFlow nodes for debug wrappers. Returns [] when SHOW_DEBUG_WRAPPERS is false. */
|
||||
export function buildDebugWrapperNodes(
|
||||
wrappers: WrapperInfo[],
|
||||
xCenter: number
|
||||
): {
|
||||
id: string
|
||||
type: string
|
||||
position: { x: number; y: number }
|
||||
data: Record<string, unknown>
|
||||
selectable: boolean
|
||||
draggable: boolean
|
||||
zIndex: number
|
||||
style: string
|
||||
}[] {
|
||||
if (!SHOW_DEBUG_WRAPPERS) return []
|
||||
return wrappers.map((w) => ({
|
||||
id: w.id,
|
||||
type: 'debugWrapper',
|
||||
position: { x: w.x + xCenter - w.width / 2, y: w.y },
|
||||
data: {
|
||||
headId: w.headId,
|
||||
type: w.type,
|
||||
level: w.level,
|
||||
label: w.label,
|
||||
wrapperWidth: w.width,
|
||||
wrapperHeight: w.height
|
||||
},
|
||||
selectable: false,
|
||||
draggable: false,
|
||||
zIndex: w.level === 'group' ? -10 : -5,
|
||||
style: `width: ${w.width}px; height: ${w.height}px;`
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
<script lang="ts">
|
||||
interface Props {
|
||||
data: {
|
||||
headId: string
|
||||
type: string
|
||||
level: 'group' | 'branch' | 'loop-body'
|
||||
label: string
|
||||
wrapperWidth: number
|
||||
wrapperHeight: number
|
||||
}
|
||||
}
|
||||
let { data }: Props = $props()
|
||||
|
||||
// Group wrappers: solid bg, thicker border
|
||||
// Branch wrappers: lighter bg, thinner border
|
||||
const groupColors: Record<string, { bg: string; border: string }> = {
|
||||
branchall: { bg: 'rgba(59, 130, 246, 0.08)', border: 'rgba(59, 130, 246, 0.5)' },
|
||||
branchone: { bg: 'rgba(168, 85, 247, 0.08)', border: 'rgba(168, 85, 247, 0.5)' },
|
||||
forloop: { bg: 'rgba(34, 197, 94, 0.08)', border: 'rgba(34, 197, 94, 0.5)' },
|
||||
whileloop: { bg: 'rgba(234, 179, 8, 0.08)', border: 'rgba(234, 179, 8, 0.5)' }
|
||||
}
|
||||
const branchColors: Record<string, { bg: string; border: string }> = {
|
||||
branchall: { bg: 'rgba(59, 130, 246, 0.12)', border: 'rgba(59, 130, 246, 0.7)' },
|
||||
branchone: { bg: 'rgba(168, 85, 247, 0.12)', border: 'rgba(168, 85, 247, 0.7)' },
|
||||
forloop: { bg: 'rgba(34, 197, 94, 0.12)', border: 'rgba(34, 197, 94, 0.7)' },
|
||||
whileloop: { bg: 'rgba(234, 179, 8, 0.12)', border: 'rgba(234, 179, 8, 0.7)' }
|
||||
}
|
||||
|
||||
const fallback = { bg: 'rgba(100,100,100,0.06)', border: 'rgba(100,100,100,0.4)' }
|
||||
const colors = data.level === 'group'
|
||||
? (groupColors[data.type] ?? fallback)
|
||||
: (branchColors[data.type] ?? fallback)
|
||||
const borderWidth = data.level === 'group' ? 2 : 1.5
|
||||
const borderStyle = data.level === 'group' ? 'dashed' : 'dotted'
|
||||
</script>
|
||||
|
||||
<div
|
||||
style="
|
||||
width: {data.wrapperWidth}px;
|
||||
height: {data.wrapperHeight}px;
|
||||
background: {colors.bg};
|
||||
border: {borderWidth}px {borderStyle} {colors.border};
|
||||
border-radius: {data.level === 'group' ? 10 : 6}px;
|
||||
pointer-events: none;
|
||||
position: relative;
|
||||
"
|
||||
>
|
||||
<span
|
||||
style="
|
||||
position: absolute;
|
||||
{data.level === 'group' ? 'top: 2px; left: 6px;' : 'bottom: 2px; right: 6px;'}
|
||||
font-size: 9px;
|
||||
color: {colors.border};
|
||||
font-family: monospace;
|
||||
opacity: 0.85;
|
||||
"
|
||||
>
|
||||
{data.label} {data.wrapperWidth}×{data.wrapperHeight}
|
||||
</span>
|
||||
</div>
|
||||
Reference in New Issue
Block a user