Merge remote-tracking branch 'origin/improve-data-pipelines' into change-6607b937

This commit is contained in:
Diego Imbert
2026-09-30 20:24:40 +02:00
4 changed files with 24 additions and 10 deletions
@@ -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) => {
@@ -1504,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)
@@ -1742,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
@@ -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)}
<!-- Several triggers, none editable here (View mode): a plain label. -->
<span
class="truncate rounded-md border px-1.5 py-1 text-3xs leading-none font-normal border-gray-300 dark:border-gray-600 text-secondary"
>Multiple triggers</span
>
{:else if upstream && coTriggers.length > 1}
<!-- Several triggers start what builds this asset: one chip, a menu to pick
the one to edit. -->
@@ -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 }
@@ -3562,7 +3562,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