diff --git a/frontend/src/lib/components/assets/AssetGraph/AssetGraphCanvas.svelte b/frontend/src/lib/components/assets/AssetGraph/AssetGraphCanvas.svelte index 5625e2dd51..e644cce06e 100644 --- a/frontend/src/lib/components/assets/AssetGraph/AssetGraphCanvas.svelte +++ b/frontend/src/lib/components/assets/AssetGraph/AssetGraphCanvas.svelte @@ -598,11 +598,11 @@ --background-color={false} >
- + n.type === 'asset' ? 'rgb(96 165 250 / 0.5)' diff --git a/frontend/src/lib/components/assets/AssetGraph/AssetGraphDetailsPane.svelte b/frontend/src/lib/components/assets/AssetGraph/AssetGraphDetailsPane.svelte index 0e63d05fb0..7c39d7f81a 100644 --- a/frontend/src/lib/components/assets/AssetGraph/AssetGraphDetailsPane.svelte +++ b/frontend/src/lib/components/assets/AssetGraph/AssetGraphDetailsPane.svelte @@ -448,6 +448,23 @@ isDraft || (selection?.kind === 'runnable' && selection.runnable_kind === 'script') ) + // A persisted script with no edits vs its loaded version is already at + // its latest save point — hide Save for it. Drafts are never "saved" + // (always show Create). Unknown/loading → treat as dirty so Save isn't + // hidden when there might be changes. + let atLatestSavePoint = $derived.by(() => { + if (isDraft || !script) return false + const orig = scriptRes.current + if (!orig) return false + return ( + script.content === orig.content && + (script.tag ?? '') === (orig.tag ?? '') && + (script.summary ?? '') === (orig.summary ?? '') && + (script.description ?? '') === (orig.description ?? '') && + JSON.stringify(script.schema ?? null) === JSON.stringify(orig.schema ?? null) + ) + }) + // Suffix editor for the draft-path popover. Seeded from the current // path each time the popover opens so the user starts with what they // see, not stale state from an earlier rename. @@ -663,7 +680,7 @@ title="Open in full editor" /> {/if} - {#if isScriptView && script} + {#if isScriptView && script && !atLatestSavePoint}