fix(frontend): highlight the runtime-chosen branch in flow graph viewer (#9755)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ruben Fiszel
2026-06-24 15:37:56 +02:00
committed by GitHub
parent 2a70ccc386
commit de6192bec1
4 changed files with 32 additions and 7 deletions
@@ -9,7 +9,11 @@
import { Database, Square } from 'lucide-svelte'
import FlowGraphPreviewButton from './FlowGraphPreviewButton.svelte'
import type { Job } from '$lib/gen'
import { getNodeColorClasses, aiActionToNodeState } from '$lib/components/graph'
import {
getNodeColorClasses,
aiActionToNodeState,
type FlowNodeState
} from '$lib/components/graph'
import { getGraphContext } from '$lib/components/graph/graphContext'
interface Props {
@@ -39,6 +43,9 @@
job?: Job
showJobStatus?: boolean
flowHasChanged?: boolean
/** When set, overrides the node outline with this run-state's colored outline.
* Used to mark the branch taken at runtime on branchone/branchall nodes. */
borderState?: FlowNodeState
}
let {
@@ -67,14 +74,13 @@
individualStepTests = false,
job,
showJobStatus = false,
flowHasChanged = false
flowHasChanged = false,
borderState = undefined
}: Props = $props()
const flowGraphContext = getGraphContext()
let isMultiSelected = $derived(
(flowGraphContext?.selectionManager?.selectedIds?.length ?? 0) > 1
)
let isMultiSelected = $derived((flowGraphContext?.selectionManager?.selectedIds?.length ?? 0) > 1)
const outputPickerVisible = $derived(
(nodeKind || (inputJson && Object.keys(inputJson).length > 0)) && editMode
@@ -96,6 +102,10 @@
// AI action colors take priority over execution state, fallback to _VirtualItem
const effectiveState = $derived(aiActionToNodeState(action) ?? outputType ?? '_VirtualItem')
let colorClasses = $derived(getNodeColorClasses(effectiveState, selected))
// The branch taken at runtime keeps its outline regardless of selection so it stays visible.
let outlineClasses = $derived(
borderState ? getNodeColorClasses(borderState, true).outline : colorClasses.outline
)
</script>
<VirtualItemWrapper
@@ -109,7 +119,7 @@
{#snippet children({ hover })}
<div class="flex flex-col w-full">
<div
class="flex flex-row justify-between {colorClasses.outline} {center
class="flex flex-row justify-between {outlineClasses} {center
? 'items-center'
: 'items-baseline'} w-full overflow-hidden rounded-md p-2 text-2xs module text-primary"
>
@@ -6,6 +6,7 @@
import { X } from 'lucide-svelte'
import type { BranchAllStartN } from '../../graphBuilder.svelte'
import { getGraphContext } from '../../graphContext'
import { computeBorderStatus } from '../utils'
interface Props {
data: BranchAllStartN['data']
id: string
@@ -14,6 +15,10 @@
let { data, id }: Props = $props()
const { selectionManager } = getGraphContext()
let borderStatus = $derived(
computeBorderStatus(data.branchIndex, 'branchall', data.flowModuleState)
)
</script>
<NodeWrapper nodeId={id}>
@@ -22,6 +27,7 @@
label={data.label}
selectable
selected={selectionManager && selectionManager.isNodeSelected(id)}
borderState={borderStatus}
on:select={() => {
setTimeout(() => data.eventHandlers.select(data.id))
}}
@@ -6,6 +6,7 @@
import { X } from 'lucide-svelte'
import type { BranchOneStartN } from '../../graphBuilder.svelte'
import { getGraphContext } from '../../graphContext'
import { computeBorderStatus } from '../utils'
interface Props {
data: BranchOneStartN['data']
id: string
@@ -13,6 +14,12 @@
const { selectionManager } = getGraphContext()
let { data, id }: Props = $props()
// branchIndex is -1 for the default branch and 0-based for explicit branches;
// branchChosen is 0 for default and 1-based, hence the +1.
let borderStatus = $derived(
computeBorderStatus(data.branchIndex + 1, 'branchone', data.flowModuleState)
)
</script>
<NodeWrapper nodeId={id}>
@@ -22,6 +29,7 @@
preLabel={data.preLabel}
selectable
selected={selectionManager && selectionManager.isNodeSelected(id)}
borderState={borderStatus}
on:select={() => {
setTimeout(() => data?.eventHandlers?.select(data.id))
}}
@@ -19,7 +19,8 @@ export function computeBorderStatus(
} else {
let flow_jobs_success = graphModuleState?.flow_jobs_success
if (!flow_jobs_success) {
return 'WaitingForPriorSteps'
// No run yet: leave the branch border neutral instead of forcing a highlight.
return undefined
} else {
let status = flow_jobs_success?.[branchIndex]
if (status == undefined) {