@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.
Files changed (33) hide show
  1. package/README.md +151 -28
  2. package/dist/components/ExecutionLogsPanel.mjs +77 -77
  3. package/dist/components/ExecutionLogsPanel.mjs.map +1 -1
  4. package/dist/components/NodeContextMenu.mjs +32 -32
  5. package/dist/components/NodeContextMenu.mjs.map +1 -1
  6. package/dist/components/PipelineCanvas.d.ts.map +1 -1
  7. package/dist/components/PipelineCanvas.mjs +199 -193
  8. package/dist/components/PipelineCanvas.mjs.map +1 -1
  9. package/dist/components/PipelineNodeConfig.d.ts.map +1 -1
  10. package/dist/components/PipelineNodeConfig.mjs +680 -668
  11. package/dist/components/PipelineNodeConfig.mjs.map +1 -1
  12. package/dist/components/PipelineNodePalette.mjs +22 -22
  13. package/dist/components/PipelineNodePalette.mjs.map +1 -1
  14. package/dist/components/PipelineThemeWrapper.d.ts +69 -0
  15. package/dist/components/PipelineThemeWrapper.d.ts.map +1 -0
  16. package/dist/components/PipelineThemeWrapper.mjs +45 -0
  17. package/dist/components/PipelineThemeWrapper.mjs.map +1 -0
  18. package/dist/components/SavePipelineDialog.mjs +48 -48
  19. package/dist/components/SavePipelineDialog.mjs.map +1 -1
  20. package/dist/components/SavedPipelinesList.mjs +63 -63
  21. package/dist/components/SavedPipelinesList.mjs.map +1 -1
  22. package/dist/components/index.d.ts +2 -0
  23. package/dist/components/index.d.ts.map +1 -1
  24. package/dist/context/ThemeContext.d.ts +41 -0
  25. package/dist/context/ThemeContext.d.ts.map +1 -0
  26. package/dist/context/ThemeContext.mjs +44 -0
  27. package/dist/context/ThemeContext.mjs.map +1 -0
  28. package/dist/index.d.ts +4 -1
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.mjs +41 -34
  31. package/dist/index.mjs.map +1 -1
  32. package/dist/store/pipelineStore.mjs.map +1 -1
  33. package/package.json +3 -19
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @novoprotein/pipeline-canvas
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 '@novoprotein/pipeline-canvas';
64
- import '@novoprotein/pipeline-canvas/style.css';
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 '@novoprotein/pipeline-canvas';
94
- import '@novoprotein/pipeline-canvas/style.css';
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 '@novoprotein/pipeline-canvas';
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 '@novoprotein/pipeline-canvas';
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 '@novoprotein/pipeline-canvas';
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 '@novoprotein/pipeline-canvas';
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 '@novoprotein/pipeline-canvas';
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 '@novoprotein/pipeline-canvas';
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 '@novoprotein/pipeline-canvas';
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 '@novoprotein/pipeline-canvas';
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 '@novoprotein/pipeline-canvas';
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 '@novoprotein/pipeline-canvas';
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
- ### Styling
459
+ ### Theming
460
460
 
461
- The library uses Tailwind CSS classes and shadcn/ui CSS variables. Make sure Tailwind is configured in your project:
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/@novoprotein/pipeline-canvas/**/*.{js,jsx,ts,tsx}',
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
- Also import the CSS file in your main entry:
487
+ #### Using the Theme Wrapper
488
+
489
+ The `PipelineThemeWrapper` component provides theme isolation and supports light/dark modes:
480
490
 
