@foresthubai/workflow-builder 0.3.0 → 0.4.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 +661 -661
- package/NOTICE +16 -16
- package/README.md +110 -93
- package/dist/components/ui/command.d.ts +2 -2
- package/dist/components/ui/input.d.ts +1 -1
- package/dist/components/ui/resizable.d.ts +1 -1
- package/dist/components/ui/textarea.d.ts +1 -1
- package/dist/graph/BaseNode.js +10 -10
- package/dist/graph/reactFlowRegistry.d.ts.map +1 -1
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +6 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/toolbars/CanvasTabsToolbar.d.ts +11 -0
- package/dist/toolbars/CanvasTabsToolbar.d.ts.map +1 -0
- package/dist/toolbars/CanvasTabsToolbar.js +101 -0
- package/dist/toolbars/CanvasTabsToolbar.js.map +1 -0
- package/package.json +2 -2
- package/src/BuilderLayout.tsx +345 -345
- package/src/Canvas.tsx +261 -261
- package/src/CanvasEditor.tsx +142 -142
- package/src/CanvasTabsToolbar.tsx +176 -176
- package/src/RightConfigPanel.tsx +266 -266
- package/src/WorkflowBuilder.tsx +412 -412
- package/src/cn.ts +6 -6
- package/src/components/ui/add-button.tsx +39 -39
- package/src/components/ui/alert-dialog.tsx +141 -141
- package/src/components/ui/alert.tsx +59 -59
- package/src/components/ui/badge.tsx +36 -36
- package/src/components/ui/button.tsx +85 -85
- package/src/components/ui/card.tsx +79 -79
- package/src/components/ui/checkbox.tsx +28 -28
- package/src/components/ui/collapsible.tsx +9 -9
- package/src/components/ui/command.tsx +153 -153
- package/src/components/ui/delete-button.tsx +23 -23
- package/src/components/ui/dialog.tsx +125 -125
- package/src/components/ui/dropdown-menu.tsx +198 -198
- package/src/components/ui/input.tsx +55 -55
- package/src/components/ui/label.tsx +24 -24
- package/src/components/ui/readonly-banner.tsx +15 -15
- package/src/components/ui/resizable.tsx +43 -43
- package/src/components/ui/scroll-area.tsx +102 -102
- package/src/components/ui/select.tsx +160 -160
- package/src/components/ui/separator.tsx +29 -29
- package/src/components/ui/switch.tsx +27 -27
- package/src/components/ui/textarea.tsx +51 -51
- package/src/components/ui/toast.tsx +127 -127
- package/src/components/ui/toaster.tsx +33 -33
- package/src/components/ui/toggle-group.tsx +59 -59
- package/src/components/ui/toggle.tsx +43 -43
- package/src/components/ui/tooltip.tsx +32 -32
- package/src/dialogs/NodePickerDialog.tsx +84 -84
- package/src/dialogs/ValidationDialog.tsx +184 -184
- package/src/graph/BaseNode.tsx +557 -557
- package/src/graph/CustomEdge.tsx +185 -185
- package/src/graph/CustomNode.tsx +16 -16
- package/src/graph/FunctionCallNode.tsx +30 -30
- package/src/graph/PortHandle.tsx +189 -189
- package/src/graph/reactFlowRegistry.ts +26 -26
- package/src/hooks/use-toast.ts +125 -125
- package/src/hooks/useAvailableVariables.ts +20 -20
- package/src/hooks/useCanvasHistory.ts +22 -22
- package/src/hooks/useCanvasTabs.ts +168 -168
- package/src/hooks/useFunctionDiagnosticsSync.ts +40 -40
- package/src/hooks/useFunctionRegistry.ts +26 -26
- package/src/hooks/useFunctions.ts +44 -44
- package/src/hooks/useGraph.ts +161 -161
- package/src/hooks/useNodeDefinitions.ts +82 -82
- package/src/hooks/useParamErrors.ts +26 -26
- package/src/hooks/useResolvedTheme.ts +30 -30
- package/src/hooks/useResourceDiagnosticsSync.ts +58 -58
- package/src/hooks/useSuppressThemeTransition.ts +79 -79
- package/src/hooks/useWorkflowSerialization.ts +127 -127
- package/src/i18n/index.ts +53 -53
- package/src/i18n/locales/de.json +501 -501
- package/src/i18n/locales/en.json +557 -557
- package/src/index.ts +27 -27
- package/src/inputs/ExpressionInput.tsx +297 -297
- package/src/inputs/ParameterEditor.tsx +515 -515
- package/src/inputs/PortSection.tsx +144 -144
- package/src/panels/BuilderSidebar.tsx +301 -301
- package/src/panels/ChannelConfigPanel.tsx +49 -49
- package/src/panels/ChannelsPanel.tsx +28 -28
- package/src/panels/DebugConsolePanel.tsx +73 -73
- package/src/panels/DebugContextPanel.tsx +77 -77
- package/src/panels/DebugExternalIOPanel.tsx +180 -180
- package/src/panels/DiagnosticsPanel.tsx +170 -170
- package/src/panels/EdgeConfigPanel.tsx +104 -104
- package/src/panels/FunctionConfigPanel.tsx +179 -179
- package/src/panels/FunctionListPanel.tsx +45 -45
- package/src/panels/MemoryConfigPanel.tsx +55 -55
- package/src/panels/MemoryPanel.tsx +40 -40
- package/src/panels/ModelConfigPanel.tsx +41 -41
- package/src/panels/ModelsPanel.tsx +36 -36
- package/src/panels/NodeConfigPanel.tsx +630 -630
- package/src/panels/NodeLibrary.tsx +288 -288
- package/src/panels/ResourceConfigPanel.tsx +132 -132
- package/src/panels/ResourceListPanel.tsx +113 -113
- package/src/panels/VariableConfigPanel.tsx +161 -161
- package/src/panels/VariablesPanel.tsx +145 -145
- package/src/stores/canvasStore.test.ts +44 -44
- package/src/stores/canvasStore.ts +245 -245
- package/src/stores/debugStore.ts +74 -74
- package/src/stores/diagnosticsStore.ts +130 -130
- package/src/stores/editorStore.ts +202 -202
- package/src/styles/index.css +526 -526
- package/src/utils/categoryConstants.ts +26 -26
- package/src/utils/channelOperations.ts +86 -86
- package/src/utils/connectionRules.ts +137 -137
- package/src/utils/functionOperations.ts +179 -179
- package/src/utils/graphOperations.ts +550 -550
- package/src/utils/history.ts +207 -207
- package/src/utils/memoryOperations.ts +57 -57
- package/src/utils/migrateFunctionNodes.ts +107 -107
- package/src/utils/modelOperations.ts +55 -55
- package/src/utils/paramDisplay.ts +71 -71
- package/src/utils/resourceHelpers.ts +32 -32
- package/src/utils/translation.ts +28 -28
- package/src/utils/variableOperations.ts +75 -75
- package/tailwind-preset.ts +166 -166
|
@@ -1,144 +1,144 @@
|
|
|
1
|
-
import type { ReactNode } from "react";
|
|
2
|
-
import { Button } from "../components/ui/button";
|
|
3
|
-
import { Input } from "../components/ui/input";
|
|
4
|
-
import { Label } from "../components/ui/label";
|
|
5
|
-
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../components/ui/select";
|
|
6
|
-
import { AddButton } from "../components/ui/add-button";
|
|
7
|
-
import { Trash2 } from "lucide-react";
|
|
8
|
-
import type { DataType } from "@foresthubai/workflow-core";
|
|
9
|
-
|
|
10
|
-
const DATA_TYPES: DataType[] = ["int", "float", "bool", "string"];
|
|
11
|
-
|
|
12
|
-
/** The editable bits of a function port: a name and a data type, keyed by uid. */
|
|
13
|
-
export interface Port {
|
|
14
|
-
uid: string;
|
|
15
|
-
name: string;
|
|
16
|
-
dataType: DataType;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* One declaration row, styled like the node Outputs rows (a `bg-card` shadow card):
|
|
21
|
-
* a header with name + dataType + remove, plus an optional body (e.g. the return
|
|
22
|
-
* expression editor for outputs).
|
|
23
|
-
*/
|
|
24
|
-
function PortRow({
|
|
25
|
-
port,
|
|
26
|
-
onUpdate,
|
|
27
|
-
onRemove,
|
|
28
|
-
errors,
|
|
29
|
-
children,
|
|
30
|
-
}: {
|
|
31
|
-
port: Port;
|
|
32
|
-
onUpdate: (patch: { name?: string; dataType?: DataType }) => void;
|
|
33
|
-
onRemove: () => void;
|
|
34
|
-
errors?: string[];
|
|
35
|
-
children?: ReactNode;
|
|
36
|
-
}) {
|
|
37
|
-
const hasError = !!errors?.length;
|
|
38
|
-
return (
|
|
39
|
-
<div
|
|
40
|
-
className={`rounded-lg bg-card shadow-sm border p-2 space-y-2 transition-all hover:shadow-md ${
|
|
41
|
-
hasError ? "border-destructive ring-1 ring-destructive" : "border-border"
|
|
42
|
-
}`}
|
|
43
|
-
>
|
|
44
|
-
<div className="flex items-center gap-2">
|
|
45
|
-
<Input
|
|
46
|
-
className="h-7 text-xs flex-1"
|
|
47
|
-
value={port.name}
|
|
48
|
-
placeholder={"name"}
|
|
49
|
-
onChange={(e) => onUpdate({ name: e.target.value })}
|
|
50
|
-
/>
|
|
51
|
-
<Select value={port.dataType} onValueChange={(dt: DataType) => onUpdate({ dataType: dt })}>
|
|
52
|
-
<SelectTrigger className="h-7 text-xs w-20">
|
|
53
|
-
<SelectValue />
|
|
54
|
-
</SelectTrigger>
|
|
55
|
-
<SelectContent>
|
|
56
|
-
{DATA_TYPES.map((dt) => (
|
|
57
|
-
<SelectItem key={dt} value={dt} className="text-xs">
|
|
58
|
-
{dt}
|
|
59
|
-
</SelectItem>
|
|
60
|
-
))}
|
|
61
|
-
</SelectContent>
|
|
62
|
-
</Select>
|
|
63
|
-
<Button
|
|
64
|
-
variant="ghost"
|
|
65
|
-
size="icon"
|
|
66
|
-
className="h-7 w-7 shrink-0 text-muted-foreground hover:text-destructive"
|
|
67
|
-
onClick={onRemove}
|
|
68
|
-
>
|
|
69
|
-
<Trash2 className="w-3.5 h-3.5" />
|
|
70
|
-
</Button>
|
|
71
|
-
</div>
|
|
72
|
-
{children}
|
|
73
|
-
{hasError && (
|
|
74
|
-
<div className="space-y-0.5">
|
|
75
|
-
{errors!.map((msg, i) => (
|
|
76
|
-
<p key={i} className="text-xs text-destructive">
|
|
77
|
-
{msg}
|
|
78
|
-
</p>
|
|
79
|
-
))}
|
|
80
|
-
</div>
|
|
81
|
-
)}
|
|
82
|
-
</div>
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* A titled section of function ports — a strong label + description (the shared
|
|
88
|
-
* panel field pattern), a card per port, and an Add button. Used for both inputs
|
|
89
|
-
* and outputs; outputs supply the return-expression editor via `renderExtra`.
|
|
90
|
-
*/
|
|
91
|
-
export function PortSection<P extends Port>({
|
|
92
|
-
title,
|
|
93
|
-
description,
|
|
94
|
-
addLabel,
|
|
95
|
-
emptyText,
|
|
96
|
-
ports,
|
|
97
|
-
onAdd,
|
|
98
|
-
onUpdate,
|
|
99
|
-
onRemove,
|
|
100
|
-
errorsFor,
|
|
101
|
-
renderExtra,
|
|
102
|
-
}: {
|
|
103
|
-
title: string;
|
|
104
|
-
description: string;
|
|
105
|
-
addLabel: string;
|
|
106
|
-
emptyText: string;
|
|
107
|
-
ports: readonly P[];
|
|
108
|
-
onAdd: () => void;
|
|
109
|
-
onUpdate: (index: number, patch: { name?: string; dataType?: DataType }) => void;
|
|
110
|
-
onRemove: (index: number) => void;
|
|
111
|
-
/** Per-port error messages — rings the row red and lists them (e.g. a missing or
|
|
112
|
-
* invalid return expression on that output). */
|
|
113
|
-
errorsFor?: (port: P) => string[];
|
|
114
|
-
renderExtra?: (port: P, index: number) => ReactNode;
|
|
115
|
-
}) {
|
|
116
|
-
return (
|
|
117
|
-
<div className="space-y-2">
|
|
118
|
-
<div>
|
|
119
|
-
<Label className="text-sm font-medium">{title}</Label>
|
|
120
|
-
<p className="text-xs text-muted-foreground">{description}</p>
|
|
121
|
-
</div>
|
|
122
|
-
|
|
123
|
-
{ports.length === 0 ? (
|
|
124
|
-
<p className="text-xs text-muted-foreground italic">{emptyText}</p>
|
|
125
|
-
) : (
|
|
126
|
-
<div className="space-y-2">
|
|
127
|
-
{ports.map((port, index) => (
|
|
128
|
-
<PortRow
|
|
129
|
-
key={port.uid}
|
|
130
|
-
port={port}
|
|
131
|
-
onUpdate={(patch) => onUpdate(index, patch)}
|
|
132
|
-
onRemove={() => onRemove(index)}
|
|
133
|
-
errors={errorsFor?.(port)}
|
|
134
|
-
>
|
|
135
|
-
{renderExtra?.(port, index)}
|
|
136
|
-
</PortRow>
|
|
137
|
-
))}
|
|
138
|
-
</div>
|
|
139
|
-
)}
|
|
140
|
-
|
|
141
|
-
<AddButton onClick={onAdd}>{addLabel}</AddButton>
|
|
142
|
-
</div>
|
|
143
|
-
);
|
|
144
|
-
}
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { Button } from "../components/ui/button";
|
|
3
|
+
import { Input } from "../components/ui/input";
|
|
4
|
+
import { Label } from "../components/ui/label";
|
|
5
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../components/ui/select";
|
|
6
|
+
import { AddButton } from "../components/ui/add-button";
|
|
7
|
+
import { Trash2 } from "lucide-react";
|
|
8
|
+
import type { DataType } from "@foresthubai/workflow-core";
|
|
9
|
+
|
|
10
|
+
const DATA_TYPES: DataType[] = ["int", "float", "bool", "string"];
|
|
11
|
+
|
|
12
|
+
/** The editable bits of a function port: a name and a data type, keyed by uid. */
|
|
13
|
+
export interface Port {
|
|
14
|
+
uid: string;
|
|
15
|
+
name: string;
|
|
16
|
+
dataType: DataType;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* One declaration row, styled like the node Outputs rows (a `bg-card` shadow card):
|
|
21
|
+
* a header with name + dataType + remove, plus an optional body (e.g. the return
|
|
22
|
+
* expression editor for outputs).
|
|
23
|
+
*/
|
|
24
|
+
function PortRow({
|
|
25
|
+
port,
|
|
26
|
+
onUpdate,
|
|
27
|
+
onRemove,
|
|
28
|
+
errors,
|
|
29
|
+
children,
|
|
30
|
+
}: {
|
|
31
|
+
port: Port;
|
|
32
|
+
onUpdate: (patch: { name?: string; dataType?: DataType }) => void;
|
|
33
|
+
onRemove: () => void;
|
|
34
|
+
errors?: string[];
|
|
35
|
+
children?: ReactNode;
|
|
36
|
+
}) {
|
|
37
|
+
const hasError = !!errors?.length;
|
|
38
|
+
return (
|
|
39
|
+
<div
|
|
40
|
+
className={`rounded-lg bg-card shadow-sm border p-2 space-y-2 transition-all hover:shadow-md ${
|
|
41
|
+
hasError ? "border-destructive ring-1 ring-destructive" : "border-border"
|
|
42
|
+
}`}
|
|
43
|
+
>
|
|
44
|
+
<div className="flex items-center gap-2">
|
|
45
|
+
<Input
|
|
46
|
+
className="h-7 text-xs flex-1"
|
|
47
|
+
value={port.name}
|
|
48
|
+
placeholder={"name"}
|
|
49
|
+
onChange={(e) => onUpdate({ name: e.target.value })}
|
|
50
|
+
/>
|
|
51
|
+
<Select value={port.dataType} onValueChange={(dt: DataType) => onUpdate({ dataType: dt })}>
|
|
52
|
+
<SelectTrigger className="h-7 text-xs w-20">
|
|
53
|
+
<SelectValue />
|
|
54
|
+
</SelectTrigger>
|
|
55
|
+
<SelectContent>
|
|
56
|
+
{DATA_TYPES.map((dt) => (
|
|
57
|
+
<SelectItem key={dt} value={dt} className="text-xs">
|
|
58
|
+
{dt}
|
|
59
|
+
</SelectItem>
|
|
60
|
+
))}
|
|
61
|
+
</SelectContent>
|
|
62
|
+
</Select>
|
|
63
|
+
<Button
|
|
64
|
+
variant="ghost"
|
|
65
|
+
size="icon"
|
|
66
|
+
className="h-7 w-7 shrink-0 text-muted-foreground hover:text-destructive"
|
|
67
|
+
onClick={onRemove}
|
|
68
|
+
>
|
|
69
|
+
<Trash2 className="w-3.5 h-3.5" />
|
|
70
|
+
</Button>
|
|
71
|
+
</div>
|
|
72
|
+
{children}
|
|
73
|
+
{hasError && (
|
|
74
|
+
<div className="space-y-0.5">
|
|
75
|
+
{errors!.map((msg, i) => (
|
|
76
|
+
<p key={i} className="text-xs text-destructive">
|
|
77
|
+
{msg}
|
|
78
|
+
</p>
|
|
79
|
+
))}
|
|
80
|
+
</div>
|
|
81
|
+
)}
|
|
82
|
+
</div>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* A titled section of function ports — a strong label + description (the shared
|
|
88
|
+
* panel field pattern), a card per port, and an Add button. Used for both inputs
|
|
89
|
+
* and outputs; outputs supply the return-expression editor via `renderExtra`.
|
|
90
|
+
*/
|
|
91
|
+
export function PortSection<P extends Port>({
|
|
92
|
+
title,
|
|
93
|
+
description,
|
|
94
|
+
addLabel,
|
|
95
|
+
emptyText,
|
|
96
|
+
ports,
|
|
97
|
+
onAdd,
|
|
98
|
+
onUpdate,
|
|
99
|
+
onRemove,
|
|
100
|
+
errorsFor,
|
|
101
|
+
renderExtra,
|
|
102
|
+
}: {
|
|
103
|
+
title: string;
|
|
104
|
+
description: string;
|
|
105
|
+
addLabel: string;
|
|
106
|
+
emptyText: string;
|
|
107
|
+
ports: readonly P[];
|
|
108
|
+
onAdd: () => void;
|
|
109
|
+
onUpdate: (index: number, patch: { name?: string; dataType?: DataType }) => void;
|
|
110
|
+
onRemove: (index: number) => void;
|
|
111
|
+
/** Per-port error messages — rings the row red and lists them (e.g. a missing or
|
|
112
|
+
* invalid return expression on that output). */
|
|
113
|
+
errorsFor?: (port: P) => string[];
|
|
114
|
+
renderExtra?: (port: P, index: number) => ReactNode;
|
|
115
|
+
}) {
|
|
116
|
+
return (
|
|
117
|
+
<div className="space-y-2">
|
|
118
|
+
<div>
|
|
119
|
+
<Label className="text-sm font-medium">{title}</Label>
|
|
120
|
+
<p className="text-xs text-muted-foreground">{description}</p>
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
{ports.length === 0 ? (
|
|
124
|
+
<p className="text-xs text-muted-foreground italic">{emptyText}</p>
|
|
125
|
+
) : (
|
|
126
|
+
<div className="space-y-2">
|
|
127
|
+
{ports.map((port, index) => (
|
|
128
|
+
<PortRow
|
|
129
|
+
key={port.uid}
|
|
130
|
+
port={port}
|
|
131
|
+
onUpdate={(patch) => onUpdate(index, patch)}
|
|
132
|
+
onRemove={() => onRemove(index)}
|
|
133
|
+
errors={errorsFor?.(port)}
|
|
134
|
+
>
|
|
135
|
+
{renderExtra?.(port, index)}
|
|
136
|
+
</PortRow>
|
|
137
|
+
))}
|
|
138
|
+
</div>
|
|
139
|
+
)}
|
|
140
|
+
|
|
141
|
+
<AddButton onClick={onAdd}>{addLabel}</AddButton>
|
|
142
|
+
</div>
|
|
143
|
+
);
|
|
144
|
+
}
|