fix(frontend): collapse flow topbar buttons to icon-only in narrow panes (#8322)

* feat: collapse flow topbar buttons to icon-only mode in narrow panes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: show delete button on top-right of compact error handler

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: preserve bug icon and diff action bar in compact error handler

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: avoid duplicate delete buttons when diff action bar is active

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: use undefined instead of empty string for wrapperClasses

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Guilhem
2026-03-13 13:08:19 +01:00
committed by GitHub
parent 96229575e6
commit b585dee64d
3 changed files with 65 additions and 31 deletions
@@ -15,11 +15,13 @@
let {
disableAi,
small,
diffManager
diffManager,
compact = false
}: {
small: boolean
disableAi?: boolean
diffManager?: FlowDiffManager
compact?: boolean
} = $props()
const dispatch = createEventDispatcher<{
@@ -58,6 +60,8 @@
selectionManager.selectId('failure')
refreshStateStore(flowStore)
}
const smallFailureModule = $derived(!(failureModuleId && diffManager && moduleAction) && compact)
</script>
{#if flowStore.val?.value?.failure_module}
@@ -67,7 +71,7 @@
<Button
variant="default"
unifiedSize="sm"
wrapperClasses={twMerge('min-w-36', small ? 'max-w-52' : 'max-w-64')}
wrapperClasses={compact ? undefined : twMerge('min-w-36', small ? 'max-w-52' : 'max-w-64')}
id="flow-editor-error-handler"
selected={selectionManager.getSelectedId()?.includes('failure')}
onClick={() => {
@@ -87,26 +91,40 @@
/>
{/if}
<Bug size={14} class="shrink-0" />
{#if !smallFailureModule}
<div class="truncate grow min-w-0 text-center text-xs">
{flowStore.val.value.failure_module?.summary ||
(flowStore.val.value.failure_module?.value.type === 'rawscript'
? `${flowStore.val.value.failure_module?.value.language}`
: 'TBD')}
</div>
<div class="truncate grow min-w-0 text-center text-xs">
{flowStore.val.value.failure_module?.summary ||
(flowStore.val.value.failure_module?.value.type === 'rawscript'
? `${flowStore.val.value.failure_module?.value.language}`
: 'TBD')}
</div>
<button
title="Delete failure script"
type="button"
class="ml-1"
onclick={() => {
flowStore.val.value.failure_module = undefined
selectionManager.selectId('settings-metadata')
}}
>
<X size={12} />
</button>
{/if}
</Button>
{#if smallFailureModule}
<button
title="Delete failure script"
type="button"
class="ml-1"
class="absolute -top-1.5 -right-1.5 rounded-full bg-surface border border-border p-0.5 hover:bg-surface-hover"
onclick={() => {
flowStore.val.value.failure_module = undefined
selectionManager.selectId('settings-metadata')
}}
>
<X size={12} />
<X size={10} />
</button>
</Button>
{/if}
</div>
{:else}
<!-- Index 0 is used by the tutorial to identify the first "Add step" -->
@@ -124,14 +142,17 @@
{#snippet trigger()}
<Button
unifiedSize="sm"
wrapperClasses="min-w-36"
wrapperClasses={compact ? undefined : 'min-w-36'}
title={`Add failure module`}
variant="default"
id={`flow-editor-add-step-error-handler-button`}
nonCaptureEvent
startIcon={{ icon: Bug }}
iconOnly={compact}
>
Error Handler
{#if !compact}
Error Handler
{/if}
</Button>
{/snippet}
</InsertModulePopover>
@@ -271,6 +271,8 @@
let sidebarMode: 'list' | 'graph' = 'graph'
let minHeight = $state(0)
let flowPaneWidth = $state(0)
let compactTopbar = $derived(flowPaneWidth < 700)
export function selectNextId(id: any) {
if (flowStore.val.value.modules) {
@@ -505,11 +507,12 @@
{/each}
</ConfirmationModal>
</Portal>
<div class="flex flex-col h-full relative -pt-1">
<div class="flex flex-col h-full relative -pt-1" bind:clientWidth={flowPaneWidth}>
<div
class={`z-50 absolute inline-flex flex-col gap-2 top-3 left-1/2 -translate-x-1/2 flex-initial items-center transition-colors duration-[400ms] ease-linear bg-surface-100`}
>
<FlowStickyNode
compact={compactTopbar}
{disableAi}
{showFlowAiButton}
{disableSettings}
@@ -21,6 +21,7 @@
toggleNoteMode?: () => void
disableAi?: boolean
diffManager?: FlowDiffManager
compact?: boolean
}
let {
@@ -33,7 +34,8 @@
noteMode,
toggleNoteMode,
disableAi,
diffManager
diffManager,
compact = false
}: Props = $props()
const { selectionManager, flowStore } = getContext<FlowEditorContext>('FlowEditorContext')
@@ -42,23 +44,31 @@
<div class="flex flex-row gap-2 p-1 rounded-md bg-surface">
{#if !disableSettings}
<Button
unifiedSize="sm"
wrapperClasses="min-w-36"
startIcon={{ icon: Settings }}
selected={selectedId?.startsWith('settings')}
variant="default"
title="Settings"
onClick={() => selectionManager.selectId('settings')}
>
Settings
{#if flowStore.val.value.same_worker}
<Badge color="blue" wrapperClass="max-h-[18px]">./shared</Badge>
{/if}
</Button>
<Popover>
<Button
unifiedSize="sm"
wrapperClasses={compact ? undefined : 'min-w-36'}
startIcon={{ icon: Settings }}
selected={selectedId?.startsWith('settings')}
variant="default"
title="Settings"
iconOnly={compact && !flowStore.val.value.same_worker}
onClick={() => selectionManager.selectId('settings')}
>
{#if !compact}
Settings
{/if}
{#if flowStore.val.value.same_worker}
<Badge color="blue" wrapperClass="max-h-[18px]">./shared</Badge>
{/if}
</Button>
{#snippet text()}
Settings
{/snippet}
</Popover>
{/if}
<Popover>
<FlowErrorHandlerItem {disableAi} small={smallErrorHandler} {diffManager} on:generateStep />
<FlowErrorHandlerItem {disableAi} small={smallErrorHandler} {compact} {diffManager} on:generateStep />
{#snippet text()}
Error Handler
{/snippet}