@workflow/web-shared 4.1.0-beta.64 → 4.1.0-beta.65
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/event-list-view.d.ts +5 -1
- package/dist/components/event-list-view.d.ts.map +1 -1
- package/dist/components/event-list-view.js +40 -19
- package/dist/components/event-list-view.js.map +1 -1
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +3 -0
- package/dist/components/index.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 +4 -14
- package/dist/components/sidebar/entity-detail-panel.js.map +1 -1
- package/dist/components/stream-viewer.d.ts +3 -1
- package/dist/components/stream-viewer.d.ts.map +1 -1
- package/dist/components/stream-viewer.js +23 -28
- package/dist/components/stream-viewer.js.map +1 -1
- package/dist/components/ui/decrypt-button.d.ts +15 -0
- package/dist/components/ui/decrypt-button.d.ts.map +1 -0
- package/dist/components/ui/decrypt-button.js +12 -0
- package/dist/components/ui/decrypt-button.js.map +1 -0
- package/dist/components/ui/load-more-button.d.ts +13 -0
- package/dist/components/ui/load-more-button.d.ts.map +1 -0
- package/dist/components/ui/load-more-button.js +12 -0
- package/dist/components/ui/load-more-button.js.map +1 -0
- package/dist/components/ui/menu-dropdown.d.ts.map +1 -1
- package/dist/components/ui/menu-dropdown.js +2 -6
- package/dist/components/ui/menu-dropdown.js.map +1 -1
- package/dist/components/ui/spinner.d.ts +9 -0
- package/dist/components/ui/spinner.d.ts.map +1 -0
- package/dist/components/ui/spinner.js +57 -0
- package/dist/components/ui/spinner.js.map +1 -0
- 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 +4 -3
- package/dist/components/workflow-trace-view.js.map +1 -1
- package/package.json +2 -2
- package/src/components/event-list-view.tsx +153 -113
- package/src/components/index.ts +3 -0
- package/src/components/sidebar/entity-detail-panel.tsx +9 -25
- package/src/components/stream-viewer.tsx +52 -63
- package/src/components/ui/decrypt-button.tsx +69 -0
- package/src/components/ui/load-more-button.tsx +38 -0
- package/src/components/ui/menu-dropdown.tsx +3 -6
- package/src/components/ui/spinner.tsx +76 -0
- package/src/components/workflow-trace-view.tsx +6 -19
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { Spinner } from './spinner';
|
|
4
|
+
|
|
5
|
+
const STYLES = `.wf-load-more{appearance:none;-webkit-appearance:none;border:none;display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;border-radius:6px;font-size:13px;font-weight:500;line-height:20px;color:var(--ds-gray-1000);background:var(--ds-background-100);box-shadow:0 0 0 1px var(--ds-gray-400);cursor:pointer;white-space:nowrap;gap:6px;transition:background 150ms}.wf-load-more:hover{background:var(--ds-gray-alpha-200)}.wf-load-more:disabled{opacity:.6;cursor:default}.wf-load-more:disabled:hover{background:var(--ds-background-100)}`;
|
|
6
|
+
|
|
7
|
+
interface LoadMoreButtonProps {
|
|
8
|
+
loading?: boolean;
|
|
9
|
+
onClick?: () => void;
|
|
10
|
+
label?: string;
|
|
11
|
+
loadingLabel?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A "Load more" button matching Geist's Button type="secondary" size="small"
|
|
16
|
+
* with a spinner prefix when loading.
|
|
17
|
+
*/
|
|
18
|
+
export function LoadMoreButton({
|
|
19
|
+
loading = false,
|
|
20
|
+
onClick,
|
|
21
|
+
label = 'Load more',
|
|
22
|
+
loadingLabel = 'Loading...',
|
|
23
|
+
}: LoadMoreButtonProps) {
|
|
24
|
+
return (
|
|
25
|
+
<>
|
|
26
|
+
<style dangerouslySetInnerHTML={{ __html: STYLES }} />
|
|
27
|
+
<button
|
|
28
|
+
type="button"
|
|
29
|
+
onClick={onClick}
|
|
30
|
+
disabled={loading}
|
|
31
|
+
className="wf-load-more"
|
|
32
|
+
>
|
|
33
|
+
{loading && <Spinner size={14} />}
|
|
34
|
+
{loading ? loadingLabel : label}
|
|
35
|
+
</button>
|
|
36
|
+
</>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import { useEffect, useRef, useState } from 'react';
|
|
4
4
|
|
|
5
|
+
const STYLES = `.wf-menu-btn{appearance:none;-webkit-appearance:none;border:none;display:inline-flex;align-items:center;justify-content:center;height:40px;padding:0 12px;border-radius:6px;font-size:14px;font-weight:500;line-height:20px;color:var(--ds-gray-1000);background:var(--ds-background-100);box-shadow:0 0 0 1px var(--ds-gray-400);cursor:pointer;white-space:nowrap;transition:background 150ms}.wf-menu-btn:hover{background:var(--ds-gray-alpha-200)}.wf-menu-item{appearance:none;-webkit-appearance:none;border:none;display:flex;align-items:center;width:100%;height:40px;padding:0 8px;border-radius:6px;font-size:14px;color:var(--ds-gray-1000);background:transparent;cursor:pointer;transition:background 150ms}.wf-menu-item:hover{background:var(--ds-gray-alpha-100)}`;
|
|
6
|
+
|
|
5
7
|
export interface MenuDropdownOption<T extends string = string> {
|
|
6
8
|
value: T;
|
|
7
9
|
label: string;
|
|
@@ -40,12 +42,7 @@ export function MenuDropdown<T extends string = string>({
|
|
|
40
42
|
|
|
41
43
|
return (
|
|
42
44
|
<div ref={ref} style={{ position: 'relative', flexShrink: 0 }}>
|
|
43
|
-
<style
|
|
44
|
-
.wf-menu-btn{appearance:none;-webkit-appearance:none;border:none;display:inline-flex;align-items:center;justify-content:center;height:40px;padding:0 12px;border-radius:6px;font-size:14px;font-weight:500;line-height:20px;color:var(--ds-gray-1000);background:var(--ds-background-100);box-shadow:0 0 0 1px var(--ds-gray-400);cursor:pointer;white-space:nowrap;transition:background 150ms}
|
|
45
|
-
.wf-menu-btn:hover{background:var(--ds-gray-alpha-200)}
|
|
46
|
-
.wf-menu-item{appearance:none;-webkit-appearance:none;border:none;display:flex;align-items:center;width:100%;height:40px;padding:0 8px;border-radius:6px;font-size:14px;color:var(--ds-gray-1000);background:transparent;cursor:pointer;transition:background 150ms}
|
|
47
|
-
.wf-menu-item:hover{background:var(--ds-gray-alpha-100)}
|
|
48
|
-
`}</style>
|
|
45
|
+
<style dangerouslySetInnerHTML={{ __html: STYLES }} />
|
|
49
46
|
|
|
50
47
|
<button
|
|
51
48
|
type="button"
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const KEYFRAMES = `@keyframes wf-spinner-fade{0%{opacity:1}100%{opacity:.15}}`;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Spinner matching Geist's multi-line fade spinner.
|
|
5
|
+
* At size ≤12: 8 lines, ≤16: 10 lines, else: 12 lines.
|
|
6
|
+
*/
|
|
7
|
+
export function Spinner({
|
|
8
|
+
size = 14,
|
|
9
|
+
color,
|
|
10
|
+
}: {
|
|
11
|
+
size?: number;
|
|
12
|
+
color?: string;
|
|
13
|
+
}) {
|
|
14
|
+
const config =
|
|
15
|
+
size <= 12
|
|
16
|
+
? {
|
|
17
|
+
count: 8,
|
|
18
|
+
angle: 45,
|
|
19
|
+
delays: [-875, -750, -625, -500, -375, -250, -125, 0],
|
|
20
|
+
duration: 1000,
|
|
21
|
+
lineW: 3,
|
|
22
|
+
lineH: 1.5,
|
|
23
|
+
}
|
|
24
|
+
: size <= 16
|
|
25
|
+
? {
|
|
26
|
+
count: 10,
|
|
27
|
+
angle: 36,
|
|
28
|
+
delays: [-900, -800, -700, -600, -500, -400, -300, -200, -100, 0],
|
|
29
|
+
duration: 1000,
|
|
30
|
+
lineW: 4,
|
|
31
|
+
lineH: 1.5,
|
|
32
|
+
}
|
|
33
|
+
: {
|
|
34
|
+
count: 12,
|
|
35
|
+
angle: 30,
|
|
36
|
+
delays: [
|
|
37
|
+
-1100, -1000, -900, -800, -700, -600, -500, -400, -300, -200,
|
|
38
|
+
-100, 0,
|
|
39
|
+
],
|
|
40
|
+
duration: 1200,
|
|
41
|
+
lineW: size * 0.24,
|
|
42
|
+
lineH: size * 0.08,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<span
|
|
47
|
+
style={{
|
|
48
|
+
display: 'inline-flex',
|
|
49
|
+
position: 'relative',
|
|
50
|
+
width: size,
|
|
51
|
+
height: size,
|
|
52
|
+
}}
|
|
53
|
+
>
|
|
54
|
+
<style dangerouslySetInnerHTML={{ __html: KEYFRAMES }} />
|
|
55
|
+
{config.delays.map((delay, i) => (
|
|
56
|
+
<span
|
|
57
|
+
key={delay}
|
|
58
|
+
style={{
|
|
59
|
+
position: 'absolute',
|
|
60
|
+
left: '50%',
|
|
61
|
+
top: '50%',
|
|
62
|
+
width: config.lineW,
|
|
63
|
+
height: config.lineH,
|
|
64
|
+
marginLeft: -config.lineW / 2,
|
|
65
|
+
marginTop: -config.lineH / 2,
|
|
66
|
+
borderRadius: 1,
|
|
67
|
+
backgroundColor: color ?? 'var(--ds-gray-700)',
|
|
68
|
+
transform: `rotate(${i * config.angle}deg) translate(${size * 0.36}px)`,
|
|
69
|
+
animation: `wf-spinner-fade ${config.duration}ms linear infinite`,
|
|
70
|
+
animationDelay: `${delay}ms`,
|
|
71
|
+
}}
|
|
72
|
+
/>
|
|
73
|
+
))}
|
|
74
|
+
</span>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
} from './trace-viewer';
|
|
32
32
|
import type { Span } from './trace-viewer/types';
|
|
33
33
|
import { Skeleton } from './ui/skeleton';
|
|
34
|
+
import { Spinner } from './ui/spinner';
|
|
34
35
|
import {
|
|
35
36
|
getCustomSpanClassName,
|
|
36
37
|
getCustomSpanEventClassName,
|
|
@@ -719,25 +720,7 @@ function TraceViewerFooter({
|
|
|
719
720
|
className="flex items-center justify-center gap-2 py-3 text-xs"
|
|
720
721
|
style={style}
|
|
721
722
|
>
|
|
722
|
-
<
|
|
723
|
-
className="h-3.5 w-3.5 animate-spin"
|
|
724
|
-
viewBox="0 0 24 24"
|
|
725
|
-
fill="none"
|
|
726
|
-
>
|
|
727
|
-
<circle
|
|
728
|
-
className="opacity-25"
|
|
729
|
-
cx="12"
|
|
730
|
-
cy="12"
|
|
731
|
-
r="10"
|
|
732
|
-
stroke="currentColor"
|
|
733
|
-
strokeWidth="4"
|
|
734
|
-
/>
|
|
735
|
-
<path
|
|
736
|
-
className="opacity-75"
|
|
737
|
-
fill="currentColor"
|
|
738
|
-
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
|
|
739
|
-
/>
|
|
740
|
-
</svg>
|
|
723
|
+
<Spinner size={14} />
|
|
741
724
|
Loading more events…
|
|
742
725
|
</div>
|
|
743
726
|
);
|
|
@@ -785,6 +768,7 @@ export const WorkflowTraceViewer = ({
|
|
|
785
768
|
isLoadingMoreSpans = false,
|
|
786
769
|
encryptionKey,
|
|
787
770
|
onDecrypt,
|
|
771
|
+
isDecrypting = false,
|
|
788
772
|
}: {
|
|
789
773
|
run: WorkflowRun;
|
|
790
774
|
events: Event[];
|
|
@@ -823,6 +807,8 @@ export const WorkflowTraceViewer = ({
|
|
|
823
807
|
encryptionKey?: Uint8Array;
|
|
824
808
|
/** Callback to initiate decryption of encrypted run data */
|
|
825
809
|
onDecrypt?: () => void;
|
|
810
|
+
/** Whether the encryption key is currently being fetched */
|
|
811
|
+
isDecrypting?: boolean;
|
|
826
812
|
}) => {
|
|
827
813
|
const [selectedSpan, setSelectedSpan] = useState<SelectedSpanInfo | null>(
|
|
828
814
|
null
|
|
@@ -1156,6 +1142,7 @@ export const WorkflowTraceViewer = ({
|
|
|
1156
1142
|
onResolveHook={onResolveHook}
|
|
1157
1143
|
encryptionKey={encryptionKey}
|
|
1158
1144
|
onDecrypt={onDecrypt}
|
|
1145
|
+
isDecrypting={isDecrypting}
|
|
1159
1146
|
selectedSpan={selectedSpan}
|
|
1160
1147
|
/>
|
|
1161
1148
|
</ErrorBoundary>
|