@railtownai/railtracks-visualizer 0.0.3 → 0.0.5

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.
Files changed (55) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +52 -23
  3. package/dist/cjs/index.js +55 -0
  4. package/dist/cjs/index.js.map +1 -0
  5. package/dist/esm/index.js +55 -0
  6. package/dist/esm/index.js.map +1 -0
  7. package/dist/{AgenticFlowVisualizer.d.ts → types/src/AgenticFlowVisualizer.d.ts} +2 -2
  8. package/dist/types/src/AgenticFlowVisualizer.d.ts.map +1 -0
  9. package/dist/types/src/App.d.ts.map +1 -0
  10. package/dist/types/src/Visualizer.d.ts +9 -0
  11. package/dist/types/src/Visualizer.d.ts.map +1 -0
  12. package/dist/types/src/components/Edge.d.ts.map +1 -0
  13. package/dist/types/src/components/FileSelector.d.ts.map +1 -0
  14. package/dist/types/src/components/Node.d.ts.map +1 -0
  15. package/dist/types/src/components/Timeline.d.ts.map +1 -0
  16. package/dist/types/src/components/VerticalTimeline.d.ts.map +1 -0
  17. package/dist/types/src/hooks/index.d.ts.map +1 -0
  18. package/dist/types/src/hooks/useApi.d.ts.map +1 -0
  19. package/dist/types/src/hooks/useFlowData.d.ts.map +1 -0
  20. package/dist/{index.d.ts → types/src/index.d.ts} +1 -2
  21. package/dist/types/src/index.d.ts.map +1 -0
  22. package/dist/types/tests/setup.d.ts +2 -0
  23. package/dist/types/tests/setup.d.ts.map +1 -0
  24. package/package.json +93 -75
  25. package/dist/AgenticFlowVisualizer.d.ts.map +0 -1
  26. package/dist/AgenticFlowVisualizer.js +0 -710
  27. package/dist/App.d.ts.map +0 -1
  28. package/dist/App.js +0 -89
  29. package/dist/components/Edge.d.ts.map +0 -1
  30. package/dist/components/Edge.js +0 -74
  31. package/dist/components/FileSelector.d.ts.map +0 -1
  32. package/dist/components/FileSelector.js +0 -24
  33. package/dist/components/Node.d.ts.map +0 -1
  34. package/dist/components/Node.js +0 -100
  35. package/dist/components/Timeline.d.ts.map +0 -1
  36. package/dist/components/Timeline.js +0 -118
  37. package/dist/components/VerticalTimeline.d.ts.map +0 -1
  38. package/dist/components/VerticalTimeline.js +0 -156
  39. package/dist/hooks/index.d.ts.map +0 -1
  40. package/dist/hooks/index.js +0 -2
  41. package/dist/hooks/useApi.d.ts.map +0 -1
  42. package/dist/hooks/useApi.js +0 -95
  43. package/dist/hooks/useFlowData.d.ts.map +0 -1
  44. package/dist/hooks/useFlowData.js +0 -66
  45. package/dist/index.d.ts.map +0 -1
  46. package/dist/index.js +0 -13
  47. /package/dist/{App.d.ts → types/src/App.d.ts} +0 -0
  48. /package/dist/{components → types/src/components}/Edge.d.ts +0 -0
  49. /package/dist/{components → types/src/components}/FileSelector.d.ts +0 -0
  50. /package/dist/{components → types/src/components}/Node.d.ts +0 -0
  51. /package/dist/{components → types/src/components}/Timeline.d.ts +0 -0
  52. /package/dist/{components → types/src/components}/VerticalTimeline.d.ts +0 -0
  53. /package/dist/{hooks → types/src/hooks}/index.d.ts +0 -0
  54. /package/dist/{hooks → types/src/hooks}/useApi.d.ts +0 -0
  55. /package/dist/{hooks → types/src/hooks}/useFlowData.d.ts +0 -0
