@mesantosrai/pipeline-canvas 1.0.0 → 1.0.2
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 +151 -28
- package/dist/components/ExecutionLogsPanel.mjs +77 -77
- package/dist/components/ExecutionLogsPanel.mjs.map +1 -1
- package/dist/components/NodeContextMenu.mjs +32 -32
- package/dist/components/NodeContextMenu.mjs.map +1 -1
- package/dist/components/PipelineCanvas.d.ts.map +1 -1
- package/dist/components/PipelineCanvas.mjs +199 -193
- package/dist/components/PipelineCanvas.mjs.map +1 -1
- package/dist/components/PipelineNodeConfig.d.ts.map +1 -1
- package/dist/components/PipelineNodeConfig.mjs +680 -668
- package/dist/components/PipelineNodeConfig.mjs.map +1 -1
- package/dist/components/PipelineNodePalette.mjs +22 -22
- package/dist/components/PipelineNodePalette.mjs.map +1 -1
- package/dist/components/PipelineThemeWrapper.d.ts +69 -0
- package/dist/components/PipelineThemeWrapper.d.ts.map +1 -0
- package/dist/components/PipelineThemeWrapper.mjs +45 -0
- package/dist/components/PipelineThemeWrapper.mjs.map +1 -0
- package/dist/components/SavePipelineDialog.mjs +48 -48
- package/dist/components/SavePipelineDialog.mjs.map +1 -1
- package/dist/components/SavedPipelinesList.mjs +63 -63
- package/dist/components/SavedPipelinesList.mjs.map +1 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/context/ThemeContext.d.ts +41 -0
- package/dist/context/ThemeContext.d.ts.map +1 -0
- package/dist/context/ThemeContext.mjs +44 -0
- package/dist/context/ThemeContext.mjs.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +41 -34
- package/dist/index.mjs.map +1 -1
- package/dist/store/pipelineStore.mjs.map +1 -1
- package/package.json +3 -19
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @mesantosrai/pipeline-canvas
|
|
2
2
|
|
|
3
3
|
A React component library for building visual pipeline/workflow canvases using React Flow.
|
|
4
4
|
|
|
@@ -60,8 +60,8 @@ npm install @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react
|
|
|
60
60
|
The library works completely standalone without any dependencies:
|
|
61
61
|
|
|
62
62
|
```tsx
|
|
63
|
-
import { PipelineCanvas, PipelineCanvasProvider } from '@
|
|
64
|
-
import '@
|
|
63
|
+
import { PipelineCanvas, PipelineCanvasProvider } from '@mesantosrai/pipeline-canvas';
|
|
64
|
+
import '@mesantosrai/pipeline-canvas/style.css';
|
|
65
65
|
|
|
66
66
|
function App() {
|
|
67
67
|
return (
|
|
@@ -90,8 +90,8 @@ import {
|
|
|
90
90
|
PipelineCanvasProvider,
|
|
91
91
|
type ApiClient,
|
|
92
92
|
type AuthState
|
|
93
|
-
} from '@
|
|
94
|
-
import '@
|
|
93
|
+
} from '@mesantosrai/pipeline-canvas';
|
|
94
|
+
import '@mesantosrai/pipeline-canvas/style.css';
|
|
95
95
|
|
|
96
96
|
function App() {
|
|
97
97
|
// Your API client (compatible with axios, fetch, or custom)
|
|
@@ -151,7 +151,7 @@ If you're using axios:
|
|
|
151
151
|
|
|
152
152
|
```tsx
|
|
153
153
|
import axios from 'axios';
|
|
154
|
-
import { PipelineCanvasProvider, type ApiClient } from '@
|
|
154
|
+
import { PipelineCanvasProvider, type ApiClient } from '@mesantosrai/pipeline-canvas';
|
|
155
155
|
|
|
156
156
|
const apiClient: ApiClient = {
|
|
157
157
|
get: (url: string, config?) => axios.get(url, config),
|
|
@@ -194,7 +194,7 @@ You can provide only the dependencies you need:
|
|
|
194
194
|
### Using the Store
|
|
195
195
|
|
|
196
196
|
```tsx
|
|
197
|
-
import { usePipelineStore } from '@
|
|
197
|
+
import { usePipelineStore } from '@mesantosrai/pipeline-canvas';
|
|
198
198
|
|
|
199
199
|
function MyComponent() {
|
|
200
200
|
const { nodes, edges, addNode } = usePipelineStore();
|
|
@@ -215,7 +215,7 @@ function MyComponent() {
|
|
|
215
215
|
You can also access dependencies directly from context:
|
|
216
216
|
|
|
217
217
|
```tsx
|
|
218
|
-
import { usePipelineContext } from '@
|
|
218
|
+
import { usePipelineContext } from '@mesantosrai/pipeline-canvas';
|
|
219
219
|
|
|
220
220
|
function MyComponent() {
|
|
221
221
|
const { apiClient, authState, sessionId, getAuthHeaders } = usePipelineContext();
|
|
@@ -256,7 +256,7 @@ When dependencies are not provided:
|
|
|
256
256
|
|
|
257
257
|
```tsx
|
|
258
258
|
import { useAuthStore } from './stores/authStore';
|
|
259
|
-
import { PipelineCanvasProvider } from '@
|
|
259
|
+
import { PipelineCanvasProvider } from '@mesantosrai/pipeline-canvas';
|
|
260
260
|
|
|
261
261
|
function App() {
|
|
262
262
|
const user = useAuthStore(state => state.user);
|
|
@@ -281,7 +281,7 @@ function App() {
|
|
|
281
281
|
```tsx
|
|
282
282
|
import { useContext } from 'react';
|
|
283
283
|
import { AuthContext } from './AuthContext';
|
|
284
|
-
import { PipelineCanvasProvider } from '@
|
|
284
|
+
import { PipelineCanvasProvider } from '@mesantosrai/pipeline-canvas';
|
|
285
285
|
|
|
286
286
|
function App() {
|
|
287
287
|
const { user, token } = useContext(AuthContext);
|
|
@@ -305,7 +305,7 @@ The library supports structured logging and error tracking through dependency in
|
|
|
305
305
|
By default, the library uses a console logger that only logs in development mode:
|
|
306
306
|
|
|
307
307
|
```tsx
|
|
308
|
-
import { PipelineCanvasProvider } from '@
|
|
308
|
+
import { PipelineCanvasProvider } from '@mesantosrai/pipeline-canvas';
|
|
309
309
|
|
|
310
310
|
// No logger needed - uses default console logger (development only)
|
|
311
311
|
<PipelineCanvasProvider>
|
|
@@ -321,7 +321,7 @@ Provide your own logger for structured logging:
|
|
|
321
321
|
import {
|
|
322
322
|
PipelineCanvasProvider,
|
|
323
323
|
type Logger
|
|
324
|
-
} from '@
|
|
324
|
+
} from '@mesantosrai/pipeline-canvas';
|
|
325
325
|
|
|
326
326
|
const myLogger: Logger = {
|
|
327
327
|
debug: (message, data) => {
|
|
@@ -356,7 +356,7 @@ import * as Sentry from '@sentry/react';
|
|
|
356
356
|
import {
|
|
357
357
|
PipelineCanvasProvider,
|
|
358
358
|
type ErrorReporter
|
|
359
|
-
} from '@
|
|
359
|
+
} from '@mesantosrai/pipeline-canvas';
|
|
360
360
|
|
|
361
361
|
const errorReporter: ErrorReporter = {
|
|
362
362
|
captureException: (error, context) => {
|
|
@@ -396,7 +396,7 @@ const errorReporter: ErrorReporter = {
|
|
|
396
396
|
|
|
397
397
|
```tsx
|
|
398
398
|
import LogRocket from 'logrocket';
|
|
399
|
-
import { PipelineCanvasProvider, type ErrorReporter } from '@
|
|
399
|
+
import { PipelineCanvasProvider, type ErrorReporter } from '@mesantosrai/pipeline-canvas';
|
|
400
400
|
|
|
401
401
|
const errorReporter: ErrorReporter = {
|
|
402
402
|
captureException: (error, context) => {
|
|
@@ -427,7 +427,7 @@ const errorReporter: ErrorReporter = {
|
|
|
427
427
|
You can access the logger from context:
|
|
428
428
|
|
|
429
429
|
```tsx
|
|
430
|
-
import { usePipelineContext } from '@
|
|
430
|
+
import { usePipelineContext } from '@mesantosrai/pipeline-canvas';
|
|
431
431
|
|
|
432
432
|
function MyComponent() {
|
|
433
433
|
const { logger } = usePipelineContext();
|
|
@@ -456,34 +456,152 @@ The library logs:
|
|
|
456
456
|
- **No external calls**: Default logger only uses console (no network requests)
|
|
457
457
|
- **Context-aware**: All logs include relevant context (pipeline ID, node ID, etc.)
|
|
458
458
|
|
|
459
|
-
###
|
|
459
|
+
### Theming
|
|
460
460
|
|
|
461
|
-
The library uses
|
|
461
|
+
The library uses a **scoped theming system** with CSS variables prefixed with `--pc-` to avoid conflicts with your parent application's theme. This allows you to integrate the pipeline canvas into any app regardless of its existing styling.
|
|
462
|
+
|
|
463
|
+
#### Basic Setup
|
|
464
|
+
|
|
465
|
+
1. **Import the CSS file** in your main entry:
|
|
466
|
+
|
|
467
|
+
```tsx
|
|
468
|
+
// main.tsx or App.tsx
|
|
469
|
+
import '@mesantosrai/pipeline-canvas/style.css';
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
2. **Configure Tailwind** to include the library's classes:
|
|
462
473
|
|
|
463
474
|
```js
|
|
464
475
|
// tailwind.config.js
|
|
465
476
|
module.exports = {
|
|
466
477
|
content: [
|
|
467
478
|
'./src/**/*.{js,jsx,ts,tsx}',
|
|
468
|
-
'./node_modules/@
|
|
479
|
+
'./node_modules/@mesantosrai/pipeline-canvas/**/*.{js,jsx,ts,tsx}',
|
|
469
480
|
],
|
|
470
481
|
theme: {
|
|
471
|
-
extend: {
|
|
472
|
-
// shadcn/ui theme variables are included in the library's style.css
|
|
473
|
-
},
|
|
482
|
+
extend: {},
|
|
474
483
|
},
|
|
475
|
-
// ... rest of config
|
|
476
484
|
};
|
|
477
485
|
```
|
|
478
486
|
|
|
479
|
-
|
|
487
|
+
#### Using the Theme Wrapper
|
|
488
|
+
|
|
489
|
+
The `PipelineThemeWrapper` component provides theme isolation and supports light/dark modes:
|
|
480
490
|
|
|
481
491
|
```tsx
|
|
482
|
-
|
|
483
|
-
|
|
492
|
+
import {
|
|
493
|
+
PipelineCanvas,
|
|
494
|
+
PipelineThemeWrapper,
|
|
495
|
+
PipelineCanvasProvider
|
|
496
|
+
} from '@mesantosrai/pipeline-canvas';
|
|
497
|
+
|
|
498
|
+
// Option 1: Follow system preference (default)
|
|
499
|
+
<PipelineThemeWrapper>
|
|
500
|
+
<PipelineCanvasProvider {...deps}>
|
|
501
|
+
<PipelineCanvas />
|
|
502
|
+
</PipelineCanvasProvider>
|
|
503
|
+
</PipelineThemeWrapper>
|
|
504
|
+
|
|
505
|
+
// Option 2: Force a specific theme
|
|
506
|
+
<PipelineThemeWrapper theme="dark">
|
|
507
|
+
<PipelineCanvasProvider {...deps}>
|
|
508
|
+
<PipelineCanvas />
|
|
509
|
+
</PipelineCanvasProvider>
|
|
510
|
+
</PipelineThemeWrapper>
|
|
511
|
+
|
|
512
|
+
// Option 3: Sync with your app's theme state
|
|
513
|
+
const [appTheme, setAppTheme] = useState<'light' | 'dark'>('dark');
|
|
514
|
+
|
|
515
|
+
<PipelineThemeWrapper externalTheme={appTheme}>
|
|
516
|
+
<PipelineCanvasProvider {...deps}>
|
|
517
|
+
<PipelineCanvas />
|
|
518
|
+
</PipelineCanvasProvider>
|
|
519
|
+
</PipelineThemeWrapper>
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
#### Theme Toggle Button
|
|
523
|
+
|
|
524
|
+
Include a theme toggle button using the `PipelineThemeToggle` component:
|
|
525
|
+
|
|
526
|
+
```tsx
|
|
527
|
+
import { PipelineThemeToggle, PipelineThemeWrapper } from '@mesantosrai/pipeline-canvas';
|
|
528
|
+
|
|
529
|
+
<PipelineThemeWrapper>
|
|
530
|
+
<div className="flex justify-end p-2">
|
|
531
|
+
<PipelineThemeToggle />
|
|
532
|
+
</div>
|
|
533
|
+
<PipelineCanvasProvider {...deps}>
|
|
534
|
+
<PipelineCanvas />
|
|
535
|
+
</PipelineCanvasProvider>
|
|
536
|
+
</PipelineThemeWrapper>
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
#### Using the Theme Hook
|
|
540
|
+
|
|
541
|
+
Access the current theme programmatically:
|
|
542
|
+
|
|
543
|
+
```tsx
|
|
544
|
+
import { usePipelineTheme, useIsDarkTheme } from '@mesantosrai/pipeline-canvas';
|
|
545
|
+
|
|
546
|
+
function MyComponent() {
|
|
547
|
+
const { theme, resolvedTheme, setTheme, toggleTheme } = usePipelineTheme();
|
|
548
|
+
const isDark = useIsDarkTheme();
|
|
549
|
+
|
|
550
|
+
return (
|
|
551
|
+
<div>
|
|
552
|
+
<p>Current theme: {resolvedTheme}</p>
|
|
553
|
+
<button onClick={toggleTheme}>Toggle Theme</button>
|
|
554
|
+
</div>
|
|
555
|
+
);
|
|
556
|
+
}
|
|
484
557
|
```
|
|
485
558
|
|
|
486
|
-
|
|
559
|
+
#### Customizing Theme Colors
|
|
560
|
+
|
|
561
|
+
Override the CSS variables in your own stylesheet to customize colors:
|
|
562
|
+
|
|
563
|
+
```css
|
|
564
|
+
/* Your app's CSS file */
|
|
565
|
+
.pipeline-canvas-root {
|
|
566
|
+
/* Light theme overrides */
|
|
567
|
+
--pc-primary: 210 100% 50%;
|
|
568
|
+
--pc-canvas-bg: 0 0% 98%;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
.pipeline-canvas-root[data-theme="dark"] {
|
|
572
|
+
/* Dark theme overrides */
|
|
573
|
+
--pc-primary: 210 100% 60%;
|
|
574
|
+
--pc-canvas-bg: 220 20% 10%;
|
|
575
|
+
}
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
#### Available CSS Variables
|
|
579
|
+
|
|
580
|
+
| Variable | Description |
|
|
581
|
+
|----------|-------------|
|
|
582
|
+
| `--pc-background` | Main background color |
|
|
583
|
+
| `--pc-foreground` | Main text color |
|
|
584
|
+
| `--pc-card` | Card/panel background |
|
|
585
|
+
| `--pc-primary` | Primary accent color |
|
|
586
|
+
| `--pc-secondary` | Secondary color |
|
|
587
|
+
| `--pc-muted` | Muted/disabled color |
|
|
588
|
+
| `--pc-border` | Border color |
|
|
589
|
+
| `--pc-canvas-bg` | Canvas background |
|
|
590
|
+
| `--pc-toolbar-bg` | Toolbar background |
|
|
591
|
+
| `--pc-sidebar-bg` | Sidebar background |
|
|
592
|
+
| `--pc-panel-bg` | Panel background |
|
|
593
|
+
| `--pc-text-primary` | Primary text |
|
|
594
|
+
| `--pc-text-secondary` | Secondary text |
|
|
595
|
+
| `--pc-text-muted` | Muted text |
|
|
596
|
+
|
|
597
|
+
#### Theme Props Reference
|
|
598
|
+
|
|
599
|
+
| Prop | Type | Default | Description |
|
|
600
|
+
|------|------|---------|-------------|
|
|
601
|
+
| `theme` | `'light' \| 'dark' \| 'system'` | `'system'` | Theme preference |
|
|
602
|
+
| `externalTheme` | `'light' \| 'dark'` | - | External theme override from parent app |
|
|
603
|
+
| `onThemeChange` | `(theme: 'light' \| 'dark') => void` | - | Callback when theme changes |
|
|
604
|
+
| `className` | `string` | - | Additional CSS classes |
|
|
487
605
|
|
|
488
606
|
## Development
|
|
489
607
|
|
|
@@ -518,7 +636,12 @@ pipeline-canvas/
|
|
|
518
636
|
│ ├── PipelineExecution.tsx
|
|
519
637
|
│ ├── PipelineManager.tsx
|
|
520
638
|
│ ├── CustomHandle.tsx
|
|
521
|
-
│
|
|
639
|
+
│ ├── ExecutionLogsPanel.tsx
|
|
640
|
+
│ ├── PipelineThemeWrapper.tsx # Theme isolation wrapper
|
|
641
|
+
│ └── index.ts
|
|
642
|
+
├── context/ # React contexts
|
|
643
|
+
│ ├── PipelineContext.tsx
|
|
644
|
+
│ └── ThemeContext.tsx # Theme state management
|
|
522
645
|
├── nodes/ # Node type configurations (JSON)
|
|
523
646
|
│ ├── input_node/
|
|
524
647
|
│ ├── rfdiffusion_node/
|
|
@@ -533,7 +656,7 @@ pipeline-canvas/
|
|
|
533
656
|
│ └── nodeLoader.ts
|
|
534
657
|
├── dist/ # Build output (generated)
|
|
535
658
|
├── index.ts # Main export file
|
|
536
|
-
├── style.css # CSS styles
|
|
659
|
+
├── style.css # CSS styles (scoped --pc- variables)
|
|
537
660
|
├── package.json
|
|
538
661
|
├── tsconfig.json
|
|
539
662
|
└── vite.config.ts
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { jsxs as
|
|
1
|
+
import { jsxs as s, jsx as e } from "react/jsx-runtime";
|
|
2
2
|
import { usePipelineStore as w } from "../store/pipelineStore.mjs";
|
|
3
|
-
import { Loader2 as x, CheckCircle2 as f, FileInput as
|
|
4
|
-
const
|
|
3
|
+
import { Loader2 as x, CheckCircle2 as f, FileInput as g, ChevronRight as L, Clock as I, ExternalLink as S, ChevronDown as p, XCircle as j, Atom as C, Dna as $, Sparkles as _ } from "lucide-react";
|
|
4
|
+
const v = (t) => {
|
|
5
5
|
switch (t) {
|
|
6
6
|
case "input_node":
|
|
7
|
-
return /* @__PURE__ */ e(
|
|
7
|
+
return /* @__PURE__ */ e(g, { className: "w-4 h-4" });
|
|
8
8
|
case "rfdiffusion_node":
|
|
9
9
|
return /* @__PURE__ */ e(_, { className: "w-4 h-4" });
|
|
10
10
|
case "proteinmpnn_node":
|
|
@@ -14,7 +14,7 @@ const N = (t) => {
|
|
|
14
14
|
default:
|
|
15
15
|
return /* @__PURE__ */ e("div", { className: "w-4 h-4 rounded bg-gray-600" });
|
|
16
16
|
}
|
|
17
|
-
},
|
|
17
|
+
}, N = (t) => {
|
|
18
18
|
switch (t) {
|
|
19
19
|
case "input_node":
|
|
20
20
|
return "text-blue-400";
|
|
@@ -27,29 +27,29 @@ const N = (t) => {
|
|
|
27
27
|
default:
|
|
28
28
|
return "text-gray-400";
|
|
29
29
|
}
|
|
30
|
-
},
|
|
30
|
+
}, c = (t) => {
|
|
31
31
|
if (t < 1e3) return `${t}ms`;
|
|
32
32
|
if (t < 6e4) return `${(t / 1e3).toFixed(1)}s`;
|
|
33
|
-
const
|
|
34
|
-
return `${
|
|
35
|
-
},
|
|
33
|
+
const r = Math.floor(t / 6e4), l = Math.floor(t % 6e4 / 1e3);
|
|
34
|
+
return `${r}m ${l}s`;
|
|
35
|
+
}, b = (t) => new Date(t).toLocaleTimeString("en-US", {
|
|
36
36
|
hour: "2-digit",
|
|
37
37
|
minute: "2-digit",
|
|
38
38
|
second: "2-digit",
|
|
39
39
|
hour12: !1
|
|
40
|
-
}), T = ({ log: t, isSelected:
|
|
40
|
+
}), T = ({ log: t, isSelected: r, onSelect: l }) => /* @__PURE__ */ s(
|
|
41
41
|
"div",
|
|
42
42
|
{
|
|
43
|
-
onClick:
|
|
43
|
+
onClick: l,
|
|
44
44
|
className: `
|
|
45
45
|
group flex items-center gap-3 px-3 py-2.5 cursor-pointer transition-all animate-slide-in
|
|
46
|
-
${
|
|
46
|
+
${r ? "bg-blue-500/10 border-l-2 border-blue-400" : "hover:bg-gray-700/30 border-l-2 border-transparent"}
|
|
47
47
|
`,
|
|
48
48
|
children: [
|
|
49
49
|
(() => {
|
|
50
50
|
switch (t.status) {
|
|
51
51
|
case "running":
|
|
52
|
-
return /* @__PURE__ */
|
|
52
|
+
return /* @__PURE__ */ s("div", { className: "relative", children: [
|
|
53
53
|
/* @__PURE__ */ e("div", { className: "w-5 h-5 rounded-full bg-blue-500/20 flex items-center justify-center", children: /* @__PURE__ */ e(x, { className: "w-3 h-3 animate-spin text-blue-400" }) }),
|
|
54
54
|
/* @__PURE__ */ e("div", { className: "absolute inset-0 rounded-full bg-blue-500/30 animate-ping" })
|
|
55
55
|
] });
|
|
@@ -63,122 +63,122 @@ const N = (t) => {
|
|
|
63
63
|
return /* @__PURE__ */ e("div", { className: "w-5 h-5 rounded-full bg-gray-600/20 flex items-center justify-center", children: /* @__PURE__ */ e("div", { className: "w-2 h-2 rounded-full bg-gray-500" }) });
|
|
64
64
|
}
|
|
65
65
|
})(),
|
|
66
|
-
/* @__PURE__ */ e("div", { className: `${
|
|
67
|
-
/* @__PURE__ */ e("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ e("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ e("span", { className: `text-sm font-medium truncate ${
|
|
68
|
-
t.duration !== void 0 && /* @__PURE__ */ e("span", { className: "text-xs text-gray-500 font-mono", children:
|
|
69
|
-
/* @__PURE__ */ e(L, { className: `w-4 h-4 text-gray-500 transition-transform ${
|
|
66
|
+
/* @__PURE__ */ e("div", { className: `${N(t.nodeType)}`, children: v(t.nodeType) }),
|
|
67
|
+
/* @__PURE__ */ e("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ e("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ e("span", { className: `text-sm font-medium truncate ${r ? "text-gray-100" : "text-gray-300"}`, children: t.nodeLabel }) }) }),
|
|
68
|
+
t.duration !== void 0 && /* @__PURE__ */ e("span", { className: "text-xs text-gray-500 font-mono", children: c(t.duration) }),
|
|
69
|
+
/* @__PURE__ */ e(L, { className: `w-4 h-4 text-gray-500 transition-transform ${r ? "rotate-90" : ""}` })
|
|
70
70
|
]
|
|
71
71
|
}
|
|
72
|
-
), k = ({ log: t }) => /* @__PURE__ */
|
|
73
|
-
/* @__PURE__ */
|
|
74
|
-
/* @__PURE__ */
|
|
75
|
-
/* @__PURE__ */ e("div", { className:
|
|
76
|
-
/* @__PURE__ */ e("h3", { className: "text-sm font-semibold text-
|
|
72
|
+
), k = ({ log: t }) => /* @__PURE__ */ s("div", { className: "border-l border-gray-200 pc-bg-canvas flex flex-col h-full", children: [
|
|
73
|
+
/* @__PURE__ */ s("div", { className: "px-4 py-3 border-b border-gray-200 pc-bg-panel", children: [
|
|
74
|
+
/* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
|
|
75
|
+
/* @__PURE__ */ e("div", { className: N(t.nodeType), children: v(t.nodeType) }),
|
|
76
|
+
/* @__PURE__ */ e("h3", { className: "text-sm font-semibold text-[hsl(var(--pc-text-primary))]", children: t.nodeLabel })
|
|
77
77
|
] }),
|
|
78
|
-
/* @__PURE__ */
|
|
79
|
-
t.duration !== void 0 && /* @__PURE__ */
|
|
78
|
+
/* @__PURE__ */ s("div", { className: "flex items-center gap-4 mt-2 text-xs text-[hsl(var(--pc-text-muted))]", children: [
|
|
79
|
+
t.duration !== void 0 && /* @__PURE__ */ s("div", { className: "flex items-center gap-1", children: [
|
|
80
80
|
/* @__PURE__ */ e(I, { className: "w-3 h-3" }),
|
|
81
|
-
/* @__PURE__ */ e("span", { children:
|
|
81
|
+
/* @__PURE__ */ e("span", { children: c(t.duration) })
|
|
82
82
|
] }),
|
|
83
|
-
t.startedAt && /* @__PURE__ */
|
|
83
|
+
t.startedAt && /* @__PURE__ */ s("span", { children: [
|
|
84
84
|
"Started at ",
|
|
85
|
-
|
|
85
|
+
b(t.startedAt)
|
|
86
86
|
] })
|
|
87
87
|
] }),
|
|
88
|
-
(t.status === "success" || t.status === "completed") && /* @__PURE__ */
|
|
88
|
+
(t.status === "success" || t.status === "completed") && /* @__PURE__ */ s("button", { className: "mt-2 flex items-center gap-1 text-xs text-blue-400 hover:text-blue-300 transition-colors", children: [
|
|
89
89
|
/* @__PURE__ */ e(S, { className: "w-3 h-3" }),
|
|
90
90
|
"View sub-execution"
|
|
91
91
|
] })
|
|
92
92
|
] }),
|
|
93
|
-
/* @__PURE__ */
|
|
94
|
-
/* @__PURE__ */
|
|
95
|
-
/* @__PURE__ */ e(
|
|
96
|
-
/* @__PURE__ */ e("span", { className: "text-sm font-medium text-
|
|
93
|
+
/* @__PURE__ */ s("div", { className: "px-4 py-3 border-b border-gray-200", children: [
|
|
94
|
+
/* @__PURE__ */ s("button", { className: "flex items-center gap-2 w-full", children: [
|
|
95
|
+
/* @__PURE__ */ e(p, { className: "w-4 h-4 text-[hsl(var(--pc-text-muted))]" }),
|
|
96
|
+
/* @__PURE__ */ e("span", { className: "text-sm font-medium text-[hsl(var(--pc-text-secondary))]", children: "Input" })
|
|
97
97
|
] }),
|
|
98
|
-
/* @__PURE__ */ e("div", { className: "mt-3 bg-
|
|
98
|
+
/* @__PURE__ */ e("div", { className: "mt-3 bg-[hsl(var(--pc-muted)/0.3)] rounded-lg p-3 text-xs font-mono text-[hsl(var(--pc-text-secondary))] overflow-x-auto border border-gray-200", children: /* @__PURE__ */ e("pre", { className: "whitespace-pre-wrap", children: JSON.stringify(t.input || { query: { message: "..." } }, null, 2) }) })
|
|
99
99
|
] }),
|
|
100
|
-
/* @__PURE__ */
|
|
101
|
-
/* @__PURE__ */
|
|
102
|
-
/* @__PURE__ */ e(
|
|
103
|
-
/* @__PURE__ */ e("span", { className: "text-sm font-medium text-
|
|
100
|
+
/* @__PURE__ */ s("div", { className: "px-4 py-3 flex-1 overflow-y-auto", children: [
|
|
101
|
+
/* @__PURE__ */ s("button", { className: "flex items-center gap-2 w-full", children: [
|
|
102
|
+
/* @__PURE__ */ e(p, { className: "w-4 h-4 text-[hsl(var(--pc-text-muted))]" }),
|
|
103
|
+
/* @__PURE__ */ e("span", { className: "text-sm font-medium text-[hsl(var(--pc-text-secondary))]", children: "Output" })
|
|
104
104
|
] }),
|
|
105
|
-
/* @__PURE__ */ e("div", { className: "mt-3 bg-
|
|
105
|
+
/* @__PURE__ */ e("div", { className: "mt-3 bg-[hsl(var(--pc-muted)/0.3)] rounded-lg p-3 text-xs font-mono text-[hsl(var(--pc-text-secondary))] overflow-x-auto border border-gray-200", children: /* @__PURE__ */ e("pre", { className: "whitespace-pre-wrap", children: t.error ? /* @__PURE__ */ e("span", { className: "text-red-400", children: JSON.stringify({ error: t.error }, null, 2) }) : JSON.stringify(t.output || { message: "..." }, null, 2) }) })
|
|
106
106
|
] })
|
|
107
107
|
] }), J = () => {
|
|
108
108
|
const {
|
|
109
109
|
currentPipeline: t,
|
|
110
|
-
currentExecution:
|
|
111
|
-
selectedLogNodeId:
|
|
112
|
-
setSelectedLogNodeId:
|
|
110
|
+
currentExecution: r,
|
|
111
|
+
selectedLogNodeId: l,
|
|
112
|
+
setSelectedLogNodeId: i,
|
|
113
113
|
isExecuting: d
|
|
114
|
-
} = w(), o = (
|
|
115
|
-
nodeId:
|
|
116
|
-
nodeLabel:
|
|
117
|
-
nodeType:
|
|
118
|
-
status:
|
|
119
|
-
}))) || [], m =
|
|
120
|
-
return /* @__PURE__ */
|
|
121
|
-
/* @__PURE__ */
|
|
122
|
-
/* @__PURE__ */
|
|
123
|
-
/* @__PURE__ */
|
|
124
|
-
/* @__PURE__ */ e("span", { className: "text-sm font-semibold text-
|
|
125
|
-
h > 0 && /* @__PURE__ */
|
|
114
|
+
} = w(), o = (r == null ? void 0 : r.logs) || [], n = o.length > 0 ? o : (t == null ? void 0 : t.nodes.map((a) => ({
|
|
115
|
+
nodeId: a.id,
|
|
116
|
+
nodeLabel: a.label,
|
|
117
|
+
nodeType: a.type,
|
|
118
|
+
status: a.status
|
|
119
|
+
}))) || [], m = n.find((a) => a.nodeId === l), u = n.filter((a) => a.status === "success" || a.status === "completed").length, h = n.reduce((a, y) => a + (y.duration || 0), 0);
|
|
120
|
+
return /* @__PURE__ */ s("div", { className: "h-full flex flex-col pc-bg-panel", children: [
|
|
121
|
+
/* @__PURE__ */ s("div", { className: "px-4 py-3 border-b border-gray-200 bg-gradient-to-r from-[hsl(var(--pc-canvas-bg))] to-[hsl(var(--pc-panel-bg))]", children: [
|
|
122
|
+
/* @__PURE__ */ s("div", { className: "flex items-center justify-between", children: [
|
|
123
|
+
/* @__PURE__ */ s("div", { children: [
|
|
124
|
+
/* @__PURE__ */ e("span", { className: "text-sm font-semibold text-[hsl(var(--pc-text-primary))]", children: d ? "Running..." : r ? "Execution Complete" : "Logs from Pipeline" }),
|
|
125
|
+
h > 0 && /* @__PURE__ */ s("span", { className: "ml-2 text-xs text-[hsl(var(--pc-text-muted))]", children: [
|
|
126
126
|
"| ",
|
|
127
|
-
|
|
127
|
+
c(h)
|
|
128
128
|
] }),
|
|
129
|
-
(
|
|
129
|
+
(r == null ? void 0 : r.startedAt) && /* @__PURE__ */ s("span", { className: "ml-2 text-xs text-[hsl(var(--pc-text-muted))]", children: [
|
|
130
130
|
"| Started at ",
|
|
131
|
-
|
|
131
|
+
b(r.startedAt)
|
|
132
132
|
] })
|
|
133
133
|
] }),
|
|
134
|
-
/* @__PURE__ */
|
|
135
|
-
/* @__PURE__ */
|
|
134
|
+
/* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
|
|
135
|
+
/* @__PURE__ */ s("span", { className: "text-xs text-[hsl(var(--pc-text-muted))]", children: [
|
|
136
136
|
u,
|
|
137
137
|
" / ",
|
|
138
|
-
|
|
138
|
+
n.length,
|
|
139
139
|
" nodes"
|
|
140
140
|
] }),
|
|
141
|
-
d && /* @__PURE__ */
|
|
141
|
+
d && /* @__PURE__ */ s("span", { className: "relative flex h-2 w-2", children: [
|
|
142
142
|
/* @__PURE__ */ e("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75" }),
|
|
143
143
|
/* @__PURE__ */ e("span", { className: "relative inline-flex rounded-full h-2 w-2 bg-green-500" })
|
|
144
144
|
] })
|
|
145
145
|
] })
|
|
146
146
|
] }),
|
|
147
|
-
|
|
147
|
+
n.length > 0 && /* @__PURE__ */ e("div", { className: "mt-3 w-full bg-[hsl(var(--pc-muted)/0.5)] rounded-full h-1.5 overflow-hidden", children: /* @__PURE__ */ e(
|
|
148
148
|
"div",
|
|
149
149
|
{
|
|
150
150
|
className: `h-1.5 rounded-full transition-all duration-500 ${d ? "bg-blue-500 animate-shimmer" : "bg-green-500"}`,
|
|
151
|
-
style: { width: `${u /
|
|
151
|
+
style: { width: `${u / n.length * 100}%` }
|
|
152
152
|
}
|
|
153
153
|
) })
|
|
154
154
|
] }),
|
|
155
|
-
/* @__PURE__ */
|
|
156
|
-
/* @__PURE__ */
|
|
157
|
-
/* @__PURE__ */ e("div", { className: "px-3 py-2.5 bg-
|
|
155
|
+
/* @__PURE__ */ s("div", { className: "flex-1 flex min-h-0", children: [
|
|
156
|
+
/* @__PURE__ */ s("div", { className: "w-64 border-r border-gray-200 flex flex-col bg-[hsl(var(--pc-canvas-bg)/0.5)]", children: [
|
|
157
|
+
/* @__PURE__ */ e("div", { className: "px-3 py-2.5 bg-[hsl(var(--pc-muted)/0.3)] border-b border-gray-200", children: /* @__PURE__ */ s("span", { className: "text-xs font-medium text-[hsl(var(--pc-text-muted))] uppercase tracking-wider", children: [
|
|
158
158
|
"Latest Logs from ",
|
|
159
159
|
(t == null ? void 0 : t.name) || "Pipeline"
|
|
160
160
|
] }) }),
|
|
161
|
-
/* @__PURE__ */
|
|
162
|
-
/* @__PURE__ */
|
|
161
|
+
/* @__PURE__ */ s("div", { className: "flex-1 overflow-y-auto", children: [
|
|
162
|
+
/* @__PURE__ */ s("div", { className: "px-3 py-2.5 flex items-center gap-2 bg-[hsl(var(--pc-muted)/0.2)] border-b border-gray-200", children: [
|
|
163
163
|
/* @__PURE__ */ e("div", { className: "w-5 h-5 rounded bg-green-500/20 flex items-center justify-center", children: d ? /* @__PURE__ */ e(x, { className: "w-3 h-3 animate-spin text-green-400" }) : /* @__PURE__ */ e(f, { className: "w-3 h-3 text-green-400" }) }),
|
|
164
|
-
/* @__PURE__ */ e("span", { className: "text-sm font-medium text-
|
|
164
|
+
/* @__PURE__ */ e("span", { className: "text-sm font-medium text-[hsl(var(--pc-text-secondary))]", children: (t == null ? void 0 : t.name) || "Pipeline" })
|
|
165
165
|
] }),
|
|
166
|
-
/* @__PURE__ */ e("div", { className: "pl-2", children:
|
|
166
|
+
/* @__PURE__ */ e("div", { className: "pl-2", children: n.map((a) => /* @__PURE__ */ e(
|
|
167
167
|
T,
|
|
168
168
|
{
|
|
169
|
-
log:
|
|
170
|
-
isSelected:
|
|
171
|
-
onSelect: () =>
|
|
172
|
-
|
|
169
|
+
log: a,
|
|
170
|
+
isSelected: l === a.nodeId,
|
|
171
|
+
onSelect: () => i(
|
|
172
|
+
l === a.nodeId ? null : a.nodeId
|
|
173
173
|
)
|
|
174
174
|
},
|
|
175
|
-
|
|
175
|
+
a.nodeId
|
|
176
176
|
)) })
|
|
177
177
|
] })
|
|
178
178
|
] }),
|
|
179
|
-
/* @__PURE__ */ e("div", { className: "flex-1 min-w-0", children: m ? /* @__PURE__ */ e(k, { log: m }) : /* @__PURE__ */ e("div", { className: "h-full flex items-center justify-center bg-
|
|
180
|
-
/* @__PURE__ */ e("div", { className: "w-12 h-12 rounded-full bg-
|
|
181
|
-
/* @__PURE__ */ e("p", { className: "text-sm text-
|
|
179
|
+
/* @__PURE__ */ e("div", { className: "flex-1 min-w-0", children: m ? /* @__PURE__ */ e(k, { log: m }) : /* @__PURE__ */ e("div", { className: "h-full flex items-center justify-center pc-bg-canvas", children: /* @__PURE__ */ s("div", { className: "text-center", children: [
|
|
180
|
+
/* @__PURE__ */ e("div", { className: "w-12 h-12 rounded-full bg-[hsl(var(--pc-muted)/0.5)] flex items-center justify-center mx-auto mb-3", children: /* @__PURE__ */ e(g, { className: "w-5 h-5 text-[hsl(var(--pc-text-muted))]" }) }),
|
|
181
|
+
/* @__PURE__ */ e("p", { className: "text-sm text-[hsl(var(--pc-text-muted))]", children: "Select a node to view execution details" })
|
|
182
182
|
] }) }) })
|
|
183
183
|
] })
|
|
184
184
|
] });
|