Files
windmill/frontend/src/lib/components/sessions/VariableEditorView.svelte
T
Diego ImbertandClaude Opus 5 8202413bb9 fix(sessions): mount a hosted entity editor per item, and scope its reports to its workspace
The schedule and variable views re-pointed one live editor at each new path, so
the previous item's load — `openEdit`, `editVariable` and everything they await
— finished into the new item's form, baseline, draft cell and permissions,
last response winning. Keying each on its path gives every item its own
instance, with nothing of the next one's to land on. The resource host already
worked this way.

A report's guard also matched kind and path but not workspace, so re-scoping an
unsent session left a rename from the old workspace free to retarget the new
one's tab onto a path that exists only where it was written.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KcyBRxE8j3ujCYkum9KrC4
2026-09-06 03:02:34 +02:00

57 lines
2.0 KiB
Svelte

<script lang="ts">
import VariableEditor from '$lib/components/VariableEditor.svelte'
import { untrack } from 'svelte'
let {
path,
workspaceId,
onBack,
onRemoved,
onRenamed
}: {
/** The variable this tab edits (the row its location deep-links). */
path: string
/** The session's acting workspace, which the editor operates on instead of
* `$workspaceStore` (the nav workspace, which a session leaves put). */
workspaceId: string
/** Back to the list this editor was reached through; the tab replaced it. */
onBack?: () => void
/** The item at `fromPath` is gone — a draft-only one whose draft was discarded.
* Distinct from `onBack`, which moves whichever tab is active: only this tab is
* the one to send back, and only while it still shows that item. */
onRemoved?: (fromPath: string, fromWorkspace: string) => void
/** The item at `fromPath` was saved under a different path. The tab addresses
* it by path — as do its label, the chat's ACTIVE PREVIEW and the draft key —
* so the tab has to follow, or all four keep naming an item that no longer
* exists. */
onRenamed?: (newPath: string, fromPath: string, fromWorkspace: string) => void
} = $props()
let editor = $state<VariableEditor | undefined>()
// Selects the variable this tab holds, on the instance the `{#key}` below just
// mounted for it — `editor` is rebound per instance, so this re-runs per path.
$effect(() => {
const e = editor
if (!path || !e) return
untrack(() => e.editVariable(path))
})
</script>
<!-- Keyed on the path: the editor loads asynchronously, and re-pointing a live one
would leave the previous item's load to finish into the new item's state — its
draft cell, its baseline, its permissions. A fresh instance per path has none
of that to overwrite. -->
{#key path}
<VariableEditor
bind:this={editor}
useDrawer={false}
workspace={workspaceId}
{onBack}
{onRemoved}
onSaved={(saved, from, fromWs) => {
if (saved && from && fromWs && saved !== from) onRenamed?.(saved, from, fromWs)
}}
/>
{/key}