From 3be851e4abf526f33c1b482f41ef8e1d8fbe7c34 Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Wed, 30 Sep 2026 20:08:19 +0200 Subject: [PATCH 1/3] fix: iterate NodeLists with Array.from so svelte-check passes Co-Authored-By: Claude Opus 5.5 (1M context) --- .../assets/AssetGraph/AssetGraphCanvas.svelte | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/frontend/src/lib/components/assets/AssetGraph/AssetGraphCanvas.svelte b/frontend/src/lib/components/assets/AssetGraph/AssetGraphCanvas.svelte index 4b53b32fb4..f66b35ab23 100644 --- a/frontend/src/lib/components/assets/AssetGraph/AssetGraphCanvas.svelte +++ b/frontend/src/lib/components/assets/AssetGraph/AssetGraphCanvas.svelte @@ -317,17 +317,15 @@ } let flowEl: HTMLElement | undefined = $state() const nodeUnder = (x: number, y: number) => - [...(flowEl?.querySelectorAll('.svelte-flow__node') ?? [])] + Array.from(flowEl?.querySelectorAll('.svelte-flow__node') ?? []) .find((el) => within(el, x, y)) ?.getAttribute('data-id') ?? undefined const overBlank = (x: number, y: number) => !!flowEl && within(flowEl, x, y) && - ![ - ...flowEl.querySelectorAll( - '.svelte-flow__panel, .svelte-flow__controls, .svelte-flow__minimap' - ) - ].some((el) => within(el, x, y)) + !Array.from( + flowEl.querySelectorAll('.svelte-flow__panel, .svelte-flow__controls, .svelte-flow__minimap') + ).some((el) => within(el, x, y)) const readsAsset = (assetId: string, scriptId: string) => model.edges.some((x) => x.kind === 'lineage-read' && x.source === assetId && x.target === scriptId) const assetOf = (assetId: string) => { From ccfb2590801203d27843dd7fc654e8bf8a7f1965 Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Wed, 30 Sep 2026 20:10:25 +0200 Subject: [PATCH 2/3] fix: no trigger delete for flow-built assets; Multiple triggers chip shows the one being edited Co-Authored-By: Claude Opus 5.5 (1M context) --- .../assets/AssetGraph/AssetGraphCanvas.svelte | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/frontend/src/lib/components/assets/AssetGraph/AssetGraphCanvas.svelte b/frontend/src/lib/components/assets/AssetGraph/AssetGraphCanvas.svelte index f66b35ab23..8a06ae70f0 100644 --- a/frontend/src/lib/components/assets/AssetGraph/AssetGraphCanvas.svelte +++ b/frontend/src/lib/components/assets/AssetGraph/AssetGraphCanvas.svelte @@ -1502,7 +1502,10 @@ // Its scripts' own triggers: a row that starts only them, which // webhooks and data uploads (no row) and missing ones are not. triggerDeletes: scriptIds.flatMap((id) => { - const scriptPath = runnables.get(id)?.data?.path + const runnable = runnables.get(id)?.data + // A flow is not deleted from here, and neither are its triggers. + if (runnable?.runnable_kind !== 'script') return [] + const scriptPath = runnable.path return m.edges .filter((e) => e.kind === 'trigger-native' && e.target === id) .map((e) => m.nodes.find((n) => n.id === e.source)?.data) @@ -1740,7 +1743,11 @@ ...up, selected: up.scripts.some( (sc: { runnableId: string }) => sc.runnableId === selectedId - ) + ), + triggers: (up.triggers ?? []).map((t: { nodeId?: string }) => ({ + ...t, + selected: !!t.nodeId && t.nodeId === activeTriggerId + })) } } : up?.runnableId !== undefined From 8f6118c0e128f61247d70713f67fdd2f488e6ec4 Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Wed, 30 Sep 2026 20:19:05 +0200 Subject: [PATCH 3/3] fix: Archive button for archive-only deletes, single delete doc, inert Multiple triggers label in View Co-Authored-By: Claude Opus 5.5 (1M context) --- .../src/lib/components/assets/AssetGraph/AssetNode.svelte | 6 ++++++ .../src/lib/components/assets/AssetGraph/assetsOnlyView.ts | 1 - .../routes/(root)/(logged)/pipeline/[folder]/+page.svelte | 6 +++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/frontend/src/lib/components/assets/AssetGraph/AssetNode.svelte b/frontend/src/lib/components/assets/AssetGraph/AssetNode.svelte index 37006afa0b..6e6c8e03f9 100644 --- a/frontend/src/lib/components/assets/AssetGraph/AssetNode.svelte +++ b/frontend/src/lib/components/assets/AssetGraph/AssetNode.svelte @@ -468,6 +468,12 @@ fix={data.foldedFixes[0]} label={`${data.foldedFixes.length} error${data.foldedFixes.length === 1 ? '' : 's'} ยท Fix`} /> + {:else if upstream && coTriggers.length > 1 && !coTriggers.some((t) => t.onOpen)} + + Multiple triggers {:else if upstream && coTriggers.length > 1} diff --git a/frontend/src/lib/components/assets/AssetGraph/assetsOnlyView.ts b/frontend/src/lib/components/assets/AssetGraph/assetsOnlyView.ts index ac2b366a93..c7bf85d144 100644 --- a/frontend/src/lib/components/assets/AssetGraph/assetsOnlyView.ts +++ b/frontend/src/lib/components/assets/AssetGraph/assetsOnlyView.ts @@ -19,7 +19,6 @@ export type ViewEdge = { export const noAssetNodeId = (runnableId: string) => `no-asset:${runnableId}` export const isNoAssetNode = (id: string) => id.startsWith('no-asset:') -/** The script and trigger an assets-only asset's delete removes. */ /** What an assets-only delete removes: the script, its trigger, or both. */ export type AssetUpstreamDelete = { script?: { path: string; unsaved: boolean } diff --git a/frontend/src/routes/(root)/(logged)/pipeline/[folder]/+page.svelte b/frontend/src/routes/(root)/(logged)/pipeline/[folder]/+page.svelte index 46b11dc76f..9541b77fc7 100644 --- a/frontend/src/routes/(root)/(logged)/pipeline/[folder]/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/pipeline/[folder]/+page.svelte @@ -3531,7 +3531,11 @@ : assetDeleteTarget?.script ? `${canHardDeleteScripts ? 'Delete' : 'Archive'} script?` : 'Delete trigger?'} - confirmationText="Delete" + confirmationText={assetDeleteTarget?.script && !canHardDeleteScripts + ? assetDeleteTarget.trigger + ? 'Archive and delete' + : 'Archive' + : 'Delete'} onConfirmed={confirmAssetUpstreamDelete} onCanceled={() => { if (!assetDeleteLoading) assetDeleteTarget = undefined