From 146f7706260fefe02f8ceae88bdba291925e712d Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Wed, 30 Sep 2026 13:18:46 +0200 Subject: [PATCH] fix: default schedule handlers, unique trigger draft paths, zoned cadence, valid script names Co-Authored-By: Claude Opus 5.5 (1M context) --- .../assets/AssetGraph/AssetGraphCanvas.svelte | 11 +- .../AssetGraph/PipelineInsertMenu.svelte | 40 +++++- .../AssetGraph/PipelineTriggerEditors.svelte | 35 ++++- .../assets/AssetGraph/TriggerNode.svelte | 5 +- .../AssetGraph/pipelineEditorState.svelte.ts | 12 +- .../AssetGraph/pipelineEditorState.test.ts | 13 ++ .../assets/AssetGraph/resolveGraph.ts | 4 +- .../lib/components/assets/AssetGraph/types.ts | 3 +- .../triggers/amqp/AmqpTriggerEditor.svelte | 2 +- .../amqp/AmqpTriggerEditorInner.svelte | 6 +- .../triggers/email/EmailTriggerEditor.svelte | 2 +- .../email/EmailTriggerEditorInner.svelte | 6 +- .../triggers/gcp/GcpTriggerEditor.svelte | 2 +- .../triggers/gcp/GcpTriggerEditorInner.svelte | 6 +- .../triggers/kafka/KafkaTriggerEditor.svelte | 2 +- .../kafka/KafkaTriggerEditorInner.svelte | 6 +- .../triggers/mqtt/MqttTriggerEditor.svelte | 2 +- .../mqtt/MqttTriggerEditorInner.svelte | 6 +- .../triggers/nats/NatsTriggerEditor.svelte | 2 +- .../nats/NatsTriggerEditorInner.svelte | 6 +- .../postgres/PostgresTriggerEditor.svelte | 2 +- .../PostgresTriggerEditorInner.svelte | 6 +- .../schedules/ScheduleAdvancedOptions.svelte | 75 ++++++++++- .../triggers/schedules/ScheduleEditor.svelte | 2 +- .../schedules/ScheduleEditorInner.svelte | 120 ++++-------------- .../triggers/sqs/SqsTriggerEditor.svelte | 2 +- .../triggers/sqs/SqsTriggerEditorInner.svelte | 6 +- frontend/src/lib/utils/describeCron.test.ts | 9 +- frontend/src/lib/utils/describeCron.ts | 20 +++ .../(logged)/pipeline/[folder]/+page.svelte | 29 +++-- 30 files changed, 282 insertions(+), 160 deletions(-) diff --git a/frontend/src/lib/components/assets/AssetGraph/AssetGraphCanvas.svelte b/frontend/src/lib/components/assets/AssetGraph/AssetGraphCanvas.svelte index 15ea720a60..7e442f1d04 100644 --- a/frontend/src/lib/components/assets/AssetGraph/AssetGraphCanvas.svelte +++ b/frontend/src/lib/components/assets/AssetGraph/AssetGraphCanvas.svelte @@ -21,7 +21,7 @@ import { layoutAssetGraph, PIPELINE_NODE_EXTRA_ROW } from './assetGraphLayout' import { assetsOnlyView, type AssetUpstream } from './assetsOnlyView' import { TRIGGER_NODE_STYLE } from './TriggerNode.svelte' - import { describeCron } from '$lib/utils/describeCron' + import { describeSchedule } from '$lib/utils/describeCron' import Toggle from '$lib/components/Toggle.svelte' import { computeMutedReadKeys, dbtAssociations } from './resolveGraph' import { buildDownstreamMap } from './graphTraversal' @@ -732,6 +732,7 @@ missing: boolean draft: boolean schedule?: string + timezone?: string summary?: string // First target script (drives the per-script create/edit flows). runnable_path?: string @@ -751,6 +752,7 @@ draft: boolean, runnable_path?: string, schedule?: string, + timezone?: string, summary?: string ) { const prev = triggerSourceNodes.get(id) @@ -762,6 +764,7 @@ missing, draft, schedule, + timezone, summary, runnable_path, runnable_paths: runnable_path ? [runnable_path] : [] @@ -820,6 +823,7 @@ // on every attached native trigger. t.runnable_path, t.schedule, + t.timezone, t.summary ) edges.push({ @@ -850,6 +854,7 @@ missing: info.missing, draft: info.draft, schedule: info.schedule, + timezone: info.timezone, summary: info.summary, runnable_path: info.runnable_path, // data_upload nodes go green once a file is staged for their @@ -910,7 +915,7 @@ const style = TRIGGER_NODE_STYLE[t.kind as TriggerNodeKind] const label = t.kind === 'schedule' && t.data?.schedule - ? (describeCron(t.data.schedule) ?? `Schedule (${t.data.schedule})`) + ? (describeSchedule(t.data.schedule, t.data.timezone) ?? `Schedule (${t.data.schedule})`) : (style?.label ?? t.kind) return { label, @@ -1450,7 +1455,7 @@ {#if assetsOnlyToggle} diff --git a/frontend/src/lib/components/assets/AssetGraph/PipelineInsertMenu.svelte b/frontend/src/lib/components/assets/AssetGraph/PipelineInsertMenu.svelte index b6105c5207..e32b2c2fa9 100644 --- a/frontend/src/lib/components/assets/AssetGraph/PipelineInsertMenu.svelte +++ b/frontend/src/lib/components/assets/AssetGraph/PipelineInsertMenu.svelte @@ -67,6 +67,7 @@ import DateTimeInput from '$lib/components/DateTimeInput.svelte' import ScheduleAdvancedOptions, { emptyScheduleAdvanced, + loadDefaultScheduleAdvanced, scheduleAdvancedCfg } from '$lib/components/triggers/schedules/ScheduleAdvancedOptions.svelte' import { workspaceStore } from '$lib/stores' @@ -147,14 +148,31 @@ tableEdited: false }) let config = $state(buildEmptyConfig()) + loadAdvancedDefaults() + + // The workspace's default handlers, as the schedule drawer applies to a new schedule. + function loadAdvancedDefaults() { + const ws = $workspaceStore + if (!ws) return + const target = config + loadDefaultScheduleAdvanced(ws) + .then((d) => { + if (config === target) config.advanced = d + }) + .catch(() => {}) + } function resetWizard() { selected = buildEmptySelected() config = buildEmptyConfig() + loadAdvancedDefaults() step = 0 } const TABLE_NAME_RE = /^[^/\s]+$/ + // The path grammar of `Path.svelte`: word segments, no empty or trailing ones. + const SCRIPT_NAME_RE = /^[\w-]+(\/[\w-]+)*$/ + let scriptNameValid = $derived(SCRIPT_NAME_RE.test(selected.scriptPath.trim())) let assetValid = $derived( !!config.asset?.store && TABLE_NAME_RE.test(config.asset.table.trim()) ) @@ -163,7 +181,7 @@ ? config.validCron && !!config.schedule.trim() && !config.schedulePathError : currentConfigStep === 'asset' ? assetValid - : !!selected.scriptPath.trim() + : scriptNameValid && !!selected.triggerId && !!selected.language && !!selected.outputId ) function enterAssetStep() { @@ -428,14 +446,30 @@ {#snippet bottomSection(close: () => void)}