From 712473d5b6083fb322d2d47e51ac29ba478f81f3 Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Fri, 11 Sep 2026 18:29:19 +0200 Subject: [PATCH] fix: edit, not re-create, an item the drawer created and kept open Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01ViTUkt4czrvZdxdWwxqRAQ --- .../src/lib/components/VariableEditor.svelte | 13 +++++++++--- .../schedules/ScheduleEditorInner.svelte | 21 ++++++++++++------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/frontend/src/lib/components/VariableEditor.svelte b/frontend/src/lib/components/VariableEditor.svelte index e511b034cf..355aece019 100644 --- a/frontend/src/lib/components/VariableEditor.svelte +++ b/frontend/src/lib/components/VariableEditor.svelte @@ -25,6 +25,7 @@ import DraftConflictAlert from './DraftConflictAlert.svelte' import { isEncryptedDraftValue } from '$lib/encryptedDraft' import { + isTemporaryPath, newItemPath, saveEach, useItems, @@ -62,8 +63,6 @@ const acting = useActingUser(() => selected) const MAX_VARIABLE_LENGTH = 10000 - const edit = $derived(editPath !== undefined) - const initialPath = $derived(editPath ?? '') function isValid(v: VariableState | undefined): boolean { // `$encrypted:` markers are ciphertext; the backend re-derives the real value on save, @@ -193,12 +192,20 @@ pageDrawerSessionSource(VARIABLES_PATH, editPath, selected ?? curWs) ) const selectedItem = $derived(selected ? items[selected] : undefined) + // A variable this drawer created is edited from then on: the drawer stays open on it when an + // edit was typed during the create. + const edit = $derived(editPath !== undefined || selectedItem?.origin === 'deployed') + const initialPath = $derived( + editPath ?? + (selectedItem && !isTemporaryPath(selectedItem.key.path) ? selectedItem.key.path : '') + ) const current = $derived(selectedItem?.value) // `undefined` until the selected workspace's permissions and acting user have both // landed — a pending verdict is neither a grant nor the denial the read-only alert // announces, so the two must stay distinguishable. const can_write: boolean | undefined = $derived.by(() => { - if (!selected || !edit) return true + // Nobody else's permissions apply to a variable this drawer is creating, or just created. + if (!selected || editPath === undefined) return true const perms = extraPermsOf(selected) if (!perms || !acting.resolved(selected)) return undefined return canWrite(editPath ?? '', perms, acting.in(selected)) diff --git a/frontend/src/lib/components/triggers/schedules/ScheduleEditorInner.svelte b/frontend/src/lib/components/triggers/schedules/ScheduleEditorInner.svelte index 2d8c7cf970..8ee8b23828 100644 --- a/frontend/src/lib/components/triggers/schedules/ScheduleEditorInner.svelte +++ b/frontend/src/lib/components/triggers/schedules/ScheduleEditorInner.svelte @@ -217,8 +217,15 @@ scheduleAdapter ) - // A schedule read from the server is created, not updated, while it only exists as a draft. - const edit = $derived(mode === 'fixed' || (mode === 'edit' && item.origin !== 'draft')) + // A schedule read from the server is created, not updated, while it only exists as a draft; + // one this editor created is edited from then on, as the drawer can outlive the create. + const edit = $derived( + mode === 'fixed' || item.origin === 'deployed' || (mode === 'edit' && item.origin !== 'draft') + ) + // Where the schedule is stored: the item's own path once it has one. + const schedulePath = $derived( + item.current && !isTemporaryPath(item.key.path) ? item.key.path : initialPath + ) const hasBaseline = $derived( item.loaded && (item.origin === 'deployed' || item.origin === 'draft') ) @@ -284,7 +291,7 @@ $effect(() => { if (!item.removed) return untrack(() => { - onUpdate?.(initialPath) + onUpdate?.(schedulePath) drawer?.closeDrawer() }) }) @@ -589,7 +596,7 @@ async function handleToggleEnabled(nEnabled: boolean) { enabled = nEnabled if (trigger?.draftConfig) return - const target = initialPath + const target = schedulePath const workspace = wsId ?? '' // Queued behind any save of this schedule; on refusal the item gives the field back and // the form re-reads it. @@ -621,7 +628,7 @@ {#snippet saveButton()} {#if !drawerLoading}