diff --git a/js-packages/common-ui/src/lib/TabsPanel.svelte b/js-packages/common-ui/src/lib/TabsPanel.svelte index b84fc1c5c78..63bdc6a9e48 100644 --- a/js-packages/common-ui/src/lib/TabsPanel.svelte +++ b/js-packages/common-ui/src/lib/TabsPanel.svelte @@ -15,6 +15,9 @@ panel: Component keepAlive: boolean tabBarEnd?: Snippet + /** When true, the trigger is rendered but cannot be selected. Use for tabs whose data the + * loaded profile does not carry. */ + disabled?: boolean } /** Visual style of the tab strip: @@ -53,7 +56,9 @@ // Segment items only need a `value`; the visual label is rendered via the `segmentLabel` // snippet, which dispatches back to each TabSpec's own `label` snippet so a tab definition // stays the single source of truth regardless of the chosen variant. - const segmentItems = $derived[]>(tabs.map((t) => ({ value: t.id }))) + const segmentItems = $derived[]>( + tabs.map((t) => ({ value: t.id, disabled: t.disabled })) + ) {#snippet defaultTabContainer(tab: Snippet, hidden: boolean)} @@ -113,12 +118,15 @@ minimum width on the surrounding Pane. `min-w-0` on the row + a row gap keeps the wrapped rows visually grouped. --> - {#each tabs as { id, label }} + {#each tabs as { id, label, disabled }} {@render label()} diff --git a/js-packages/profiler-app/src/App.svelte b/js-packages/profiler-app/src/App.svelte index 3f1afa0c5e1..d59000790d5 100644 --- a/js-packages/profiler-app/src/App.svelte +++ b/js-packages/profiler-app/src/App.svelte @@ -2,6 +2,7 @@ import { createLoadGuard, getSuitableProfiles, + type GlobalMetrics, processProfileFiles, SupportBundleViewerLayout, type ZipItem @@ -23,6 +24,8 @@ dataflow: Dataflow | undefined sources: string[] | undefined logText: string | undefined + globalMetrics: GlobalMetrics | undefined + runtimeConfig: unknown } | null = $state(null) let fileInput: HTMLInputElement | null = $state(null) @@ -44,7 +47,9 @@ profile: data.profile, dataflow: data.dataflow, sources: data.sources, - logText: data.logText + logText: data.logText, + globalMetrics: data.globalMetrics, + runtimeConfig: data.runtimeConfig } } @@ -111,6 +116,8 @@ dataflowData={profileData.dataflow} programCode={profileData.sources} logText={profileData.logText} + globalMetrics={profileData.globalMetrics} + runtimeConfig={profileData.runtimeConfig} triageResults={new TriageResults()} {profileFiles} {selectedTimestamp} diff --git a/js-packages/profiler-layout/src/lib/components/ConfigView.svelte b/js-packages/profiler-layout/src/lib/components/ConfigView.svelte new file mode 100644 index 00000000000..4f51ce2b109 --- /dev/null +++ b/js-packages/profiler-layout/src/lib/components/ConfigView.svelte @@ -0,0 +1,23 @@ + + +
+ {#if formatted === ''} +
+ No runtime configuration available in this bundle +
+ {:else} +
{formatted}
+ {/if} +
diff --git a/js-packages/profiler-layout/src/lib/components/MetricsView.svelte b/js-packages/profiler-layout/src/lib/components/MetricsView.svelte index 15e06c77e53..35b82fa28c0 100644 --- a/js-packages/profiler-layout/src/lib/components/MetricsView.svelte +++ b/js-packages/profiler-layout/src/lib/components/MetricsView.svelte @@ -28,8 +28,10 @@ {#snippet attributesView()} - {#if !nodeAttributes} + {#if !nodeAttributes && globalMetricEntries.length === 0}
{#if mode === 'node'} Click a node in the graph to see its metrics. @@ -140,7 +151,7 @@ {/if}
{:else} - {#if isNodeView} + {#if nodeAttributes && isNodeView}