Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion web-admin/src/routes/-/embed/canvas/[name]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@

{#key `${instanceId}::${canvasName}`}
<CanvasProvider {canvasName} {instanceId} showBanner>
<CanvasDashboardEmbed {canvasName} {navigationEnabled} />
<CanvasDashboardEmbed
{canvasName}
{navigationEnabled}
tableOfContents={false}
/>
</CanvasProvider>
{/key}
9 changes: 8 additions & 1 deletion web-common/src/features/canvas/CanvasDashboardEmbed.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

export let canvasName: string;
export let navigationEnabled: boolean = true;
export let tableOfContents: boolean = true;

const runtimeClient = useRuntimeClient();

Expand Down Expand Up @@ -62,7 +63,13 @@
</script>

{#if canvasName}
<CanvasDashboardWrapper {maxWidth} {canvasName} {filtersEnabled} embedded>
<CanvasDashboardWrapper
{maxWidth}
{canvasName}
{filtersEnabled}
showTableOfContents={tableOfContents}
embedded
>
{#each blocks as block (block.kind === "tab-group" ? `g-${block.group.name}` : `r-${block.rowIndex}`)}
{#if block.kind === "tab-group"}
<CanvasTabGroupView
Expand Down
114 changes: 71 additions & 43 deletions web-common/src/features/canvas/CanvasDashboardWrapper.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import { getCanvasStore } from "./state-managers/state-managers";
import ThemeProvider from "../dashboards/ThemeProvider.svelte";
import CanvasPdfExportView from "../exports/pdf/CanvasPdfExportView.svelte";
import CanvasTableOfContents from "./toc/CanvasTableOfContents.svelte";

const client = useRuntimeClient();

Expand All @@ -17,9 +18,21 @@
export let canvasName: string;
export let embedded: boolean = false;
export let builder = false;
export let showTableOfContents = false;
export let onClick: () => void = () => {};

let contentRect = new DOMRectReadOnly(0, 0, 0, 0);
let scrollContainer: HTMLElement | undefined;
let bandWidth = 0;

// Collapse the rail's bars to dots once the viewport is too narrow for the bars to sit in the
// content's left margin (i.e. the centered content is near full width). Based on the stable
// `maxWidth` rather than the measured content width, so there's no feedback loop.
const RAIL_BAR_MARGIN_PX = 48;
$: compactRail =
showTableOfContents &&
bandWidth > 0 &&
bandWidth < maxWidth + RAIL_BAR_MARGIN_PX;

$: ({ instanceId } = client);

Expand Down Expand Up @@ -76,55 +89,70 @@

<div
role="presentation"
id="canvas-scroll-container"
class="p-2 flex flex-col items-center bg-surface-background select-none overflow-y-auto overflow-x-hidden"
class:!cursor-grabbing={showGrabCursor}
class="relative flex overflow-hidden"
class:w-full={$dynamicHeight}
class:size-full={!$dynamicHeight}
class:pb-48={!embedded}
onclick={(e) => {
if (e.target === e.currentTarget) onClick();
}}
bind:clientWidth={bandWidth}
>
{#if hasMissingRequired}
<div class="w-full flex justify-center px-6 pt-24 pb-12">
<!-- Overlays the content's left margin without reserving layout width, so the content stays
centered in the full viewport. On narrow screens the bars collapse to dots so they don't
overlap the content. -->
{#if showTableOfContents && scrollContainer}
<CanvasTableOfContents {scrollContainer} compact={compactRail} />
{/if}

<div
role="presentation"
id="canvas-scroll-container"
bind:this={scrollContainer}
class="p-2 flex flex-col items-center bg-surface-background select-none overflow-y-auto overflow-x-hidden flex-1 min-w-0"
class:!cursor-grabbing={showGrabCursor}
class:h-full={!$dynamicHeight}
class:pb-48={!embedded}
onclick={(e) => {
if (e.target === e.currentTarget) onClick();
}}
>
{#if hasMissingRequired}
<div class="w-full flex justify-center px-6 pt-24 pb-12">
<div
class="flex flex-col items-center text-center gap-y-3 px-8 py-10 rounded-lg border border-gray-200 bg-surface-subtle shadow-sm w-full max-w-lg"
role="alert"
>
<WarningIcon size="32px" className="text-amber-500" />
<h2 class="text-lg font-semibold text-fg-primary">
Select a value to continue
</h2>
<p class="text-sm text-fg-secondary">
This dashboard requires values for the following filter{missingRequiredFilters.length >
1
? "s"
: ""}:
</p>
<ul
class="text-sm text-fg-primary flex flex-wrap justify-center gap-x-2 gap-y-1"
>
{#each missingRequiredFilters as missing (missing.key)}
<li
class="px-2 py-0.5 rounded-md bg-red-50 border border-red-200 text-red-700"
>
{missing.label}
</li>
{/each}
</ul>
</div>
</div>
{:else}
<div
class="flex flex-col items-center text-center gap-y-3 px-8 py-10 rounded-lg border border-gray-200 bg-surface-subtle shadow-sm w-full max-w-lg"
role="alert"
class="w-full h-fit flex flex-col items-center row-container relative"
style:max-width="{maxWidth}px"
style:min-width="420px"
bind:contentRect
>
<WarningIcon size="32px" className="text-amber-500" />
<h2 class="text-lg font-semibold text-fg-primary">
Select a value to continue
</h2>
<p class="text-sm text-fg-secondary">
This dashboard requires values for the following filter{missingRequiredFilters.length >
1
? "s"
: ""}:
</p>
<ul
class="text-sm text-fg-primary flex flex-wrap justify-center gap-x-2 gap-y-1"
>
{#each missingRequiredFilters as missing (missing.key)}
<li
class="px-2 py-0.5 rounded-md bg-red-50 border border-red-200 text-red-700"
>
{missing.label}
</li>
{/each}
</ul>
<slot />
</div>
</div>
{:else}
<div
class="w-full h-fit flex flex-col items-center row-container relative"
style:max-width="{maxWidth}px"
style:min-width="420px"
bind:contentRect
>
<slot />
</div>
{/if}
{/if}
</div>
</div>

<CellInspector />
Expand Down
Loading
Loading