fix: keep the simplified view out of diffs and share the graph selection

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Diego Imbert
2026-09-27 00:48:34 +02:00
co-authored by Claude Opus 5.5
parent 158fae46c1
commit 1683bfbe26
3 changed files with 34 additions and 9 deletions
@@ -118,7 +118,8 @@
let useDataflow: Writable<boolean | undefined> = writable<boolean | undefined>(false)
let showAssets: Writable<boolean | undefined> = writable<boolean | undefined>(true)
// Read-only alternative layout; editing needs the insert/drag affordances of the full graph.
// Read-only alternative layout; editing needs the insert/drag affordances of the full graph,
// and it draws no diff markers, so a diff would read as an unchanged flow.
let simplifiedView = $state(false)
let showNotes = $state(true)
@@ -343,6 +344,7 @@
// Selection manager - create one if not provided
let selectionManager = untrack(() => selectionManagerProp) || new SelectionManager()
const selectedId = $derived(selectionManager.getSelectedId())
let simplifiedAvailable = $derived(!editMode && !diffBeforeFlow && !moduleActions)
const noteEditorContext = getNoteEditorContext()
@@ -1305,7 +1307,7 @@
<DiffDrawer bind:this={diffDrawer} />
{/if}
<div
style={simplifiedView && !editMode
style={simplifiedView && simplifiedAvailable
? undefined
: `height: ${height}px; max-height: ${maxHeight}px;`}
class="overflow-clip relative {outerDivClass}"
@@ -1325,14 +1327,18 @@
>
</Alert>
</div>
{:else if simplifiedView && !editMode}
{:else if simplifiedView && simplifiedAvailable}
<SimplifiedFlowGraph
{modules}
{failureModule}
{preprocessorModule}
{minHeight}
{maxHeight}
onSelect={(id) => onSelect?.(id)}
{selectedId}
onSelect={(id) => {
selectionManager.selectId(id)
if (!notSelectable) onSelect?.(id)
}}
>
{#snippet topLeftControls()}
{@render simplifiedViewToggle()}
@@ -1526,7 +1532,7 @@
{#if showDataflow}
<Toggle bind:checked={$useDataflow} size="xs" options={{ right: 'Dataflow' }} />
{/if}
{#if !editMode}
{#if simplifiedAvailable}
{@render simplifiedViewToggle()}
{/if}
</Controls>
@@ -1,12 +1,25 @@
<script lang="ts">
import { twMerge } from 'tailwind-merge'
import FlowModuleIcon from '$lib/components/flows/FlowModuleIcon.svelte'
import { getFlowRunStatusContext } from '../flowRunStatus.svelte'
import { SIMPLIFIED, type SimplifiedBoxData } from './simplifiedLayout'
let { data, selected }: { data: SimplifiedBoxData; selected?: boolean } = $props()
let { id, data, selected }: { id: string; data: SimplifiedBoxData; selected?: boolean } = $props()
let header = $derived(data.header)
// The loop or branch step has no node of its own here, so a run that fails or waits at the
// step itself (an iterator or predicate throwing) is shown on its bracket. Success stays
// neutral: the steps inside already carry it.
const flowRunStatus = getFlowRunStatusContext()
const STATUS_BRACKET: Record<string, string> = {
Failure: 'border-red-500',
InProgress: 'border-orange-400',
WaitingForExecutor: 'border-orange-400',
WaitingForEvents: 'border-purple-400'
}
let statusBracket = $derived(STATUS_BRACKET[flowRunStatus?.getModuleState(id)?.type ?? ''])
const headerTop = SIMPLIFIED.loopPad / 2
</script>
@@ -16,7 +29,9 @@
<div
class={twMerge(
'absolute inset-x-0 h-2.5 rounded-t-lg border-t border-x',
selected ? 'border-border-selected' : 'border-gray-300 dark:border-gray-600'
selected
? 'border-border-selected'
: (statusBracket ?? 'border-gray-300 dark:border-gray-600')
)}
style="top: {headerTop + SIMPLIFIED.loopHeader + 1}px;"
></div>
@@ -17,6 +17,8 @@
maxHeight?: number
/** Called with a module id, or `Input` / `Result` / `failure` / `preprocessor` */
onSelect?: (nodeId: string) => void
/** The graph's selection, owned by the caller so it survives switching views */
selectedId?: string
/** Rendered in the top-left control stack, e.g. the toggle leading back to the full graph */
topLeftControls?: Snippet
}
@@ -28,12 +30,14 @@
minHeight = 0,
maxHeight,
onSelect,
selectedId,
topLeftControls
}: Props = $props()
let layout = $derived(
layoutSimplifiedFlow({ modules: modules ?? [], failureModule, preprocessorModule })
)
let nodes = $derived(layout.nodes.map((n) => ({ ...n, selected: n.id === selectedId })))
const PAD = 72
const MIN_READABLE_ZOOM = 0.7
@@ -75,7 +79,7 @@
{#if width > 0}
<SvelteFlowProvider>
<SvelteFlow
nodes={layout.nodes}
{nodes}
edges={layout.edges}
{nodeTypes}
{edgeTypes}
@@ -84,7 +88,7 @@
maxZoom={1.6}
nodesDraggable={false}
nodesConnectable={false}
elementsSelectable={true}
elementsSelectable={false}
zoomOnDoubleClick={false}
deleteKey={null}
onnodeclick={({ node }) => {