481
491
  ```tsx
482
- // main.tsx or App.tsx
483
- import '@novoprotein/pipeline-canvas/style.css';
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
- The library includes shadcn/ui CSS variables for theming. The components support both light and dark themes via CSS variables.
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
- └── ExecutionLogsPanel.tsx
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 a, jsx as e } from "react/jsx-runtime";
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 p, ChevronRight as L, Clock as I, ExternalLink as S, ChevronDown as g, XCircle as j, Atom as C, Dna as $, Sparkles as _ } from "lucide-react";
4
- const N = (t) => {
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(p, { className: "w-4 h-4" });
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
- }, b = (t) => {
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
- }, i = (t) => {
30
+ }, c = (t) => {
31
31
  if (t < 1e3) return `${t}ms`;
32
32
  if (t < 6e4) return `${(t / 1e3).toFixed(1)}s`;
33
- const s = Math.floor(t / 6e4), n = Math.floor(t % 6e4 / 1e3);
34
- return `${s}m ${n}s`;
35
- }, y = (t) => new Date(t).toLocaleTimeString("en-US", {
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: s, onSelect: n }) => /* @__PURE__ */ a(
40
+ }), T = ({ log: t, isSelected: r, onSelect: l }) => /* @__PURE__ */ s(
41
41
  "div",
42
42
  {
43
- onClick: n,
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
- ${s ? "bg-blue-500/10 border-l-2 border-blue-400" : "hover:bg-gray-700/30 border-l-2 border-transparent"}
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__ */ a("div", { className: "relative", children: [
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: `${b(t.nodeType)}`, children: N(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 ${s ? "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: i(t.duration) }),
69
- /* @__PURE__ */ e(L, { className: `w-4 h-4 text-gray-500 transition-transform ${s ? "rotate-90" : ""}` })
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__ */ a("div", { className: "border-l border-gray-700/50 bg-[#1a1a2e] flex flex-col h-full", children: [
73
- /* @__PURE__ */ a("div", { className: "px-4 py-3 border-b border-gray-700/50 bg-[#1e1e32]", children: [
74
- /* @__PURE__ */ a("div", { className: "flex items-center gap-2", children: [
75
- /* @__PURE__ */ e("div", { className: b(t.nodeType), children: N(t.nodeType) }),
76
- /* @__PURE__ */ e("h3", { className: "text-sm font-semibold text-gray-200", children: t.nodeLabel })
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__ */ a("div", { className: "flex items-center gap-4 mt-2 text-xs text-gray-500", children: [
79
- t.duration !== void 0 && /* @__PURE__ */ a("div", { className: "flex items-center gap-1", children: [
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: i(t.duration) })
81
+ /* @__PURE__ */ e("span", { children: c(t.duration) })
82
82
  ] }),
83
- t.startedAt && /* @__PURE__ */ a("span", { children: [
83
+ t.startedAt && /* @__PURE__ */ s("span", { children: [
84
84
  "Started at ",
85
- y(t.startedAt)
85
+ b(t.startedAt)
86
86
  ] })
87
87
  ] }),
88
- (t.status === "success" || t.status === "completed") && /* @__PURE__ */ a("button", { className: "mt-2 flex items-center gap-1 text-xs text-blue-400 hover:text-blue-300 transition-colors", children: [
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__ */ a("div", { className: "px-4 py-3 border-b border-gray-700/50", children: [
94
- /* @__PURE__ */ a("button", { className: "flex items-center gap-2 w-full", children: [
95
- /* @__PURE__ */ e(g, { className: "w-4 h-4 text-gray-500" }),
96
- /* @__PURE__ */ e("span", { className: "text-sm font-medium text-gray-300", children: "Input" })
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-gray-900/50 rounded-lg p-3 text-xs font-mono text-gray-400 overflow-x-auto border border-gray-700/30", children: /* @__PURE__ */ e("pre", { className: "whitespace-pre-wrap", children: JSON.stringify(t.input || { query: { message: "..." } }, null, 2) }) })
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__ */ a("div", { className: "px-4 py-3 flex-1 overflow-y-auto", children: [
101
- /* @__PURE__ */ a("button", { className: "flex items-center gap-2 w-full", children: [
102
- /* @__PURE__ */ e(g, { className: "w-4 h-4 text-gray-500" }),
103
- /* @__PURE__ */ e("span", { className: "text-sm font-medium text-gray-300", children: "Output" })
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-gray-900/50 rounded-lg p-3 text-xs font-mono text-gray-400 overflow-x-auto border border-gray-700/30", 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) }) })
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: s,
111
- selectedLogNodeId: n,
112
- setSelectedLogNodeId: c,
110
+ currentExecution: r,
111
+ selectedLogNodeId: l,
112
+ setSelectedLogNodeId: i,
113
113
  isExecuting: d
114
- } = w(), o = (s == null ? void 0 : s.logs) || [], l = o.length > 0 ? o : (t == null ? void 0 : t.nodes.map((r) => ({
115
- nodeId: r.id,
116
- nodeLabel: r.label,
117
- nodeType: r.type,
118
- status: r.status
119
- }))) || [], m = l.find((r) => r.nodeId === n), u = l.filter((r) => r.status === "success" || r.status === "completed").length, h = l.reduce((r, v) => r + (v.duration || 0), 0);
120
- return /* @__PURE__ */ a("div", { className: "h-full flex flex-col bg-[#1e1e32]", children: [
121
- /* @__PURE__ */ a("div", { className: "px-4 py-3 border-b border-gray-700/50 bg-gradient-to-r from-[#1a1a2e] to-[#1e1e32]", children: [
122
- /* @__PURE__ */ a("div", { className: "flex items-center justify-between", children: [
123
- /* @__PURE__ */ a("div", { children: [
124
- /* @__PURE__ */ e("span", { className: "text-sm font-semibold text-gray-200", children: d ? "Running..." : s ? "Execution Complete" : "Logs from Pipeline" }),
125
- h > 0 && /* @__PURE__ */ a("span", { className: "ml-2 text-xs text-gray-500", children: [
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
- i(h)
127
+ c(h)
128
128
  ] }),
129
- (s == null ? void 0 : s.startedAt) && /* @__PURE__ */ a("span", { className: "ml-2 text-xs text-gray-500", children: [
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
- y(s.startedAt)
131
+ b(r.startedAt)
132
132
  ] })
133
133
  ] }),
134
- /* @__PURE__ */ a("div", { className: "flex items-center gap-2", children: [
135
- /* @__PURE__ */ a("span", { className: "text-xs text-gray-500", children: [
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
- l.length,
138
+ n.length,
139
139
  " nodes"
140
140
  ] }),
141
- d && /* @__PURE__ */ a("span", { className: "relative flex h-2 w-2", children: [
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
- l.length > 0 && /* @__PURE__ */ e("div", { className: "mt-3 w-full bg-gray-700/50 rounded-full h-1.5 overflow-hidden", children: /* @__PURE__ */ e(
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 / l.length * 100}%` }
151
+ style: { width: `${u / n.length * 100}%` }
152
152
  }
