diff --git a/frontend/src/lib/components/CompareDrafts.svelte b/frontend/src/lib/components/CompareDrafts.svelte index c8514e1fb6..867268cd1a 100644 --- a/frontend/src/lib/components/CompareDrafts.svelte +++ b/frontend/src/lib/components/CompareDrafts.svelte @@ -192,7 +192,7 @@ // side to diff the name against. Raw apps are fetched via the apps endpoint too // (it auto-detects raw from the deployed row and overlays the raw_app draft). const summaryCache = $state< - Record + Record >({}) async function fetchDraftSummary(item: Row) { @@ -216,9 +216,27 @@ path: item.path, getDraft: true }))) as any + // A draft is stale when the version it forked from no longer matches the + // current deployed head: a newer version was deployed after the draft began. + // Scripts compare `parent_hash` vs the deployed `hash`; flows the pinned + // `version_id` vs the deployed head `version_id`; apps the pinned + // `parent_version` vs the deployed head (`versions[last]`). + const draftBlob = r.draft as any + const appHead = Array.isArray(r.versions) ? r.versions[r.versions.length - 1] : undefined + const stale = + item.draftKind === 'script' + ? !!r.hash && !!draftBlob?.parent_hash && draftBlob.parent_hash !== r.hash + : item.draftKind === 'flow' + ? r.version_id != null && + draftBlob?.version_id != null && + draftBlob.version_id !== r.version_id + : appHead != null && + draftBlob?.parent_version != null && + draftBlob.parent_version !== appHead summaryCache[item.key] = { deployed: r.summary, - draft: (r.draft as any)?.summary, + draft: draftBlob?.summary, + stale, loading: false } } catch (error) { @@ -618,6 +636,19 @@ {/snippet} {/if} + {#if draftItem.mine && summaryCache[draftItem.key]?.stale} + + {#snippet trigger()} + + {/snippet} + {#snippet content()} +
+ Started from an older deployed version. A newer version was deployed after this + draft began. Review the latest deploy before deploying. +
+ {/snippet} +
+ {/if} {#if deploymentStatus[draftItem.key]?.status !== 'deployed'} {#if draftItem.draftKind === 'data_pipeline'}