package/dist/App.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../src/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,QAAA,MAAM,GAAG,EAAE,KAAK,CAAC,EA6HhB,CAAC;AAEF,eAAe,GAAG,CAAC"}
package/dist/App.js DELETED
@@ -1,89 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { ReactFlowProvider } from "reactflow";
3
- import { useFlowData } from "./hooks";
4
- import { FileSelector } from "./components/FileSelector";
5
- import AgenticFlowVisualizer from "./AgenticFlowVisualizer";
6
- const App = () => {
7
- const { availableFiles, currentFile, flowData, loading, error, loadFile, refreshFiles } = useFlowData();
8
- const handleFileSelect = (filename) => {
9
- loadFile(filename);
10
- };
11
- return (_jsxs("div", { className: "app", children: [_jsxs("div", { className: "app-header", children: [_jsx("h1", { children: "RailTracks Visualizer" }), _jsx("div", { className: "file-selector-container", children: _jsx(FileSelector, { files: availableFiles, currentFile: currentFile, onFileSelect: handleFileSelect, onRefresh: refreshFiles, loading: loading, disabled: loading }) })] }), error && (_jsx("div", { className: "error-message", children: _jsxs("p", { children: ["Error: ", error] }) })), _jsx("div", { className: "visualizer-container", children: loading ? (_jsxs("div", { className: "loading-state", children: [_jsx("div", { className: "loading-spinner" }), _jsx("p", { children: "Loading flow data..." })] })) : flowData ? (_jsx(ReactFlowProvider, { children: _jsx(AgenticFlowVisualizer, { flowData: flowData }) })) : (_jsx("div", { className: "no-data-state", children: _jsx("p", { children: "Please select a file to visualize the flow data" }) })) }), _jsx("style", { children: `
12
- .app {
13
- min-height: 100vh;
14
- background: #f9fafb;
15
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
16
- }
17
-
18
- .app-header {
19
- background: white;
20
- border-bottom: 1px solid #e5e7eb;
21
- padding: 5px;
22
- display: flex;
23
- align-items: center;
24
- justify-content: space-between;
25
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
26
- }
27
-
28
- .app-header h1 {
29
- margin: 0;
30
- font-size: 18px;
31
- font-weight: 600;
32
- color: #1f2937;
33
- }
34
-
35
- .file-selector-container {
36
- display: flex;
37
- align-items: center;
38
- }
39
-
40
- .error-message {
41
- background: #fee2e2;
42
- border: 1px solid #fecaca;
43
- color: #991b1b;
44
- padding: 12px 20px;
45
- margin: 20px;
46
- border-radius: 6px;
47
- font-size: 14px;
48
- }
49
-
50
- .visualizer-container {
51
- padding: 20px;
52
- min-height: calc(100vh - 100px);
53
- }
54
-
55
- .loading-state {
56
- display: flex;
57
- flex-direction: column;
58
- align-items: center;
59
- justify-content: center;
60
- height: 400px;
61
- color: #6b7280;
62
- }
63
-
64
- .loading-spinner {
65
- width: 40px;
66
- height: 40px;
67
- border: 4px solid #e5e7eb;
68
- border-top: 4px solid #6366f1;
69
- border-radius: 50%;
70
- animation: spin 1s linear infinite;
71
- margin-bottom: 16px;
72
- }
73
-
74
- @keyframes spin {
75
- 0% { transform: rotate(0deg); }
76
- 100% { transform: rotate(360deg); }
77
- }
78
-
79
- .no-data-state {
80
- display: flex;
81
- align-items: center;
82
- justify-content: center;
83
- height: 400px;
84
- color: #6b7280;
85
- font-size: 16px;
86
- }
87
- ` })] }));
88
- };
89
- export default App;
@@ -1 +0,0 @@
1
- {"version":3,"file":"Edge.d.ts","sourceRoot":"","sources":["../../src/components/Edge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAE5D,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,GAAG,CAAC;IACpB,cAAc,EAAE,GAAG,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,IAAI,CAAC,EAAE;QACL,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,GAAG,CAAC;KACf,CAAC;IACF,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnF,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;IACxC,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,CAAC;CACrC;AAED,eAAO,MAAM,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CA8JpC,CAAC"}
@@ -1,74 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useMemo, useState } from "react";
3
- export const Edge = ({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, style = {}, markerEnd, bidirectional = false, data, clientToSvgCoords, svgRef, onInspect }) => {
4
- const [isHovered, setIsHovered] = useState(false);
5
- // Function to determine stroke color based on edge state
6
- const getStrokeColor = () => {
7
- const state = data?.details?.state;
8
- switch (state) {
9
- case "Open":
10
- return "#000000"; // Black
11
- case "Completed":
12
- return "#15803d"; // Darker Green
13
- case "Error":
14
- return "#ef4444"; // Red
15
- default:
16
- return style.stroke || "#6366f1"; // Default color
17
- }
18
- };
19
- const [edgePath, arrowMarkers] = useMemo(() => {
20
- // Always use curved paths for better visual appeal
21
- const centerX = (sourceX + targetX) / 2;
22
- const centerY = (sourceY + targetY) / 2;
23
- const path = `M ${sourceX} ${sourceY} Q ${centerX} ${centerY} ${targetX} ${targetY}`;
24
- // Create arrow markers for bidirectional edges
25
- const markers = [];
26
- if (bidirectional) {
27
- const strokeColor = getStrokeColor();
28
- // Forward arrow (source to target)
29
- markers.push(_jsxs("defs", { children: [_jsx("marker", { id: `${id}-arrowhead-forward`, markerWidth: "10", markerHeight: "7", refX: "9", refY: "3.5", orient: "auto", markerUnits: "strokeWidth", children: _jsx("polygon", { points: "0 0, 10 3.5, 0 7", fill: strokeColor }) }), _jsx("marker", { id: `${id}-arrowhead-backward`, markerWidth: "10", markerHeight: "7", refX: "1", refY: "3.5", orient: "auto", markerUnits: "strokeWidth", children: _jsx("polygon", { points: "10 0, 0 3.5, 10 7", fill: strokeColor }) })] }, `${id}-markers`));
30
- }
31
- return [path, markers];
32
- }, [sourceX, sourceY, targetX, targetY, id, bidirectional, data?.details?.state]);
33
- const hoverStyle = {
34
- ...style,
35
- stroke: getStrokeColor(),
36
- strokeWidth: style.strokeWidth || 4,
37
- cursor: "pointer"
38
- };
39
- const handleInspectClick = (event) => {
40
- event.stopPropagation();
41
- if (onInspect && data) {
42
- onInspect(data);
43
- }
44
- };
45
- return (_jsxs("g", { "data-edge-id": id, children: [arrowMarkers, _jsx("path", { id: id, className: "react-flow__edge-path", d: edgePath, markerEnd: bidirectional ? `url(#${id}-arrowhead-forward)` : markerEnd, markerStart: bidirectional ? `url(#${id}-arrowhead-backward)` : undefined, style: hoverStyle }), data?.label && (_jsx("foreignObject", { x: (sourceX + targetX) / 2 - 50, y: (sourceY + targetY) / 2 - 20, width: "100", height: "40", style: { overflow: "visible", pointerEvents: "none" }, children: _jsx("div", { className: "edge-label-renderer", style: {
46
- display: "flex",
47
- alignItems: "center",
48
- justifyContent: "center",
49
- width: "100%",
50
- height: "100%",
51
- pointerEvents: "auto"
52
- }, children: _jsx("button", { className: "edge-label-button", onClick: handleInspectClick, style: {
53
- background: "#6366f1",
54
- color: "white",
55
- border: "none",
56
- borderRadius: 6,
57
- padding: "4px 12px",
58
- fontSize: 12,
59
- fontWeight: 600,
60
- cursor: "pointer",
61
- boxShadow: "0 2px 8px rgba(99,102,241,0.10)",
62
- transition: "background 0.2s"
63
- }, children: "Inspect" }) }) })), _jsx("style", { children: `
64
- .edge-label-renderer {
65
- z-index: 8001;
66
- user-select: none;
67
- pointer-events: auto;
68
- }
69
-
70
- .edge-label-button {
71
- pointer-events: auto;
72
- }
73
- ` })] }));
74
- };
@@ -1 +0,0 @@
1
- {"version":3,"file":"FileSelector.d.ts","sourceRoot":"","sources":["../../src/components/FileSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,UAAU,iBAAiB;IACzB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAsDpD,CAAC"}
@@ -1,24 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { RefreshCw } from "lucide-react";
3
- export const FileSelector = ({ files, currentFile, onFileSelect, onRefresh, loading = false, disabled = false }) => {
4
- const handleRefresh = (e) => {
5
- e.stopPropagation();
6
- onRefresh();
7
- };
8
- return (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [_jsxs("select", { value: currentFile || "", onChange: (e) => onFileSelect(e.target.value), disabled: disabled, style: {
9
- cursor: "pointer",
10
- padding: "8px 16px 8px 16px",
11
- borderRadius: "4px",
12
- fontSize: "14px",
13
- border: "1px solid #ccc",
14
- appearance: "none",
15
- WebkitAppearance: "none",
16
- MozAppearance: "none"
17
- }, children: [_jsx("option", { value: "", children: "Select a RailTracks Run..." }), files.map((file) => (_jsx("option", { value: file.name, children: file.name }, file.name)))] }), _jsx("button", { onClick: handleRefresh, disabled: loading || disabled, title: "Refresh files", style: {
18
- background: "none",
19
- border: "none",
20
- cursor: "pointer",
21
- padding: "4px",
22
- borderRadius: "4px"
23
- }, children: _jsx(RefreshCw, { size: 16, style: { animation: loading ? "spin 1s linear infinite" : "none" } }) })] }));
24
- };
@@ -1 +0,0 @@
1
- {"version":3,"file":"Node.d.ts","sourceRoot":"","sources":["../../src/components/Node.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,UAAU,QAAQ;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,CAAC;IACpC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;CACf;AAED,UAAU,SAAS;IACjB,IAAI,EAAE,QAAQ,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,QAAA,MAAM,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CA0H7B,CAAC;AAEF,OAAO,EAAE,IAAI,EAAE,CAAC;AAChB,YAAY,EAAE,QAAQ,EAAE,CAAC"}
@@ -1,100 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Handle, Position, useReactFlow } from "reactflow";
3
- const Node = ({ data, id }) => {
4
- const { fitView } = useReactFlow();
5
- // Check if this node has any outgoing edges (source edges)
6
- const hasOutgoingEdges = data.edges?.some((edge) => edge.source === id) || false;
7
- const handleNodeClick = () => {
8
- // Zoom to the node
9
- fitView({
10
- nodes: [{ id }],
11
- duration: 800,
12
- padding: 0.1,
13
- minZoom: 0.5,
14
- maxZoom: 1.5
15
- });
16
- // Open inspection drawer
17
- if (data.onInspect) {
18
- data.onInspect({
19
- label: data.label,
20
- description: data.description,
21
- nodeType: data.nodeType,
22
- step: data.step,
23
- time: data.time,
24
- icon: data.icon
25
- });
26
- }
27
- };
28
- return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "agent-node", onClick: handleNodeClick, style: { cursor: "pointer" }, children: [_jsx(Handle, { type: "target", position: Position.Top, style: { background: "#6366f1" } }), _jsxs("div", { className: "agent-header", children: [_jsx("div", { className: "agent-icon", children: data.icon || "📋" }), _jsx("div", { className: "agent-label", children: data.label })] }), data.description && _jsx("div", { className: "agent-description", children: data.description }), data.step && (_jsxs("div", { className: "agent-meta", children: [_jsxs("span", { className: "step", children: ["Step: ", data.step] }), data.time && _jsx("span", { className: "time", children: new Date(data.time * 1000).toLocaleTimeString() })] })), hasOutgoingEdges && _jsx(Handle, { type: "source", position: Position.Bottom, style: { background: "#6366f1" } })] }), _jsx("style", { children: `
29
- .agent-node {
30
- padding: 12px;
31
- border-radius: 8px;
32
- background: white;
33
- border: 2px solid #e5e7eb;
34
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
35
- min-width: 200px;
36
- max-width: 250px;
37
- transition: all 0.2s ease;
38
- position: relative;
39
- z-index: -5;
40
- }
41
-
42
- .agent-node:hover {
43
- border-color: #6366f1;
44
- box-shadow: 0 4px 8px rgba(99, 102, 241, 0.2);
45
- }
46
-
47
- .agent-header {
48
- display: flex;
49
- align-items: center;
50
- gap: 8px;
51
- margin-bottom: 8px;
52
- }
53
-
54
- .agent-icon {
55
- font-size: 20px;
56
- }
57
-
58
- .agent-label {
59
- font-weight: 600;
60
- color: #1f2937;
61
- font-size: 14px;
62
- word-break: break-word;
63
- }
64
-
65
- .agent-description {
66
- color: #6b7280;
67
- font-size: 12px;
68
- line-height: 1.4;
69
- word-break: break-word;
70
- white-space: pre-line;
71
- }
72
-
73
- .agent-meta {
74
- margin-top: 8px;
75
- padding-top: 8px;
76
- border-top: 1px solid #e5e7eb;
77
- display: flex;
78
- justify-content: space-between;
79
- font-size: 10px;
80
- color: #9ca3af;
81
- }
82
-
83
- .step {
84
- background: #f3f4f6;
85
- padding: 2px 6px;
86
- border-radius: 4px;
87
- }
88
-
89
- .time {
90
- font-family: monospace;
91
- }
92
-
93
- .react-flow__handle {
94
- width: 8px;
95
- height: 8px;
96
- border: 2px solid #6366f1;
97
- }
98
- ` })] }));
99
- };
100
- export { Node };
@@ -1 +0,0 @@
1
- {"version":3,"file":"Timeline.d.ts","sourceRoot":"","sources":["../../src/components/Timeline.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAEzC,UAAU,aAAa;IACrB,MAAM,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,QAAA,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA4KrC,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -1,118 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect } from "react";
3
- const Timeline = ({ stamps, currentStep, isPlaying, onStepChange, onPlayPause }) => {
4
- const maxStep = stamps.length > 0 ? Math.max(...stamps.map((s) => s.step)) : 0;
5
- const minStep = stamps.length > 0 ? Math.min(...stamps.map((s) => s.step)) : 0;
6
- const totalSteps = maxStep - minStep + 1;
7
- // Initialize Bootstrap tooltips
8
- useEffect(() => {
9
- // Initialize all tooltips
10
- const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]');
11
- const tooltipList = Array.from(tooltipTriggerList).map((tooltipTriggerEl) => new window.bootstrap.Tooltip(tooltipTriggerEl));
12
- // Cleanup function to dispose tooltips
13
- return () => {
14
- tooltipList.forEach((tooltip) => tooltip.dispose());
15
- };
16
- }, [stamps, currentStep]); // Re-initialize when stamps or currentStep changes
17
- return (_jsxs("div", { style: {
18
- position: "absolute",
19
- bottom: 0,
20
- left: 0,
21
- right: 0,
22
- height: "60px",
23
- backgroundColor: "white",
24
- borderTop: "1px solid #e5e7eb",
25
- display: "flex",
26
- alignItems: "center",
27
- padding: "0 16px",
28
- gap: "12px",
29
- zIndex: 10
30
- }, children: [_jsx("button", { onClick: onPlayPause, style: {
31
- width: "32px",
32
- height: "32px",
33
- borderRadius: "50%",
34
- border: "1px solid #d1d5db",
35
- backgroundColor: "white",
36
- display: "flex",
37
- alignItems: "center",
38
- justifyContent: "center",
39
- cursor: "pointer",
40
- transition: "all 0.2s ease"
41
- }, onMouseEnter: (e) => {
42
- e.currentTarget.style.backgroundColor = "#f3f4f6";
43
- }, onMouseLeave: (e) => {
44
- e.currentTarget.style.backgroundColor = "white";
45
- }, children: isPlaying ? (_jsxs("div", { style: { display: "flex", gap: "2px" }, children: [_jsx("div", { style: {
46
- width: "3px",
47
- height: "12px",
48
- backgroundColor: "#374151"
49
- } }), _jsx("div", { style: {
50
- width: "3px",
51
- height: "12px",
52
- backgroundColor: "#374151"
53
- } })] })) : (_jsx("div", { style: {
54
- width: 0,
55
- height: 0,
56
- borderLeft: "8px solid #374151",
57
- borderTop: "6px solid transparent",
58
- borderBottom: "6px solid transparent",
59
- marginLeft: "2px"
60
- } })) }), _jsx("div", { style: {
61
- flex: 1,
62
- display: "flex",
63
- alignItems: "center",
64
- gap: "8px",
65
- padding: "0 8px"
66
- }, children: Array.from({ length: totalSteps }, (_, index) => {
67
- const step = minStep + index;
68
- const isActive = step === currentStep;
69
- const isPast = step < currentStep;
70
- const hasStep = stamps.some((s) => s.step === step);
71
- // Determine background color based on step state
72
- let backgroundColor = "white";
73
- if (isActive) {
74
- backgroundColor = "#6366f1";
75
- }
76
- else if (isPast) {
77
- backgroundColor = hasStep ? "#fef3c7" : "#fef3c7"; // Light yellow for past steps
78
- }
79
- else if (hasStep) {
80
- backgroundColor = "#e5e7eb";
81
- }
82
- const tooltipText = `Step ${step}${hasStep ? ` - ${stamps.find((s) => s.step === step)?.identifier || ""}` : " - No activity"}`;
83
- return (_jsx("button", { onClick: () => onStepChange(step), "data-bs-toggle": "tooltip", "data-bs-placement": "top", "data-bs-title": tooltipText, style: {
84
- width: "16px",
85
- height: "16px",
86
- borderRadius: "50%",
87
- border: isActive ? "2px solid #6366f1" : "1px solid #d1d5db",
88
- backgroundColor: backgroundColor,
89
- cursor: "pointer",
90
- transition: "all 0.2s ease",
91
- position: "relative"
92
- }, onMouseEnter: (e) => {
93
- if (!isActive) {
94
- if (isPast) {
95
- e.currentTarget.style.backgroundColor = hasStep ? "#fde68a" : "#fde68a"; // Darker yellow on hover for past steps
96
- }
97
- else {
98
- e.currentTarget.style.backgroundColor = hasStep ? "#d1d5db" : "#f3f4f6";
99
- }
100
- }
101
- }, onMouseLeave: (e) => {
102
- if (!isActive) {
103
- if (isPast) {
104
- e.currentTarget.style.backgroundColor = hasStep ? "#fef3c7" : "#fef3c7"; // Back to light yellow for past steps
105
- }
106
- else {
107
- e.currentTarget.style.backgroundColor = hasStep ? "#e5e7eb" : "white";
108
- }
109
- }
110
- } }, step));
111
- }) }), _jsxs("div", { style: {
112
- fontSize: "12px",
113
- color: "#6b7280",
114
- minWidth: "60px",
115
- textAlign: "right"
116
- }, children: [currentStep, " / ", maxStep] })] }));
117
- };
118
- export { Timeline };
@@ -1 +0,0 @@
1
- {"version":3,"file":"VerticalTimeline.d.ts","sourceRoot":"","sources":["../../src/components/VerticalTimeline.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,UAAU,MAAM;IACd,MAAM,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,QAAA,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,MAAM,CAkPtC,CAAC;AAEF,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
@@ -1,156 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { PanelLeft } from "lucide-react";
3
- const VerticalTimeline = ({ stamps, currentStep, onStepChange, onToggle }) => {
4
- const maxStep = stamps.length > 0 ? Math.max(...stamps.map((s) => s.step)) : 0;
5
- const minStep = stamps.length > 0 ? Math.min(...stamps.map((s) => s.step)) : 0;
6
- const totalSteps = maxStep - minStep + 1;
7
- // Calculate latency for each step
8
- const getStepLatency = (step) => {
9
- const stepStamps = stamps.filter((s) => s.step === step);
10
- if (stepStamps.length === 0)
11
- return null;
12
- // Calculate time difference from previous step
13
- const prevStep = step - 1;
14
- const prevStepStamps = stamps.filter((s) => s.step === prevStep);
15
- if (prevStepStamps.length === 0)
16
- return null;
17
- const currentTime = Math.min(...stepStamps.map((s) => s.time));
18
- const prevTime = Math.max(...prevStepStamps.map((s) => s.time));
19
- return currentTime - prevTime;
20
- };
21
- // Get step label
22
- const getStepLabel = (step) => {
23
- const stepStamps = stamps.filter((s) => s.step === step);
24
- if (stepStamps.length === 0)
25
- return `Step ${step}`;
26
- // Get the first identifier for this step
27
- const identifier = stepStamps[0]?.identifier || "";
28
- return identifier || `Step ${step}`;
29
- };
30
- // Format latency
31
- const formatLatency = (latency) => {
32
- if (latency < 1000) {
33
- return `${latency.toFixed(0)}ms`;
34
- }
35
- else if (latency < 60000) {
36
- return `${(latency / 1000).toFixed(1)}s`;
37
- }
38
- else {
39
- return `${(latency / 60000).toFixed(1)}m`;
40
- }
41
- };
42
- return (_jsxs("div", { style: {
43
- width: "100%",
44
- height: "100%",
45
- backgroundColor: "white",
46
- display: "flex",
47
- flexDirection: "column",
48
- overflow: "hidden"
49
- }, children: [_jsxs("div", { style: {
50
- padding: "16px",
51
- borderBottom: "1px solid #e5e7eb",
52
- backgroundColor: "#f9fafb",
53
- display: "flex",
54
- justifyContent: "space-between",
55
- alignItems: "flex-start"
56
- }, children: [_jsxs("div", { children: [_jsx("h3", { style: {
57
- margin: 0,
58
- fontSize: "16px",
59
- fontWeight: 600,
60
- color: "#1f2937"
61
- }, children: "Timeline" }), _jsx("p", { style: {
62
- margin: "4px 0 0 0",
63
- fontSize: "12px",
64
- color: "#6b7280"
65
- }, children: "Click to jump to step" })] }), onToggle && (_jsx("button", { onClick: onToggle, style: {
66
- border: "none",
67
- background: "none",
68
- cursor: "pointer",
69
- color: "#6b7280",
70
- padding: "4px",
71
- display: "flex",
72
- alignItems: "center",
73
- justifyContent: "center",
74
- transition: "color 0.2s ease"
75
- }, title: "Collapse Panel", children: _jsx(PanelLeft, { size: 16 }) }))] }), _jsx("div", { style: {
76
- flex: 1,
77
- overflowY: "auto",
78
- padding: "8px 0 16px 0" // Add bottom padding
79
- }, children: Array.from({ length: totalSteps }, (_, index) => {
80
- const step = minStep + index;
81
- const isActive = step === currentStep;
82
- const isPast = step < currentStep;
83
- const hasStep = stamps.some((s) => s.step === step);
84
- const latency = getStepLatency(step);
85
- const label = getStepLabel(step);
86
- return (_jsxs("div", { onClick: () => hasStep && onStepChange(step), style: {
87
- padding: "12px 16px",
88
- borderBottom: "1px solid #f3f4f6",
89
- cursor: hasStep ? "pointer" : "default",
90
- backgroundColor: isActive ? "#f0f9ff" : "transparent",
91
- borderLeft: isActive ? "4px solid #6366f1" : "4px solid transparent",
92
- transition: "all 0.2s ease",
93
- position: "relative"
94
- }, onMouseEnter: (e) => {
95
- if (hasStep && !isActive) {
96
- e.currentTarget.style.backgroundColor = "#f8fafc";
97
- }
98
- }, onMouseLeave: (e) => {
99
- if (hasStep && !isActive) {
100
- e.currentTarget.style.backgroundColor = "transparent";
101
- }
102
- }, children: [_jsxs("div", { style: {
103
- display: "flex",
104
- alignItems: "center",
105
- gap: "8px",
106
- marginBottom: "4px"
107
- }, children: [_jsx("div", { style: {
108
- width: "12px",
109
- height: "12px",
110
- borderRadius: "50%",
111
- backgroundColor: isActive ? "#6366f1" : isPast ? "#fbbf24" : hasStep ? "#9ca3af" : "#e5e7eb",
112
- border: isActive ? "2px solid #6366f1" : "1px solid #d1d5db",
113
- flexShrink: 0
114
- } }), _jsxs("span", { style: {
115
- fontSize: "14px",
116
- fontWeight: isActive ? 600 : 500,
117
- color: isActive ? "#1f2937" : "#6b7280"
118
- }, children: ["Step ", step] }), latency && (_jsx("span", { style: {
119
- fontSize: "11px",
120
- color: "#9ca3af",
121
- backgroundColor: "#f3f4f6",
122
- padding: "2px 6px",
123
- borderRadius: "4px",
124
- marginLeft: "auto"
125
- }, children: formatLatency(latency) }))] }), _jsx("div", { style: {
126
- fontSize: "13px",
127
- color: hasStep ? "#1f2937" : "#9ca3af",
128
- lineHeight: "1.4",
129
- wordBreak: "break-word",
130
- fontStyle: hasStep ? "normal" : "italic"
131
- }, children: hasStep ? label : "No activity" }), isActive && (_jsx("div", { style: {
132
- position: "absolute",
133
- right: "8px",
134
- top: "50%",
135
- transform: "translateY(-50%)",
136
- width: "6px",
137
- height: "6px",
138
- borderRadius: "50%",
139
- backgroundColor: "#6366f1",
140
- animation: "pulse 2s infinite"
141
- } }))] }, step));
142
- }) }), _jsx("style", { children: `
143
- @keyframes pulse {
144
- 0% {
145
- opacity: 1;
146
- }
147
- 50% {
148
- opacity: 0.5;
149
- }
150
- 100% {
151
- opacity: 1;
152
- }
153
- }
154
- ` })] }));
155
- };
156
- export { VerticalTimeline };
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACnD,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
@@ -1,2 +0,0 @@
1
- export { useApi } from "./useApi";
2
- export { useFlowData } from "./useFlowData";
@@ -1 +0,0 @@
1
- {"version":3,"file":"useApi.d.ts","sourceRoot":"","sources":["../../src/hooks/useApi.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,MAAM;;;yBAK2B,OAAO,CAAC,QAAQ,EAAE,CAAC;6BA6Bb,MAAM,KAAG,OAAO,CAAC,GAAG,CAAC;0BAyB1B,OAAO,CAAC,GAAG,CAAC;CAiC1D,CAAC"}