153
153
  ) })
154
154
  ] }),
155
- /* @__PURE__ */ a("div", { className: "flex-1 flex min-h-0", children: [
156
- /* @__PURE__ */ a("div", { className: "w-64 border-r border-gray-700/50 flex flex-col bg-[#1a1a2e]/50", children: [
157
- /* @__PURE__ */ e("div", { className: "px-3 py-2.5 bg-gray-800/30 border-b border-gray-700/50", children: /* @__PURE__ */ a("span", { className: "text-xs font-medium text-gray-500 uppercase tracking-wider", children: [
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__ */ a("div", { className: "flex-1 overflow-y-auto", children: [
162
- /* @__PURE__ */ a("div", { className: "px-3 py-2.5 flex items-center gap-2 bg-gray-800/20 border-b border-gray-700/30", children: [
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-gray-300", children: (t == null ? void 0 : t.name) || "Pipeline" })
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: l.map((r) => /* @__PURE__ */ e(
166
+ /* @__PURE__ */ e("div", { className: "pl-2", children: n.map((a) => /* @__PURE__ */ e(
167
167
  T,
168
168
  {
169
- log: r,
170
- isSelected: n === r.nodeId,
171
- onSelect: () => c(
172
- n === r.nodeId ? null : r.nodeId
169
+ log: a,
170
+ isSelected: l === a.nodeId,
171
+ onSelect: () => i(
172
+ l === a.nodeId ? null : a.nodeId
173
173
  )
174
174
  },
175
- r.nodeId
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-[#1a1a2e]", children: /* @__PURE__ */ a("div", { className: "text-center", children: [
180
- /* @__PURE__ */ e("div", { className: "w-12 h-12 rounded-full bg-gray-800/50 flex items-center justify-center mx-auto mb-3", children: /* @__PURE__ */ e(p, { className: "w-5 h-5 text-gray-600" }) }),
181
- /* @__PURE__ */ e("p", { className: "text-sm text-gray-500", children: "Select a node to view execution details" })
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
  ] });