From 090da05c50b6cfd20b44a8fd89ee0c9519319c4f Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Wed, 30 Sep 2026 14:39:43 +0200 Subject: [PATCH] feat: assets-only delete in both modes, why it is blocked, and a Show scripts toggle Co-Authored-By: Claude Opus 5.5 (1M context) --- .../assets/AssetGraph/AssetGraphCanvas.svelte | 19 ++++++++++++++----- .../assets/AssetGraph/AssetNode.svelte | 12 +++++++++++- .../(logged)/pipeline/[folder]/+page.svelte | 2 +- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/frontend/src/lib/components/assets/AssetGraph/AssetGraphCanvas.svelte b/frontend/src/lib/components/assets/AssetGraph/AssetGraphCanvas.svelte index dac7d93d98..93a874b77b 100644 --- a/frontend/src/lib/components/assets/AssetGraph/AssetGraphCanvas.svelte +++ b/frontend/src/lib/components/assets/AssetGraph/AssetGraphCanvas.svelte @@ -211,7 +211,7 @@ * canvas is embedded inline inside a scrollable container, so a wheel * gesture over it scrolls the container instead of being captured. */ scrollZoom?: boolean - /** Offer the "Assets only" switch, which folds scripts and triggers into the + /** Offer the "Show scripts and triggers" switch; off folds scripts and triggers into the * assets they produce. */ assetsOnlyToggle?: boolean /** The pipeline folder, when the toggle's state should be remembered for it. */ @@ -1088,7 +1088,15 @@ deleteCount: toDelete.trigger ? 2 : 1, onDeleteUpstream: () => onDeleteAssetUpstream?.(toDelete) } - : {}) + : onDeleteAssetUpstream && u + ? { + deleteBlocked: !u.multiple + ? 'its script builds other assets too' + : u.runnableIds.length > 1 + ? 'several scripts build it' + : 'its script has several triggers' + } + : {}) } } }) @@ -1625,11 +1633,12 @@ class="!m-3" > { - if (assetsOnlyFolder != undefined) setAssetsOnlyFolder(assetsOnlyFolder, e.detail) + assetsOnly = !e.detail + if (assetsOnlyFolder != undefined) setAssetsOnlyFolder(assetsOnlyFolder, assetsOnly) }} /> diff --git a/frontend/src/lib/components/assets/AssetGraph/AssetNode.svelte b/frontend/src/lib/components/assets/AssetGraph/AssetNode.svelte index e5e7435080..eb6776a6a3 100644 --- a/frontend/src/lib/components/assets/AssetGraph/AssetNode.svelte +++ b/frontend/src/lib/components/assets/AssetGraph/AssetNode.svelte @@ -154,6 +154,8 @@ * asset shares; `deleteCount` is how many that is. */ onDeleteUpstream?: () => void deleteCount?: number + /** Why nothing can be deleted, when the producer is shared. */ + deleteBlocked?: string } // SvelteFlow injects this on the node component when the user clicks // the node. Combined with our own `hovered` state to drive the @@ -219,7 +221,15 @@ action: () => data.onDeleteUpstream?.() } ] - : [] + : data.deleteBlocked + ? [ + { + displayName: `Can't delete: ${data.deleteBlocked}`, + icon: Trash2, + disabled: true + } + ] + : [] ) let upstream = $derived(data.upstream) const CHIP_CLASS = diff --git a/frontend/src/routes/(root)/(logged)/pipeline/[folder]/+page.svelte b/frontend/src/routes/(root)/(logged)/pipeline/[folder]/+page.svelte index cc2691127f..5f9da5e3db 100644 --- a/frontend/src/routes/(root)/(logged)/pipeline/[folder]/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/pipeline/[folder]/+page.svelte @@ -2918,7 +2918,7 @@ onAddScriptForAsset={mode === 'edit' ? handleAddScriptForAsset : undefined} onAddPipelineScript={mode === 'edit' ? handleAddPipelineScript : undefined} onRunnableMenuRemove={mode === 'edit' ? handleRunnableMenuRemove : undefined} - onDeleteAssetUpstream={mode === 'edit' ? (t) => (assetDeleteTarget = t) : undefined} + onDeleteAssetUpstream={(t) => (assetDeleteTarget = t)} onRunProducer={mode === 'edit' ? handleRunProducer : undefined} onRequestEdit={isOperator ? undefined : () => setMode('edit')} canRunByPath={openScriptHasDataUpload}