@workflow/web-shared 4.1.0-beta.51 → 4.1.0-beta.53
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/error-boundary.d.ts +15 -20
- package/dist/components/error-boundary.d.ts.map +1 -1
- package/dist/components/error-boundary.js +17 -31
- package/dist/components/error-boundary.js.map +1 -1
- package/dist/components/event-list-view.d.ts +7 -6
- package/dist/components/event-list-view.d.ts.map +1 -1
- package/dist/components/event-list-view.js +492 -109
- package/dist/components/event-list-view.js.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/run-trace-view.d.ts +2 -1
- package/dist/components/run-trace-view.d.ts.map +1 -1
- package/dist/components/run-trace-view.js +2 -2
- package/dist/components/run-trace-view.js.map +1 -1
- package/dist/components/sidebar/attribute-panel.d.ts +2 -1
- package/dist/components/sidebar/attribute-panel.d.ts.map +1 -1
- package/dist/components/sidebar/attribute-panel.js +53 -142
- package/dist/components/sidebar/attribute-panel.js.map +1 -1
- package/dist/components/sidebar/conversation-view.d.ts.map +1 -1
- package/dist/components/sidebar/conversation-view.js +3 -17
- package/dist/components/sidebar/conversation-view.js.map +1 -1
- package/dist/components/sidebar/entity-detail-panel.d.ts +3 -1
- package/dist/components/sidebar/entity-detail-panel.d.ts.map +1 -1
- package/dist/components/sidebar/entity-detail-panel.js +63 -10
- package/dist/components/sidebar/entity-detail-panel.js.map +1 -1
- package/dist/components/sidebar/events-list.d.ts.map +1 -1
- package/dist/components/sidebar/events-list.js +4 -8
- package/dist/components/sidebar/events-list.js.map +1 -1
- package/dist/components/sidebar/resolve-hook-modal.d.ts +3 -0
- package/dist/components/sidebar/resolve-hook-modal.d.ts.map +1 -1
- package/dist/components/sidebar/resolve-hook-modal.js +152 -3
- package/dist/components/sidebar/resolve-hook-modal.js.map +1 -1
- package/dist/components/stream-viewer.d.ts +7 -5
- package/dist/components/stream-viewer.d.ts.map +1 -1
- package/dist/components/stream-viewer.js +54 -22
- package/dist/components/stream-viewer.js.map +1 -1
- package/dist/components/trace-viewer/components/markers.d.ts +2 -1
- package/dist/components/trace-viewer/components/markers.d.ts.map +1 -1
- package/dist/components/trace-viewer/components/markers.js +59 -20
- package/dist/components/trace-viewer/components/markers.js.map +1 -1
- package/dist/components/trace-viewer/components/node.d.ts +5 -1
- package/dist/components/trace-viewer/components/node.d.ts.map +1 -1
- package/dist/components/trace-viewer/components/node.js +250 -68
- package/dist/components/trace-viewer/components/node.js.map +1 -1
- package/dist/components/trace-viewer/components/span-content.d.ts +19 -0
- package/dist/components/trace-viewer/components/span-content.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/span-content.js +137 -0
- package/dist/components/trace-viewer/components/span-content.js.map +1 -0
- package/dist/components/trace-viewer/components/span-detail-panel.d.ts.map +1 -1
- package/dist/components/trace-viewer/components/span-detail-panel.js +3 -2
- package/dist/components/trace-viewer/components/span-detail-panel.js.map +1 -1
- package/dist/components/trace-viewer/components/span-segments.d.ts +50 -0
- package/dist/components/trace-viewer/components/span-segments.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/span-segments.js +392 -0
- package/dist/components/trace-viewer/components/span-segments.js.map +1 -0
- package/dist/components/trace-viewer/components/span-strategies.d.ts +46 -0
- package/dist/components/trace-viewer/components/span-strategies.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/span-strategies.js +108 -0
- package/dist/components/trace-viewer/components/span-strategies.js.map +1 -0
- package/dist/components/trace-viewer/context.d.ts +7 -6
- package/dist/components/trace-viewer/context.d.ts.map +1 -1
- package/dist/components/trace-viewer/context.js +47 -18
- package/dist/components/trace-viewer/context.js.map +1 -1
- package/dist/components/trace-viewer/trace-viewer.d.ts +5 -1
- package/dist/components/trace-viewer/trace-viewer.d.ts.map +1 -1
- package/dist/components/trace-viewer/trace-viewer.js +87 -11
- package/dist/components/trace-viewer/trace-viewer.js.map +1 -1
- package/dist/components/trace-viewer/trace-viewer.module.css +179 -6
- package/dist/components/trace-viewer/util/timing.d.ts +5 -0
- package/dist/components/trace-viewer/util/timing.d.ts.map +1 -1
- package/dist/components/trace-viewer/util/timing.js +12 -0
- package/dist/components/trace-viewer/util/timing.js.map +1 -1
- package/dist/components/trace-viewer/util/use-streaming-spans.d.ts +1 -1
- package/dist/components/trace-viewer/util/use-streaming-spans.d.ts.map +1 -1
- package/dist/components/trace-viewer/util/use-streaming-spans.js +29 -17
- package/dist/components/trace-viewer/util/use-streaming-spans.js.map +1 -1
- package/dist/components/trace-viewer/worker.js +3 -1
- package/dist/components/trace-viewer/worker.js.map +1 -1
- package/dist/components/ui/alert.js +3 -3
- package/dist/components/ui/alert.js.map +1 -1
- package/dist/components/ui/card.d.ts.map +1 -1
- package/dist/components/ui/card.js +2 -2
- package/dist/components/ui/card.js.map +1 -1
- package/dist/components/ui/data-inspector.d.ts +17 -0
- package/dist/components/ui/data-inspector.d.ts.map +1 -0
- package/dist/components/ui/data-inspector.js +184 -0
- package/dist/components/ui/data-inspector.js.map +1 -0
- package/dist/components/ui/error-card.d.ts.map +1 -1
- package/dist/components/ui/error-card.js +4 -1
- package/dist/components/ui/error-card.js.map +1 -1
- package/dist/components/ui/inspector-theme.d.ts +39 -24
- package/dist/components/ui/inspector-theme.d.ts.map +1 -1
- package/dist/components/ui/inspector-theme.js +90 -38
- package/dist/components/ui/inspector-theme.js.map +1 -1
- package/dist/components/ui/skeleton.d.ts +1 -1
- package/dist/components/ui/skeleton.d.ts.map +1 -1
- package/dist/components/ui/skeleton.js +2 -2
- package/dist/components/ui/skeleton.js.map +1 -1
- package/dist/components/workflow-trace-view.d.ts +3 -1
- package/dist/components/workflow-trace-view.d.ts.map +1 -1
- package/dist/components/workflow-trace-view.js +435 -21
- package/dist/components/workflow-trace-view.js.map +1 -1
- package/dist/components/workflow-traces/trace-span-construction.d.ts +1 -1
- package/dist/components/workflow-traces/trace-span-construction.d.ts.map +1 -1
- package/dist/components/workflow-traces/trace-span-construction.js +2 -2
- package/dist/components/workflow-traces/trace-span-construction.js.map +1 -1
- package/dist/lib/hydration.d.ts.map +1 -1
- package/dist/lib/hydration.js +17 -3
- package/dist/lib/hydration.js.map +1 -1
- package/dist/styles.css +186 -0
- package/package.json +8 -7
- package/src/components/error-boundary.tsx +29 -40
- package/src/components/event-list-view.tsx +1000 -287
- package/src/components/index.ts +1 -0
- package/src/components/run-trace-view.tsx +3 -0
- package/src/components/sidebar/attribute-panel.tsx +58 -258
- package/src/components/sidebar/conversation-view.tsx +30 -27
- package/src/components/sidebar/entity-detail-panel.tsx +86 -20
- package/src/components/sidebar/events-list.tsx +4 -11
- package/src/components/sidebar/resolve-hook-modal.tsx +206 -47
- package/src/components/stream-viewer.tsx +138 -61
- package/src/components/trace-viewer/components/markers.tsx +69 -21
- package/src/components/trace-viewer/components/node.tsx +346 -100
- package/src/components/trace-viewer/components/span-content.tsx +247 -0
- package/src/components/trace-viewer/components/span-detail-panel.tsx +7 -2
- package/src/components/trace-viewer/components/span-segments.ts +516 -0
- package/src/components/trace-viewer/components/span-strategies.ts +205 -0
- package/src/components/trace-viewer/context.tsx +92 -40
- package/src/components/trace-viewer/trace-viewer.module.css +179 -6
- package/src/components/trace-viewer/trace-viewer.tsx +115 -11
- package/src/components/trace-viewer/util/timing.ts +13 -0
- package/src/components/trace-viewer/util/use-streaming-spans.ts +28 -17
- package/src/components/trace-viewer/worker.ts +4 -1
- package/src/components/ui/alert.tsx +3 -3
- package/src/components/ui/card.tsx +3 -5
- package/src/components/ui/data-inspector.tsx +318 -0
- package/src/components/ui/error-card.tsx +17 -6
- package/src/components/ui/inspector-theme.ts +127 -39
- package/src/components/ui/skeleton.tsx +3 -1
- package/src/components/workflow-trace-view.tsx +625 -26
- package/src/components/workflow-traces/trace-span-construction.ts +3 -2
- package/src/lib/hydration.ts +17 -8
- package/src/styles.css +186 -0
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { parseStepName, parseWorkflowName } from '@workflow/utils/parse-name';
|
|
4
|
+
import { Check, ChevronRight, Copy } from 'lucide-react';
|
|
5
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
6
|
+
import { Virtuoso } from 'react-virtuoso';
|
|
7
|
+
import { formatDuration } from '../lib/utils';
|
|
8
|
+
import { DataInspector } from './ui/data-inspector';
|
|
9
|
+
import { Skeleton } from './ui/skeleton';
|
|
10
|
+
const BUTTON_RESET_STYLE = {
|
|
11
|
+
appearance: 'none',
|
|
12
|
+
WebkitAppearance: 'none',
|
|
13
|
+
border: 'none',
|
|
14
|
+
background: 'transparent',
|
|
15
|
+
};
|
|
16
|
+
const DOT_PULSE_ANIMATION = 'workflow-dot-pulse 1.25s cubic-bezier(0, 0, 0.2, 1) infinite';
|
|
17
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
18
|
+
// Helpers
|
|
19
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
12
20
|
function formatEventTime(date) {
|
|
13
21
|
return (date.toLocaleTimeString('en-US', {
|
|
14
22
|
hour: '2-digit',
|
|
@@ -19,48 +27,331 @@ function formatEventTime(date) {
|
|
|
19
27
|
'.' +
|
|
20
28
|
date.getMilliseconds().toString().padStart(3, '0'));
|
|
21
29
|
}
|
|
22
|
-
/**
|
|
23
|
-
* Format a date to full local datetime string with milliseconds
|
|
24
|
-
*/
|
|
25
|
-
function formatEventDateTime(date) {
|
|
26
|
-
return date.toLocaleString(undefined, {
|
|
27
|
-
year: 'numeric',
|
|
28
|
-
month: 'numeric',
|
|
29
|
-
day: 'numeric',
|
|
30
|
-
hour: 'numeric',
|
|
31
|
-
minute: 'numeric',
|
|
32
|
-
second: 'numeric',
|
|
33
|
-
fractionalSecondDigits: 3,
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Format event type to a more readable label
|
|
38
|
-
*/
|
|
39
30
|
function formatEventType(eventType) {
|
|
40
31
|
return eventType
|
|
41
32
|
.split('_')
|
|
42
33
|
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
43
34
|
.join(' ');
|
|
44
35
|
}
|
|
36
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
37
|
+
// Event type → status color (small dot only)
|
|
38
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
39
|
+
/** Returns a CSS color using Geist design tokens for the status dot. */
|
|
40
|
+
function getStatusDotColor(eventType) {
|
|
41
|
+
// Failed → red
|
|
42
|
+
if (eventType === 'step_failed' ||
|
|
43
|
+
eventType === 'run_failed' ||
|
|
44
|
+
eventType === 'workflow_failed') {
|
|
45
|
+
return 'var(--ds-red-700)';
|
|
46
|
+
}
|
|
47
|
+
// Cancelled → amber
|
|
48
|
+
if (eventType === 'run_cancelled') {
|
|
49
|
+
return 'var(--ds-amber-700)';
|
|
50
|
+
}
|
|
51
|
+
// Retrying → amber
|
|
52
|
+
if (eventType === 'step_retrying') {
|
|
53
|
+
return 'var(--ds-amber-700)';
|
|
54
|
+
}
|
|
55
|
+
// Completed/succeeded → green
|
|
56
|
+
if (eventType === 'step_completed' ||
|
|
57
|
+
eventType === 'run_completed' ||
|
|
58
|
+
eventType === 'workflow_completed' ||
|
|
59
|
+
eventType === 'hook_disposed' ||
|
|
60
|
+
eventType === 'wait_completed') {
|
|
61
|
+
return 'var(--ds-green-700)';
|
|
62
|
+
}
|
|
63
|
+
// Started/running → blue
|
|
64
|
+
if (eventType === 'step_started' ||
|
|
65
|
+
eventType === 'run_started' ||
|
|
66
|
+
eventType === 'workflow_started' ||
|
|
67
|
+
eventType === 'hook_received') {
|
|
68
|
+
return 'var(--ds-blue-700)';
|
|
69
|
+
}
|
|
70
|
+
// Created/pending → gray
|
|
71
|
+
return 'var(--ds-gray-600)';
|
|
72
|
+
}
|
|
45
73
|
/**
|
|
46
|
-
*
|
|
74
|
+
* Build a map from correlationId (stepId) → display name using step entities,
|
|
75
|
+
* and parse the workflow name from the run.
|
|
47
76
|
*/
|
|
48
|
-
function
|
|
49
|
-
const
|
|
77
|
+
function buildNameMaps(steps, run) {
|
|
78
|
+
const correlationNameMap = new Map();
|
|
79
|
+
// Map step correlationId (= stepId) → parsed step name
|
|
80
|
+
if (steps) {
|
|
81
|
+
for (const step of steps) {
|
|
82
|
+
const parsed = parseStepName(String(step.stepName));
|
|
83
|
+
correlationNameMap.set(step.stepId, parsed?.shortName ?? step.stepName);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Parse workflow name from run
|
|
87
|
+
const workflowName = run?.workflowName
|
|
88
|
+
? (parseWorkflowName(run.workflowName)?.shortName ?? run.workflowName)
|
|
89
|
+
: null;
|
|
90
|
+
return { correlationNameMap, workflowName };
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Build a map from correlationId → duration info by diffing
|
|
94
|
+
* created ↔ started (queued) and started ↔ completed/failed/cancelled (ran).
|
|
95
|
+
* Also computes run-level durations under the key '__run__'.
|
|
96
|
+
*/
|
|
97
|
+
function buildDurationMap(events) {
|
|
98
|
+
const createdTimes = new Map();
|
|
99
|
+
const startedTimes = new Map();
|
|
100
|
+
const durations = new Map();
|
|
101
|
+
for (const event of events) {
|
|
102
|
+
const ts = new Date(event.createdAt).getTime();
|
|
103
|
+
const key = event.correlationId ?? '__run__';
|
|
104
|
+
const type = event.eventType;
|
|
105
|
+
// Track created times (first event for each correlation)
|
|
106
|
+
if (type === 'step_created' || type === 'run_created') {
|
|
107
|
+
createdTimes.set(key, ts);
|
|
108
|
+
}
|
|
109
|
+
// Track started times & compute queued duration
|
|
110
|
+
if (type === 'step_started' ||
|
|
111
|
+
type === 'run_started' ||
|
|
112
|
+
type === 'workflow_started') {
|
|
113
|
+
startedTimes.set(key, ts);
|
|
114
|
+
// If no explicit created event was seen, use the started time as created
|
|
115
|
+
if (!createdTimes.has(key)) {
|
|
116
|
+
createdTimes.set(key, ts);
|
|
117
|
+
}
|
|
118
|
+
const createdAt = createdTimes.get(key);
|
|
119
|
+
const info = durations.get(key) ?? {};
|
|
120
|
+
if (createdAt !== undefined) {
|
|
121
|
+
info.queued = ts - createdAt;
|
|
122
|
+
}
|
|
123
|
+
durations.set(key, info);
|
|
124
|
+
}
|
|
125
|
+
// Compute ran duration on terminal events
|
|
126
|
+
if (type === 'step_completed' ||
|
|
127
|
+
type === 'step_failed' ||
|
|
128
|
+
type === 'run_completed' ||
|
|
129
|
+
type === 'run_failed' ||
|
|
130
|
+
type === 'run_cancelled' ||
|
|
131
|
+
type === 'workflow_completed' ||
|
|
132
|
+
type === 'workflow_failed' ||
|
|
133
|
+
type === 'wait_completed' ||
|
|
134
|
+
type === 'hook_disposed') {
|
|
135
|
+
const startedAt = startedTimes.get(key);
|
|
136
|
+
const info = durations.get(key) ?? {};
|
|
137
|
+
if (startedAt !== undefined) {
|
|
138
|
+
info.ran = ts - startedAt;
|
|
139
|
+
}
|
|
140
|
+
durations.set(key, info);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return durations;
|
|
144
|
+
}
|
|
145
|
+
function isRunLevel(eventType) {
|
|
146
|
+
return (eventType === 'run_created' ||
|
|
147
|
+
eventType === 'run_started' ||
|
|
148
|
+
eventType === 'run_completed' ||
|
|
149
|
+
eventType === 'run_failed' ||
|
|
150
|
+
eventType === 'run_cancelled' ||
|
|
151
|
+
eventType === 'workflow_started' ||
|
|
152
|
+
eventType === 'workflow_completed' ||
|
|
153
|
+
eventType === 'workflow_failed');
|
|
154
|
+
}
|
|
155
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
156
|
+
// Tree gutter — fixed-width, shows branch lines only for the selected group
|
|
157
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
158
|
+
/** Fixed gutter width: 20px root area + 16px for one branch lane */
|
|
159
|
+
const GUTTER_WIDTH = 36;
|
|
160
|
+
/** X position of the single branch lane line */
|
|
161
|
+
const LANE_X = 20;
|
|
162
|
+
const ROOT_LINE_COLOR = 'var(--ds-gray-500)';
|
|
163
|
+
function TreeGutter({ isFirst, isLast, isRunLevel: isRun, statusDotColor, pulse = false, hasSelection, showBranch, showLaneLine, isLaneStart, isLaneEnd, continuationOnly = false, }) {
|
|
164
|
+
const dotSize = isRun ? 8 : 6;
|
|
165
|
+
const dotLeft = isRun ? 5 : 6;
|
|
166
|
+
const dotOpacity = hasSelection && !showBranch && !isRun ? 0.3 : 1;
|
|
167
|
+
return (_jsxs("div", { className: "relative flex-shrink-0 self-stretch", style: {
|
|
168
|
+
width: GUTTER_WIDTH,
|
|
169
|
+
minHeight: continuationOnly ? 0 : undefined,
|
|
170
|
+
}, children: [_jsx("div", { style: {
|
|
171
|
+
position: 'absolute',
|
|
172
|
+
left: 8,
|
|
173
|
+
top: continuationOnly ? 0 : isFirst ? '50%' : 0,
|
|
174
|
+
bottom: continuationOnly ? 0 : isLast ? '50%' : 0,
|
|
175
|
+
width: 2,
|
|
176
|
+
backgroundColor: ROOT_LINE_COLOR,
|
|
177
|
+
zIndex: 0,
|
|
178
|
+
} }), !continuationOnly && (_jsxs(_Fragment, { children: [_jsxs("div", { style: {
|
|
179
|
+
position: 'absolute',
|
|
180
|
+
left: dotLeft,
|
|
181
|
+
top: '50%',
|
|
182
|
+
transform: 'translateY(-50%)',
|
|
183
|
+
width: dotSize,
|
|
184
|
+
height: dotSize,
|
|
185
|
+
zIndex: 2,
|
|
186
|
+
}, children: [_jsx("div", { style: {
|
|
187
|
+
position: 'absolute',
|
|
188
|
+
inset: 0,
|
|
189
|
+
borderRadius: '50%',
|
|
190
|
+
backgroundColor: 'var(--ds-background-100)',
|
|
191
|
+
zIndex: 0,
|
|
192
|
+
} }), pulse && (_jsx("div", { style: {
|
|
193
|
+
position: 'absolute',
|
|
194
|
+
inset: 0,
|
|
195
|
+
borderRadius: '50%',
|
|
196
|
+
backgroundColor: statusDotColor,
|
|
197
|
+
opacity: 0.75 * dotOpacity,
|
|
198
|
+
animation: DOT_PULSE_ANIMATION,
|
|
199
|
+
zIndex: 1,
|
|
200
|
+
} })), _jsx("div", { style: {
|
|
201
|
+
position: 'relative',
|
|
202
|
+
width: '100%',
|
|
203
|
+
height: '100%',
|
|
204
|
+
borderRadius: '50%',
|
|
205
|
+
backgroundColor: statusDotColor,
|
|
206
|
+
opacity: dotOpacity,
|
|
207
|
+
transition: 'opacity 150ms',
|
|
208
|
+
zIndex: 2,
|
|
209
|
+
} })] }), showBranch && (_jsx("div", { style: {
|
|
210
|
+
position: 'absolute',
|
|
211
|
+
left: 9,
|
|
212
|
+
top: '50%',
|
|
213
|
+
width: GUTTER_WIDTH - 9,
|
|
214
|
+
height: 2,
|
|
215
|
+
backgroundColor: ROOT_LINE_COLOR,
|
|
216
|
+
zIndex: 0,
|
|
217
|
+
} }))] })), showLaneLine && (_jsx("div", { style: {
|
|
218
|
+
position: 'absolute',
|
|
219
|
+
left: LANE_X,
|
|
220
|
+
top: continuationOnly ? 0 : isLaneStart ? '50%' : 0,
|
|
221
|
+
bottom: continuationOnly ? 0 : isLaneEnd ? '50%' : 0,
|
|
222
|
+
width: 2,
|
|
223
|
+
backgroundColor: ROOT_LINE_COLOR,
|
|
224
|
+
zIndex: 0,
|
|
225
|
+
} }))] }));
|
|
226
|
+
}
|
|
227
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
228
|
+
// Copyable cell — shows a copy button on hover
|
|
229
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
230
|
+
function CopyableCell({ value, className, }) {
|
|
231
|
+
const [copied, setCopied] = useState(false);
|
|
232
|
+
const resetCopiedTimeoutRef = useRef(null);
|
|
233
|
+
useEffect(() => {
|
|
234
|
+
return () => {
|
|
235
|
+
if (resetCopiedTimeoutRef.current !== null) {
|
|
236
|
+
window.clearTimeout(resetCopiedTimeoutRef.current);
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
}, []);
|
|
240
|
+
const handleCopy = useCallback((e) => {
|
|
241
|
+
e.stopPropagation();
|
|
242
|
+
navigator.clipboard.writeText(value).then(() => {
|
|
243
|
+
setCopied(true);
|
|
244
|
+
if (resetCopiedTimeoutRef.current !== null) {
|
|
245
|
+
window.clearTimeout(resetCopiedTimeoutRef.current);
|
|
246
|
+
}
|
|
247
|
+
resetCopiedTimeoutRef.current = window.setTimeout(() => {
|
|
248
|
+
setCopied(false);
|
|
249
|
+
resetCopiedTimeoutRef.current = null;
|
|
250
|
+
}, 1500);
|
|
251
|
+
});
|
|
252
|
+
}, [value]);
|
|
253
|
+
return (_jsxs("div", { className: `group/copy flex items-center gap-1 flex-1 min-w-0 px-4 ${className ?? ''}`, children: [_jsx("span", { className: "overflow-hidden text-ellipsis whitespace-nowrap", children: value || '-' }), value ? (_jsx("button", { type: "button", onClick: handleCopy, className: "flex-shrink-0 opacity-0 group-hover/copy:opacity-100 transition-opacity p-0.5 rounded hover:bg-[var(--ds-gray-alpha-200)]", style: BUTTON_RESET_STYLE, "aria-label": `Copy ${value}`, children: copied ? (_jsx(Check, { className: "h-3 w-3", style: { color: 'var(--ds-green-700)' } })) : (_jsx(Copy, { className: "h-3 w-3", style: { color: 'var(--ds-gray-700)' } })) })) : null] }));
|
|
254
|
+
}
|
|
255
|
+
/** Recursively parse stringified JSON values so escaped slashes / quotes are cleaned up */
|
|
256
|
+
function deepParseJson(value) {
|
|
257
|
+
if (typeof value === 'string') {
|
|
258
|
+
const trimmed = value.trim();
|
|
259
|
+
if ((trimmed.startsWith('{') && trimmed.endsWith('}')) ||
|
|
260
|
+
(trimmed.startsWith('[') && trimmed.endsWith(']')) ||
|
|
261
|
+
(trimmed.startsWith('"') && trimmed.endsWith('"'))) {
|
|
262
|
+
try {
|
|
263
|
+
return deepParseJson(JSON.parse(trimmed));
|
|
264
|
+
}
|
|
265
|
+
catch {
|
|
266
|
+
return value;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return value;
|
|
270
|
+
}
|
|
271
|
+
if (Array.isArray(value)) {
|
|
272
|
+
return value.map(deepParseJson);
|
|
273
|
+
}
|
|
274
|
+
if (value !== null && typeof value === 'object') {
|
|
275
|
+
const result = {};
|
|
276
|
+
for (const [k, v] of Object.entries(value)) {
|
|
277
|
+
result[k] = deepParseJson(v);
|
|
278
|
+
}
|
|
279
|
+
return result;
|
|
280
|
+
}
|
|
281
|
+
return value;
|
|
282
|
+
}
|
|
283
|
+
function PayloadBlock({ data }) {
|
|
284
|
+
const [copied, setCopied] = useState(false);
|
|
285
|
+
const resetCopiedTimeoutRef = useRef(null);
|
|
286
|
+
const cleaned = useMemo(() => deepParseJson(data), [data]);
|
|
287
|
+
useEffect(() => {
|
|
288
|
+
return () => {
|
|
289
|
+
if (resetCopiedTimeoutRef.current !== null) {
|
|
290
|
+
window.clearTimeout(resetCopiedTimeoutRef.current);
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
}, []);
|
|
294
|
+
const formatted = useMemo(() => {
|
|
295
|
+
try {
|
|
296
|
+
return JSON.stringify(cleaned, null, 2);
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
return String(cleaned);
|
|
300
|
+
}
|
|
301
|
+
}, [cleaned]);
|
|
302
|
+
const handleCopy = useCallback((e) => {
|
|
303
|
+
e.stopPropagation();
|
|
304
|
+
navigator.clipboard.writeText(formatted).then(() => {
|
|
305
|
+
setCopied(true);
|
|
306
|
+
if (resetCopiedTimeoutRef.current !== null) {
|
|
307
|
+
window.clearTimeout(resetCopiedTimeoutRef.current);
|
|
308
|
+
}
|
|
309
|
+
resetCopiedTimeoutRef.current = window.setTimeout(() => {
|
|
310
|
+
setCopied(false);
|
|
311
|
+
resetCopiedTimeoutRef.current = null;
|
|
312
|
+
}, 1500);
|
|
313
|
+
});
|
|
314
|
+
}, [formatted]);
|
|
315
|
+
return (_jsxs("div", { className: "relative group/payload", children: [_jsx("div", { className: "overflow-x-auto p-2 text-[11px]", style: { color: 'var(--ds-gray-1000)' }, children: _jsx(DataInspector, { data: cleaned, expandLevel: 2 }) }), _jsx("button", { type: "button", onClick: handleCopy, className: "absolute bottom-2 right-2 opacity-0 group-hover/payload:opacity-100 transition-opacity flex items-center gap-1 px-2 py-1 rounded-md text-xs hover:bg-[var(--ds-gray-alpha-200)]", style: { ...BUTTON_RESET_STYLE, color: 'var(--ds-gray-700)' }, "aria-label": "Copy payload", children: copied ? (_jsxs(_Fragment, { children: [_jsx(Check, { className: "h-3 w-3", style: { color: 'var(--ds-green-700)' } }), _jsx("span", { style: { color: 'var(--ds-green-700)' }, children: "Copied" })] })) : (_jsxs(_Fragment, { children: [_jsx(Copy, { className: "h-3 w-3" }), _jsx("span", { children: "Copy" })] })) })] }));
|
|
316
|
+
}
|
|
317
|
+
function EventRow({ event, index, isFirst, isLast, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, }) {
|
|
50
318
|
const [isExpanded, setIsExpanded] = useState(false);
|
|
51
319
|
const [isLoading, setIsLoading] = useState(false);
|
|
52
320
|
const [loadedEventData, setLoadedEventData] = useState(null);
|
|
53
321
|
const [loadError, setLoadError] = useState(null);
|
|
54
|
-
const
|
|
322
|
+
const [hasAttemptedLoad, setHasAttemptedLoad] = useState(false);
|
|
323
|
+
const rowGroupKey = event.correlationId ??
|
|
324
|
+
(isRunLevel(event.eventType) ? '__run__' : undefined);
|
|
325
|
+
// Collapse when a different group gets selected
|
|
326
|
+
useEffect(() => {
|
|
327
|
+
if (selectedGroupKey !== undefined && selectedGroupKey !== rowGroupKey) {
|
|
328
|
+
setIsExpanded(false);
|
|
329
|
+
}
|
|
330
|
+
}, [selectedGroupKey, rowGroupKey]);
|
|
331
|
+
const statusDotColor = getStatusDotColor(event.eventType);
|
|
55
332
|
const createdAt = new Date(event.createdAt);
|
|
56
|
-
// Check if event already has eventData (from initial fetch)
|
|
57
333
|
const hasExistingEventData = 'eventData' in event && event.eventData != null;
|
|
58
|
-
|
|
334
|
+
const isRun = isRunLevel(event.eventType);
|
|
335
|
+
const eventName = isRun
|
|
336
|
+
? (workflowName ?? '-')
|
|
337
|
+
: event.correlationId
|
|
338
|
+
? (correlationNameMap.get(event.correlationId) ?? '-')
|
|
339
|
+
: '-';
|
|
340
|
+
const durationKey = event.correlationId ?? (isRun ? '__run__' : '');
|
|
341
|
+
const durationInfo = durationKey ? durationMap.get(durationKey) : undefined;
|
|
342
|
+
const hasActive = activeGroupKey !== undefined;
|
|
343
|
+
const isRelated = rowGroupKey !== undefined && rowGroupKey === activeGroupKey;
|
|
344
|
+
const isDimmed = hasActive && !isRelated;
|
|
345
|
+
const isPulsing = hasActive && isRelated;
|
|
346
|
+
// Gutter state derived from selectedGroupRange
|
|
347
|
+
const showBranch = hasActive && isRelated && !isRun;
|
|
348
|
+
const showLaneLine = selectedGroupRange !== null &&
|
|
349
|
+
index >= selectedGroupRange.first &&
|
|
350
|
+
index <= selectedGroupRange.last;
|
|
351
|
+
const isLaneStart = selectedGroupRange !== null && index === selectedGroupRange.first;
|
|
352
|
+
const isLaneEnd = selectedGroupRange !== null && index === selectedGroupRange.last;
|
|
59
353
|
const loadEventDetails = useCallback(async () => {
|
|
60
|
-
|
|
61
|
-
if (loadedEventData !== null ||
|
|
62
|
-
hasExistingEventData ||
|
|
63
|
-
!event.correlationId) {
|
|
354
|
+
if (loadedEventData !== null || hasExistingEventData) {
|
|
64
355
|
return;
|
|
65
356
|
}
|
|
66
357
|
setIsLoading(true);
|
|
@@ -80,99 +371,191 @@ function EventRow({ event, onLoadEventData, }) {
|
|
|
80
371
|
}
|
|
81
372
|
finally {
|
|
82
373
|
setIsLoading(false);
|
|
374
|
+
setHasAttemptedLoad(true);
|
|
83
375
|
}
|
|
84
|
-
}, [
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
hasExistingEventData,
|
|
88
|
-
onLoadEventData,
|
|
89
|
-
]);
|
|
90
|
-
// Handle expand/collapse
|
|
91
|
-
const handleToggle = useCallback(() => {
|
|
376
|
+
}, [event, loadedEventData, hasExistingEventData, onLoadEventData]);
|
|
377
|
+
const handleExpandToggle = useCallback((e) => {
|
|
378
|
+
e.stopPropagation();
|
|
92
379
|
const newExpanded = !isExpanded;
|
|
93
380
|
setIsExpanded(newExpanded);
|
|
94
|
-
// Load details when expanding for the first time
|
|
95
381
|
if (newExpanded && loadedEventData === null && !hasExistingEventData) {
|
|
96
382
|
loadEventDetails();
|
|
97
383
|
}
|
|
98
384
|
}, [isExpanded, loadedEventData, hasExistingEventData, loadEventDetails]);
|
|
99
|
-
|
|
385
|
+
const handleRowClick = useCallback(() => {
|
|
386
|
+
if (selectedGroupKey === rowGroupKey) {
|
|
387
|
+
onSelectGroup(undefined);
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
onSelectGroup(rowGroupKey);
|
|
391
|
+
}
|
|
392
|
+
}, [selectedGroupKey, rowGroupKey, onSelectGroup]);
|
|
100
393
|
const eventData = hasExistingEventData
|
|
101
394
|
? event.eventData
|
|
102
395
|
: loadedEventData;
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
396
|
+
const contentOpacity = isDimmed ? 0.3 : 1;
|
|
397
|
+
return (_jsxs("div", { "data-event-id": event.eventId, onMouseEnter: () => onHoverGroup(rowGroupKey), onMouseLeave: () => onHoverGroup(undefined), children: [_jsxs("div", { role: "button", tabIndex: 0, onClick: handleRowClick, onKeyDown: (e) => {
|
|
398
|
+
if (e.key === 'Enter' || e.key === ' ')
|
|
399
|
+
handleRowClick();
|
|
400
|
+
}, className: "w-full text-left flex items-center gap-0 text-sm hover:bg-[var(--ds-gray-alpha-100)] transition-colors cursor-pointer", style: { minHeight: 40 }, children: [_jsx(TreeGutter, { isFirst: isFirst, isLast: isLast && !isExpanded, isRunLevel: isRun, statusDotColor: statusDotColor, pulse: isPulsing, hasSelection: hasActive, showBranch: showBranch, showLaneLine: showLaneLine, isLaneStart: isLaneStart, isLaneEnd: isLaneEnd }), _jsxs("div", { className: "flex items-center flex-1 min-w-0", style: { opacity: contentOpacity, transition: 'opacity 150ms' }, children: [_jsx("button", { type: "button", onClick: handleExpandToggle, className: "flex items-center justify-center w-5 h-5 flex-shrink-0 rounded hover:bg-[var(--ds-gray-alpha-200)] transition-colors", style: {
|
|
401
|
+
...BUTTON_RESET_STYLE,
|
|
402
|
+
border: '1px solid var(--ds-gray-alpha-400)',
|
|
403
|
+
}, "aria-label": isExpanded ? 'Collapse details' : 'Expand details', children: _jsx(ChevronRight, { className: "h-3 w-3 transition-transform", style: {
|
|
404
|
+
color: 'var(--ds-gray-700)',
|
|
405
|
+
transform: isExpanded ? 'rotate(90deg)' : 'rotate(0deg)',
|
|
406
|
+
} }) }), _jsx("div", { className: "text-xs tabular-nums flex-1 min-w-0 px-4", style: { color: 'var(--ds-gray-900)' }, children: formatEventTime(createdAt) }), _jsx("div", { className: "text-xs font-medium flex-1 min-w-0 px-4", children: _jsxs("span", { className: "inline-flex items-center gap-1.5", style: { color: 'var(--ds-gray-900)' }, children: [_jsxs("span", { style: {
|
|
407
|
+
position: 'relative',
|
|
408
|
+
display: 'inline-flex',
|
|
409
|
+
width: 6,
|
|
410
|
+
height: 6,
|
|
411
|
+
flexShrink: 0,
|
|
412
|
+
}, children: [isPulsing && (_jsx("span", { style: {
|
|
413
|
+
position: 'absolute',
|
|
414
|
+
inset: 0,
|
|
415
|
+
borderRadius: '50%',
|
|
416
|
+
backgroundColor: statusDotColor,
|
|
417
|
+
opacity: 0.75,
|
|
418
|
+
animation: DOT_PULSE_ANIMATION,
|
|
419
|
+
} })), _jsx("span", { style: {
|
|
420
|
+
position: 'relative',
|
|
421
|
+
width: 6,
|
|
422
|
+
height: 6,
|
|
423
|
+
borderRadius: '50%',
|
|
424
|
+
backgroundColor: statusDotColor,
|
|
425
|
+
} })] }), formatEventType(event.eventType)] }) }), _jsx("div", { className: "text-xs flex-1 min-w-0 px-4 overflow-hidden text-ellipsis whitespace-nowrap", title: eventName !== '-' ? eventName : undefined, children: eventName }), _jsx(CopyableCell, { value: event.correlationId || '', className: "font-mono text-xs" }), _jsx(CopyableCell, { value: event.eventId, className: "font-mono text-xs" })] })] }), isExpanded && (_jsxs("div", { className: "flex", children: [_jsx(TreeGutter, { isFirst: false, isLast: isLast, isRunLevel: isRun, hasSelection: hasActive, showBranch: false, showLaneLine: showLaneLine && !isLaneEnd, isLaneStart: false, isLaneEnd: false, continuationOnly: true }), _jsx("div", { className: "w-5 flex-shrink-0" }), _jsxs("div", { className: "flex-1 my-1.5 mr-3 ml-2 py-2 rounded-md border overflow-hidden", style: {
|
|
426
|
+
borderColor: 'var(--ds-gray-alpha-200)',
|
|
427
|
+
opacity: contentOpacity,
|
|
428
|
+
transition: 'opacity 150ms',
|
|
429
|
+
}, children: [(durationInfo?.queued !== undefined ||
|
|
430
|
+
durationInfo?.ran !== undefined) && (_jsxs("div", { className: "px-2 pb-1.5 text-xs flex gap-3", style: { color: 'var(--ds-gray-900)' }, children: [durationInfo.queued !== undefined &&
|
|
431
|
+
durationInfo.queued > 0 && (_jsxs("span", { children: ["Queued for", ' ', _jsx("span", { className: "font-mono tabular-nums", children: formatDuration(durationInfo.queued) })] })), durationInfo.ran !== undefined && (_jsxs("span", { children: ["Ran for", ' ', _jsx("span", { className: "font-mono tabular-nums", children: formatDuration(durationInfo.ran) })] }))] })), eventData != null ? (_jsx(PayloadBlock, { data: eventData })) : loadError ? (_jsx("div", { className: "rounded-md border p-3 text-xs", style: {
|
|
124
432
|
borderColor: 'var(--ds-red-400)',
|
|
125
433
|
backgroundColor: 'var(--ds-red-100)',
|
|
126
434
|
color: 'var(--ds-red-900)',
|
|
127
|
-
}, children: loadError }))
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
!loadError &&
|
|
132
|
-
eventData == null &&
|
|
133
|
-
!event.correlationId && (_jsx("div", { className: "rounded-md border p-3 text-xs", style: {
|
|
134
|
-
borderColor: 'var(--ds-gray-300)',
|
|
135
|
-
backgroundColor: 'var(--ds-gray-100)',
|
|
136
|
-
color: 'var(--ds-gray-700)',
|
|
137
|
-
}, children: "No event data available" })), !isLoading &&
|
|
138
|
-
!loadError &&
|
|
139
|
-
eventData == null &&
|
|
140
|
-
event.correlationId &&
|
|
141
|
-
!hasExistingEventData &&
|
|
142
|
-
loadedEventData === null && (_jsx("div", { className: "rounded-md border p-3 text-xs", style: {
|
|
143
|
-
borderColor: 'var(--ds-gray-300)',
|
|
144
|
-
backgroundColor: 'var(--ds-gray-100)',
|
|
145
|
-
color: 'var(--ds-gray-700)',
|
|
146
|
-
}, children: "No event data for this event type" }))] })] }))] }));
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Helper component for attribute rows in the expanded details
|
|
150
|
-
*/
|
|
151
|
-
function AttributeRow({ label, value, mono = false, }) {
|
|
152
|
-
return (_jsxs("div", { className: "flex items-center justify-between px-2.5 py-1.5", style: { borderColor: 'var(--ds-gray-300)' }, children: [_jsx("span", { className: "text-[11px] font-medium", style: { color: 'var(--ds-gray-700)' }, children: label }), _jsx("span", { className: `text-[11px] ${mono ? 'font-mono' : ''} text-right max-w-[70%] break-all`, style: { color: 'var(--ds-gray-1000)' }, children: value })] }));
|
|
435
|
+
}, children: loadError })) : isLoading ||
|
|
436
|
+
(!hasExistingEventData &&
|
|
437
|
+
!hasAttemptedLoad &&
|
|
438
|
+
event.correlationId) ? (_jsxs("div", { className: "flex flex-col gap-2 p-3", children: [_jsx(Skeleton, { className: "h-3", style: { width: '75%' } }), _jsx(Skeleton, { className: "h-3", style: { width: '50%' } }), _jsx(Skeleton, { className: "h-3", style: { width: '60%' } })] })) : (_jsx("div", { className: "p-2 text-xs", style: { color: 'var(--ds-gray-900)' }, children: "No data" }))] })] }))] }));
|
|
153
439
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
export function EventListView({ events, onLoadEventData }) {
|
|
159
|
-
// Sort events by createdAt (oldest first)
|
|
440
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
441
|
+
// Main component
|
|
442
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
443
|
+
export function EventListView({ events, steps, run, onLoadEventData, hasMoreEvents = false, isLoadingMoreEvents = false, onLoadMoreEvents, }) {
|
|
160
444
|
const sortedEvents = useMemo(() => {
|
|
161
445
|
if (!events || events.length === 0)
|
|
162
446
|
return [];
|
|
163
447
|
return [...events].sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
164
448
|
}, [events]);
|
|
449
|
+
const { correlationNameMap, workflowName } = useMemo(() => buildNameMaps(steps ?? null, run ?? null), [steps, run]);
|
|
450
|
+
const durationMap = useMemo(() => buildDurationMap(sortedEvents), [sortedEvents]);
|
|
451
|
+
const [selectedGroupKey, setSelectedGroupKey] = useState(undefined);
|
|
452
|
+
const [hoveredGroupKey, setHoveredGroupKey] = useState(undefined);
|
|
453
|
+
const onSelectGroup = useCallback((groupKey) => {
|
|
454
|
+
setSelectedGroupKey(groupKey);
|
|
455
|
+
}, []);
|
|
456
|
+
const onHoverGroup = useCallback((groupKey) => {
|
|
457
|
+
setHoveredGroupKey(groupKey);
|
|
458
|
+
}, []);
|
|
459
|
+
const activeGroupKey = selectedGroupKey ?? hoveredGroupKey;
|
|
460
|
+
// Compute the row-index range for the active group's connecting lane line.
|
|
461
|
+
// Only applies to non-run groups (step/hook/wait correlations).
|
|
462
|
+
const selectedGroupRange = useMemo(() => {
|
|
463
|
+
if (!activeGroupKey || activeGroupKey === '__run__')
|
|
464
|
+
return null;
|
|
465
|
+
let first = -1;
|
|
466
|
+
let last = -1;
|
|
467
|
+
for (let i = 0; i < sortedEvents.length; i++) {
|
|
468
|
+
if (sortedEvents[i].correlationId === activeGroupKey) {
|
|
469
|
+
if (first === -1)
|
|
470
|
+
first = i;
|
|
471
|
+
last = i;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
return first >= 0 ? { first, last } : null;
|
|
475
|
+
}, [activeGroupKey, sortedEvents]);
|
|
476
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
477
|
+
const virtuosoRef = useRef(null);
|
|
478
|
+
const searchIndex = useMemo(() => {
|
|
479
|
+
const entries = [];
|
|
480
|
+
for (let i = 0; i < sortedEvents.length; i++) {
|
|
481
|
+
const ev = sortedEvents[i];
|
|
482
|
+
entries.push({
|
|
483
|
+
text: [ev.eventId, ev.correlationId ?? ''].join(' ').toLowerCase(),
|
|
484
|
+
groupKey: ev.correlationId ??
|
|
485
|
+
(isRunLevel(ev.eventType) ? '__run__' : undefined),
|
|
486
|
+
eventId: ev.eventId,
|
|
487
|
+
index: i,
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
return entries;
|
|
491
|
+
}, [sortedEvents]);
|
|
492
|
+
useEffect(() => {
|
|
493
|
+
const q = searchQuery.trim().toLowerCase();
|
|
494
|
+
if (!q) {
|
|
495
|
+
setSelectedGroupKey(undefined);
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
const match = searchIndex.find((entry) => entry.text.includes(q));
|
|
499
|
+
if (match) {
|
|
500
|
+
setSelectedGroupKey(match.groupKey);
|
|
501
|
+
virtuosoRef.current?.scrollToIndex({
|
|
502
|
+
index: match.index,
|
|
503
|
+
align: 'center',
|
|
504
|
+
behavior: 'smooth',
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
}, [searchQuery, searchIndex]);
|
|
165
508
|
if (!events || events.length === 0) {
|
|
166
509
|
return (_jsx("div", { className: "flex items-center justify-center h-full text-sm", style: { color: 'var(--ds-gray-700)' }, children: "No events found" }));
|
|
167
510
|
}
|
|
168
|
-
return (_jsxs("div", { className: "h-full
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
511
|
+
return (_jsxs("div", { className: "h-full flex flex-col overflow-hidden", children: [_jsx("style", { children: `@keyframes workflow-dot-pulse{0%{transform:scale(1);opacity:.7}70%,100%{transform:scale(2.2);opacity:0}}` }), _jsx("div", { style: { padding: 6, backgroundColor: 'var(--ds-background-100)' }, children: _jsxs("label", { style: {
|
|
512
|
+
display: 'flex',
|
|
513
|
+
alignItems: 'center',
|
|
514
|
+
justifyContent: 'center',
|
|
515
|
+
borderRadius: 6,
|
|
516
|
+
boxShadow: '0 0 0 1px var(--ds-gray-alpha-400)',
|
|
517
|
+
background: 'var(--ds-background-100)',
|
|
518
|
+
height: 40,
|
|
519
|
+
}, children: [_jsx("div", { style: {
|
|
520
|
+
width: 40,
|
|
521
|
+
height: 40,
|
|
522
|
+
display: 'flex',
|
|
523
|
+
alignItems: 'center',
|
|
524
|
+
justifyContent: 'center',
|
|
525
|
+
color: 'var(--ds-gray-800)',
|
|
526
|
+
flexShrink: 0,
|
|
527
|
+
}, children: _jsxs("svg", { width: 16, height: 16, viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", focusable: "false", children: [_jsx("circle", { cx: "7", cy: "7", r: "4.5", stroke: "currentColor", strokeWidth: "1.5" }), _jsx("path", { d: "M11.5 11.5L14 14", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })] }) }), _jsx("input", { type: "search", placeholder: "Search by event ID or correlation ID\u2026", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), style: {
|
|
528
|
+
marginLeft: -16,
|
|
529
|
+
paddingInline: 12,
|
|
530
|
+
fontFamily: 'inherit',
|
|
531
|
+
fontSize: 14,
|
|
532
|
+
background: 'transparent',
|
|
533
|
+
border: 'none',
|
|
534
|
+
outline: 'none',
|
|
535
|
+
height: 40,
|
|
536
|
+
width: '100%',
|
|
537
|
+
} })] }) }), _jsxs("div", { className: "flex items-center gap-0 text-sm font-medium h-10 border-b flex-shrink-0", style: {
|
|
538
|
+
borderColor: 'var(--ds-gray-alpha-200)',
|
|
539
|
+
color: 'var(--ds-gray-900)',
|
|
540
|
+
backgroundColor: 'var(--ds-background-100)',
|
|
541
|
+
}, children: [_jsx("div", { className: "flex-shrink-0", style: { width: GUTTER_WIDTH } }), _jsx("div", { className: "w-5 flex-shrink-0" }), _jsx("div", { className: "flex-1 min-w-0 px-4", children: "Time" }), _jsx("div", { className: "flex-1 min-w-0 px-4", children: "Event Type" }), _jsx("div", { className: "flex-1 min-w-0 px-4", children: "Name" }), _jsx("div", { className: "flex-1 min-w-0 px-4", children: "Correlation ID" }), _jsx("div", { className: "flex-1 min-w-0 px-4", children: "Event ID" })] }), _jsx(Virtuoso, { ref: virtuosoRef, totalCount: sortedEvents.length, overscan: 20, defaultItemHeight: 40, endReached: () => {
|
|
542
|
+
if (!hasMoreEvents || isLoadingMoreEvents) {
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
void onLoadMoreEvents?.();
|
|
546
|
+
}, itemContent: (index) => {
|
|
547
|
+
return (_jsx(EventRow, { event: sortedEvents[index], index: index, isFirst: index === 0, isLast: index === sortedEvents.length - 1, activeGroupKey: activeGroupKey, selectedGroupKey: selectedGroupKey, selectedGroupRange: selectedGroupRange, correlationNameMap: correlationNameMap, workflowName: workflowName, durationMap: durationMap, onSelectGroup: onSelectGroup, onHoverGroup: onHoverGroup, onLoadEventData: onLoadEventData }));
|
|
548
|
+
}, components: {
|
|
549
|
+
Footer: () => (_jsxs(_Fragment, { children: [hasMoreEvents && (_jsx("div", { className: "px-3 pt-3 flex justify-center", children: _jsx("button", { type: "button", onClick: () => void onLoadMoreEvents?.(), disabled: isLoadingMoreEvents, className: "h-8 px-3 text-xs rounded-md border transition-colors disabled:opacity-60 disabled:cursor-not-allowed", style: {
|
|
550
|
+
borderColor: 'var(--ds-gray-alpha-400)',
|
|
551
|
+
color: 'var(--ds-gray-900)',
|
|
552
|
+
backgroundColor: 'var(--ds-background-100)',
|
|
553
|
+
}, children: isLoadingMoreEvents
|
|
554
|
+
? 'Loading more events...'
|
|
555
|
+
: 'Load more' }) })), _jsxs("div", { className: "mt-4 pt-3 border-t text-xs px-3", style: {
|
|
556
|
+
borderColor: 'var(--ds-gray-alpha-200)',
|
|
557
|
+
color: 'var(--ds-gray-900)',
|
|
558
|
+
}, children: [sortedEvents.length, " event", sortedEvents.length !== 1 ? 's' : '', " total"] })] })),
|
|
559
|
+
}, style: { flex: 1, minHeight: 0 } })] }));
|
|
177
560
|
}
|
|
178
561
|
//# sourceMappingURL=event-list-view.js.map
|