@mesantosrai/pipeline-canvas 1.0.0
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/LICENSE +21 -0
- package/README.md +545 -0
- package/dist/_virtual/dynamic-import-helper.mjs +17 -0
- package/dist/_virtual/dynamic-import-helper.mjs.map +1 -0
- package/dist/components/CustomHandle.d.ts +9 -0
- package/dist/components/CustomHandle.d.ts.map +1 -0
- package/dist/components/CustomHandle.mjs +18 -0
- package/dist/components/CustomHandle.mjs.map +1 -0
- package/dist/components/ExecutionLogsPanel.d.ts +3 -0
- package/dist/components/ExecutionLogsPanel.d.ts.map +1 -0
- package/dist/components/ExecutionLogsPanel.mjs +189 -0
- package/dist/components/ExecutionLogsPanel.mjs.map +1 -0
- package/dist/components/NodeContextMenu.d.ts +15 -0
- package/dist/components/NodeContextMenu.d.ts.map +1 -0
- package/dist/components/NodeContextMenu.mjs +110 -0
- package/dist/components/NodeContextMenu.mjs.map +1 -0
- package/dist/components/PipelineCanvas.d.ts +4 -0
- package/dist/components/PipelineCanvas.d.ts.map +1 -0
- package/dist/components/PipelineCanvas.mjs +1016 -0
- package/dist/components/PipelineCanvas.mjs.map +1 -0
- package/dist/components/PipelineCanvasProvider.d.ts +30 -0
- package/dist/components/PipelineCanvasProvider.d.ts.map +1 -0
- package/dist/components/PipelineCanvasProvider.mjs +7 -0
- package/dist/components/PipelineCanvasProvider.mjs.map +1 -0
- package/dist/components/PipelineExecution.d.ts +16 -0
- package/dist/components/PipelineExecution.d.ts.map +1 -0
- package/dist/components/PipelineExecution.mjs +310 -0
- package/dist/components/PipelineExecution.mjs.map +1 -0
- package/dist/components/PipelineManager.d.ts +8 -0
- package/dist/components/PipelineManager.d.ts.map +1 -0
- package/dist/components/PipelineManager.mjs +143 -0
- package/dist/components/PipelineManager.mjs.map +1 -0
- package/dist/components/PipelineNodeConfig.d.ts +11 -0
- package/dist/components/PipelineNodeConfig.d.ts.map +1 -0
- package/dist/components/PipelineNodeConfig.mjs +1808 -0
- package/dist/components/PipelineNodeConfig.mjs.map +1 -0
- package/dist/components/PipelineNodePalette.d.ts +3 -0
- package/dist/components/PipelineNodePalette.d.ts.map +1 -0
- package/dist/components/PipelineNodePalette.mjs +87 -0
- package/dist/components/PipelineNodePalette.mjs.map +1 -0
- package/dist/components/SavePipelineDialog.d.ts +9 -0
- package/dist/components/SavePipelineDialog.d.ts.map +1 -0
- package/dist/components/SavePipelineDialog.mjs +140 -0
- package/dist/components/SavePipelineDialog.mjs.map +1 -0
- package/dist/components/SavedPipelinesList.d.ts +3 -0
- package/dist/components/SavedPipelinesList.d.ts.map +1 -0
- package/dist/components/SavedPipelinesList.mjs +172 -0
- package/dist/components/SavedPipelinesList.mjs.map +1 -0
- package/dist/components/index.d.ts +8 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/ui/alert.d.ts +9 -0
- package/dist/components/ui/alert.d.ts.map +1 -0
- package/dist/components/ui/alert.mjs +51 -0
- package/dist/components/ui/alert.mjs.map +1 -0
- package/dist/components/ui/button.d.ts +12 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/button.mjs +45 -0
- package/dist/components/ui/button.mjs.map +1 -0
- package/dist/components/ui/dialog.d.ts +20 -0
- package/dist/components/ui/dialog.d.ts.map +1 -0
- package/dist/components/ui/dialog.mjs +99 -0
- package/dist/components/ui/dialog.mjs.map +1 -0
- package/dist/components/ui/index.d.ts +8 -0
- package/dist/components/ui/index.d.ts.map +1 -0
- package/dist/components/ui/input.d.ts +6 -0
- package/dist/components/ui/input.d.ts.map +1 -0
- package/dist/components/ui/input.mjs +22 -0
- package/dist/components/ui/input.mjs.map +1 -0
- package/dist/components/ui/label.d.ts +6 -0
- package/dist/components/ui/label.d.ts.map +1 -0
- package/dist/components/ui/label.mjs +20 -0
- package/dist/components/ui/label.mjs.map +1 -0
- package/dist/components/ui/select.d.ts +14 -0
- package/dist/components/ui/select.d.ts.map +1 -0
- package/dist/components/ui/select.mjs +121 -0
- package/dist/components/ui/select.mjs.map +1 -0
- package/dist/components/ui/tooltip.d.ts +8 -0
- package/dist/components/ui/tooltip.d.ts.map +1 -0
- package/dist/components/ui/tooltip.mjs +24 -0
- package/dist/components/ui/tooltip.mjs.map +1 -0
- package/dist/context/PipelineContext.d.ts +50 -0
- package/dist/context/PipelineContext.d.ts.map +1 -0
- package/dist/context/PipelineContext.mjs +36 -0
- package/dist/context/PipelineContext.mjs.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +45 -0
- package/dist/index.mjs.map +1 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.mjs +9 -0
- package/dist/lib/utils.mjs.map +1 -0
- package/dist/node_modules/zustand/esm/middleware.mjs +256 -0
- package/dist/node_modules/zustand/esm/middleware.mjs.map +1 -0
- package/dist/nodes/alphafold_node/node.json.mjs +82 -0
- package/dist/nodes/alphafold_node/node.json.mjs.map +1 -0
- package/dist/nodes/http_request_node/node.json.mjs +383 -0
- package/dist/nodes/http_request_node/node.json.mjs.map +1 -0
- package/dist/nodes/input_node/node.json.mjs +51 -0
- package/dist/nodes/input_node/node.json.mjs.map +1 -0
- package/dist/nodes/message_input_node/node.json.mjs +90 -0
- package/dist/nodes/message_input_node/node.json.mjs.map +1 -0
- package/dist/nodes/proteinmpnn_node/node.json.mjs +83 -0
- package/dist/nodes/proteinmpnn_node/node.json.mjs.map +1 -0
- package/dist/nodes/rfdiffusion_node/node.json.mjs +281 -0
- package/dist/nodes/rfdiffusion_node/node.json.mjs.map +1 -0
- package/dist/store/pipelineStore.d.ts +108 -0
- package/dist/store/pipelineStore.d.ts.map +1 -0
- package/dist/store/pipelineStore.mjs +633 -0
- package/dist/store/pipelineStore.mjs.map +1 -0
- package/dist/style.css +1 -0
- package/dist/types/dependencies.d.ts +93 -0
- package/dist/types/dependencies.d.ts.map +1 -0
- package/dist/types/index.d.ts +56 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/logger.d.ts +67 -0
- package/dist/types/logger.d.ts.map +1 -0
- package/dist/types/logger.mjs +22 -0
- package/dist/types/logger.mjs.map +1 -0
- package/dist/utils/executionEngine.d.ts +27 -0
- package/dist/utils/executionEngine.d.ts.map +1 -0
- package/dist/utils/executionEngine.mjs +461 -0
- package/dist/utils/executionEngine.mjs.map +1 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/logger.d.ts +23 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.mjs +29 -0
- package/dist/utils/logger.mjs.map +1 -0
- package/dist/utils/nodeLoader.d.ts +76 -0
- package/dist/utils/nodeLoader.d.ts.map +1 -0
- package/dist/utils/nodeLoader.mjs +48 -0
- package/dist/utils/nodeLoader.mjs.map +1 -0
- package/dist/utils/templateResolver.d.ts +10 -0
- package/dist/utils/templateResolver.d.ts.map +1 -0
- package/dist/utils/templateResolver.mjs +64 -0
- package/dist/utils/templateResolver.mjs.map +1 -0
- package/dist/utils/topologicalSort.d.ts +10 -0
- package/dist/utils/topologicalSort.d.ts.map +1 -0
- package/dist/utils/topologicalSort.mjs +25 -0
- package/dist/utils/topologicalSort.mjs.map +1 -0
- package/nodes/alphafold_node/node.json +77 -0
- package/nodes/http_request_node/node.json +311 -0
- package/nodes/input_node/node.json +47 -0
- package/nodes/message_input_node/node.json +56 -0
- package/nodes/proteinmpnn_node/node.json +78 -0
- package/nodes/rfdiffusion_node/node.json +231 -0
- package/package.json +94 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { jsxs as m, jsx as u } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect as H } from "react";
|
|
3
|
+
import { usePipelineStore as d } from "../store/pipelineStore.mjs";
|
|
4
|
+
import { usePipelineContext as U } from "../context/PipelineContext.mjs";
|
|
5
|
+
import { Loader2 as K, CheckCircle2 as X, XCircle as B, AlertCircle as G } from "lucide-react";
|
|
6
|
+
import { executeNode as Q } from "../utils/executionEngine.mjs";
|
|
7
|
+
const se = ({ apiClient: b }) => {
|
|
8
|
+
const {
|
|
9
|
+
currentPipeline: l,
|
|
10
|
+
isExecuting: _,
|
|
11
|
+
executionOrder: x,
|
|
12
|
+
updateNodeStatus: N,
|
|
13
|
+
stopExecution: z
|
|
14
|
+
} = d(), { sessionId: J } = U(), y = J;
|
|
15
|
+
if (H(() => {
|
|
16
|
+
y ? console.log("[PipelineExecution] Active session ID:", y) : console.warn("[PipelineExecution] No active session ID found");
|
|
17
|
+
}, [y]), H(() => {
|
|
18
|
+
if (!_ || !l || x.length === 0)
|
|
19
|
+
return;
|
|
20
|
+
const a = x.some((w) => {
|
|
21
|
+
const h = l.nodes.find((v) => v.id === w);
|
|
22
|
+
return (h == null ? void 0 : h.type) === "input_node";
|
|
23
|
+
});
|
|
24
|
+
!b && !a && console.warn("[PipelineExecution] apiClient not provided but may be required for node execution");
|
|
25
|
+
let S = !1;
|
|
26
|
+
return (async () => {
|
|
27
|
+
var w, h, v, $, T, k, I, A, L, O, D, M;
|
|
28
|
+
console.log("[PipelineExecution] Starting execution:", {
|
|
29
|
+
executionOrder: x,
|
|
30
|
+
nodeCount: x.length,
|
|
31
|
+
hasApiClient: !!b
|
|
32
|
+
});
|
|
33
|
+
for (const i of x) {
|
|
34
|
+
if (S) break;
|
|
35
|
+
const o = l.nodes.find((s) => s.id === i);
|
|
36
|
+
if (!o) {
|
|
37
|
+
console.warn(`[PipelineExecution] Node ${i} not found`);
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (console.log(`[PipelineExecution] Processing node ${i} (${o.type}):`, {
|
|
41
|
+
status: o.status,
|
|
42
|
+
label: o.label
|
|
43
|
+
}), o.status === "success" || o.status === "completed") {
|
|
44
|
+
console.log(`[PipelineExecution] Skipping ${i} - already completed`);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const p = {};
|
|
48
|
+
o.config && (p.config = o.config);
|
|
49
|
+
try {
|
|
50
|
+
N(i, "running");
|
|
51
|
+
const s = Date.now();
|
|
52
|
+
let t;
|
|
53
|
+
try {
|
|
54
|
+
t = await Q(o, {
|
|
55
|
+
pipeline: l,
|
|
56
|
+
apiClient: b || {
|
|
57
|
+
post: async () => {
|
|
58
|
+
throw new Error("apiClient not available");
|
|
59
|
+
},
|
|
60
|
+
get: async () => {
|
|
61
|
+
throw new Error("apiClient not available");
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
sessionId: y
|
|
65
|
+
});
|
|
66
|
+
} catch (n) {
|
|
67
|
+
throw console.error(`[PipelineExecution] Error executing node ${i}:`, n), n;
|
|
68
|
+
}
|
|
69
|
+
const f = Date.now() - s;
|
|
70
|
+
let e;
|
|
71
|
+
try {
|
|
72
|
+
e = (t == null ? void 0 : t.data) || t, e && typeof e != "object" && (console.warn(`[PipelineExecution] Unexpected result type for node ${i}:`, typeof e, e), e = { value: e });
|
|
73
|
+
} catch (n) {
|
|
74
|
+
console.error(`[PipelineExecution] Error extracting result for node ${i}:`, n), e = { error: "Failed to extract result" };
|
|
75
|
+
}
|
|
76
|
+
if (e)
|
|
77
|
+
try {
|
|
78
|
+
const n = {};
|
|
79
|
+
if (o.type === "input_node" && e.data)
|
|
80
|
+
n.file_info = e.data, n.type = e.data.type || "pdb_file", n.filename = e.data.filename, n.file_id = e.data.file_id, n.file_url = e.data.file_url, n.data = e.data;
|
|
81
|
+
else if (o.type === "rfdiffusion_node") {
|
|
82
|
+
const g = e.filepath || ((w = e.data) == null ? void 0 : w.filepath), E = e.filename || ((h = e.data) == null ? void 0 : h.filename), F = e.output_pdb || ((v = e.data) == null ? void 0 : v.pdbContent);
|
|
83
|
+
g && (n.output_file = {
|
|
84
|
+
type: "pdb_file",
|
|
85
|
+
filename: E || `rfdiffusion_${o.id}.pdb`,
|
|
86
|
+
filepath: g,
|
|
87
|
+
file_id: o.id,
|
|
88
|
+
// Use node ID as file identifier
|
|
89
|
+
// Store relative path from server directory (e.g., "rfdiffusion_results/rfdiffusion_xxx.pdb")
|
|
90
|
+
file_url: `/api/files/${g}`
|
|
91
|
+
}, n.filepath = g, n.filename = E), F && (n.pdbContent = F), e.data && (n.data = e.data);
|
|
92
|
+
} else
|
|
93
|
+
(e.output_file || e.file) && (n.output_file = e.output_file || e.file), e.sequence && (n.sequence = e.sequence), e.message && (n.message = e.message), e.data && (n.data = e.data), Object.keys(n).length === 0 && typeof e == "object" && Object.assign(n, e);
|
|
94
|
+
d.getState().updateNode(i, {
|
|
95
|
+
result_metadata: n
|
|
96
|
+
}), o.type === "rfdiffusion_node" && n.filepath && (console.log("[PipelineExecution] RFdiffusion completed, triggering file refresh. Active session:", y), setTimeout(() => {
|
|
97
|
+
window.dispatchEvent(new CustomEvent("session-file-added")), console.log("[PipelineExecution] Dispatched session-file-added event");
|
|
98
|
+
}, 1e3));
|
|
99
|
+
} catch (n) {
|
|
100
|
+
console.error(`[PipelineExecution] Error storing metadata for node ${i}:`, n);
|
|
101
|
+
}
|
|
102
|
+
N(i, "completed"), l && window.dispatchEvent(new CustomEvent("pipeline-node-completed", {
|
|
103
|
+
detail: {
|
|
104
|
+
pipelineId: l.id,
|
|
105
|
+
nodeId: i,
|
|
106
|
+
status: "completed",
|
|
107
|
+
result: e
|
|
108
|
+
}
|
|
109
|
+
}));
|
|
110
|
+
const c = ($ = d.getState().currentPipeline) == null ? void 0 : $.nodes.find((n) => n.id === i);
|
|
111
|
+
console.log(`[PipelineExecution] Node ${i} final state:`, {
|
|
112
|
+
status: c == null ? void 0 : c.status,
|
|
113
|
+
hasResultMetadata: !!(c != null && c.result_metadata && Object.keys(c.result_metadata).length > 0),
|
|
114
|
+
resultMetadataKeys: c != null && c.result_metadata ? Object.keys(c.result_metadata) : []
|
|
115
|
+
});
|
|
116
|
+
const P = (T = d.getState().currentExecution) == null ? void 0 : T.logs.find(
|
|
117
|
+
(n) => n.nodeId === i
|
|
118
|
+
);
|
|
119
|
+
o.type === "http_request_node" && console.log("[PipelineExecution] HTTP Request result:", {
|
|
120
|
+
nodeId: i,
|
|
121
|
+
hasExecutionResult: !!t,
|
|
122
|
+
executionResultKeys: t ? Object.keys(t) : [],
|
|
123
|
+
hasData: !!(t != null && t.data),
|
|
124
|
+
hasRequest: !!(t != null && t.request),
|
|
125
|
+
hasResponse: !!(t != null && t.response),
|
|
126
|
+
resultType: typeof e,
|
|
127
|
+
resultKeys: e && typeof e == "object" ? Object.keys(e) : null,
|
|
128
|
+
responseData: (k = t == null ? void 0 : t.response) == null ? void 0 : k.data
|
|
129
|
+
}), P ? d.getState().updateExecutionLog(i, {
|
|
130
|
+
output: e,
|
|
131
|
+
input: p,
|
|
132
|
+
request: t == null ? void 0 : t.request,
|
|
133
|
+
response: t == null ? void 0 : t.response,
|
|
134
|
+
duration: f
|
|
135
|
+
// Ensure duration is set
|
|
136
|
+
}) : d.getState().addExecutionLog({
|
|
137
|
+
nodeId: i,
|
|
138
|
+
nodeLabel: o.label,
|
|
139
|
+
nodeType: o.type,
|
|
140
|
+
status: "completed",
|
|
141
|
+
completedAt: /* @__PURE__ */ new Date(),
|
|
142
|
+
duration: f,
|
|
143
|
+
output: e,
|
|
144
|
+
input: p,
|
|
145
|
+
request: t == null ? void 0 : t.request,
|
|
146
|
+
response: t == null ? void 0 : t.response
|
|
147
|
+
}), console.log(`[PipelineExecution] Node ${i} completed successfully`);
|
|
148
|
+
} catch (s) {
|
|
149
|
+
console.error(`[PipelineExecution] Error in node ${i} (${o.type}):`, s);
|
|
150
|
+
const t = s.response, r = t == null ? void 0 : t.data, f = (r == null ? void 0 : r.error) || (r == null ? void 0 : r.detail) || ((I = r == null ? void 0 : r.data) == null ? void 0 : I.detail) || ((L = (A = r == null ? void 0 : r.response) == null ? void 0 : A.data) == null ? void 0 : L.detail) || s.message;
|
|
151
|
+
console.error("[PipelineExecution] Error details:", {
|
|
152
|
+
message: s.message,
|
|
153
|
+
stack: s.stack,
|
|
154
|
+
response: t,
|
|
155
|
+
responseData: r,
|
|
156
|
+
responseStatus: t == null ? void 0 : t.status,
|
|
157
|
+
errorMessage: f,
|
|
158
|
+
fullErrorData: JSON.stringify(r, null, 2)
|
|
159
|
+
}), f && f !== s.message && console.error(`[PipelineExecution] Server Error Message: ${f}`);
|
|
160
|
+
const e = Date.now(), c = (D = (O = d.getState().currentExecution) == null ? void 0 : O.logs.find(
|
|
161
|
+
(E) => E.nodeId === i
|
|
162
|
+
)) == null ? void 0 : D.startedAt, P = c ? e - new Date(c).getTime() : 0;
|
|
163
|
+
N(i, "error", s.message || "Execution failed"), l && window.dispatchEvent(new CustomEvent("pipeline-node-completed", {
|
|
164
|
+
detail: {
|
|
165
|
+
pipelineId: l.id,
|
|
166
|
+
nodeId: i,
|
|
167
|
+
status: "error",
|
|
168
|
+
error: s.message || "Execution failed"
|
|
169
|
+
}
|
|
170
|
+
}));
|
|
171
|
+
const n = (M = d.getState().currentExecution) == null ? void 0 : M.logs.find(
|
|
172
|
+
(E) => E.nodeId === i
|
|
173
|
+
), g = s.response || (s.response ? {
|
|
174
|
+
status: s.response.status,
|
|
175
|
+
statusText: s.response.statusText,
|
|
176
|
+
data: s.response.data
|
|
177
|
+
} : void 0);
|
|
178
|
+
n ? d.getState().updateExecutionLog(i, {
|
|
179
|
+
input: p,
|
|
180
|
+
request: s.request,
|
|
181
|
+
response: g,
|
|
182
|
+
duration: P
|
|
183
|
+
// Ensure duration is set
|
|
184
|
+
}) : d.getState().addExecutionLog({
|
|
185
|
+
nodeId: i,
|
|
186
|
+
nodeLabel: o.label,
|
|
187
|
+
nodeType: o.type,
|
|
188
|
+
status: "error",
|
|
189
|
+
completedAt: /* @__PURE__ */ new Date(),
|
|
190
|
+
duration: P,
|
|
191
|
+
error: s.message || "Execution failed",
|
|
192
|
+
input: p,
|
|
193
|
+
request: s.request,
|
|
194
|
+
response: g
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (!S) {
|
|
199
|
+
const i = d.getState();
|
|
200
|
+
if (i.currentExecution) {
|
|
201
|
+
const p = {
|
|
202
|
+
...i.currentExecution,
|
|
203
|
+
completedAt: /* @__PURE__ */ new Date(),
|
|
204
|
+
status: "completed"
|
|
205
|
+
};
|
|
206
|
+
d.setState({
|
|
207
|
+
executionHistory: [p, ...i.executionHistory].slice(0, 50),
|
|
208
|
+
currentExecution: p,
|
|
209
|
+
// Keep currentExecution so users can view results
|
|
210
|
+
isExecuting: !1
|
|
211
|
+
});
|
|
212
|
+
} else
|
|
213
|
+
d.getState().stopExecution();
|
|
214
|
+
const o = d.getState().currentPipeline;
|
|
215
|
+
if (o) {
|
|
216
|
+
const p = {
|
|
217
|
+
...o,
|
|
218
|
+
status: "completed",
|
|
219
|
+
// Preserve node states - ensure completed/error nodes keep their status
|
|
220
|
+
nodes: o.nodes.map((s) => {
|
|
221
|
+
const t = s.result_metadata && Object.keys(s.result_metadata).length > 0, r = s.status === "error" || !!s.error;
|
|
222
|
+
let f = s.status;
|
|
223
|
+
return t && (s.status === "idle" || s.status === "pending" || !s.status) ? f = "completed" : r && s.status !== "error" ? f = "error" : s.status === "running" && (f = t ? "completed" : "error"), {
|
|
224
|
+
...s,
|
|
225
|
+
status: f,
|
|
226
|
+
// Ensure result_metadata is preserved
|
|
227
|
+
result_metadata: s.result_metadata || void 0
|
|
228
|
+
};
|
|
229
|
+
})
|
|
230
|
+
};
|
|
231
|
+
console.log("[PipelineExecution] Preserving node states after completion:", {
|
|
232
|
+
nodeCount: p.nodes.length,
|
|
233
|
+
nodeStates: p.nodes.map((s) => ({
|
|
234
|
+
id: s.id,
|
|
235
|
+
label: s.label,
|
|
236
|
+
status: s.status,
|
|
237
|
+
hasResultMetadata: !!(s.result_metadata && Object.keys(s.result_metadata).length > 0)
|
|
238
|
+
}))
|
|
239
|
+
}), d.getState().setCurrentPipeline(p), window.dispatchEvent(new CustomEvent("pipeline-completed", {
|
|
240
|
+
detail: {
|
|
241
|
+
pipelineId: o.id,
|
|
242
|
+
status: "completed",
|
|
243
|
+
nodes: p.nodes
|
|
244
|
+
}
|
|
245
|
+
}));
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
})(), () => {
|
|
249
|
+
S = !0;
|
|
250
|
+
};
|
|
251
|
+
}, [_, l == null ? void 0 : l.id, x.join(","), b]), !_ || !l)
|
|
252
|
+
return null;
|
|
253
|
+
const C = l.nodes.find((a) => a.status === "running"), j = l.nodes.filter((a) => a.status === "completed" || a.status === "success").length, q = l.nodes.length;
|
|
254
|
+
return /* @__PURE__ */ m("div", { className: "fixed bottom-4 right-4 bg-white border border-gray-200 rounded-lg shadow-lg p-4 z-50 min-w-[300px]", children: [
|
|
255
|
+
/* @__PURE__ */ m("div", { className: "flex items-center justify-between mb-3", children: [
|
|
256
|
+
/* @__PURE__ */ u("h3", { className: "text-sm font-semibold text-gray-900", children: "Pipeline Execution" }),
|
|
257
|
+
/* @__PURE__ */ u(
|
|
258
|
+
"button",
|
|
259
|
+
{
|
|
260
|
+
onClick: z,
|
|
261
|
+
className: "text-xs text-red-600 hover:text-red-700",
|
|
262
|
+
children: "Stop"
|
|
263
|
+
}
|
|
264
|
+
)
|
|
265
|
+
] }),
|
|
266
|
+
/* @__PURE__ */ m("div", { className: "space-y-2", children: [
|
|
267
|
+
/* @__PURE__ */ m("div", { className: "flex items-center justify-between text-xs", children: [
|
|
268
|
+
/* @__PURE__ */ u("span", { className: "text-gray-600", children: "Progress" }),
|
|
269
|
+
/* @__PURE__ */ m("span", { className: "text-gray-900 font-medium", children: [
|
|
270
|
+
j,
|
|
271
|
+
" / ",
|
|
272
|
+
q
|
|
273
|
+
] })
|
|
274
|
+
] }),
|
|
275
|
+
/* @__PURE__ */ u("div", { className: "w-full bg-gray-200 rounded-full h-2", children: /* @__PURE__ */ u(
|
|
276
|
+
"div",
|
|
277
|
+
{
|
|
278
|
+
className: "bg-blue-600 h-2 rounded-full transition-all",
|
|
279
|
+
style: { width: `${j / q * 100}%` }
|
|
280
|
+
}
|
|
281
|
+
) }),
|
|
282
|
+
C && /* @__PURE__ */ m("div", { className: "flex items-center gap-2 text-xs text-gray-600 mt-3", children: [
|
|
283
|
+
/* @__PURE__ */ u(K, { className: "w-3 h-3 animate-spin text-blue-600" }),
|
|
284
|
+
/* @__PURE__ */ m("span", { children: [
|
|
285
|
+
"Running: ",
|
|
286
|
+
C.label
|
|
287
|
+
] })
|
|
288
|
+
] }),
|
|
289
|
+
/* @__PURE__ */ u("div", { className: "mt-3 space-y-1 max-h-32 overflow-y-auto", children: l.nodes.map((a) => /* @__PURE__ */ m(
|
|
290
|
+
"div",
|
|
291
|
+
{
|
|
292
|
+
className: "flex items-center gap-2 text-xs",
|
|
293
|
+
children: [
|
|
294
|
+
a.status === "running" && /* @__PURE__ */ u(K, { className: "w-3 h-3 animate-spin text-blue-600" }),
|
|
295
|
+
(a.status === "success" || a.status === "completed") && /* @__PURE__ */ u(X, { className: "w-3 h-3 text-green-600" }),
|
|
296
|
+
a.status === "error" && /* @__PURE__ */ u(B, { className: "w-3 h-3 text-red-600" }),
|
|
297
|
+
a.status === "pending" && /* @__PURE__ */ u("div", { className: "w-3 h-3 rounded-full border-2 border-gray-300" }),
|
|
298
|
+
/* @__PURE__ */ u("span", { className: a.status === "error" ? "text-red-600" : "text-gray-700", children: a.label }),
|
|
299
|
+
a.error && /* @__PURE__ */ u("div", { title: a.error, children: /* @__PURE__ */ u(G, { className: "w-3 h-3 text-red-600" }) })
|
|
300
|
+
]
|
|
301
|
+
},
|
|
302
|
+
a.id
|
|
303
|
+
)) })
|
|
304
|
+
] })
|
|
305
|
+
] });
|
|
306
|
+
};
|
|
307
|
+
export {
|
|
308
|
+
se as PipelineExecution
|
|
309
|
+
};
|
|
310
|
+
//# sourceMappingURL=PipelineExecution.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PipelineExecution.mjs","sources":["../../components/PipelineExecution.tsx"],"sourcesContent":["import React, { useEffect } from 'react';\nimport { usePipelineStore } from '../store/pipelineStore';\nimport { usePipelineContext } from '../context/PipelineContext';\nimport { Loader2, CheckCircle2, XCircle, AlertCircle } from 'lucide-react';\nimport { executeNode } from '../utils/executionEngine';\n\ninterface ApiClient {\n post: (endpoint: string, data: any, config?: { headers?: Record<string, string>; method?: string }) => Promise<any>;\n get: (endpoint: string, config?: { headers?: Record<string, string> }) => Promise<any>;\n}\n\ninterface PipelineExecutionProps {\n apiClient?: ApiClient;\n}\n\nexport const PipelineExecution: React.FC<PipelineExecutionProps> = ({ apiClient }) => {\n const {\n currentPipeline,\n isExecuting,\n executionOrder,\n updateNodeStatus,\n stopExecution,\n } = usePipelineStore();\n \n const { sessionId } = usePipelineContext();\n const effectiveSessionId = sessionId;\n \n // Debug: Log session ID\n useEffect(() => {\n if (effectiveSessionId) {\n console.log('[PipelineExecution] Active session ID:', effectiveSessionId);\n } else {\n console.warn('[PipelineExecution] No active session ID found');\n }\n }, [effectiveSessionId]);\n\n useEffect(() => {\n if (!isExecuting || !currentPipeline || executionOrder.length === 0) {\n return;\n }\n \n // Check if any node in execution order needs apiClient\n // Input nodes (file_check) don't need apiClient, so allow execution to proceed\n // The execution engine will handle missing apiClient gracefully\n const hasInputNodes = executionOrder.some(nodeId => {\n const node = currentPipeline.nodes.find(n => n.id === nodeId);\n return node?.type === 'input_node';\n });\n \n // Only warn if apiClient is missing and we have non-input nodes\n if (!apiClient && !hasInputNodes) {\n console.warn('[PipelineExecution] apiClient not provided but may be required for node execution');\n // Still allow execution to proceed - it will fail gracefully if apiClient is needed\n }\n\n let cancelled = false;\n\n const executePipeline = async () => {\n console.log('[PipelineExecution] Starting execution:', {\n executionOrder,\n nodeCount: executionOrder.length,\n hasApiClient: !!apiClient,\n });\n \n for (const nodeId of executionOrder) {\n if (cancelled) break;\n\n const node = currentPipeline.nodes.find((n) => n.id === nodeId);\n if (!node) {\n console.warn(`[PipelineExecution] Node ${nodeId} not found`);\n continue;\n }\n\n console.log(`[PipelineExecution] Processing node ${nodeId} (${node.type}):`, {\n status: node.status,\n label: node.label,\n });\n\n // Skip if already successful or completed\n if (node.status === 'success' || node.status === 'completed') {\n console.log(`[PipelineExecution] Skipping ${nodeId} - already completed`);\n continue;\n }\n\n // Capture input data for logging (outside try block for error handling)\n const inputDataForLog: Record<string, any> = {};\n if (node.config) {\n inputDataForLog.config = node.config;\n }\n\n try {\n updateNodeStatus(nodeId, 'running');\n const startTime = Date.now();\n\n // Execute node using dynamic execution engine with logging\n // For input nodes, apiClient is not needed\n let executionResult: any;\n try {\n // Create a minimal apiClient for nodes that don't need it\n const nodeApiClient = apiClient || {\n post: async () => { throw new Error('apiClient not available'); },\n get: async () => { throw new Error('apiClient not available'); },\n };\n \n executionResult = await executeNode(node, {\n pipeline: currentPipeline,\n apiClient: nodeApiClient,\n sessionId: effectiveSessionId,\n });\n } catch (execError: any) {\n console.error(`[PipelineExecution] Error executing node ${nodeId}:`, execError);\n throw execError;\n }\n \n const endTime = Date.now();\n const duration = endTime - startTime;\n\n // Extract request/response details from execution result\n let result: any;\n try {\n result = executionResult?.data || executionResult;\n \n // Safety check: ensure result is an object or can be safely handled\n if (result && typeof result !== 'object') {\n console.warn(`[PipelineExecution] Unexpected result type for node ${nodeId}:`, typeof result, result);\n // Convert to object if it's a primitive\n result = { value: result };\n }\n } catch (resultError: any) {\n console.error(`[PipelineExecution] Error extracting result for node ${nodeId}:`, resultError);\n result = { error: 'Failed to extract result' };\n }\n\n // Store result metadata if available\n if (result) {\n try {\n const resultMetadata: Record<string, any> = {};\n \n // For input nodes, store all file metadata\n if (node.type === 'input_node' && result.data) {\n // Store the full file data including all metadata\n resultMetadata.file_info = result.data;\n resultMetadata.type = result.data.type || 'pdb_file';\n resultMetadata.filename = result.data.filename;\n resultMetadata.file_id = result.data.file_id;\n resultMetadata.file_url = result.data.file_url;\n // Also store in data for consistency\n resultMetadata.data = result.data;\n } else {\n // Special handling for RFdiffusion nodes - extract filepath from response\n if (node.type === 'rfdiffusion_node') {\n // RFdiffusion API returns: { status, output_pdb, filename, filepath, data: { pdbContent, filename, filepath } }\n const filepath = result.filepath || result.data?.filepath;\n const filename = result.filename || result.data?.filename;\n const pdbContent = result.output_pdb || result.data?.pdbContent;\n \n if (filepath) {\n // Store filepath as output_file for downstream nodes to use\n resultMetadata.output_file = {\n type: 'pdb_file',\n filename: filename || `rfdiffusion_${node.id}.pdb`,\n filepath: filepath,\n file_id: node.id, // Use node ID as file identifier\n // Store relative path from server directory (e.g., \"rfdiffusion_results/rfdiffusion_xxx.pdb\")\n file_url: `/api/files/${filepath}`,\n };\n resultMetadata.filepath = filepath;\n resultMetadata.filename = filename;\n }\n \n if (pdbContent) {\n resultMetadata.pdbContent = pdbContent;\n }\n \n // Store full data for reference\n if (result.data) {\n resultMetadata.data = result.data;\n }\n } else {\n // Extract common result fields for other node types\n if (result.output_file || result.file) {\n resultMetadata.output_file = result.output_file || result.file;\n }\n if (result.sequence) {\n resultMetadata.sequence = result.sequence;\n }\n if (result.message) {\n resultMetadata.message = result.message;\n }\n if (result.data) {\n resultMetadata.data = result.data;\n }\n \n // Store full result if no specific fields found\n if (Object.keys(resultMetadata).length === 0 && typeof result === 'object') {\n Object.assign(resultMetadata, result);\n }\n }\n }\n\n // Update node with result metadata\n usePipelineStore.getState().updateNode(nodeId, {\n result_metadata: resultMetadata,\n });\n \n // Trigger file refresh event for RFdiffusion nodes (so FileBrowser updates)\n if (node.type === 'rfdiffusion_node' && resultMetadata.filepath) {\n console.log('[PipelineExecution] RFdiffusion completed, triggering file refresh. Active session:', effectiveSessionId);\n // Small delay to ensure backend has saved the file and associated it with session\n setTimeout(() => {\n window.dispatchEvent(new CustomEvent('session-file-added'));\n console.log('[PipelineExecution] Dispatched session-file-added event');\n }, 1000); // Increased delay to ensure backend processing completes\n }\n } catch (metadataError: any) {\n console.error(`[PipelineExecution] Error storing metadata for node ${nodeId}:`, metadataError);\n }\n }\n\n // Update node status to completed - this should preserve result_metadata\n // The result_metadata was already set above, so updateNodeStatus won't overwrite it\n updateNodeStatus(nodeId, 'completed');\n \n // Emit pipeline node completed event\n if (currentPipeline) {\n window.dispatchEvent(new CustomEvent('pipeline-node-completed', {\n detail: {\n pipelineId: currentPipeline.id,\n nodeId: nodeId,\n status: 'completed',\n result: result,\n }\n }));\n }\n \n // Log the final state to verify\n const finalNode = usePipelineStore.getState().currentPipeline?.nodes.find(n => n.id === nodeId);\n console.log(`[PipelineExecution] Node ${nodeId} final state:`, {\n status: finalNode?.status,\n hasResultMetadata: !!(finalNode?.result_metadata && Object.keys(finalNode.result_metadata).length > 0),\n resultMetadataKeys: finalNode?.result_metadata ? Object.keys(finalNode.result_metadata) : []\n });\n \n // Then add detailed request/response info to the log\n // This ensures the execution panel shows status updates immediately\n const existingLog = usePipelineStore.getState().currentExecution?.logs.find(\n l => l.nodeId === nodeId\n );\n \n // Debug logging for HTTP request nodes\n if (node.type === 'http_request_node') {\n console.log('[PipelineExecution] HTTP Request result:', {\n nodeId,\n hasExecutionResult: !!executionResult,\n executionResultKeys: executionResult ? Object.keys(executionResult) : [],\n hasData: !!executionResult?.data,\n hasRequest: !!executionResult?.request,\n hasResponse: !!executionResult?.response,\n resultType: typeof result,\n resultKeys: result && typeof result === 'object' ? Object.keys(result) : null,\n responseData: executionResult?.response?.data,\n });\n }\n \n // Add detailed execution info (request/response) to the log\n // updateNodeStatus already updated the status, so this just adds details\n if (existingLog) {\n usePipelineStore.getState().updateExecutionLog(nodeId, {\n output: result,\n input: inputDataForLog,\n request: executionResult?.request,\n response: executionResult?.response,\n duration, // Ensure duration is set\n });\n } else {\n // Create new log entry if it doesn't exist (shouldn't happen, but handle it)\n usePipelineStore.getState().addExecutionLog({\n nodeId,\n nodeLabel: node.label,\n nodeType: node.type,\n status: 'completed',\n completedAt: new Date(),\n duration,\n output: result,\n input: inputDataForLog,\n request: executionResult?.request,\n response: executionResult?.response,\n });\n }\n\n console.log(`[PipelineExecution] Node ${nodeId} completed successfully`);\n } catch (error: any) {\n console.error(`[PipelineExecution] Error in node ${nodeId} (${node.type}):`, error);\n const errorResponse = (error as any).response;\n const errorData = errorResponse?.data;\n const errorMessage = errorData?.error || errorData?.detail || errorData?.data?.detail || errorData?.response?.data?.detail || error.message;\n console.error(`[PipelineExecution] Error details:`, {\n message: error.message,\n stack: error.stack,\n response: errorResponse,\n responseData: errorData,\n responseStatus: errorResponse?.status,\n errorMessage: errorMessage,\n fullErrorData: JSON.stringify(errorData, null, 2)\n });\n // Log the actual error message prominently\n if (errorMessage && errorMessage !== error.message) {\n console.error(`[PipelineExecution] Server Error Message: ${errorMessage}`);\n }\n const endTime = Date.now();\n const startTime = usePipelineStore.getState().currentExecution?.logs.find(\n l => l.nodeId === nodeId\n )?.startedAt;\n const duration = startTime ? endTime - new Date(startTime).getTime() : 0;\n\n // Update node status first to sync with execution panel\n updateNodeStatus(nodeId, 'error', error.message || 'Execution failed');\n \n // Emit pipeline node error event\n if (currentPipeline) {\n window.dispatchEvent(new CustomEvent('pipeline-node-completed', {\n detail: {\n pipelineId: currentPipeline.id,\n nodeId: nodeId,\n status: 'error',\n error: error.message || 'Execution failed',\n }\n }));\n }\n \n // Then add detailed error info to the log\n const existingErrorLog = usePipelineStore.getState().currentExecution?.logs.find(\n l => l.nodeId === nodeId\n );\n \n const errorResponseData = (error as any).response || (error.response ? {\n status: error.response.status,\n statusText: error.response.statusText,\n data: error.response.data,\n } : undefined);\n\n // Add detailed error info (request/response) to the log\n // updateNodeStatus already updated the status, so this just adds details\n if (existingErrorLog) {\n usePipelineStore.getState().updateExecutionLog(nodeId, {\n input: inputDataForLog,\n request: (error as any).request,\n response: errorResponseData,\n duration, // Ensure duration is set\n });\n } else {\n // Create new log entry if it doesn't exist (shouldn't happen, but handle it)\n usePipelineStore.getState().addExecutionLog({\n nodeId,\n nodeLabel: node.label,\n nodeType: node.type,\n status: 'error',\n completedAt: new Date(),\n duration,\n error: error.message || 'Execution failed',\n input: inputDataForLog,\n request: (error as any).request,\n response: errorResponseData,\n });\n }\n }\n }\n\n if (!cancelled) {\n // Mark execution as completed - update currentExecution to keep logs visible\n const state = usePipelineStore.getState();\n if (state.currentExecution) {\n const completedExecution = {\n ...state.currentExecution,\n completedAt: new Date(),\n status: 'completed' as const,\n };\n // Update execution history and keep currentExecution for viewing results\n usePipelineStore.setState({\n executionHistory: [completedExecution, ...state.executionHistory].slice(0, 50),\n currentExecution: completedExecution, // Keep currentExecution so users can view results\n isExecuting: false,\n });\n } else {\n usePipelineStore.getState().stopExecution();\n }\n \n // IMPORTANT: Read current pipeline fresh from store to get latest node states\n // The closure's currentPipeline might be stale after node updates\n const freshPipeline = usePipelineStore.getState().currentPipeline;\n if (freshPipeline) {\n // Explicitly preserve all node statuses and result_metadata after execution completes\n // This ensures nodes maintain their success/failure visual states (green/red borders)\n const updatedPipeline = {\n ...freshPipeline,\n status: 'completed' as const,\n // Preserve node states - ensure completed/error nodes keep their status\n nodes: freshPipeline.nodes.map(node => {\n const hasResult = node.result_metadata && Object.keys(node.result_metadata).length > 0;\n const hasError = node.status === 'error' || !!node.error;\n \n // If node has result_metadata but status was reset, restore to 'completed'\n // If node has error, ensure status is 'error'\n let finalStatus = node.status;\n if (hasResult && (node.status === 'idle' || node.status === 'pending' || !node.status)) {\n finalStatus = 'completed';\n } else if (hasError && node.status !== 'error') {\n finalStatus = 'error';\n } else if (node.status === 'running') {\n // If still marked as running but execution completed, mark as completed if has result\n finalStatus = hasResult ? 'completed' : 'error';\n }\n \n return {\n ...node,\n status: finalStatus,\n // Ensure result_metadata is preserved\n result_metadata: node.result_metadata || undefined,\n };\n }),\n };\n \n console.log('[PipelineExecution] Preserving node states after completion:', {\n nodeCount: updatedPipeline.nodes.length,\n nodeStates: updatedPipeline.nodes.map(n => ({\n id: n.id,\n label: n.label,\n status: n.status,\n hasResultMetadata: !!(n.result_metadata && Object.keys(n.result_metadata).length > 0),\n })),\n });\n \n usePipelineStore.getState().setCurrentPipeline(updatedPipeline);\n \n // Emit pipeline completed event\n window.dispatchEvent(new CustomEvent('pipeline-completed', {\n detail: {\n pipelineId: freshPipeline.id,\n status: 'completed',\n nodes: updatedPipeline.nodes,\n }\n }));\n }\n }\n };\n\n executePipeline();\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isExecuting, currentPipeline?.id, executionOrder.join(','), apiClient]);\n\n if (!isExecuting || !currentPipeline) {\n return null;\n }\n\n const runningNode = currentPipeline.nodes.find((n) => n.status === 'running');\n const completedCount = currentPipeline.nodes.filter((n) => n.status === 'completed' || n.status === 'success').length;\n const totalCount = currentPipeline.nodes.length;\n\n return (\n <div className=\"fixed bottom-4 right-4 bg-white border border-gray-200 rounded-lg shadow-lg p-4 z-50 min-w-[300px]\">\n <div className=\"flex items-center justify-between mb-3\">\n <h3 className=\"text-sm font-semibold text-gray-900\">Pipeline Execution</h3>\n <button\n onClick={stopExecution}\n className=\"text-xs text-red-600 hover:text-red-700\"\n >\n Stop\n </button>\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between text-xs\">\n <span className=\"text-gray-600\">Progress</span>\n <span className=\"text-gray-900 font-medium\">\n {completedCount} / {totalCount}\n </span>\n </div>\n\n <div className=\"w-full bg-gray-200 rounded-full h-2\">\n <div\n className=\"bg-blue-600 h-2 rounded-full transition-all\"\n style={{ width: `${(completedCount / totalCount) * 100}%` }}\n />\n </div>\n\n {runningNode && (\n <div className=\"flex items-center gap-2 text-xs text-gray-600 mt-3\">\n <Loader2 className=\"w-3 h-3 animate-spin text-blue-600\" />\n <span>Running: {runningNode.label}</span>\n </div>\n )}\n\n <div className=\"mt-3 space-y-1 max-h-32 overflow-y-auto\">\n {currentPipeline.nodes.map((node) => (\n <div\n key={node.id}\n className=\"flex items-center gap-2 text-xs\"\n >\n {node.status === 'running' && (\n <Loader2 className=\"w-3 h-3 animate-spin text-blue-600\" />\n )}\n {(node.status === 'success' || node.status === 'completed') && (\n <CheckCircle2 className=\"w-3 h-3 text-green-600\" />\n )}\n {node.status === 'error' && (\n <XCircle className=\"w-3 h-3 text-red-600\" />\n )}\n {node.status === 'pending' && (\n <div className=\"w-3 h-3 rounded-full border-2 border-gray-300\" />\n )}\n <span className={node.status === 'error' ? 'text-red-600' : 'text-gray-700'}>\n {node.label}\n </span>\n {node.error && (\n <div title={node.error}>\n <AlertCircle className=\"w-3 h-3 text-red-600\" />\n </div>\n )}\n </div>\n ))}\n </div>\n </div>\n </div>\n );\n};\n\n\n\n\n\n"],"names":["PipelineExecution","apiClient","currentPipeline","isExecuting","executionOrder","updateNodeStatus","stopExecution","usePipelineStore","sessionId","usePipelineContext","effectiveSessionId","useEffect","hasInputNodes","nodeId","node","n","cancelled","inputDataForLog","startTime","executionResult","executeNode","execError","duration","result","resultError","resultMetadata","filepath","_a","filename","_b","pdbContent","_c","metadataError","finalNode","_d","existingLog","_e","l","_f","error","errorResponse","errorData","errorMessage","_g","_i","_h","endTime","_k","_j","existingErrorLog","_l","errorResponseData","state","completedExecution","freshPipeline","updatedPipeline","hasResult","hasError","finalStatus","runningNode","completedCount","totalCount","jsxs","jsx","Loader2","CheckCircle2","XCircle","AlertCircle"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PipelineManager.d.ts","sourceRoot":"","sources":["../../components/PipelineManager.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAcnD,UAAU,oBAAoB;IAC5B,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAyK1D,CAAC"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { jsx as t, jsxs as a } from "react/jsx-runtime";
|
|
2
|
+
import { useState as p, useEffect as E } from "react";
|
|
3
|
+
import { usePipelineStore as u } from "../store/pipelineStore.mjs";
|
|
4
|
+
import { usePipelineContext as k } from "../context/PipelineContext.mjs";
|
|
5
|
+
import { Play as z, Edit2 as M, Trash2 as j } from "lucide-react";
|
|
6
|
+
import { Dialog as I, DialogContent as L, DialogHeader as A, DialogTitle as F } from "./ui/dialog.mjs";
|
|
7
|
+
import { Input as T } from "./ui/input.mjs";
|
|
8
|
+
import { Button as s } from "./ui/button.mjs";
|
|
9
|
+
const Q = ({ isOpen: r, onClose: m }) => {
|
|
10
|
+
const { savedPipelines: c, loadPipeline: f, deletePipeline: v, syncPipelines: h } = u(), { authState: n, apiClient: i } = k(), g = n == null ? void 0 : n.user, [N, o] = p(null), [d, l] = p("");
|
|
11
|
+
E(() => {
|
|
12
|
+
r && g && i && (console.log("[PipelineManager] Syncing pipelines from backend..."), h({ apiClient: i, authState: n }).catch((e) => {
|
|
13
|
+
console.error("[PipelineManager] Failed to sync pipelines:", e);
|
|
14
|
+
}));
|
|
15
|
+
}, [r, g, i, n, h]);
|
|
16
|
+
const y = (e) => {
|
|
17
|
+
f(e.id), m();
|
|
18
|
+
}, b = (e) => {
|
|
19
|
+
confirm("Are you sure you want to delete this pipeline?") && v(e, { apiClient: i, authState: n });
|
|
20
|
+
}, C = (e) => {
|
|
21
|
+
o(e.id), l(e.name);
|
|
22
|
+
}, P = (e) => {
|
|
23
|
+
c.find((S) => S.id === e) && d.trim() && (u.getState().savePipeline(d.trim(), void 0, void 0, {
|
|
24
|
+
apiClient: i,
|
|
25
|
+
authState: n
|
|
26
|
+
}), o(null), l(""));
|
|
27
|
+
}, w = () => {
|
|
28
|
+
o(null), l("");
|
|
29
|
+
}, D = (e) => {
|
|
30
|
+
switch (e) {
|
|
31
|
+
case "running":
|
|
32
|
+
return "bg-blue-100 text-blue-800";
|
|
33
|
+
case "completed":
|
|
34
|
+
return "bg-green-100 text-green-800";
|
|
35
|
+
case "failed":
|
|
36
|
+
return "bg-red-100 text-red-800";
|
|
37
|
+
default:
|
|
38
|
+
return "bg-gray-100 text-gray-800";
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
return /* @__PURE__ */ t(I, { open: r, onOpenChange: (e) => !e && m(), children: /* @__PURE__ */ a(L, { className: "sm:max-w-4xl max-h-[90vh] flex flex-col", children: [
|
|
42
|
+
/* @__PURE__ */ t(A, { children: /* @__PURE__ */ t(F, { children: "Pipeline Manager" }) }),
|
|
43
|
+
/* @__PURE__ */ t("div", { className: "flex-1 overflow-y-auto", children: c.length === 0 ? /* @__PURE__ */ a("div", { className: "text-center py-12", children: [
|
|
44
|
+
/* @__PURE__ */ t("p", { className: "text-gray-500 mb-2", children: "No saved pipelines" }),
|
|
45
|
+
/* @__PURE__ */ t("p", { className: "text-sm text-gray-400", children: "Create a pipeline and save it to see it here" })
|
|
46
|
+
] }) : /* @__PURE__ */ t("div", { className: "space-y-3", children: c.map((e) => /* @__PURE__ */ t(
|
|
47
|
+
"div",
|
|
48
|
+
{
|
|
49
|
+
className: "border border-gray-200 rounded-lg p-4 hover:border-gray-300 transition-colors",
|
|
50
|
+
children: /* @__PURE__ */ a("div", { className: "flex items-start justify-between", children: [
|
|
51
|
+
/* @__PURE__ */ a("div", { className: "flex-1", children: [
|
|
52
|
+
N === e.id ? /* @__PURE__ */ a("div", { className: "flex items-center gap-2 mb-2", children: [
|
|
53
|
+
/* @__PURE__ */ t(
|
|
54
|
+
T,
|
|
55
|
+
{
|
|
56
|
+
type: "text",
|
|
57
|
+
value: d,
|
|
58
|
+
onChange: (x) => l(x.target.value),
|
|
59
|
+
className: "text-sm",
|
|
60
|
+
autoFocus: !0
|
|
61
|
+
}
|
|
62
|
+
),
|
|
63
|
+
/* @__PURE__ */ t(
|
|
64
|
+
s,
|
|
65
|
+
{
|
|
66
|
+
onClick: () => P(e.id),
|
|
67
|
+
size: "sm",
|
|
68
|
+
className: "text-xs",
|
|
69
|
+
children: "Save"
|
|
70
|
+
}
|
|
71
|
+
),
|
|
72
|
+
/* @__PURE__ */ t(
|
|
73
|
+
s,
|
|
74
|
+
{
|
|
75
|
+
onClick: w,
|
|
76
|
+
variant: "outline",
|
|
77
|
+
size: "sm",
|
|
78
|
+
className: "text-xs",
|
|
79
|
+
children: "Cancel"
|
|
80
|
+
}
|
|
81
|
+
)
|
|
82
|
+
] }) : /* @__PURE__ */ t("h3", { className: "text-sm font-semibold text-gray-900 mb-1", children: e.name }),
|
|
83
|
+
/* @__PURE__ */ a("div", { className: "flex items-center gap-3 text-xs text-gray-500 mb-2", children: [
|
|
84
|
+
/* @__PURE__ */ a("span", { children: [
|
|
85
|
+
e.nodes.length,
|
|
86
|
+
" nodes"
|
|
87
|
+
] }),
|
|
88
|
+
/* @__PURE__ */ t("span", { children: "•" }),
|
|
89
|
+
/* @__PURE__ */ a("span", { children: [
|
|
90
|
+
e.edges.length,
|
|
91
|
+
" edges"
|
|
92
|
+
] }),
|
|
93
|
+
/* @__PURE__ */ t("span", { children: "•" }),
|
|
94
|
+
/* @__PURE__ */ t("span", { className: `px-2 py-0.5 rounded ${D(e.status)}`, children: e.status })
|
|
95
|
+
] }),
|
|
96
|
+
/* @__PURE__ */ a("p", { className: "text-xs text-gray-400", children: [
|
|
97
|
+
"Created: ",
|
|
98
|
+
new Date(e.createdAt).toLocaleDateString()
|
|
99
|
+
] })
|
|
100
|
+
] }),
|
|
101
|
+
/* @__PURE__ */ a("div", { className: "flex items-center gap-2 ml-4", children: [
|
|
102
|
+
/* @__PURE__ */ t(
|
|
103
|
+
s,
|
|
104
|
+
{
|
|
105
|
+
variant: "ghost",
|
|
106
|
+
size: "icon",
|
|
107
|
+
onClick: () => y(e),
|
|
108
|
+
title: "Load pipeline",
|
|
109
|
+
children: /* @__PURE__ */ t(z, { className: "w-4 h-4" })
|
|
110
|
+
}
|
|
111
|
+
),
|
|
112
|
+
/* @__PURE__ */ t(
|
|
113
|
+
s,
|
|
114
|
+
{
|
|
115
|
+
variant: "ghost",
|
|
116
|
+
size: "icon",
|
|
117
|
+
onClick: () => C(e),
|
|
118
|
+
title: "Rename pipeline",
|
|
119
|
+
children: /* @__PURE__ */ t(M, { className: "w-4 h-4" })
|
|
120
|
+
}
|
|
121
|
+
),
|
|
122
|
+
/* @__PURE__ */ t(
|
|
123
|
+
s,
|
|
124
|
+
{
|
|
125
|
+
variant: "ghost",
|
|
126
|
+
size: "icon",
|
|
127
|
+
onClick: () => b(e.id),
|
|
128
|
+
title: "Delete pipeline",
|
|
129
|
+
className: "text-red-600 hover:text-red-700 hover:bg-red-50",
|
|
130
|
+
children: /* @__PURE__ */ t(j, { className: "w-4 h-4" })
|
|
131
|
+
}
|
|
132
|
+
)
|
|
133
|
+
] })
|
|
134
|
+
] })
|
|
135
|
+
},
|
|
136
|
+
e.id
|
|
137
|
+
)) }) })
|
|
138
|
+
] }) });
|
|
139
|
+
};
|
|
140
|
+
export {
|
|
141
|
+
Q as PipelineManager
|
|
142
|
+
};
|
|
143
|
+
//# sourceMappingURL=PipelineManager.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PipelineManager.mjs","sources":["../../components/PipelineManager.tsx"],"sourcesContent":["import React, { useState, useEffect } from 'react';\nimport { usePipelineStore } from '../store/pipelineStore';\nimport { usePipelineContext } from '../context/PipelineContext';\nimport { Pipeline } from '../types/index';\nimport { Trash2, Play, Edit2 } from 'lucide-react';\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n} from './ui/dialog';\nimport { Input } from './ui/input';\nimport { Button } from './ui/button';\n\ninterface PipelineManagerProps {\n isOpen: boolean;\n onClose: () => void;\n}\n\nexport const PipelineManager: React.FC<PipelineManagerProps> = ({ isOpen, onClose }) => {\n const { savedPipelines, loadPipeline, deletePipeline, syncPipelines } = usePipelineStore();\n const { authState, apiClient } = usePipelineContext();\n const user = authState?.user;\n const [editingId, setEditingId] = useState<string | null>(null);\n const [editName, setEditName] = useState('');\n\n // Sync pipelines from backend when modal opens and user is authenticated\n useEffect(() => {\n if (isOpen && user && apiClient) {\n console.log('[PipelineManager] Syncing pipelines from backend...');\n syncPipelines({ apiClient, authState }).catch((error) => {\n console.error('[PipelineManager] Failed to sync pipelines:', error);\n });\n }\n }, [isOpen, user, apiClient, authState, syncPipelines]);\n\n const handleLoad = (pipeline: Pipeline) => {\n loadPipeline(pipeline.id);\n onClose();\n };\n\n const handleDelete = (pipelineId: string) => {\n if (confirm('Are you sure you want to delete this pipeline?')) {\n deletePipeline(pipelineId, { apiClient, authState });\n }\n };\n\n const handleStartEdit = (pipeline: Pipeline) => {\n setEditingId(pipeline.id);\n setEditName(pipeline.name);\n };\n\n const handleSaveEdit = (pipelineId: string) => {\n const pipeline = savedPipelines.find((p) => p.id === pipelineId);\n if (pipeline && editName.trim()) {\n usePipelineStore.getState().savePipeline(editName.trim(), undefined, undefined, {\n apiClient,\n authState,\n });\n setEditingId(null);\n setEditName('');\n }\n };\n\n const handleCancelEdit = () => {\n setEditingId(null);\n setEditName('');\n };\n\n const getStatusColor = (status: Pipeline['status']) => {\n switch (status) {\n case 'running':\n return 'bg-blue-100 text-blue-800';\n case 'completed':\n return 'bg-green-100 text-green-800';\n case 'failed':\n return 'bg-red-100 text-red-800';\n default:\n return 'bg-gray-100 text-gray-800';\n }\n };\n\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>\n <DialogContent className=\"sm:max-w-4xl max-h-[90vh] flex flex-col\">\n <DialogHeader>\n <DialogTitle>Pipeline Manager</DialogTitle>\n </DialogHeader>\n\n <div className=\"flex-1 overflow-y-auto\">\n {savedPipelines.length === 0 ? (\n <div className=\"text-center py-12\">\n <p className=\"text-gray-500 mb-2\">No saved pipelines</p>\n <p className=\"text-sm text-gray-400\">\n Create a pipeline and save it to see it here\n </p>\n </div>\n ) : (\n <div className=\"space-y-3\">\n {savedPipelines.map((pipeline) => (\n <div\n key={pipeline.id}\n className=\"border border-gray-200 rounded-lg p-4 hover:border-gray-300 transition-colors\"\n >\n <div className=\"flex items-start justify-between\">\n <div className=\"flex-1\">\n {editingId === pipeline.id ? (\n <div className=\"flex items-center gap-2 mb-2\">\n <Input\n type=\"text\"\n value={editName}\n onChange={(e) => setEditName(e.target.value)}\n className=\"text-sm\"\n autoFocus\n />\n <Button\n onClick={() => handleSaveEdit(pipeline.id)}\n size=\"sm\"\n className=\"text-xs\"\n >\n Save\n </Button>\n <Button\n onClick={handleCancelEdit}\n variant=\"outline\"\n size=\"sm\"\n className=\"text-xs\"\n >\n Cancel\n </Button>\n </div>\n ) : (\n <h3 className=\"text-sm font-semibold text-gray-900 mb-1\">\n {pipeline.name}\n </h3>\n )}\n \n <div className=\"flex items-center gap-3 text-xs text-gray-500 mb-2\">\n <span>{pipeline.nodes.length} nodes</span>\n <span>•</span>\n <span>{pipeline.edges.length} edges</span>\n <span>•</span>\n <span className={`px-2 py-0.5 rounded ${getStatusColor(pipeline.status)}`}>\n {pipeline.status}\n </span>\n </div>\n \n <p className=\"text-xs text-gray-400\">\n Created: {new Date(pipeline.createdAt).toLocaleDateString()}\n </p>\n </div>\n \n <div className=\"flex items-center gap-2 ml-4\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleLoad(pipeline)}\n title=\"Load pipeline\"\n >\n <Play className=\"w-4 h-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleStartEdit(pipeline)}\n title=\"Rename pipeline\"\n >\n <Edit2 className=\"w-4 h-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleDelete(pipeline.id)}\n title=\"Delete pipeline\"\n className=\"text-red-600 hover:text-red-700 hover:bg-red-50\"\n >\n <Trash2 className=\"w-4 h-4\" />\n </Button>\n </div>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n </DialogContent>\n </Dialog>\n );\n};\n\n\n\n\n\n"],"names":["PipelineManager","isOpen","onClose","savedPipelines","loadPipeline","deletePipeline","syncPipelines","usePipelineStore","authState","apiClient","usePipelineContext","user","editingId","setEditingId","useState","editName","setEditName","useEffect","error","handleLoad","pipeline","handleDelete","pipelineId","handleStartEdit","handleSaveEdit","p","handleCancelEdit","getStatusColor","status","jsx","Dialog","open","jsxs","DialogContent","DialogHeader","DialogTitle","Input","e","Button","Play","Edit2","Trash2"],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { PipelineNode } from '../types/index';
|
|
3
|
+
interface PipelineNodeConfigProps {
|
|
4
|
+
nodeId: string;
|
|
5
|
+
onUpdate: (updates: Partial<PipelineNode>) => void;
|
|
6
|
+
onDelete: () => void;
|
|
7
|
+
onClose?: () => void;
|
|
8
|
+
}
|
|
9
|
+
export declare const PipelineNodeConfig: React.FC<PipelineNodeConfigProps>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=PipelineNodeConfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PipelineNodeConfig.d.ts","sourceRoot":"","sources":["../../components/PipelineNodeConfig.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAG3D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAS9C,UAAU,uBAAuB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IACnD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AA8ED,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CA2yEhE,CAAC"}
|