@workflow/web-shared 5.0.0-beta.26 → 5.0.0-beta.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/new-trace-viewer/components/detail-panel-width.d.ts +34 -0
- package/dist/components/new-trace-viewer/components/detail-panel-width.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/detail-panel-width.js +67 -0
- package/dist/components/new-trace-viewer/components/detail-panel.d.ts +14 -0
- package/dist/components/new-trace-viewer/components/detail-panel.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/detail-panel.js +122 -0
- package/dist/components/new-trace-viewer/components/draggable-border.d.ts +31 -0
- package/dist/components/new-trace-viewer/components/draggable-border.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/draggable-border.js +140 -0
- package/dist/components/new-trace-viewer/components/event-list.d.ts +1 -1
- package/dist/components/new-trace-viewer/components/event-list.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/components/event-list.js +3 -5
- package/dist/components/new-trace-viewer/components/middle-truncate/truncate.d.ts +1 -1
- package/dist/components/new-trace-viewer/components/middle-truncate/truncate.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/components/middle-truncate/truncate.js +2 -2
- package/dist/components/new-trace-viewer/components/minimap.d.ts +14 -0
- package/dist/components/new-trace-viewer/components/minimap.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/minimap.js +337 -0
- package/dist/components/new-trace-viewer/components/pane-constants.d.ts +14 -0
- package/dist/components/new-trace-viewer/components/pane-constants.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/pane-constants.js +16 -0
- package/dist/components/new-trace-viewer/components/split-pane.d.ts +1 -4
- package/dist/components/new-trace-viewer/components/split-pane.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/components/split-pane.js +18 -16
- package/dist/components/new-trace-viewer/components/timeline.d.ts +2 -2
- package/dist/components/new-trace-viewer/components/timeline.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/components/timeline.js +5 -7
- package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.js +10 -3
- package/dist/components/new-trace-viewer/components/use-element-width.d.ts +8 -0
- package/dist/components/new-trace-viewer/components/use-element-width.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/use-element-width.js +25 -0
- package/dist/components/new-trace-viewer/context.d.ts +2 -0
- package/dist/components/new-trace-viewer/context.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/context.js +3 -2
- package/dist/components/new-trace-viewer/trace-viewer.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/trace-viewer.js +53 -181
- package/dist/components/new-trace-viewer/utils.d.ts +21 -0
- package/dist/components/new-trace-viewer/utils.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/utils.js +44 -3
- package/dist/components/sidebar/attribute-panel.d.ts.map +1 -1
- package/dist/components/sidebar/attribute-panel.js +38 -35
- package/dist/components/sidebar/attributes-block.d.ts +18 -7
- package/dist/components/sidebar/attributes-block.d.ts.map +1 -1
- package/dist/components/sidebar/attributes-block.js +76 -18
- package/dist/components/sidebar/events-list.d.ts +1 -1
- package/dist/components/sidebar/events-list.d.ts.map +1 -1
- package/dist/components/sidebar/events-list.js +9 -10
- package/dist/components/trace-viewer/components/map.d.ts +2 -2
- package/dist/components/trace-viewer/components/map.d.ts.map +1 -1
- package/dist/components/trace-viewer/components/node.d.ts +7 -7
- package/dist/components/trace-viewer/components/node.d.ts.map +1 -1
- package/dist/components/ui/collapsible.d.ts +46 -0
- package/dist/components/ui/collapsible.d.ts.map +1 -0
- package/dist/components/ui/collapsible.js +66 -0
- package/dist/components/ui/data-inspector.js +2 -7
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/lib/hydration.d.ts +12 -2
- package/dist/lib/hydration.d.ts.map +1 -1
- package/dist/lib/hydration.js +41 -18
- package/dist/lib/utils.d.ts +8 -5
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +13 -16
- package/package.json +6 -6
- package/src/components/new-trace-viewer/components/detail-panel-width.test.ts +123 -0
- package/src/components/new-trace-viewer/components/detail-panel-width.ts +76 -0
- package/src/components/new-trace-viewer/components/detail-panel.tsx +272 -0
- package/src/components/new-trace-viewer/components/draggable-border.tsx +216 -0
- package/src/components/new-trace-viewer/components/event-list.tsx +3 -5
- package/src/components/new-trace-viewer/components/middle-truncate/truncate.ts +1 -1
- package/src/components/new-trace-viewer/components/minimap.tsx +559 -0
- package/src/components/new-trace-viewer/components/pane-constants.ts +19 -0
- package/src/components/new-trace-viewer/components/split-pane.tsx +44 -55
- package/src/components/new-trace-viewer/components/timeline.tsx +3 -5
- package/src/components/new-trace-viewer/components/trace-viewer-skeleton.tsx +21 -1
- package/src/components/new-trace-viewer/components/use-element-width.ts +29 -0
- package/src/components/new-trace-viewer/context.tsx +4 -1
- package/src/components/new-trace-viewer/trace-viewer.tsx +93 -312
- package/src/components/new-trace-viewer/utils.test.ts +65 -0
- package/src/components/new-trace-viewer/utils.ts +76 -2
- package/src/components/sidebar/attribute-panel.tsx +106 -105
- package/src/components/sidebar/attributes-block.tsx +170 -50
- package/src/components/sidebar/events-list.tsx +107 -92
- package/src/components/ui/collapsible.tsx +219 -0
- package/src/index.ts +8 -7
- package/src/lib/hydration.ts +48 -25
- package/src/lib/utils.test.ts +33 -0
- package/src/lib/utils.ts +12 -16
- package/dist/components/sidebar/detail-card.d.ts +0 -13
- package/dist/components/sidebar/detail-card.d.ts.map +0 -1
- package/dist/components/sidebar/detail-card.js +0 -36
- package/src/components/sidebar/detail-card.tsx +0 -143
|
@@ -11,20 +11,17 @@ import {
|
|
|
11
11
|
useState,
|
|
12
12
|
} from 'react';
|
|
13
13
|
import { cn } from '../../../lib/cn';
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
14
|
+
import {
|
|
15
|
+
DEFAULT_START_PX,
|
|
16
|
+
GUTTER_PX,
|
|
17
|
+
MIN_PX,
|
|
18
|
+
paneColTemplate,
|
|
19
|
+
} from './pane-constants';
|
|
20
|
+
import { useElementWidth } from './use-element-width';
|
|
22
21
|
|
|
23
22
|
export interface SplitPaneProps {
|
|
24
23
|
children: ReactNode;
|
|
25
24
|
className?: string;
|
|
26
|
-
/** Fixed pixel width for the start (left) pane. Default 220. */
|
|
27
|
-
defaultStartWidth?: number;
|
|
28
25
|
/** Fixed (non-scrolling) header rendered above the start pane. */
|
|
29
26
|
startHeader?: ReactNode;
|
|
30
27
|
/** Fixed (non-scrolling) header rendered above the end pane. */
|
|
@@ -35,7 +32,6 @@ export interface SplitPaneProps {
|
|
|
35
32
|
export function SplitPane({
|
|
36
33
|
children,
|
|
37
34
|
className,
|
|
38
|
-
defaultStartWidth = DEFAULT_START_PX,
|
|
39
35
|
startHeader,
|
|
40
36
|
endHeader,
|
|
41
37
|
scrollContainerRef,
|
|
@@ -46,13 +42,18 @@ export function SplitPane({
|
|
|
46
42
|
}
|
|
47
43
|
const [start, end] = parts;
|
|
48
44
|
|
|
49
|
-
|
|
45
|
+
// `startPx` is the user's preferred width; the rendered width is derived by
|
|
46
|
+
// clamping against the live container width (same model as the detail
|
|
47
|
+
// panel), so shrinking the container compresses the pane without destroying
|
|
48
|
+
// the preference, and re-growing restores it.
|
|
49
|
+
const [startPx, setStartPx] = useState(DEFAULT_START_PX);
|
|
50
50
|
const [isDragging, setIsDragging] = useState(false);
|
|
51
51
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
52
52
|
const gutterRef = useRef<HTMLDivElement>(null);
|
|
53
53
|
const rafRef = useRef<number | null>(null);
|
|
54
|
-
const pendingPx = useRef(
|
|
54
|
+
const pendingPx = useRef(DEFAULT_START_PX);
|
|
55
55
|
const pointerIdRef = useRef<number | null>(null);
|
|
56
|
+
const containerWidth = useElementWidth(containerRef);
|
|
56
57
|
|
|
57
58
|
useEffect(() => {
|
|
58
59
|
return () => {
|
|
@@ -134,8 +135,14 @@ export function SplitPane({
|
|
|
134
135
|
}
|
|
135
136
|
};
|
|
136
137
|
|
|
137
|
-
|
|
138
|
-
|
|
138
|
+
// Floor applied last so the start column can never collapse below MIN_PX
|
|
139
|
+
// (which would produce an invalid negative grid track on tiny containers).
|
|
140
|
+
const effectiveStartPx =
|
|
141
|
+
containerWidth > 0
|
|
142
|
+
? Math.max(MIN_PX, Math.min(containerWidth - MIN_PX - GUTTER_PX, startPx))
|
|
143
|
+
: startPx;
|
|
144
|
+
|
|
145
|
+
const colTemplate = paneColTemplate(effectiveStartPx);
|
|
139
146
|
|
|
140
147
|
const gutter = (
|
|
141
148
|
<div
|
|
@@ -151,48 +158,30 @@ export function SplitPane({
|
|
|
151
158
|
</div>
|
|
152
159
|
);
|
|
153
160
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
<div
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
>
|
|
161
|
-
|
|
162
|
-
<
|
|
163
|
-
<span className="h-full w-px bg-gray-alpha-400" aria-hidden />
|
|
164
|
-
</div>
|
|
165
|
-
<div>{endHeader}</div>
|
|
166
|
-
</div>
|
|
167
|
-
<div
|
|
168
|
-
ref={setContainerRef}
|
|
169
|
-
className={cn(
|
|
170
|
-
'grid flex-1 min-h-0 overflow-x-hidden overflow-y-auto',
|
|
171
|
-
isDragging && 'select-none'
|
|
172
|
-
)}
|
|
173
|
-
style={{ gridTemplateColumns: colTemplate }}
|
|
174
|
-
>
|
|
175
|
-
{start}
|
|
176
|
-
{gutter}
|
|
177
|
-
{end}
|
|
161
|
+
return (
|
|
162
|
+
<div className={cn('flex flex-col h-full min-h-0', className)}>
|
|
163
|
+
<div
|
|
164
|
+
className="shrink-0 grid"
|
|
165
|
+
style={{ gridTemplateColumns: colTemplate }}
|
|
166
|
+
>
|
|
167
|
+
<div>{startHeader}</div>
|
|
168
|
+
<div className="flex justify-center">
|
|
169
|
+
<span className="h-full w-px bg-gray-alpha-400" aria-hidden />
|
|
178
170
|
</div>
|
|
171
|
+
<div>{endHeader}</div>
|
|
172
|
+
</div>
|
|
173
|
+
<div
|
|
174
|
+
ref={setContainerRef}
|
|
175
|
+
className={cn(
|
|
176
|
+
'grid flex-1 min-h-0 overflow-x-hidden overflow-y-auto',
|
|
177
|
+
isDragging && 'select-none'
|
|
178
|
+
)}
|
|
179
|
+
style={{ gridTemplateColumns: colTemplate }}
|
|
180
|
+
>
|
|
181
|
+
{start}
|
|
182
|
+
{gutter}
|
|
183
|
+
{end}
|
|
179
184
|
</div>
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return (
|
|
184
|
-
<div
|
|
185
|
-
ref={setContainerRef}
|
|
186
|
-
className={cn(
|
|
187
|
-
'grid h-full min-h-0 content-start overflow-x-hidden overflow-y-auto',
|
|
188
|
-
isDragging && 'select-none',
|
|
189
|
-
className
|
|
190
|
-
)}
|
|
191
|
-
style={{ gridTemplateColumns: colTemplate, height: '100%' }}
|
|
192
|
-
>
|
|
193
|
-
{start}
|
|
194
|
-
{gutter}
|
|
195
|
-
{end}
|
|
196
185
|
</div>
|
|
197
186
|
);
|
|
198
187
|
}
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
} from 'react';
|
|
14
14
|
import { cn } from '../../../lib/cn';
|
|
15
15
|
import {
|
|
16
|
-
formatDuration,
|
|
17
16
|
formatDurationPrecise,
|
|
18
17
|
getHighResInMs,
|
|
19
18
|
} from '../../trace-viewer/util/timing';
|
|
@@ -32,6 +31,7 @@ import {
|
|
|
32
31
|
computeSpanSegments,
|
|
33
32
|
getResourceColor,
|
|
34
33
|
getSpanDurationMs,
|
|
34
|
+
isSpanErrored,
|
|
35
35
|
} from '../utils';
|
|
36
36
|
import {
|
|
37
37
|
cullCollidingMarkers,
|
|
@@ -451,9 +451,7 @@ const TimelineBar = memo(function TimelineBar({
|
|
|
451
451
|
const hasMarkers =
|
|
452
452
|
markers.length > 0 || offscreen.left !== null || offscreen.right !== null;
|
|
453
453
|
|
|
454
|
-
const
|
|
455
|
-
?.status as string | undefined;
|
|
456
|
-
const isErrored = span.status.code === 2 || workflowStatus === 'failed';
|
|
454
|
+
const isErrored = isSpanErrored(span);
|
|
457
455
|
const colors = getResourceColor(span.resource);
|
|
458
456
|
const fallbackBg = isErrored
|
|
459
457
|
? (colors.errorBg ?? 'var(--ds-red-200)')
|
|
@@ -733,7 +731,7 @@ export function Timeline({
|
|
|
733
731
|
key={gap.rowIndex}
|
|
734
732
|
leftFrac={gap.leftFrac}
|
|
735
733
|
rightFrac={gap.rightFrac}
|
|
736
|
-
label={
|
|
734
|
+
label={formatDurationPrecise(gap.gapMs)}
|
|
737
735
|
rowIndex={gap.rowIndex}
|
|
738
736
|
/>
|
|
739
737
|
))}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { Skeleton } from '../../ui/skeleton';
|
|
2
|
+
import { DEFAULT_START_PX, paneColTemplate } from './pane-constants';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
// Mirrors SplitPane's initial column template so the skeleton lines up with
|
|
5
|
+
// the real viewer's first paint.
|
|
6
|
+
const COL_TEMPLATE = paneColTemplate(DEFAULT_START_PX);
|
|
4
7
|
|
|
5
8
|
const ROWS: { id: string; name: number; off: number; bar: number }[] = [
|
|
6
9
|
{ id: 'r0', name: 62, off: 0, bar: 72 },
|
|
@@ -30,6 +33,23 @@ export function TraceViewerSkeleton() {
|
|
|
30
33
|
>
|
|
31
34
|
<span className="sr-only">Loading trace…</span>
|
|
32
35
|
|
|
36
|
+
{/* Minimap strip: thin density lines tracing the same shape as the bars */}
|
|
37
|
+
<div className="relative h-10 min-h-10 shrink-0 border-b border-gray-alpha-400">
|
|
38
|
+
<div className="absolute inset-x-4 top-[6px]">
|
|
39
|
+
{ROWS.map((row, index) => (
|
|
40
|
+
<Skeleton
|
|
41
|
+
key={row.id}
|
|
42
|
+
className="absolute h-[3px] rounded-full"
|
|
43
|
+
style={{
|
|
44
|
+
left: `${row.off}%`,
|
|
45
|
+
width: `${row.bar}%`,
|
|
46
|
+
top: index * 3.5,
|
|
47
|
+
}}
|
|
48
|
+
/>
|
|
49
|
+
))}
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
33
53
|
{/* Header row: search header | divider | timeline header */}
|
|
34
54
|
<div
|
|
35
55
|
className="shrink-0 grid"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { type RefObject, useLayoutEffect, useState } from 'react';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Observed width (px) of `ref`'s element. Measures synchronously before paint
|
|
7
|
+
* when (re-)enabled, then tracks resizes. While disabled it keeps the last
|
|
8
|
+
* measured value; re-enabling re-measures before the next paint.
|
|
9
|
+
*/
|
|
10
|
+
export function useElementWidth(
|
|
11
|
+
ref: RefObject<HTMLElement | null>,
|
|
12
|
+
enabled = true
|
|
13
|
+
): number {
|
|
14
|
+
const [width, setWidth] = useState(0);
|
|
15
|
+
|
|
16
|
+
useLayoutEffect(() => {
|
|
17
|
+
if (!enabled) return;
|
|
18
|
+
const el = ref.current;
|
|
19
|
+
if (!el) return;
|
|
20
|
+
setWidth(Math.round(el.getBoundingClientRect().width));
|
|
21
|
+
const observer = new ResizeObserver(([entry]) => {
|
|
22
|
+
setWidth(Math.round(entry?.contentRect.width ?? 0));
|
|
23
|
+
});
|
|
24
|
+
observer.observe(el);
|
|
25
|
+
return () => observer.disconnect();
|
|
26
|
+
}, [ref, enabled]);
|
|
27
|
+
|
|
28
|
+
return width;
|
|
29
|
+
}
|
|
@@ -14,6 +14,8 @@ import type { Span } from './types';
|
|
|
14
14
|
interface ActiveSpanContextValue {
|
|
15
15
|
activeSpanId: string | null;
|
|
16
16
|
activeSpan: Span | null;
|
|
17
|
+
/** The full span list the selection lives in (ordered as rendered). */
|
|
18
|
+
spans: Span[];
|
|
17
19
|
setActiveSpan: (spanId: string) => void;
|
|
18
20
|
clearActiveSpan: () => void;
|
|
19
21
|
}
|
|
@@ -67,10 +69,11 @@ export function ActiveSpanProvider({
|
|
|
67
69
|
() => ({
|
|
68
70
|
activeSpanId,
|
|
69
71
|
activeSpan,
|
|
72
|
+
spans,
|
|
70
73
|
setActiveSpan,
|
|
71
74
|
clearActiveSpan,
|
|
72
75
|
}),
|
|
73
|
-
[activeSpanId, activeSpan, setActiveSpan, clearActiveSpan]
|
|
76
|
+
[activeSpanId, activeSpan, spans, setActiveSpan, clearActiveSpan]
|
|
74
77
|
);
|
|
75
78
|
|
|
76
79
|
return (
|