@workflow/web-shared 4.1.0-beta.47 → 4.1.0-beta.49
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/README.md +26 -52
- package/dist/components/error-boundary.d.ts.map +1 -0
- package/dist/{error-boundary.js → components/error-boundary.js} +1 -1
- package/dist/components/error-boundary.js.map +1 -0
- package/dist/{event-list-view.d.ts → components/event-list-view.d.ts} +2 -3
- package/dist/components/event-list-view.d.ts.map +1 -0
- package/dist/{event-list-view.js → components/event-list-view.js} +9 -17
- package/dist/components/event-list-view.js.map +1 -0
- package/dist/{hook-actions.d.ts → components/hook-actions.d.ts} +2 -3
- package/dist/components/hook-actions.d.ts.map +1 -0
- package/dist/{hook-actions.js → components/hook-actions.js} +3 -4
- package/dist/components/hook-actions.js.map +1 -0
- package/dist/components/index.d.ts +10 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +8 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/run-trace-view.d.ts +22 -0
- package/dist/components/run-trace-view.d.ts.map +1 -0
- package/dist/components/run-trace-view.js +11 -0
- package/dist/components/run-trace-view.js.map +1 -0
- package/dist/components/sidebar/attribute-panel.d.ts.map +1 -0
- package/dist/{sidebar → components/sidebar}/attribute-panel.js +3 -3
- package/dist/components/sidebar/attribute-panel.js.map +1 -0
- package/dist/components/sidebar/conversation-view.d.ts.map +1 -0
- package/dist/components/sidebar/conversation-view.js.map +1 -0
- package/dist/components/sidebar/detail-card.d.ts.map +1 -0
- package/dist/components/sidebar/detail-card.js.map +1 -0
- package/dist/components/sidebar/entity-detail-panel.d.ts +32 -0
- package/dist/components/sidebar/entity-detail-panel.d.ts.map +1 -0
- package/dist/{sidebar → components/sidebar}/entity-detail-panel.js +61 -49
- package/dist/components/sidebar/entity-detail-panel.js.map +1 -0
- package/dist/components/sidebar/events-list.d.ts +8 -0
- package/dist/components/sidebar/events-list.d.ts.map +1 -0
- package/dist/components/sidebar/events-list.js +16 -0
- package/dist/components/sidebar/events-list.js.map +1 -0
- package/dist/components/sidebar/resolve-hook-modal.d.ts.map +1 -0
- package/dist/components/sidebar/resolve-hook-modal.js.map +1 -0
- package/dist/components/stream-viewer.d.ts +18 -0
- package/dist/components/stream-viewer.d.ts.map +1 -0
- package/dist/{stream-viewer.js → components/stream-viewer.js} +1 -59
- package/dist/components/stream-viewer.js.map +1 -0
- package/dist/components/trace-viewer/components/map.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/map.js.map +1 -0
- package/dist/components/trace-viewer/components/markers.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/markers.js.map +1 -0
- package/dist/components/trace-viewer/components/node.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/node.js.map +1 -0
- package/dist/components/trace-viewer/components/search-input.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/search-input.js.map +1 -0
- package/dist/components/trace-viewer/components/search.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/search.js.map +1 -0
- package/dist/components/trace-viewer/components/span-detail-panel.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/span-detail-panel.js.map +1 -0
- package/dist/components/trace-viewer/components/ui.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/ui.js.map +1 -0
- package/dist/components/trace-viewer/components/zoom-button.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/zoom-button.js.map +1 -0
- package/dist/components/trace-viewer/components/zoom-icons.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/zoom-icons.js.map +1 -0
- package/dist/components/trace-viewer/context.d.ts.map +1 -0
- package/dist/components/trace-viewer/context.js.map +1 -0
- package/dist/components/trace-viewer/index.d.ts.map +1 -0
- package/dist/components/trace-viewer/index.js.map +1 -0
- package/dist/components/trace-viewer/trace-viewer.d.ts.map +1 -0
- package/dist/components/trace-viewer/trace-viewer.js.map +1 -0
- package/dist/components/trace-viewer/types.d.ts.map +1 -0
- package/dist/components/trace-viewer/types.js.map +1 -0
- package/dist/components/trace-viewer/util/constants.d.ts.map +1 -0
- package/dist/components/trace-viewer/util/constants.js.map +1 -0
- package/dist/components/trace-viewer/util/scrollbar-width.d.ts.map +1 -0
- package/dist/components/trace-viewer/util/scrollbar-width.js.map +1 -0
- package/dist/{trace-viewer → components/trace-viewer}/util/timing.d.ts +1 -1
- package/dist/components/trace-viewer/util/timing.d.ts.map +1 -0
- package/dist/{trace-viewer → components/trace-viewer}/util/timing.js +1 -1
- package/dist/components/trace-viewer/util/timing.js.map +1 -0
- package/dist/components/trace-viewer/util/tree.d.ts.map +1 -0
- package/dist/components/trace-viewer/util/tree.js.map +1 -0
- package/dist/components/trace-viewer/util/use-immediate-style.d.ts.map +1 -0
- package/dist/components/trace-viewer/util/use-immediate-style.js.map +1 -0
- package/dist/components/trace-viewer/util/use-streaming-spans.d.ts.map +1 -0
- package/dist/components/trace-viewer/util/use-streaming-spans.js.map +1 -0
- package/dist/components/trace-viewer/util/use-trackpad-zoom.d.ts.map +1 -0
- package/dist/components/trace-viewer/util/use-trackpad-zoom.js.map +1 -0
- package/dist/components/trace-viewer/worker.d.ts.map +1 -0
- package/dist/components/trace-viewer/worker.js.map +1 -0
- package/dist/components/workflow-trace-view.d.ts +24 -0
- package/dist/components/workflow-trace-view.d.ts.map +1 -0
- package/dist/components/workflow-trace-view.js +152 -0
- package/dist/components/workflow-trace-view.js.map +1 -0
- package/dist/components/workflow-traces/event-colors.d.ts.map +1 -0
- package/dist/components/workflow-traces/event-colors.js.map +1 -0
- package/dist/components/workflow-traces/trace-colors.d.ts.map +1 -0
- package/dist/components/workflow-traces/trace-colors.js.map +1 -0
- package/dist/components/workflow-traces/trace-span-construction.d.ts.map +1 -0
- package/dist/components/workflow-traces/trace-span-construction.js.map +1 -0
- package/dist/components/workflow-traces/trace-time-utils.d.ts.map +1 -0
- package/dist/components/workflow-traces/trace-time-utils.js.map +1 -0
- package/dist/index.d.ts +3 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -9
- package/dist/index.js.map +1 -1
- package/package.json +15 -11
- package/src/components/error-boundary.tsx +79 -0
- package/src/components/event-list-view.tsx +429 -0
- package/src/components/hook-actions.tsx +167 -0
- package/src/components/index.d.ts +1 -0
- package/src/components/index.ts +23 -0
- package/src/components/run-trace-view.tsx +75 -0
- package/src/components/sidebar/attribute-panel.tsx +938 -0
- package/src/components/sidebar/conversation-view.tsx +235 -0
- package/src/components/sidebar/detail-card.tsx +43 -0
- package/src/components/sidebar/entity-detail-panel.tsx +338 -0
- package/src/components/sidebar/events-list.tsx +119 -0
- package/src/components/sidebar/resolve-hook-modal.tsx +219 -0
- package/src/components/stream-viewer.tsx +143 -0
- package/src/components/trace-viewer/components/map.tsx +226 -0
- package/src/components/trace-viewer/components/markers.tsx +564 -0
- package/src/components/trace-viewer/components/node.tsx +259 -0
- package/src/components/trace-viewer/components/search-input.tsx +52 -0
- package/src/components/trace-viewer/components/search.tsx +47 -0
- package/src/components/trace-viewer/components/span-detail-panel.tsx +650 -0
- package/src/components/trace-viewer/components/ui.tsx +156 -0
- package/src/components/trace-viewer/components/zoom-button.tsx +61 -0
- package/src/components/trace-viewer/components/zoom-icons.tsx +65 -0
- package/src/components/trace-viewer/context.tsx +633 -0
- package/src/components/trace-viewer/index.tsx +4 -0
- package/src/components/trace-viewer/modules.d.ts +16 -0
- package/src/components/trace-viewer/trace-viewer.module.css +1292 -0
- package/src/components/trace-viewer/trace-viewer.tsx +448 -0
- package/src/components/trace-viewer/types.ts +234 -0
- package/src/components/trace-viewer/util/constants.ts +8 -0
- package/src/components/trace-viewer/util/scrollbar-width.ts +13 -0
- package/src/components/trace-viewer/util/timing.ts +33 -0
- package/src/components/trace-viewer/util/tree.ts +277 -0
- package/src/components/trace-viewer/util/use-immediate-style.ts +38 -0
- package/src/components/trace-viewer/util/use-streaming-spans.ts +415 -0
- package/src/components/trace-viewer/util/use-trackpad-zoom.tsx +51 -0
- package/src/components/trace-viewer/worker.ts +128 -0
- package/src/components/ui/alert.tsx +59 -0
- package/src/components/ui/card.tsx +88 -0
- package/src/components/ui/error-card.tsx +65 -0
- package/src/components/ui/skeleton.tsx +15 -0
- package/src/components/workflow-trace-view.tsx +306 -0
- package/src/components/workflow-traces/event-colors.ts +94 -0
- package/src/components/workflow-traces/trace-colors.ts +112 -0
- package/src/components/workflow-traces/trace-span-construction.ts +299 -0
- package/src/components/workflow-traces/trace-time-utils.ts +50 -0
- package/src/hooks/use-dark-mode.ts +34 -0
- package/src/index.d.ts +1 -0
- package/src/index.ts +29 -0
- package/src/lib/event-analysis.ts +231 -0
- package/src/lib/utils.ts +166 -0
- package/dist/api/workflow-api-client.d.ts +0 -543
- package/dist/api/workflow-api-client.d.ts.map +0 -1
- package/dist/api/workflow-api-client.js +0 -953
- package/dist/api/workflow-api-client.js.map +0 -1
- package/dist/api/workflow-server-actions.d.ts +0 -230
- package/dist/api/workflow-server-actions.d.ts.map +0 -1
- package/dist/api/workflow-server-actions.js +0 -861
- package/dist/api/workflow-server-actions.js.map +0 -1
- package/dist/error-boundary.d.ts.map +0 -1
- package/dist/error-boundary.js.map +0 -1
- package/dist/event-list-view.d.ts.map +0 -1
- package/dist/event-list-view.js.map +0 -1
- package/dist/hook-actions.d.ts.map +0 -1
- package/dist/hook-actions.js.map +0 -1
- package/dist/run-trace-view.d.ts +0 -8
- package/dist/run-trace-view.d.ts.map +0 -1
- package/dist/run-trace-view.js +0 -15
- package/dist/run-trace-view.js.map +0 -1
- package/dist/sidebar/attribute-panel.d.ts.map +0 -1
- package/dist/sidebar/attribute-panel.js.map +0 -1
- package/dist/sidebar/conversation-view.d.ts.map +0 -1
- package/dist/sidebar/conversation-view.js.map +0 -1
- package/dist/sidebar/detail-card.d.ts.map +0 -1
- package/dist/sidebar/detail-card.js.map +0 -1
- package/dist/sidebar/entity-detail-panel.d.ts +0 -12
- package/dist/sidebar/entity-detail-panel.d.ts.map +0 -1
- package/dist/sidebar/entity-detail-panel.js.map +0 -1
- package/dist/sidebar/events-list.d.ts +0 -9
- package/dist/sidebar/events-list.d.ts.map +0 -1
- package/dist/sidebar/events-list.js +0 -36
- package/dist/sidebar/events-list.js.map +0 -1
- package/dist/sidebar/resolve-hook-modal.d.ts.map +0 -1
- package/dist/sidebar/resolve-hook-modal.js.map +0 -1
- package/dist/stream-viewer.d.ts +0 -13
- package/dist/stream-viewer.d.ts.map +0 -1
- package/dist/stream-viewer.js.map +0 -1
- package/dist/trace-viewer/components/map.d.ts.map +0 -1
- package/dist/trace-viewer/components/map.js.map +0 -1
- package/dist/trace-viewer/components/markers.d.ts.map +0 -1
- package/dist/trace-viewer/components/markers.js.map +0 -1
- package/dist/trace-viewer/components/node.d.ts.map +0 -1
- package/dist/trace-viewer/components/node.js.map +0 -1
- package/dist/trace-viewer/components/search-input.d.ts.map +0 -1
- package/dist/trace-viewer/components/search-input.js.map +0 -1
- package/dist/trace-viewer/components/search.d.ts.map +0 -1
- package/dist/trace-viewer/components/search.js.map +0 -1
- package/dist/trace-viewer/components/span-detail-panel.d.ts.map +0 -1
- package/dist/trace-viewer/components/span-detail-panel.js.map +0 -1
- package/dist/trace-viewer/components/ui.d.ts.map +0 -1
- package/dist/trace-viewer/components/ui.js.map +0 -1
- package/dist/trace-viewer/components/zoom-button.d.ts.map +0 -1
- package/dist/trace-viewer/components/zoom-button.js.map +0 -1
- package/dist/trace-viewer/components/zoom-icons.d.ts.map +0 -1
- package/dist/trace-viewer/components/zoom-icons.js.map +0 -1
- package/dist/trace-viewer/context.d.ts.map +0 -1
- package/dist/trace-viewer/context.js.map +0 -1
- package/dist/trace-viewer/index.d.ts.map +0 -1
- package/dist/trace-viewer/index.js.map +0 -1
- package/dist/trace-viewer/trace-viewer.d.ts.map +0 -1
- package/dist/trace-viewer/trace-viewer.js.map +0 -1
- package/dist/trace-viewer/types.d.ts.map +0 -1
- package/dist/trace-viewer/types.js.map +0 -1
- package/dist/trace-viewer/util/constants.d.ts.map +0 -1
- package/dist/trace-viewer/util/constants.js.map +0 -1
- package/dist/trace-viewer/util/scrollbar-width.d.ts.map +0 -1
- package/dist/trace-viewer/util/scrollbar-width.js.map +0 -1
- package/dist/trace-viewer/util/timing.d.ts.map +0 -1
- package/dist/trace-viewer/util/timing.js.map +0 -1
- package/dist/trace-viewer/util/tree.d.ts.map +0 -1
- package/dist/trace-viewer/util/tree.js.map +0 -1
- package/dist/trace-viewer/util/use-immediate-style.d.ts.map +0 -1
- package/dist/trace-viewer/util/use-immediate-style.js.map +0 -1
- package/dist/trace-viewer/util/use-streaming-spans.d.ts.map +0 -1
- package/dist/trace-viewer/util/use-streaming-spans.js.map +0 -1
- package/dist/trace-viewer/util/use-trackpad-zoom.d.ts.map +0 -1
- package/dist/trace-viewer/util/use-trackpad-zoom.js.map +0 -1
- package/dist/trace-viewer/worker.d.ts.map +0 -1
- package/dist/trace-viewer/worker.js.map +0 -1
- package/dist/workflow-trace-view.d.ts +0 -14
- package/dist/workflow-trace-view.d.ts.map +0 -1
- package/dist/workflow-trace-view.js +0 -135
- package/dist/workflow-trace-view.js.map +0 -1
- package/dist/workflow-traces/event-colors.d.ts.map +0 -1
- package/dist/workflow-traces/event-colors.js.map +0 -1
- package/dist/workflow-traces/trace-colors.d.ts.map +0 -1
- package/dist/workflow-traces/trace-colors.js.map +0 -1
- package/dist/workflow-traces/trace-span-construction.d.ts.map +0 -1
- package/dist/workflow-traces/trace-span-construction.js.map +0 -1
- package/dist/workflow-traces/trace-time-utils.d.ts.map +0 -1
- package/dist/workflow-traces/trace-time-utils.js.map +0 -1
- package/server/README.md +0 -1
- package/server/package.json +0 -4
- /package/dist/{error-boundary.d.ts → components/error-boundary.d.ts} +0 -0
- /package/dist/{sidebar → components/sidebar}/attribute-panel.d.ts +0 -0
- /package/dist/{sidebar → components/sidebar}/conversation-view.d.ts +0 -0
- /package/dist/{sidebar → components/sidebar}/conversation-view.js +0 -0
- /package/dist/{sidebar → components/sidebar}/detail-card.d.ts +0 -0
- /package/dist/{sidebar → components/sidebar}/detail-card.js +0 -0
- /package/dist/{sidebar → components/sidebar}/resolve-hook-modal.d.ts +0 -0
- /package/dist/{sidebar → components/sidebar}/resolve-hook-modal.js +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/components/map.d.ts +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/components/map.js +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/components/markers.d.ts +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/components/markers.js +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/components/node.d.ts +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/components/node.js +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/components/search-input.d.ts +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/components/search-input.js +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/components/search.d.ts +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/components/search.js +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/components/span-detail-panel.d.ts +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/components/span-detail-panel.js +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/components/ui.d.ts +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/components/ui.js +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/components/zoom-button.d.ts +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/components/zoom-button.js +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/components/zoom-icons.d.ts +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/components/zoom-icons.js +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/context.d.ts +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/context.js +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/index.d.ts +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/index.js +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/trace-viewer.d.ts +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/trace-viewer.js +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/trace-viewer.module.css +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/types.d.ts +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/types.js +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/util/constants.d.ts +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/util/constants.js +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/util/scrollbar-width.d.ts +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/util/scrollbar-width.js +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/util/tree.d.ts +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/util/tree.js +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/util/use-immediate-style.d.ts +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/util/use-immediate-style.js +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/util/use-streaming-spans.d.ts +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/util/use-streaming-spans.js +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/util/use-trackpad-zoom.d.ts +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/util/use-trackpad-zoom.js +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/worker.d.ts +0 -0
- /package/dist/{trace-viewer → components/trace-viewer}/worker.js +0 -0
- /package/dist/{workflow-traces → components/workflow-traces}/event-colors.d.ts +0 -0
- /package/dist/{workflow-traces → components/workflow-traces}/event-colors.js +0 -0
- /package/dist/{workflow-traces → components/workflow-traces}/trace-colors.d.ts +0 -0
- /package/dist/{workflow-traces → components/workflow-traces}/trace-colors.js +0 -0
- /package/dist/{workflow-traces → components/workflow-traces}/trace-span-construction.d.ts +0 -0
- /package/dist/{workflow-traces → components/workflow-traces}/trace-span-construction.js +0 -0
- /package/dist/{workflow-traces → components/workflow-traces}/trace-time-utils.d.ts +0 -0
- /package/dist/{workflow-traces → components/workflow-traces}/trace-time-utils.js +0 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import React, { type ReactNode } from 'react';
|
|
4
|
+
import { ErrorCard } from './ui/error-card';
|
|
5
|
+
|
|
6
|
+
interface ErrorBoundaryProps {
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
/** Optional title for the error message */
|
|
9
|
+
title?: string;
|
|
10
|
+
/** Optional fallback component to render on error */
|
|
11
|
+
fallback?: (error: Error, reset: () => void) => ReactNode;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface ErrorBoundaryState {
|
|
15
|
+
hasError: boolean;
|
|
16
|
+
error: Error | null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Error boundary component that catches errors in child components
|
|
21
|
+
* and displays them without breaking the entire application.
|
|
22
|
+
*
|
|
23
|
+
* Errors are localized to this boundary, so other parts of the UI
|
|
24
|
+
* remain functional.
|
|
25
|
+
*/
|
|
26
|
+
export class ErrorBoundary extends React.Component<
|
|
27
|
+
ErrorBoundaryProps,
|
|
28
|
+
ErrorBoundaryState
|
|
29
|
+
> {
|
|
30
|
+
constructor(props: ErrorBoundaryProps) {
|
|
31
|
+
super(props);
|
|
32
|
+
this.state = {
|
|
33
|
+
hasError: false,
|
|
34
|
+
error: null,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static getDerivedStateFromError(error: Error): ErrorBoundaryState {
|
|
39
|
+
return {
|
|
40
|
+
hasError: true,
|
|
41
|
+
error,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
|
|
46
|
+
// Log error for debugging
|
|
47
|
+
console.error('Error caught by boundary:', error, errorInfo);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
handleReset = () => {
|
|
51
|
+
this.setState({
|
|
52
|
+
hasError: false,
|
|
53
|
+
error: null,
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
render() {
|
|
58
|
+
if (this.state.hasError && this.state.error) {
|
|
59
|
+
// Use custom fallback if provided
|
|
60
|
+
if (this.props.fallback) {
|
|
61
|
+
return this.props.fallback(this.state.error, this.handleReset);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Default error UI
|
|
65
|
+
const errorDetails = this.state.error.stack
|
|
66
|
+
? `${this.state.error.message}\n\n${this.state.error.stack}`
|
|
67
|
+
: this.state.error.message;
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<ErrorCard
|
|
71
|
+
title={this.props.title || 'An error occurred'}
|
|
72
|
+
details={errorDetails}
|
|
73
|
+
/>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return this.props.children;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import type { Event } from '@workflow/world';
|
|
4
|
+
import { ChevronRight, Loader2 } from 'lucide-react';
|
|
5
|
+
import { useCallback, useMemo, useState } from 'react';
|
|
6
|
+
import { getEventColor } from './workflow-traces/event-colors';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Format a date to a human-readable local time string with milliseconds
|
|
10
|
+
*/
|
|
11
|
+
function formatEventTime(date: Date): string {
|
|
12
|
+
return (
|
|
13
|
+
date.toLocaleTimeString('en-US', {
|
|
14
|
+
hour: '2-digit',
|
|
15
|
+
minute: '2-digit',
|
|
16
|
+
second: '2-digit',
|
|
17
|
+
hour12: false,
|
|
18
|
+
}) +
|
|
19
|
+
'.' +
|
|
20
|
+
date.getMilliseconds().toString().padStart(3, '0')
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Format a date to full local datetime string with milliseconds
|
|
26
|
+
*/
|
|
27
|
+
function formatEventDateTime(date: Date): string {
|
|
28
|
+
return date.toLocaleString(undefined, {
|
|
29
|
+
year: 'numeric',
|
|
30
|
+
month: 'numeric',
|
|
31
|
+
day: 'numeric',
|
|
32
|
+
hour: 'numeric',
|
|
33
|
+
minute: 'numeric',
|
|
34
|
+
second: 'numeric',
|
|
35
|
+
fractionalSecondDigits: 3,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Format event type to a more readable label
|
|
41
|
+
*/
|
|
42
|
+
function formatEventType(eventType: Event['eventType']): string {
|
|
43
|
+
return eventType
|
|
44
|
+
.split('_')
|
|
45
|
+
.map((word: string) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
46
|
+
.join(' ');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface EventsListProps {
|
|
50
|
+
events: Event[] | null;
|
|
51
|
+
onLoadEventData?: (event: Event) => Promise<unknown | null>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Single event row component with expandable details
|
|
56
|
+
*/
|
|
57
|
+
function EventRow({
|
|
58
|
+
event,
|
|
59
|
+
onLoadEventData,
|
|
60
|
+
}: {
|
|
61
|
+
event: Event;
|
|
62
|
+
onLoadEventData?: (event: Event) => Promise<unknown | null>;
|
|
63
|
+
}) {
|
|
64
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
65
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
66
|
+
const [loadedEventData, setLoadedEventData] = useState<unknown | null>(null);
|
|
67
|
+
const [loadError, setLoadError] = useState<string | null>(null);
|
|
68
|
+
|
|
69
|
+
const colors = getEventColor(event.eventType);
|
|
70
|
+
const createdAt = new Date(event.createdAt);
|
|
71
|
+
|
|
72
|
+
// Check if event already has eventData (from initial fetch)
|
|
73
|
+
const hasExistingEventData = 'eventData' in event && event.eventData != null;
|
|
74
|
+
|
|
75
|
+
// Load full event details when expanding
|
|
76
|
+
const loadEventDetails = useCallback(async () => {
|
|
77
|
+
// Skip if we already have data or no correlationId
|
|
78
|
+
if (
|
|
79
|
+
loadedEventData !== null ||
|
|
80
|
+
hasExistingEventData ||
|
|
81
|
+
!event.correlationId
|
|
82
|
+
) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
setIsLoading(true);
|
|
87
|
+
setLoadError(null);
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
if (!onLoadEventData) {
|
|
91
|
+
setLoadError('Event details unavailable');
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const eventData = await onLoadEventData(event);
|
|
95
|
+
if (eventData !== null && eventData !== undefined) {
|
|
96
|
+
setLoadedEventData(eventData);
|
|
97
|
+
}
|
|
98
|
+
} catch (err) {
|
|
99
|
+
setLoadError(
|
|
100
|
+
err instanceof Error ? err.message : 'Failed to load event details'
|
|
101
|
+
);
|
|
102
|
+
} finally {
|
|
103
|
+
setIsLoading(false);
|
|
104
|
+
}
|
|
105
|
+
}, [
|
|
106
|
+
event.correlationId,
|
|
107
|
+
loadedEventData,
|
|
108
|
+
hasExistingEventData,
|
|
109
|
+
onLoadEventData,
|
|
110
|
+
]);
|
|
111
|
+
|
|
112
|
+
// Handle expand/collapse
|
|
113
|
+
const handleToggle = useCallback(() => {
|
|
114
|
+
const newExpanded = !isExpanded;
|
|
115
|
+
setIsExpanded(newExpanded);
|
|
116
|
+
|
|
117
|
+
// Load details when expanding for the first time
|
|
118
|
+
if (newExpanded && loadedEventData === null && !hasExistingEventData) {
|
|
119
|
+
loadEventDetails();
|
|
120
|
+
}
|
|
121
|
+
}, [isExpanded, loadedEventData, hasExistingEventData, loadEventDetails]);
|
|
122
|
+
|
|
123
|
+
// Get the event data to display (either from initial fetch, loaded data, or null)
|
|
124
|
+
const eventData = hasExistingEventData
|
|
125
|
+
? (event as Event & { eventData: unknown }).eventData
|
|
126
|
+
: loadedEventData;
|
|
127
|
+
|
|
128
|
+
return (
|
|
129
|
+
<div
|
|
130
|
+
className="rounded-lg border overflow-hidden transition-all"
|
|
131
|
+
style={{
|
|
132
|
+
backgroundColor: 'var(--ds-background-100)',
|
|
133
|
+
borderColor: colors.border,
|
|
134
|
+
borderLeftWidth: '1px',
|
|
135
|
+
borderLeftColor: colors.color,
|
|
136
|
+
}}
|
|
137
|
+
>
|
|
138
|
+
{/* Clickable row header */}
|
|
139
|
+
<button
|
|
140
|
+
type="button"
|
|
141
|
+
onClick={handleToggle}
|
|
142
|
+
className="w-full text-left grid gap-3 items-center px-0 py-2 text-xs hover:brightness-[0.98] transition-all cursor-pointer"
|
|
143
|
+
style={{
|
|
144
|
+
backgroundColor: 'var(--ds-background-100)',
|
|
145
|
+
gridTemplateColumns: '24px 100px minmax(120px, auto) 1fr 1fr',
|
|
146
|
+
}}
|
|
147
|
+
>
|
|
148
|
+
{/* Expand icon */}
|
|
149
|
+
<div className="flex justify-center">
|
|
150
|
+
<ChevronRight
|
|
151
|
+
className="h-3.5 w-3.5 transition-transform"
|
|
152
|
+
style={{
|
|
153
|
+
color: colors.secondary,
|
|
154
|
+
transform: isExpanded ? 'rotate(90deg)' : 'rotate(0deg)',
|
|
155
|
+
}}
|
|
156
|
+
/>
|
|
157
|
+
</div>
|
|
158
|
+
|
|
159
|
+
{/* Time */}
|
|
160
|
+
<div
|
|
161
|
+
className="font-mono tabular-nums"
|
|
162
|
+
style={{ color: colors.secondary }}
|
|
163
|
+
>
|
|
164
|
+
{formatEventTime(createdAt)}
|
|
165
|
+
</div>
|
|
166
|
+
|
|
167
|
+
{/* Event Type */}
|
|
168
|
+
<div className="font-medium" style={{ color: colors.text }}>
|
|
169
|
+
<span className="inline-flex items-center gap-1.5">
|
|
170
|
+
<span
|
|
171
|
+
className="w-2 h-2 rounded-full flex-shrink-0"
|
|
172
|
+
style={{ backgroundColor: colors.color }}
|
|
173
|
+
/>
|
|
174
|
+
{formatEventType(event.eventType)}
|
|
175
|
+
</span>
|
|
176
|
+
</div>
|
|
177
|
+
|
|
178
|
+
{/* Correlation ID */}
|
|
179
|
+
<div
|
|
180
|
+
className="font-mono text-[11px] overflow-hidden text-ellipsis whitespace-nowrap"
|
|
181
|
+
style={{ color: colors.secondary }}
|
|
182
|
+
title={event.correlationId || '-'}
|
|
183
|
+
>
|
|
184
|
+
{event.correlationId || '-'}
|
|
185
|
+
</div>
|
|
186
|
+
|
|
187
|
+
{/* Event ID */}
|
|
188
|
+
<div
|
|
189
|
+
className="font-mono text-[11px] pr-3 overflow-hidden text-ellipsis whitespace-nowrap"
|
|
190
|
+
style={{ color: colors.secondary }}
|
|
191
|
+
title={event.eventId}
|
|
192
|
+
>
|
|
193
|
+
{event.eventId}
|
|
194
|
+
</div>
|
|
195
|
+
</button>
|
|
196
|
+
|
|
197
|
+
{/* Expanded details */}
|
|
198
|
+
{isExpanded && (
|
|
199
|
+
<div
|
|
200
|
+
className="border-t px-4 py-3"
|
|
201
|
+
style={{
|
|
202
|
+
borderColor: colors.border,
|
|
203
|
+
backgroundColor: 'var(--ds-background-100)',
|
|
204
|
+
}}
|
|
205
|
+
>
|
|
206
|
+
{/* Event attributes in a structured table */}
|
|
207
|
+
<div
|
|
208
|
+
className="flex flex-col divide-y rounded-md border overflow-hidden"
|
|
209
|
+
style={{
|
|
210
|
+
borderColor: 'var(--ds-gray-300)',
|
|
211
|
+
backgroundColor: 'var(--ds-gray-100)',
|
|
212
|
+
}}
|
|
213
|
+
>
|
|
214
|
+
<AttributeRow label="Event ID" value={event.eventId} mono />
|
|
215
|
+
<AttributeRow label="Event Type" value={event.eventType} />
|
|
216
|
+
<AttributeRow
|
|
217
|
+
label="Correlation ID"
|
|
218
|
+
value={event.correlationId || '-'}
|
|
219
|
+
mono
|
|
220
|
+
/>
|
|
221
|
+
<AttributeRow label="Run ID" value={event.runId} mono />
|
|
222
|
+
<AttributeRow
|
|
223
|
+
label="Created At"
|
|
224
|
+
value={formatEventDateTime(createdAt)}
|
|
225
|
+
/>
|
|
226
|
+
</div>
|
|
227
|
+
|
|
228
|
+
{/* Event data section */}
|
|
229
|
+
<div className="mt-3">
|
|
230
|
+
<div
|
|
231
|
+
className="text-xs font-medium mb-1.5"
|
|
232
|
+
style={{ color: 'var(--ds-gray-700)' }}
|
|
233
|
+
>
|
|
234
|
+
Event Data
|
|
235
|
+
</div>
|
|
236
|
+
|
|
237
|
+
{/* Loading state */}
|
|
238
|
+
{isLoading && (
|
|
239
|
+
<div
|
|
240
|
+
className="flex items-center gap-2 rounded-md border p-3"
|
|
241
|
+
style={{
|
|
242
|
+
borderColor: 'var(--ds-gray-300)',
|
|
243
|
+
backgroundColor: 'var(--ds-gray-100)',
|
|
244
|
+
}}
|
|
245
|
+
>
|
|
246
|
+
<Loader2
|
|
247
|
+
className="h-4 w-4 animate-spin"
|
|
248
|
+
style={{ color: 'var(--ds-gray-700)' }}
|
|
249
|
+
/>
|
|
250
|
+
<span
|
|
251
|
+
className="text-xs"
|
|
252
|
+
style={{ color: 'var(--ds-gray-700)' }}
|
|
253
|
+
>
|
|
254
|
+
Loading event details...
|
|
255
|
+
</span>
|
|
256
|
+
</div>
|
|
257
|
+
)}
|
|
258
|
+
|
|
259
|
+
{/* Error state */}
|
|
260
|
+
{loadError && !isLoading && (
|
|
261
|
+
<div
|
|
262
|
+
className="rounded-md border p-3 text-xs"
|
|
263
|
+
style={{
|
|
264
|
+
borderColor: 'var(--ds-red-400)',
|
|
265
|
+
backgroundColor: 'var(--ds-red-100)',
|
|
266
|
+
color: 'var(--ds-red-900)',
|
|
267
|
+
}}
|
|
268
|
+
>
|
|
269
|
+
{loadError}
|
|
270
|
+
</div>
|
|
271
|
+
)}
|
|
272
|
+
|
|
273
|
+
{/* Event data display */}
|
|
274
|
+
{!isLoading && !loadError && eventData != null && (
|
|
275
|
+
<pre
|
|
276
|
+
className="text-[11px] overflow-x-auto rounded-md border p-3"
|
|
277
|
+
style={{
|
|
278
|
+
borderColor: 'var(--ds-gray-300)',
|
|
279
|
+
backgroundColor: 'var(--ds-gray-100)',
|
|
280
|
+
color: 'var(--ds-gray-1000)',
|
|
281
|
+
}}
|
|
282
|
+
>
|
|
283
|
+
<code>{JSON.stringify(eventData, null, 2)}</code>
|
|
284
|
+
</pre>
|
|
285
|
+
)}
|
|
286
|
+
|
|
287
|
+
{/* No event data */}
|
|
288
|
+
{!isLoading &&
|
|
289
|
+
!loadError &&
|
|
290
|
+
eventData == null &&
|
|
291
|
+
!event.correlationId && (
|
|
292
|
+
<div
|
|
293
|
+
className="rounded-md border p-3 text-xs"
|
|
294
|
+
style={{
|
|
295
|
+
borderColor: 'var(--ds-gray-300)',
|
|
296
|
+
backgroundColor: 'var(--ds-gray-100)',
|
|
297
|
+
color: 'var(--ds-gray-700)',
|
|
298
|
+
}}
|
|
299
|
+
>
|
|
300
|
+
No event data available
|
|
301
|
+
</div>
|
|
302
|
+
)}
|
|
303
|
+
|
|
304
|
+
{/* No correlation ID - can't load data */}
|
|
305
|
+
{!isLoading &&
|
|
306
|
+
!loadError &&
|
|
307
|
+
eventData == null &&
|
|
308
|
+
event.correlationId &&
|
|
309
|
+
!hasExistingEventData &&
|
|
310
|
+
loadedEventData === null && (
|
|
311
|
+
<div
|
|
312
|
+
className="rounded-md border p-3 text-xs"
|
|
313
|
+
style={{
|
|
314
|
+
borderColor: 'var(--ds-gray-300)',
|
|
315
|
+
backgroundColor: 'var(--ds-gray-100)',
|
|
316
|
+
color: 'var(--ds-gray-700)',
|
|
317
|
+
}}
|
|
318
|
+
>
|
|
319
|
+
No event data for this event type
|
|
320
|
+
</div>
|
|
321
|
+
)}
|
|
322
|
+
</div>
|
|
323
|
+
</div>
|
|
324
|
+
)}
|
|
325
|
+
</div>
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Helper component for attribute rows in the expanded details
|
|
331
|
+
*/
|
|
332
|
+
function AttributeRow({
|
|
333
|
+
label,
|
|
334
|
+
value,
|
|
335
|
+
mono = false,
|
|
336
|
+
}: {
|
|
337
|
+
label: string;
|
|
338
|
+
value: string;
|
|
339
|
+
mono?: boolean;
|
|
340
|
+
}) {
|
|
341
|
+
return (
|
|
342
|
+
<div
|
|
343
|
+
className="flex items-center justify-between px-2.5 py-1.5"
|
|
344
|
+
style={{ borderColor: 'var(--ds-gray-300)' }}
|
|
345
|
+
>
|
|
346
|
+
<span
|
|
347
|
+
className="text-[11px] font-medium"
|
|
348
|
+
style={{ color: 'var(--ds-gray-700)' }}
|
|
349
|
+
>
|
|
350
|
+
{label}
|
|
351
|
+
</span>
|
|
352
|
+
<span
|
|
353
|
+
className={`text-[11px] ${mono ? 'font-mono' : ''} text-right max-w-[70%] break-all`}
|
|
354
|
+
style={{ color: 'var(--ds-gray-1000)' }}
|
|
355
|
+
>
|
|
356
|
+
{value}
|
|
357
|
+
</span>
|
|
358
|
+
</div>
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Displays a list of all events for a workflow run as colored cards in a pseudo-table.
|
|
364
|
+
* Events are sorted by createdAt (oldest first).
|
|
365
|
+
*/
|
|
366
|
+
export function EventListView({ events, onLoadEventData }: EventsListProps) {
|
|
367
|
+
// Sort events by createdAt (oldest first)
|
|
368
|
+
const sortedEvents = useMemo(() => {
|
|
369
|
+
if (!events || events.length === 0) return [];
|
|
370
|
+
return [...events].sort(
|
|
371
|
+
(a, b) =>
|
|
372
|
+
new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
|
|
373
|
+
);
|
|
374
|
+
}, [events]);
|
|
375
|
+
|
|
376
|
+
if (!events || events.length === 0) {
|
|
377
|
+
return (
|
|
378
|
+
<div
|
|
379
|
+
className="flex items-center justify-center h-full text-sm"
|
|
380
|
+
style={{ color: 'var(--ds-gray-700)' }}
|
|
381
|
+
>
|
|
382
|
+
No events found
|
|
383
|
+
</div>
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
return (
|
|
388
|
+
<div className="h-full overflow-auto m-2">
|
|
389
|
+
{/* Header row */}
|
|
390
|
+
<div
|
|
391
|
+
className="grid gap-3 pb-2 mb-2 border-b text-xs font-medium sticky top-0 z-10"
|
|
392
|
+
style={{
|
|
393
|
+
gridTemplateColumns: '24px 100px minmax(120px, auto) 1fr 1fr',
|
|
394
|
+
borderColor: 'var(--ds-gray-300)',
|
|
395
|
+
backgroundColor: 'transparent',
|
|
396
|
+
color: 'var(--ds-gray-700)',
|
|
397
|
+
}}
|
|
398
|
+
>
|
|
399
|
+
<div>{/* Expand icon column */}</div>
|
|
400
|
+
<div>Time</div>
|
|
401
|
+
<div>Event Type</div>
|
|
402
|
+
<div>Correlation ID</div>
|
|
403
|
+
<div>Event ID</div>
|
|
404
|
+
</div>
|
|
405
|
+
|
|
406
|
+
{/* Event rows */}
|
|
407
|
+
<div className="flex flex-col gap-2">
|
|
408
|
+
{sortedEvents.map((event) => (
|
|
409
|
+
<EventRow
|
|
410
|
+
key={event.eventId}
|
|
411
|
+
event={event}
|
|
412
|
+
onLoadEventData={onLoadEventData}
|
|
413
|
+
/>
|
|
414
|
+
))}
|
|
415
|
+
</div>
|
|
416
|
+
|
|
417
|
+
{/* Summary */}
|
|
418
|
+
<div
|
|
419
|
+
className="mt-4 pt-3 border-t text-xs"
|
|
420
|
+
style={{
|
|
421
|
+
borderColor: 'var(--ds-gray-300)',
|
|
422
|
+
color: 'var(--ds-gray-700)',
|
|
423
|
+
}}
|
|
424
|
+
>
|
|
425
|
+
{sortedEvents.length} event{sortedEvents.length !== 1 ? 's' : ''} total
|
|
426
|
+
</div>
|
|
427
|
+
</div>
|
|
428
|
+
);
|
|
429
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import type { Hook, WorkflowRunStatus } from '@workflow/world';
|
|
4
|
+
import { Send } from 'lucide-react';
|
|
5
|
+
import { useCallback, useState } from 'react';
|
|
6
|
+
import { toast } from 'sonner';
|
|
7
|
+
import { ResolveHookModal } from './sidebar/resolve-hook-modal';
|
|
8
|
+
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Types
|
|
11
|
+
// ============================================================================
|
|
12
|
+
|
|
13
|
+
export interface HookActionCallbacks {
|
|
14
|
+
/** Called after a successful action */
|
|
15
|
+
onSuccess?: () => void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface UseHookActionsOptions {
|
|
19
|
+
onResolve: (hook: Hook, payload: unknown) => Promise<void>;
|
|
20
|
+
callbacks?: HookActionCallbacks;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface UseHookActionsReturn {
|
|
24
|
+
/** Whether the hook is currently being resolved */
|
|
25
|
+
isResolving: boolean;
|
|
26
|
+
/** The hook currently selected for resolution (null if none) */
|
|
27
|
+
selectedHook: Hook | null;
|
|
28
|
+
/** Open the resolve modal for a specific hook */
|
|
29
|
+
openResolveModal: (hook: Hook) => void;
|
|
30
|
+
/** Close the resolve modal */
|
|
31
|
+
closeResolveModal: () => void;
|
|
32
|
+
/** Handle submitting the resolve payload */
|
|
33
|
+
handleResolve: (payload: unknown) => Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ============================================================================
|
|
37
|
+
// Hook for managing hook actions state
|
|
38
|
+
// ============================================================================
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* React hook for managing hook action state.
|
|
42
|
+
* Use this to coordinate the resolve modal across components.
|
|
43
|
+
*/
|
|
44
|
+
export function useHookActions({
|
|
45
|
+
onResolve,
|
|
46
|
+
callbacks,
|
|
47
|
+
}: UseHookActionsOptions): UseHookActionsReturn {
|
|
48
|
+
const [isResolving, setIsResolving] = useState(false);
|
|
49
|
+
const [selectedHook, setSelectedHook] = useState<Hook | null>(null);
|
|
50
|
+
|
|
51
|
+
const openResolveModal = useCallback((hook: Hook) => {
|
|
52
|
+
setSelectedHook(hook);
|
|
53
|
+
}, []);
|
|
54
|
+
|
|
55
|
+
const closeResolveModal = useCallback(() => {
|
|
56
|
+
setSelectedHook(null);
|
|
57
|
+
}, []);
|
|
58
|
+
|
|
59
|
+
const handleResolve = useCallback(
|
|
60
|
+
async (payload: unknown) => {
|
|
61
|
+
if (isResolving || !selectedHook) return;
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
setIsResolving(true);
|
|
65
|
+
await onResolve(selectedHook, payload);
|
|
66
|
+
toast.success('Hook resolved', {
|
|
67
|
+
description: 'The payload has been sent and the hook resolved.',
|
|
68
|
+
});
|
|
69
|
+
setSelectedHook(null);
|
|
70
|
+
callbacks?.onSuccess?.();
|
|
71
|
+
} catch (err) {
|
|
72
|
+
console.error('Failed to resolve hook:', err);
|
|
73
|
+
toast.error('Failed to resolve hook', {
|
|
74
|
+
description:
|
|
75
|
+
err instanceof Error ? err.message : 'An unknown error occurred',
|
|
76
|
+
});
|
|
77
|
+
} finally {
|
|
78
|
+
setIsResolving(false);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
[onResolve, selectedHook, isResolving, callbacks]
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
isResolving,
|
|
86
|
+
selectedHook,
|
|
87
|
+
openResolveModal,
|
|
88
|
+
closeResolveModal,
|
|
89
|
+
handleResolve,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// ============================================================================
|
|
94
|
+
// Dropdown Menu Item Component
|
|
95
|
+
// ============================================================================
|
|
96
|
+
|
|
97
|
+
export interface HookActionsDropdownItemProps {
|
|
98
|
+
/** The hook to act on */
|
|
99
|
+
hook: Hook;
|
|
100
|
+
/** The current run status (used to determine if actions are available) */
|
|
101
|
+
runStatus?: WorkflowRunStatus;
|
|
102
|
+
/** Stop click event propagation (useful in table rows) */
|
|
103
|
+
stopPropagation?: boolean;
|
|
104
|
+
/** Called when the resolve action is triggered */
|
|
105
|
+
onResolveClick: (hook: Hook) => void;
|
|
106
|
+
/** Custom DropdownMenuItem component (allows using the consumer's UI library) */
|
|
107
|
+
DropdownMenuItem: React.ComponentType<{
|
|
108
|
+
onClick?: (e: React.MouseEvent) => void;
|
|
109
|
+
disabled?: boolean;
|
|
110
|
+
children: React.ReactNode;
|
|
111
|
+
}>;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Dropdown menu item for resolving a hook.
|
|
116
|
+
* This is a single menu item component that can be composed into dropdown menus.
|
|
117
|
+
*/
|
|
118
|
+
export function ResolveHookDropdownItem({
|
|
119
|
+
hook,
|
|
120
|
+
stopPropagation = false,
|
|
121
|
+
onResolveClick,
|
|
122
|
+
DropdownMenuItem,
|
|
123
|
+
}: HookActionsDropdownItemProps): React.JSX.Element {
|
|
124
|
+
const handleClick = (e: React.MouseEvent) => {
|
|
125
|
+
if (stopPropagation) e.stopPropagation();
|
|
126
|
+
onResolveClick(hook);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
return (
|
|
130
|
+
<DropdownMenuItem onClick={handleClick}>
|
|
131
|
+
<Send className="h-4 w-4 mr-2" />
|
|
132
|
+
Resolve Hook
|
|
133
|
+
</DropdownMenuItem>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// ============================================================================
|
|
138
|
+
// Modal wrapper for convenience
|
|
139
|
+
// ============================================================================
|
|
140
|
+
|
|
141
|
+
export interface HookResolveModalProps {
|
|
142
|
+
/** The hook actions state from useHookActions */
|
|
143
|
+
hookActions: UseHookActionsReturn;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Convenience wrapper that renders the ResolveHookModal using useHookActions state.
|
|
148
|
+
* Place this at the top level of your component (outside any iteration).
|
|
149
|
+
*/
|
|
150
|
+
export function HookResolveModalWrapper({
|
|
151
|
+
hookActions,
|
|
152
|
+
}: HookResolveModalProps): React.JSX.Element | null {
|
|
153
|
+
const { selectedHook, closeResolveModal, handleResolve, isResolving } =
|
|
154
|
+
hookActions;
|
|
155
|
+
|
|
156
|
+
return (
|
|
157
|
+
<ResolveHookModal
|
|
158
|
+
isOpen={selectedHook !== null}
|
|
159
|
+
onClose={closeResolveModal}
|
|
160
|
+
onSubmit={handleResolve}
|
|
161
|
+
isSubmitting={isResolving}
|
|
162
|
+
/>
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Re-export the modal for direct use
|
|
167
|
+
export { ResolveHookModal } from './sidebar/resolve-hook-modal';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './index';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export { ErrorBoundary } from './error-boundary';
|
|
2
|
+
export { EventListView } from './event-list-view';
|
|
3
|
+
export type {
|
|
4
|
+
HookActionCallbacks,
|
|
5
|
+
HookActionsDropdownItemProps,
|
|
6
|
+
HookResolveModalProps,
|
|
7
|
+
UseHookActionsOptions,
|
|
8
|
+
UseHookActionsReturn,
|
|
9
|
+
} from './hook-actions';
|
|
10
|
+
export {
|
|
11
|
+
HookResolveModalWrapper,
|
|
12
|
+
ResolveHookDropdownItem,
|
|
13
|
+
ResolveHookModal,
|
|
14
|
+
useHookActions,
|
|
15
|
+
} from './hook-actions';
|
|
16
|
+
export { RunTraceView } from './run-trace-view';
|
|
17
|
+
export { ConversationView } from './sidebar/conversation-view';
|
|
18
|
+
export { StreamViewer } from './stream-viewer';
|
|
19
|
+
export type { Span, SpanEvent } from './trace-viewer/types';
|
|
20
|
+
export {
|
|
21
|
+
WorkflowTraceViewer,
|
|
22
|
+
type SpanSelectionInfo,
|
|
23
|
+
} from './workflow-trace-view';
|