From fe94f4dc44b50eb6fb95541928e3ca3d55595f32 Mon Sep 17 00:00:00 2001 From: Guilhem Lemouel Date: Mon, 5 Oct 2026 07:35:58 -0700 Subject: [PATCH] fix: an embedded page keeps its name in the band MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A page in a session's preview panel loads in a frame that sets `nomenubar`, so the layout renders the band with `navHidden`. That flag hid the whole breadcrumb — which is what carries the page's name — while the actions beside it had no such guard, leaving a row of controls belonging to nothing. Hiding the trail is still right: it leads to the host's workspace and offers a picker that would take the reader out of the session. So the breadcrumb gains a `nameOnly` mode that drops the workspace part and its picker and keeps the page's own name, and the band asks for it instead of rendering nothing. The summary line loses the same guard, so an item in there shows its path and summary. Only the pages whose own title the band took over are affected. Variables, Resources, Schedules and Triggers still draw their own `PageHeader` and render no band when embedded, so nothing is doubled. The bar's left padding is there to sit a button against — the sidebar handle, or the workspace disc, both of which carry their own margin. Embedded there is neither, and the name started as bare text 8px from the edge, so that case takes the same 16px the bar already keeps on its right. Workspace settings drops the copy-id button from the band: the General tab names the workspace ID with a field of its own, which is where someone looks for it. Co-Authored-By: Claude Opus 5 (1M context) --- .../src/lib/components/NavBreadcrumb.svelte | 127 +++++++++--------- .../src/lib/components/PageHeaderBar.svelte | 46 ++++--- .../(logged)/workspace_settings/+page.svelte | 5 +- 3 files changed, 93 insertions(+), 85 deletions(-) diff --git a/frontend/src/lib/components/NavBreadcrumb.svelte b/frontend/src/lib/components/NavBreadcrumb.svelte index 0ea6cd92f3..5bcfd4db24 100644 --- a/frontend/src/lib/components/NavBreadcrumb.svelte +++ b/frontend/src/lib/components/NavBreadcrumb.svelte @@ -34,7 +34,8 @@ same weight, size and icon size, so the line reads as one control rather than fo section, afterName, actingWorkspaceId, - narrow = false + narrow = false, + nameOnly = false }: { item?: PageHeaderItem section?: PageHeaderSection @@ -45,6 +46,10 @@ same weight, size and icon size, so the line reads as one control rather than fo actingWorkspaceId?: string /** The bar is short of room: the workspace part drops its names and keeps its marks. */ narrow?: boolean + /** Only the page's own name, with no workspace part and no picker — the band inside a + * session's preview frame, where the workspace is the host's and leading the reader out of + * it is exactly what that band must not offer. The page still has to say what it is. */ + nameOnly?: boolean } = $props() const scopeId = $derived(actingWorkspaceId ?? $workspaceStore ?? undefined) @@ -185,79 +190,81 @@ same weight, size and icon size, so the line reads as one control rather than fo aria-label="Breadcrumb" class="flex items-center gap-1.5 min-w-0 text-xs font-normal text-primary" > - -
- - -
- - {#if narrow} - - {@render workspaceDisc()} - {#if showFork} - - + {@render workspaceDisc()} + {#if showFork} + + + {@render envBadgeMark()} + + {:else} {@render envBadgeMark()} - + {/if} {:else} - {@render envBadgeMark()} - {/if} - {:else} - - {#if showFork} - - {@render slash()} - - - {scopeName} + {@render slash()} + + + {scopeName} + {@render envBadgeMark()} + + {:else} {@render envBadgeMark()} - - {:else} - {@render envBadgeMark()} + {/if} {/if} - {/if} - + +
+ + {#snippet children({ createMenu })} + + {#snippet triggr({ trigger })} + + + + {/snippet} + {#snippet children({ item: menuItem })} + workspaceMenu?.close()} /> + {/snippet} + + {/snippet} +
- - {#snippet children({ createMenu })} - - {#snippet triggr({ trigger })} - - - - {/snippet} - {#snippet children({ item: menuItem })} - workspaceMenu?.close()} /> - {/snippet} - - {/snippet} - - + {/if} - {#if item || section || routePage} + {#if !nameOnly && (item || section || routePage)} {@render slash()} {/if} diff --git a/frontend/src/lib/components/PageHeaderBar.svelte b/frontend/src/lib/components/PageHeaderBar.svelte index ca2927712a..eb9336dfa9 100644 --- a/frontend/src/lib/components/PageHeaderBar.svelte +++ b/frontend/src/lib/components/PageHeaderBar.svelte @@ -87,6 +87,10 @@ The row's height matches the sidebar's own header row, so the two read as one ba class={twMerge( 'flex items-center gap-1 shrink-0 min-w-0 bg-surface transition-shadow duration-150', phone ? 'flex-wrap content-center min-h-11 py-1 pl-1 pr-2' : 'h-11 pl-2 pr-4', + // The small left padding is there to sit a button against: the sidebar handle, or the + // workspace disc, both of which carry their own visual margin. Embedded there is neither, + // and the page's name would start as bare text 8px from the edge. + navHidden && 'pl-4', showEdge && 'shadow-[inset_0_-1px_0_0_rgb(var(--color-border-light))] dark:shadow-[inset_0_-1px_0_0_#374151] [html.github-dark_&]:shadow-[inset_0_-1px_0_0_rgb(var(--color-border-light))]' )} @@ -121,28 +125,28 @@ The row's height matches the sidebar's own header row, so the two read as one ba On a phone it stops yielding at 10rem, and that floor is what makes the bar wrap: the page's buttons no longer fit beside a trail that wide, so they take the line below instead of squeezing the name down to an ellipsis. - An embed (`navHidden`) gets the page's controls without the trail that would offer to - navigate the host's workspace. --> - {#if !navHidden} -
- - {#key content?.contexts} - - - - {/key} -
- {/if} + An embed (`navHidden`) keeps the page's own name but drops the workspace part around it: + the trail would offer to navigate the host's workspace, while the name is what says which + page the controls beside it belong to. --> +
+ + {#key content?.contexts} + + + + {/key} +
- {#if item && !navHidden && (item.summaryContent || item.summary)} + {#if item && (item.summaryContent || item.summary)}
diff --git a/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte b/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte index f6249c59fa..022048bbf7 100644 --- a/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte @@ -3,7 +3,7 @@ import { page } from '$app/stores' import { isCloudHosted } from '$lib/cloud' import CenteredPage from '$lib/components/CenteredPage.svelte' - import { Alert, Button, CopyButton, Section, Skeleton, Tab, Tabs } from '$lib/components/common' + import { Alert, Button, Section, Skeleton, Tab, Tabs } from '$lib/components/common' import ToggleButtonGroup from '$lib/components/common/toggleButton-v2/ToggleButtonGroup.svelte' import ToggleButton from '$lib/components/common/toggleButton-v2/ToggleButton.svelte' @@ -2431,9 +2431,6 @@ export async function main( /> {#snippet settingsActions()} - {#if $workspaceStore} - - {/if} {#if $superadmin}