@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
|
@@ -4,60 +4,94 @@ import {
|
|
|
4
4
|
type AttributeChange,
|
|
5
5
|
RESERVED_ATTRIBUTE_KEY_PREFIX,
|
|
6
6
|
} from '@workflow/world';
|
|
7
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
8
|
+
import type { ReactNode } from 'react';
|
|
9
|
+
import { cn } from '../../lib/cn';
|
|
10
|
+
import { CopyButton } from '../new-trace-viewer/components/copy-button';
|
|
11
|
+
import { MiddleTruncate } from '../new-trace-viewer/components/middle-truncate/middle-truncate';
|
|
12
|
+
import {
|
|
13
|
+
CollapsibleContent,
|
|
14
|
+
CollapsibleRoot,
|
|
15
|
+
CollapsibleTrigger,
|
|
16
|
+
} from '../ui/collapsible';
|
|
7
17
|
import { CopyableDataBlock } from './copyable-data-block';
|
|
8
|
-
import { DetailCard } from './detail-card';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Check whether an attribute key is in the reserved (`$`-prefixed)
|
|
12
|
-
* namespace used by framework/library code.
|
|
13
|
-
*/
|
|
14
|
-
export const isReservedAttributeKey = (key: string): boolean =>
|
|
15
|
-
key.startsWith(RESERVED_ATTRIBUTE_KEY_PREFIX);
|
|
16
18
|
|
|
17
|
-
function
|
|
18
|
-
return (
|
|
19
|
-
<span
|
|
20
|
-
className="shrink-0 rounded border px-1 py-px text-[10px] font-medium leading-3"
|
|
21
|
-
style={{
|
|
22
|
-
borderColor: 'var(--ds-gray-alpha-400)',
|
|
23
|
-
backgroundColor: 'var(--ds-gray-100)',
|
|
24
|
-
color: 'var(--ds-gray-700)',
|
|
25
|
-
}}
|
|
26
|
-
title={`Keys prefixed with "${RESERVED_ATTRIBUTE_KEY_PREFIX}" are reserved for framework and library code`}
|
|
27
|
-
>
|
|
28
|
-
Reserved
|
|
29
|
-
</span>
|
|
30
|
-
);
|
|
19
|
+
function isReservedAttributeKey(key: string): boolean {
|
|
20
|
+
return key.startsWith(RESERVED_ATTRIBUTE_KEY_PREFIX);
|
|
31
21
|
}
|
|
32
22
|
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
const rowValueVariants = cva(
|
|
24
|
+
'max-w-[60%] truncate text-right text-copy-13 text-gray-1000',
|
|
25
|
+
{
|
|
26
|
+
variants: {
|
|
27
|
+
variant: {
|
|
28
|
+
default: '',
|
|
29
|
+
mono: 'font-mono',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
defaultVariants: {
|
|
33
|
+
variant: 'default',
|
|
34
|
+
},
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const rowCopyValueVariants = cva(
|
|
39
|
+
'flex min-w-0 max-w-[60%] items-center justify-end gap-1 text-copy-13 text-gray-1000',
|
|
40
|
+
{
|
|
41
|
+
variants: {
|
|
42
|
+
variant: {
|
|
43
|
+
default: '',
|
|
44
|
+
mono: 'font-mono',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
defaultVariants: {
|
|
48
|
+
variant: 'default',
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
type DetailKeyValueRowProps = {
|
|
54
|
+
label: string;
|
|
55
|
+
value?: ReactNode;
|
|
56
|
+
copyText?: string;
|
|
57
|
+
removed?: boolean;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
function DetailKeyValueRowBase({
|
|
61
|
+
label,
|
|
35
62
|
value,
|
|
63
|
+
copyText,
|
|
36
64
|
removed = false,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
value
|
|
40
|
-
|
|
41
|
-
}) {
|
|
42
|
-
const reserved = isReservedAttributeKey(attributeKey);
|
|
65
|
+
variant,
|
|
66
|
+
}: DetailKeyValueRowProps & VariantProps<typeof rowValueVariants>) {
|
|
67
|
+
const stringValue = typeof value === 'string' ? value : undefined;
|
|
68
|
+
|
|
43
69
|
return (
|
|
44
|
-
<div className="
|
|
45
|
-
<span
|
|
46
|
-
|
|
47
|
-
style={reserved ? { color: 'var(--ds-gray-700)' } : undefined}
|
|
48
|
-
>
|
|
49
|
-
<span className="truncate">{attributeKey}</span>
|
|
50
|
-
{reserved && <ReservedBadge />}
|
|
70
|
+
<div className="px-1.5 hover:bg-gray-100 flex justify-between gap-3 -mx-1.5 py-0.5 rounded items-center">
|
|
71
|
+
<span className="flex min-w-0 items-center gap-1.5 truncate text-label-13 text-gray-900">
|
|
72
|
+
{label}
|
|
51
73
|
</span>
|
|
52
74
|
{removed ? (
|
|
53
75
|
<span className="shrink-0 text-copy-13 italic text-gray-700">
|
|
54
76
|
removed
|
|
55
77
|
</span>
|
|
78
|
+
) : copyText ? (
|
|
79
|
+
<div className={cn(rowCopyValueVariants({ variant }))} title={copyText}>
|
|
80
|
+
<MiddleTruncate
|
|
81
|
+
value={copyText}
|
|
82
|
+
className={cn(
|
|
83
|
+
rowValueVariants({ variant, className: 'text-right' })
|
|
84
|
+
)}
|
|
85
|
+
style={{ gridTemplateColumns: 'minmax(0, 1fr)' }}
|
|
86
|
+
/>
|
|
87
|
+
<CopyButton
|
|
88
|
+
copyText={copyText}
|
|
89
|
+
ariaLabel={`Copy ${label}`}
|
|
90
|
+
className="shrink-0 -mr-1"
|
|
91
|
+
/>
|
|
92
|
+
</div>
|
|
56
93
|
) : (
|
|
57
|
-
<span
|
|
58
|
-
className="max-w-[60%] truncate text-copy-13 text-gray-1000"
|
|
59
|
-
title={value}
|
|
60
|
-
>
|
|
94
|
+
<span className={cn(rowValueVariants({ variant }))} title={stringValue}>
|
|
61
95
|
{value}
|
|
62
96
|
</span>
|
|
63
97
|
)}
|
|
@@ -65,6 +99,28 @@ function AttributeRow({
|
|
|
65
99
|
);
|
|
66
100
|
}
|
|
67
101
|
|
|
102
|
+
export function DetailKeyValueRow(props: DetailKeyValueRowProps) {
|
|
103
|
+
return <DetailKeyValueRowBase {...props} />;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function DetailMonoKeyValueRow(props: DetailKeyValueRowProps) {
|
|
107
|
+
return <DetailKeyValueRowBase {...props} variant="mono" />;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function AttributeRow({
|
|
111
|
+
attributeKey,
|
|
112
|
+
value,
|
|
113
|
+
removed = false,
|
|
114
|
+
}: {
|
|
115
|
+
attributeKey: string;
|
|
116
|
+
value?: string;
|
|
117
|
+
removed?: boolean;
|
|
118
|
+
}) {
|
|
119
|
+
return (
|
|
120
|
+
<DetailKeyValueRow label={attributeKey} value={value} removed={removed} />
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
68
124
|
/**
|
|
69
125
|
* Sort attribute keys for display: user keys first (alphabetical), then
|
|
70
126
|
* reserved `$`-prefixed keys (alphabetical), so framework metadata doesn't
|
|
@@ -81,8 +137,7 @@ export function sortAttributeKeys(keys: string[]): string[] {
|
|
|
81
137
|
|
|
82
138
|
/**
|
|
83
139
|
* Collapsible section showing a run's materialized attributes as key-value
|
|
84
|
-
* rows. Reserved (`$`-prefixed) keys are
|
|
85
|
-
* badge and sorted after user keys.
|
|
140
|
+
* rows. Reserved (`$`-prefixed) keys are sorted after user keys.
|
|
86
141
|
*/
|
|
87
142
|
export function RunAttributesCard({
|
|
88
143
|
attributes,
|
|
@@ -93,13 +148,78 @@ export function RunAttributesCard({
|
|
|
93
148
|
if (keys.length === 0) return null;
|
|
94
149
|
|
|
95
150
|
return (
|
|
96
|
-
<
|
|
97
|
-
<
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
151
|
+
<CollapsibleRoot defaultOpen>
|
|
152
|
+
<CollapsibleTrigger>Attributes</CollapsibleTrigger>
|
|
153
|
+
<CollapsibleContent className="mb-4">
|
|
154
|
+
<div className="flex flex-col">
|
|
155
|
+
{keys.map((key) => (
|
|
156
|
+
<AttributeRow
|
|
157
|
+
attributeKey={key}
|
|
158
|
+
key={key}
|
|
159
|
+
value={attributes[key]}
|
|
160
|
+
/>
|
|
161
|
+
))}
|
|
162
|
+
</div>
|
|
163
|
+
</CollapsibleContent>
|
|
164
|
+
</CollapsibleRoot>
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function formatMetadataValue(value: unknown): string {
|
|
169
|
+
if (value == null) {
|
|
170
|
+
return String(value);
|
|
171
|
+
}
|
|
172
|
+
if (typeof value === 'string') {
|
|
173
|
+
return value;
|
|
174
|
+
}
|
|
175
|
+
if (typeof value === 'number' || typeof value === 'boolean') {
|
|
176
|
+
return String(value);
|
|
177
|
+
}
|
|
178
|
+
try {
|
|
179
|
+
return JSON.stringify(value);
|
|
180
|
+
} catch {
|
|
181
|
+
return String(value);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function isMetadataRecord(value: unknown): value is Record<string, unknown> {
|
|
186
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Collapsible section showing hook (or other resource) metadata as key-value
|
|
191
|
+
* rows, matching the Attributes section styling.
|
|
192
|
+
*/
|
|
193
|
+
export function RunMetadataCard({ metadata }: { metadata: unknown }) {
|
|
194
|
+
if (!isMetadataRecord(metadata)) {
|
|
195
|
+
return (
|
|
196
|
+
<CollapsibleRoot defaultOpen>
|
|
197
|
+
<CollapsibleTrigger>Metadata</CollapsibleTrigger>
|
|
198
|
+
<CollapsibleContent className="mb-4">
|
|
199
|
+
<CopyableDataBlock data={metadata} />
|
|
200
|
+
</CollapsibleContent>
|
|
201
|
+
</CollapsibleRoot>
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const keys = Object.keys(metadata).sort((a, b) => a.localeCompare(b));
|
|
206
|
+
if (keys.length === 0) return null;
|
|
207
|
+
|
|
208
|
+
return (
|
|
209
|
+
<CollapsibleRoot defaultOpen>
|
|
210
|
+
<CollapsibleTrigger>Metadata</CollapsibleTrigger>
|
|
211
|
+
<CollapsibleContent className="mb-4">
|
|
212
|
+
<div className="flex flex-col">
|
|
213
|
+
{keys.map((key) => (
|
|
214
|
+
<AttributeRow
|
|
215
|
+
attributeKey={key}
|
|
216
|
+
key={key}
|
|
217
|
+
value={formatMetadataValue(metadata[key])}
|
|
218
|
+
/>
|
|
219
|
+
))}
|
|
220
|
+
</div>
|
|
221
|
+
</CollapsibleContent>
|
|
222
|
+
</CollapsibleRoot>
|
|
103
223
|
);
|
|
104
224
|
}
|
|
105
225
|
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import type { Event } from '@workflow/world';
|
|
4
4
|
import { useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
getEventDataRefFields,
|
|
7
|
+
hasEncryptedFields,
|
|
8
|
+
isExpiredMarker,
|
|
9
|
+
} from '../../lib/hydration';
|
|
10
|
+
import {
|
|
11
|
+
Collapsible,
|
|
12
|
+
CollapsibleContent,
|
|
13
|
+
CollapsibleRoot,
|
|
14
|
+
CollapsibleTrigger,
|
|
15
|
+
} from '../ui/collapsible';
|
|
6
16
|
import { RunClickContext, StreamClickContext } from '../ui/data-inspector';
|
|
7
17
|
import { ErrorCard } from '../ui/error-card';
|
|
8
18
|
import { ErrorStackBlock, isStructuredError } from '../ui/error-stack-block';
|
|
@@ -10,7 +20,6 @@ import { Skeleton } from '../ui/skeleton';
|
|
|
10
20
|
import { TimestampTooltip } from '../ui/timestamp-tooltip';
|
|
11
21
|
import { AttrSetEventBlock } from './attributes-block';
|
|
12
22
|
import { CopyableDataBlock, EncryptedDataBlock } from './copyable-data-block';
|
|
13
|
-
import { DetailCard } from './detail-card';
|
|
14
23
|
|
|
15
24
|
/**
|
|
16
25
|
* Event types whose eventData contains an error field with a StructuredError.
|
|
@@ -143,20 +152,9 @@ function EventItem({
|
|
|
143
152
|
const displayPayload = isLoading ? loadedData : mergedDisplay;
|
|
144
153
|
|
|
145
154
|
return (
|
|
146
|
-
<
|
|
155
|
+
<CollapsibleRoot
|
|
147
156
|
variant="card"
|
|
148
|
-
|
|
149
|
-
summary={
|
|
150
|
-
<div className="flex w-full items-center justify-between gap-3">
|
|
151
|
-
<span className="text-gray-1000 text-label-12 font-mono">
|
|
152
|
-
{event.eventType}
|
|
153
|
-
</span>
|
|
154
|
-
<span className="shrink-0 text-label-13 text-gray-900">
|
|
155
|
-
{displayedCreatedAtTime}
|
|
156
|
-
</span>
|
|
157
|
-
</div>
|
|
158
|
-
}
|
|
159
|
-
onToggle={
|
|
157
|
+
onOpenChange={
|
|
160
158
|
canHaveData
|
|
161
159
|
? (open) => {
|
|
162
160
|
if (open) handleExpand();
|
|
@@ -164,65 +162,79 @@ function EventItem({
|
|
|
164
162
|
: undefined
|
|
165
163
|
}
|
|
166
164
|
>
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
{formatEventTimestamp(occurredAt)}
|
|
175
|
-
</span>
|
|
176
|
-
</TimestampTooltip>
|
|
177
|
-
</div>
|
|
178
|
-
)}
|
|
179
|
-
<div className="flex items-center justify-between gap-2 py-2 px-3">
|
|
180
|
-
<span className="text-label-12 text-gray-900">Event ID</span>
|
|
181
|
-
<span className="max-w-[70%] truncate text-right text-label-12 font-mono">
|
|
182
|
-
{event.eventId}
|
|
165
|
+
<CollapsibleTrigger className="px-3 py-2">
|
|
166
|
+
<div className="flex w-full items-center justify-between gap-3">
|
|
167
|
+
<span className="text-gray-1000 text-label-12 font-mono">
|
|
168
|
+
{event.eventType}
|
|
169
|
+
</span>
|
|
170
|
+
<span className="shrink-0 text-label-13 text-gray-900">
|
|
171
|
+
{displayedCreatedAtTime}
|
|
183
172
|
</span>
|
|
184
173
|
</div>
|
|
185
|
-
|
|
174
|
+
</CollapsibleTrigger>
|
|
175
|
+
<CollapsibleContent>
|
|
176
|
+
{/* Event attributes */}
|
|
177
|
+
<div className="flex flex-col bg-background-200 [&:has(+_*)]:border-b [&:has(+_*)]:border-gray-alpha-400">
|
|
178
|
+
{showSeparateEventOccurrenceTimestamps && occurredAt && (
|
|
179
|
+
<div className="flex items-center justify-between gap-2 py-2 px-3">
|
|
180
|
+
<span className="text-label-12 text-gray-900">Occurred</span>
|
|
181
|
+
<TimestampTooltip date={occurredAt}>
|
|
182
|
+
<span className="max-w-[70%] truncate text-right text-label-12 font-mono">
|
|
183
|
+
{formatEventTimestamp(occurredAt)}
|
|
184
|
+
</span>
|
|
185
|
+
</TimestampTooltip>
|
|
186
|
+
</div>
|
|
187
|
+
)}
|
|
186
188
|
<div className="flex items-center justify-between gap-2 py-2 px-3">
|
|
187
|
-
<span className="text-label-12 text-gray-900">
|
|
189
|
+
<span className="text-label-12 text-gray-900">Event ID</span>
|
|
188
190
|
<span className="max-w-[70%] truncate text-right text-label-12 font-mono">
|
|
189
|
-
{event.
|
|
191
|
+
{event.eventId}
|
|
190
192
|
</span>
|
|
191
193
|
</div>
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
194
|
+
{event.correlationId && (
|
|
195
|
+
<div className="flex items-center justify-between gap-2 py-2 px-3">
|
|
196
|
+
<span className="text-label-12 text-gray-900">
|
|
197
|
+
Correlation ID
|
|
198
|
+
</span>
|
|
199
|
+
<span className="max-w-[70%] truncate text-right text-label-12 font-mono">
|
|
200
|
+
{event.correlationId}
|
|
201
|
+
</span>
|
|
202
|
+
</div>
|
|
203
|
+
)}
|
|
201
204
|
</div>
|
|
202
|
-
)}
|
|
203
205
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
206
|
+
{/* Loading state */}
|
|
207
|
+
{isLoading && (
|
|
208
|
+
<div className="p-3">
|
|
209
|
+
<Skeleton className="h-4 w-[35%]" />
|
|
210
|
+
<Skeleton className="mt-2 h-4 w-[90%]" />
|
|
211
|
+
<Skeleton className="mt-2 h-4 w-[75%]" />
|
|
212
|
+
</div>
|
|
213
|
+
)}
|
|
212
214
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
215
|
+
{/* Error state */}
|
|
216
|
+
{loadError && (
|
|
217
|
+
<ErrorCard
|
|
218
|
+
title="Failed to load event data"
|
|
219
|
+
details={loadError}
|
|
220
|
+
className="mt-2"
|
|
221
|
+
/>
|
|
222
|
+
)}
|
|
223
|
+
|
|
224
|
+
{/* Event data */}
|
|
225
|
+
{displayPayload != null && (
|
|
226
|
+
<div className="[&>div]:border-none [&>div]:rounded-none">
|
|
227
|
+
<EventDataBlock eventType={event.eventType} data={displayPayload} />
|
|
228
|
+
</div>
|
|
229
|
+
)}
|
|
230
|
+
</CollapsibleContent>
|
|
231
|
+
</CollapsibleRoot>
|
|
220
232
|
);
|
|
221
233
|
}
|
|
222
234
|
|
|
223
235
|
/**
|
|
224
236
|
* Check if an eventData object has only expired marker values in ref/payload
|
|
225
|
-
* fields for this event type (see {@link
|
|
237
|
+
* fields for this event type (see {@link getEventDataRefFields}). Other keys
|
|
226
238
|
* (e.g. `resumeAt`, `stepName`) are ignored.
|
|
227
239
|
*/
|
|
228
240
|
function hasOnlyExpiredFields(data: unknown, eventType: string): boolean {
|
|
@@ -230,7 +242,7 @@ function hasOnlyExpiredFields(data: unknown, eventType: string): boolean {
|
|
|
230
242
|
return false;
|
|
231
243
|
}
|
|
232
244
|
const record = data as Record<string, unknown>;
|
|
233
|
-
const refKeys =
|
|
245
|
+
const refKeys = getEventDataRefFields(eventType);
|
|
234
246
|
const presentKeys = refKeys.filter((k) => k in record);
|
|
235
247
|
return (
|
|
236
248
|
presentKeys.length > 0 &&
|
|
@@ -341,41 +353,44 @@ export function EventsList({
|
|
|
341
353
|
const hasEvents = sortedEvents.length > 0 && !error;
|
|
342
354
|
|
|
343
355
|
if (!hasEvents && !isLoading) {
|
|
344
|
-
return <
|
|
356
|
+
return <Collapsible label="Events" disabled />;
|
|
345
357
|
}
|
|
346
358
|
|
|
347
359
|
return (
|
|
348
360
|
<RunClickContext.Provider value={onRunClick}>
|
|
349
361
|
<StreamClickContext.Provider value={onStreamClick}>
|
|
350
|
-
<
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
362
|
+
<CollapsibleRoot defaultOpen>
|
|
363
|
+
<CollapsibleTrigger>Events</CollapsibleTrigger>
|
|
364
|
+
<CollapsibleContent className="mb-0">
|
|
365
|
+
{isLoading ? (
|
|
366
|
+
<div className="flex flex-col -mx-4">
|
|
367
|
+
{[0, 1, 2].map((i) => (
|
|
368
|
+
<div
|
|
369
|
+
key={i}
|
|
370
|
+
className="flex items-center justify-between gap-3 bg-background-200 px-4 py-2"
|
|
371
|
+
>
|
|
372
|
+
<Skeleton className="h-4 w-32 rounded" />
|
|
373
|
+
<Skeleton className="h-3 w-16 rounded" />
|
|
374
|
+
</div>
|
|
375
|
+
))}
|
|
376
|
+
</div>
|
|
377
|
+
) : (
|
|
378
|
+
<div className="flex flex-col -mx-4">
|
|
379
|
+
{sortedEvents.map((event) => (
|
|
380
|
+
<EventItem
|
|
381
|
+
key={event.eventId}
|
|
382
|
+
event={event}
|
|
383
|
+
onLoadEventData={onLoadEventData}
|
|
384
|
+
encryptionKey={encryptionKey}
|
|
385
|
+
showSeparateEventOccurrenceTimestamps={
|
|
386
|
+
showSeparateEventOccurrenceTimestamps
|
|
387
|
+
}
|
|
388
|
+
/>
|
|
389
|
+
))}
|
|
390
|
+
</div>
|
|
391
|
+
)}
|
|
392
|
+
</CollapsibleContent>
|
|
393
|
+
</CollapsibleRoot>
|
|
379
394
|
</StreamClickContext.Provider>
|
|
380
395
|
</RunClickContext.Provider>
|
|
381
396
|
);
|