@d34dman/flowdrop 0.0.22 → 0.0.24
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/dist/components/App.svelte +26 -25
- package/dist/components/ConfigForm.svelte +141 -520
- package/dist/components/ConfigForm.svelte.d.ts +5 -3
- package/dist/components/form/FormArray.svelte +1049 -0
- package/dist/components/form/FormArray.svelte.d.ts +22 -0
- package/dist/components/form/FormCheckboxGroup.svelte +152 -0
- package/dist/components/form/FormCheckboxGroup.svelte.d.ts +15 -0
- package/dist/components/form/FormField.svelte +297 -0
- package/dist/components/form/FormField.svelte.d.ts +18 -0
- package/dist/components/form/FormFieldWrapper.svelte +133 -0
- package/dist/components/form/FormFieldWrapper.svelte.d.ts +18 -0
- package/dist/components/form/FormNumberField.svelte +109 -0
- package/dist/components/form/FormNumberField.svelte.d.ts +23 -0
- package/dist/components/form/FormRangeField.svelte +252 -0
- package/dist/components/form/FormRangeField.svelte.d.ts +21 -0
- package/dist/components/form/FormSelect.svelte +126 -0
- package/dist/components/form/FormSelect.svelte.d.ts +18 -0
- package/dist/components/form/FormTextField.svelte +88 -0
- package/dist/components/form/FormTextField.svelte.d.ts +17 -0
- package/dist/components/form/FormTextarea.svelte +94 -0
- package/dist/components/form/FormTextarea.svelte.d.ts +19 -0
- package/dist/components/form/FormToggle.svelte +123 -0
- package/dist/components/form/FormToggle.svelte.d.ts +17 -0
- package/dist/components/form/index.d.ts +42 -0
- package/dist/components/form/index.js +46 -0
- package/dist/components/form/types.d.ts +224 -0
- package/dist/components/form/types.js +29 -0
- package/dist/components/nodes/GatewayNode.svelte +76 -16
- package/dist/components/nodes/SimpleNode.svelte +41 -5
- package/dist/components/nodes/SimpleNode.svelte.d.ts +2 -1
- package/dist/components/nodes/SquareNode.svelte +41 -5
- package/dist/components/nodes/SquareNode.svelte.d.ts +2 -1
- package/dist/components/nodes/WorkflowNode.svelte +88 -5
- package/dist/index.d.ts +2 -3
- package/dist/index.js +1 -3
- package/dist/stores/workflowStore.d.ts +15 -0
- package/dist/stores/workflowStore.js +28 -0
- package/dist/types/index.d.ts +176 -1
- package/dist/types/index.js +16 -0
- package/package.json +3 -3
- package/dist/config/demo.d.ts +0 -58
- package/dist/config/demo.js +0 -142
- package/dist/data/samples.d.ts +0 -51
- package/dist/data/samples.js +0 -3245
|
@@ -3,20 +3,18 @@
|
|
|
3
3
|
Visual representation of gateway/branch nodes with branching flow indicators
|
|
4
4
|
Shows active branches and execution paths
|
|
5
5
|
Styled with BEM syntax following WorkflowNode pattern
|
|
6
|
+
|
|
7
|
+
UI Extensions Support:
|
|
8
|
+
- hideUnconnectedHandles: Hides ports that are not connected to reduce visual clutter
|
|
6
9
|
-->
|
|
7
10
|
|
|
8
11
|
<script lang="ts">
|
|
9
12
|
import { Position, Handle } from '@xyflow/svelte';
|
|
10
|
-
import type { WorkflowNode } from '../../types/index.js';
|
|
13
|
+
import type { WorkflowNode, NodePort, Branch } from '../../types/index.js';
|
|
11
14
|
import Icon from '@iconify/svelte';
|
|
12
15
|
import { getNodeIcon } from '../../utils/icons.js';
|
|
13
16
|
import { getDataTypeColorToken, getCategoryColorToken } from '../../utils/colors.js';
|
|
14
|
-
|
|
15
|
-
// Define simplified branch interface - conditions are handled by backend
|
|
16
|
-
interface Branch {
|
|
17
|
-
name: string;
|
|
18
|
-
label: string;
|
|
19
|
-
}
|
|
17
|
+
import { connectedHandles } from '../../stores/workflowStore.js';
|
|
20
18
|
|
|
21
19
|
interface Props {
|
|
22
20
|
data: WorkflowNode['data'] & {
|
|
@@ -28,10 +26,70 @@
|
|
|
28
26
|
|
|
29
27
|
let props: Props = $props();
|
|
30
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Get the hideUnconnectedHandles setting from extensions
|
|
31
|
+
* Merges node type defaults with instance overrides
|
|
32
|
+
*/
|
|
33
|
+
const hideUnconnectedHandles = $derived(() => {
|
|
34
|
+
const typeDefault = props.data.metadata?.extensions?.ui?.hideUnconnectedHandles ?? false;
|
|
35
|
+
const instanceOverride = props.data.extensions?.ui?.hideUnconnectedHandles;
|
|
36
|
+
return instanceOverride ?? typeDefault;
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Check if a port should be visible based on connection state and settings
|
|
41
|
+
* @param port - The port to check
|
|
42
|
+
* @param type - Whether this is an 'input' or 'output' port
|
|
43
|
+
* @returns true if the port should be visible
|
|
44
|
+
*/
|
|
45
|
+
function isPortVisible(port: NodePort, type: 'input' | 'output'): boolean {
|
|
46
|
+
// Always show if hideUnconnectedHandles is disabled
|
|
47
|
+
if (!hideUnconnectedHandles()) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Always show required ports
|
|
52
|
+
if (port.required) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Check if port is connected
|
|
57
|
+
const handleId = `${props.data.nodeId}-${type}-${port.id}`;
|
|
58
|
+
return $connectedHandles.has(handleId);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Derived list of visible input ports based on hideUnconnectedHandles setting
|
|
63
|
+
*/
|
|
64
|
+
const visibleInputPorts = $derived(
|
|
65
|
+
props.data.metadata.inputs.filter((port) => isPortVisible(port, 'input'))
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Check if a branch output should be visible based on connection state
|
|
70
|
+
* @param branchName - The branch name to check
|
|
71
|
+
* @returns true if the branch should be visible
|
|
72
|
+
*/
|
|
73
|
+
function isBranchVisible(branchName: string): boolean {
|
|
74
|
+
// Always show if hideUnconnectedHandles is disabled
|
|
75
|
+
if (!hideUnconnectedHandles()) {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Check if branch output is connected
|
|
80
|
+
const handleId = `${props.data.nodeId}-output-${branchName}`;
|
|
81
|
+
return $connectedHandles.has(handleId);
|
|
82
|
+
}
|
|
83
|
+
|
|
31
84
|
// Gateway-specific data - branches are calculated at runtime from config
|
|
32
85
|
let branches = $derived((props.data.config?.branches as Branch[]) || []);
|
|
33
86
|
let activeBranches = $derived((props.data.executionInfo as any)?.output?.active_branches || []);
|
|
34
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Derived list of visible branches based on hideUnconnectedHandles setting
|
|
90
|
+
*/
|
|
91
|
+
const visibleBranches = $derived(branches.filter((branch) => isBranchVisible(branch.name)));
|
|
92
|
+
|
|
35
93
|
/**
|
|
36
94
|
* Handle node click - only handle selection, no config opening
|
|
37
95
|
*/
|
|
@@ -107,14 +165,14 @@
|
|
|
107
165
|
</p>
|
|
108
166
|
</div>
|
|
109
167
|
|
|
110
|
-
<!-- Input Ports Container -->
|
|
111
|
-
{#if
|
|
168
|
+
<!-- Input Ports Container (filtered based on hideUnconnectedHandles) -->
|
|
169
|
+
{#if visibleInputPorts.length > 0}
|
|
112
170
|
<div class="flowdrop-workflow-node__ports">
|
|
113
171
|
<div class="flowdrop-workflow-node__ports-header">
|
|
114
172
|
<h5 class="flowdrop-workflow-node__ports-title">Inputs</h5>
|
|
115
173
|
</div>
|
|
116
174
|
<div class="flowdrop-workflow-node__ports-list">
|
|
117
|
-
{#each
|
|
175
|
+
{#each visibleInputPorts as port (port.id)}
|
|
118
176
|
<div class="flowdrop-workflow-node__port">
|
|
119
177
|
<!-- Input Handle -->
|
|
120
178
|
<Handle
|
|
@@ -158,17 +216,17 @@
|
|
|
158
216
|
</div>
|
|
159
217
|
{/if}
|
|
160
218
|
|
|
161
|
-
<!-- Branches Section (Output Ports) -->
|
|
162
|
-
{#if
|
|
219
|
+
<!-- Branches Section (Output Ports) - filtered based on hideUnconnectedHandles -->
|
|
220
|
+
{#if visibleBranches.length > 0}
|
|
163
221
|
<div class="flowdrop-workflow-node__ports">
|
|
164
222
|
<div class="flowdrop-workflow-node__ports-header">
|
|
165
223
|
<h5 class="flowdrop-workflow-node__ports-title">
|
|
166
224
|
<Icon icon="mdi:source-branch" />
|
|
167
|
-
<span>Branches ({
|
|
225
|
+
<span>Branches ({visibleBranches.length})</span>
|
|
168
226
|
</h5>
|
|
169
227
|
</div>
|
|
170
228
|
<div class="flowdrop-workflow-node__ports-list">
|
|
171
|
-
{#each
|
|
229
|
+
{#each visibleBranches as branch (branch.name)}
|
|
172
230
|
{@const isActive = isBranchActive(branch.name)}
|
|
173
231
|
<div class="flowdrop-workflow-node__port">
|
|
174
232
|
<!-- Port Info -->
|
|
@@ -185,7 +243,7 @@
|
|
|
185
243
|
class="flowdrop-text--xs flowdrop-font--medium"
|
|
186
244
|
class:flowdrop-text--active={isActive}
|
|
187
245
|
>
|
|
188
|
-
{branch.name}
|
|
246
|
+
{branch.label || branch.name}
|
|
189
247
|
</span>
|
|
190
248
|
<span
|
|
191
249
|
class="flowdrop-badge flowdrop-badge--sm"
|
|
@@ -213,7 +271,8 @@
|
|
|
213
271
|
{/each}
|
|
214
272
|
</div>
|
|
215
273
|
</div>
|
|
216
|
-
{:else}
|
|
274
|
+
{:else if branches.length === 0}
|
|
275
|
+
<!-- No branches configured at all -->
|
|
217
276
|
<div class="flowdrop-workflow-node__ports">
|
|
218
277
|
<div class="workflow-node__no-branches">
|
|
219
278
|
<Icon icon="mdi:alert-circle-outline" />
|
|
@@ -221,6 +280,7 @@
|
|
|
221
280
|
</div>
|
|
222
281
|
</div>
|
|
223
282
|
{/if}
|
|
283
|
+
<!-- Note: When all branches are hidden due to hideUnconnectedHandles, we don't show anything -->
|
|
224
284
|
|
|
225
285
|
<!-- Config button -->
|
|
226
286
|
<button
|
|
@@ -2,13 +2,17 @@
|
|
|
2
2
|
Simple Node Component
|
|
3
3
|
A simple node with optional input and output ports
|
|
4
4
|
Styled with BEM syntax
|
|
5
|
+
|
|
6
|
+
UI Extensions Support:
|
|
7
|
+
- hideUnconnectedHandles: Hides trigger ports that are not connected to reduce visual clutter
|
|
5
8
|
-->
|
|
6
9
|
|
|
7
10
|
<script lang="ts">
|
|
8
11
|
import { Position, Handle } from '@xyflow/svelte';
|
|
9
|
-
import type { ConfigValues, NodeMetadata } from '../../types/index.js';
|
|
12
|
+
import type { ConfigValues, NodeMetadata, NodeExtensions } from '../../types/index.js';
|
|
10
13
|
import Icon from '@iconify/svelte';
|
|
11
14
|
import { getDataTypeColor } from '../../utils/colors.js';
|
|
15
|
+
import { connectedHandles } from '../../stores/workflowStore.js';
|
|
12
16
|
|
|
13
17
|
const props = $props<{
|
|
14
18
|
data: {
|
|
@@ -16,6 +20,7 @@
|
|
|
16
20
|
config: ConfigValues;
|
|
17
21
|
metadata: NodeMetadata;
|
|
18
22
|
nodeId?: string;
|
|
23
|
+
extensions?: NodeExtensions;
|
|
19
24
|
onConfigOpen?: (node: {
|
|
20
25
|
id: string;
|
|
21
26
|
type: string;
|
|
@@ -27,6 +32,37 @@
|
|
|
27
32
|
isError?: boolean;
|
|
28
33
|
}>();
|
|
29
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Get the hideUnconnectedHandles setting from extensions
|
|
37
|
+
* Merges node type defaults with instance overrides
|
|
38
|
+
*/
|
|
39
|
+
const hideUnconnectedHandles = $derived(() => {
|
|
40
|
+
const typeDefault = props.data.metadata?.extensions?.ui?.hideUnconnectedHandles ?? false;
|
|
41
|
+
const instanceOverride = props.data.extensions?.ui?.hideUnconnectedHandles;
|
|
42
|
+
return instanceOverride ?? typeDefault;
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Check if a trigger port is connected
|
|
47
|
+
* @param portId - The port ID to check
|
|
48
|
+
* @param type - Whether this is an 'input' or 'output' port
|
|
49
|
+
*/
|
|
50
|
+
function isTriggerPortConnected(portId: string, type: 'input' | 'output'): boolean {
|
|
51
|
+
const handleId = `${props.data.nodeId}-${type}-${portId}`;
|
|
52
|
+
return $connectedHandles.has(handleId);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Check if a trigger port should be visible
|
|
57
|
+
* Always shows if hideUnconnectedHandles is disabled or if port is connected
|
|
58
|
+
*/
|
|
59
|
+
function shouldShowTriggerPort(portId: string, type: 'input' | 'output'): boolean {
|
|
60
|
+
if (!hideUnconnectedHandles()) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
return isTriggerPortConnected(portId, type);
|
|
64
|
+
}
|
|
65
|
+
|
|
30
66
|
// Removed local config state - now using global ConfigSidebar
|
|
31
67
|
|
|
32
68
|
// Prioritize metadata icon over config icon for simple nodes (metadata is the node definition)
|
|
@@ -124,8 +160,8 @@
|
|
|
124
160
|
id={`${props.data.nodeId}-input-${firstDataInputPort.id}`}
|
|
125
161
|
/>
|
|
126
162
|
{/if}
|
|
127
|
-
{#if triggerInputPort}
|
|
128
|
-
<!-- Trigger Input - positioned at bottom-left -->
|
|
163
|
+
{#if triggerInputPort && shouldShowTriggerPort(triggerInputPort.id, 'input')}
|
|
164
|
+
<!-- Trigger Input - positioned at bottom-left (hidden if hideUnconnectedHandles enabled and not connected) -->
|
|
129
165
|
<Handle
|
|
130
166
|
type="target"
|
|
131
167
|
position={Position.Left}
|
|
@@ -217,8 +253,8 @@
|
|
|
217
253
|
)}; border-color: '#ffffff'; top: {hasBothOutputTypes ? '25%' : '50%'}; z-index: 30;"
|
|
218
254
|
/>
|
|
219
255
|
{/if}
|
|
220
|
-
{#if triggerOutputPort}
|
|
221
|
-
<!-- Trigger Output - positioned at bottom-right -->
|
|
256
|
+
{#if triggerOutputPort && shouldShowTriggerPort(triggerOutputPort.id, 'output')}
|
|
257
|
+
<!-- Trigger Output - positioned at bottom-right (hidden if hideUnconnectedHandles enabled and not connected) -->
|
|
222
258
|
<Handle
|
|
223
259
|
type="source"
|
|
224
260
|
position={Position.Right}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import type { ConfigValues, NodeMetadata } from '../../types/index.js';
|
|
1
|
+
import type { ConfigValues, NodeMetadata, NodeExtensions } from '../../types/index.js';
|
|
2
2
|
type $$ComponentProps = {
|
|
3
3
|
data: {
|
|
4
4
|
label: string;
|
|
5
5
|
config: ConfigValues;
|
|
6
6
|
metadata: NodeMetadata;
|
|
7
7
|
nodeId?: string;
|
|
8
|
+
extensions?: NodeExtensions;
|
|
8
9
|
onConfigOpen?: (node: {
|
|
9
10
|
id: string;
|
|
10
11
|
type: string;
|
|
@@ -2,13 +2,17 @@
|
|
|
2
2
|
Square Node Component
|
|
3
3
|
A simple square node with optional input and output ports
|
|
4
4
|
Styled with BEM syntax
|
|
5
|
+
|
|
6
|
+
UI Extensions Support:
|
|
7
|
+
- hideUnconnectedHandles: Hides trigger ports that are not connected to reduce visual clutter
|
|
5
8
|
-->
|
|
6
9
|
|
|
7
10
|
<script lang="ts">
|
|
8
11
|
import { Position, Handle } from '@xyflow/svelte';
|
|
9
|
-
import type { ConfigValues, NodeMetadata } from '../../types/index.js';
|
|
12
|
+
import type { ConfigValues, NodeMetadata, NodeExtensions } from '../../types/index.js';
|
|
10
13
|
import Icon from '@iconify/svelte';
|
|
11
14
|
import { getDataTypeColor } from '../../utils/colors.js';
|
|
15
|
+
import { connectedHandles } from '../../stores/workflowStore.js';
|
|
12
16
|
|
|
13
17
|
const props = $props<{
|
|
14
18
|
data: {
|
|
@@ -16,6 +20,7 @@
|
|
|
16
20
|
config: ConfigValues;
|
|
17
21
|
metadata: NodeMetadata;
|
|
18
22
|
nodeId?: string;
|
|
23
|
+
extensions?: NodeExtensions;
|
|
19
24
|
onConfigOpen?: (node: {
|
|
20
25
|
id: string;
|
|
21
26
|
type: string;
|
|
@@ -27,6 +32,37 @@
|
|
|
27
32
|
isError?: boolean;
|
|
28
33
|
}>();
|
|
29
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Get the hideUnconnectedHandles setting from extensions
|
|
37
|
+
* Merges node type defaults with instance overrides
|
|
38
|
+
*/
|
|
39
|
+
const hideUnconnectedHandles = $derived(() => {
|
|
40
|
+
const typeDefault = props.data.metadata?.extensions?.ui?.hideUnconnectedHandles ?? false;
|
|
41
|
+
const instanceOverride = props.data.extensions?.ui?.hideUnconnectedHandles;
|
|
42
|
+
return instanceOverride ?? typeDefault;
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Check if a trigger port is connected
|
|
47
|
+
* @param portId - The port ID to check
|
|
48
|
+
* @param type - Whether this is an 'input' or 'output' port
|
|
49
|
+
*/
|
|
50
|
+
function isTriggerPortConnected(portId: string, type: 'input' | 'output'): boolean {
|
|
51
|
+
const handleId = `${props.data.nodeId}-${type}-${portId}`;
|
|
52
|
+
return $connectedHandles.has(handleId);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Check if a trigger port should be visible
|
|
57
|
+
* Always shows if hideUnconnectedHandles is disabled or if port is connected
|
|
58
|
+
*/
|
|
59
|
+
function shouldShowTriggerPort(portId: string, type: 'input' | 'output'): boolean {
|
|
60
|
+
if (!hideUnconnectedHandles()) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
return isTriggerPortConnected(portId, type);
|
|
64
|
+
}
|
|
65
|
+
|
|
30
66
|
// Removed local config state - now using global ConfigSidebar
|
|
31
67
|
|
|
32
68
|
// Prioritize metadata icon over config icon for square nodes (metadata is the node definition)
|
|
@@ -110,8 +146,8 @@
|
|
|
110
146
|
id={`${props.data.nodeId}-input-${firstDataInputPort.id}`}
|
|
111
147
|
/>
|
|
112
148
|
{/if}
|
|
113
|
-
{#if triggerInputPort}
|
|
114
|
-
<!-- Trigger Input - positioned at bottom-left -->
|
|
149
|
+
{#if triggerInputPort && shouldShowTriggerPort(triggerInputPort.id, 'input')}
|
|
150
|
+
<!-- Trigger Input - positioned at bottom-left (hidden if hideUnconnectedHandles enabled and not connected) -->
|
|
115
151
|
<Handle
|
|
116
152
|
type="target"
|
|
117
153
|
position={Position.Left}
|
|
@@ -179,8 +215,8 @@
|
|
|
179
215
|
)}; border-color: '#ffffff'; top: {hasBothOutputTypes ? '25%' : '50%'}; z-index: 30;"
|
|
180
216
|
/>
|
|
181
217
|
{/if}
|
|
182
|
-
{#if triggerOutputPort}
|
|
183
|
-
<!-- Trigger Output - positioned at bottom-right -->
|
|
218
|
+
{#if triggerOutputPort && shouldShowTriggerPort(triggerOutputPort.id, 'output')}
|
|
219
|
+
<!-- Trigger Output - positioned at bottom-right (hidden if hideUnconnectedHandles enabled and not connected) -->
|
|
184
220
|
<Handle
|
|
185
221
|
type="source"
|
|
186
222
|
position={Position.Right}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import type { ConfigValues, NodeMetadata } from '../../types/index.js';
|
|
1
|
+
import type { ConfigValues, NodeMetadata, NodeExtensions } from '../../types/index.js';
|
|
2
2
|
type $$ComponentProps = {
|
|
3
3
|
data: {
|
|
4
4
|
label: string;
|
|
5
5
|
config: ConfigValues;
|
|
6
6
|
metadata: NodeMetadata;
|
|
7
7
|
nodeId?: string;
|
|
8
|
+
extensions?: NodeExtensions;
|
|
8
9
|
onConfigOpen?: (node: {
|
|
9
10
|
id: string;
|
|
10
11
|
type: string;
|
|
@@ -3,14 +3,19 @@
|
|
|
3
3
|
Renders individual nodes in the workflow editor with full functionality
|
|
4
4
|
Uses SvelteFlow's Handle for connection ports
|
|
5
5
|
Styled with BEM syntax
|
|
6
|
+
|
|
7
|
+
UI Extensions Support:
|
|
8
|
+
- hideUnconnectedHandles: Hides ports that are not connected to reduce visual clutter
|
|
6
9
|
-->
|
|
7
10
|
|
|
8
11
|
<script lang="ts">
|
|
9
12
|
import { Position, Handle } from '@xyflow/svelte';
|
|
10
|
-
import type { WorkflowNode } from '../../types/index.js';
|
|
13
|
+
import type { WorkflowNode, NodePort, DynamicPort } from '../../types/index.js';
|
|
14
|
+
import { dynamicPortToNodePort } from '../../types/index.js';
|
|
11
15
|
import Icon from '@iconify/svelte';
|
|
12
16
|
import { getNodeIcon } from '../../utils/icons.js';
|
|
13
17
|
import { getDataTypeColorToken, getCategoryColorToken } from '../../utils/colors.js';
|
|
18
|
+
import { connectedHandles } from '../../stores/workflowStore.js';
|
|
14
19
|
|
|
15
20
|
interface Props {
|
|
16
21
|
data: WorkflowNode['data'] & {
|
|
@@ -23,6 +28,84 @@
|
|
|
23
28
|
let props: Props = $props();
|
|
24
29
|
let isHandleInteraction = $state(false);
|
|
25
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Get the hideUnconnectedHandles setting from extensions
|
|
33
|
+
* Merges node type defaults with instance overrides
|
|
34
|
+
*/
|
|
35
|
+
const hideUnconnectedHandles = $derived(() => {
|
|
36
|
+
const typeDefault = props.data.metadata?.extensions?.ui?.hideUnconnectedHandles ?? false;
|
|
37
|
+
const instanceOverride = props.data.extensions?.ui?.hideUnconnectedHandles;
|
|
38
|
+
return instanceOverride ?? typeDefault;
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Dynamic inputs from config - user-defined input ports
|
|
43
|
+
* Similar to how branches work in GatewayNode
|
|
44
|
+
*/
|
|
45
|
+
const dynamicInputs = $derived(
|
|
46
|
+
((props.data.config?.dynamicInputs as DynamicPort[]) || []).map((port) =>
|
|
47
|
+
dynamicPortToNodePort(port, 'input')
|
|
48
|
+
)
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Dynamic outputs from config - user-defined output ports
|
|
53
|
+
* Similar to how branches work in GatewayNode
|
|
54
|
+
*/
|
|
55
|
+
const dynamicOutputs = $derived(
|
|
56
|
+
((props.data.config?.dynamicOutputs as DynamicPort[]) || []).map((port) =>
|
|
57
|
+
dynamicPortToNodePort(port, 'output')
|
|
58
|
+
)
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Combined input ports: static metadata inputs + dynamic config inputs
|
|
63
|
+
*/
|
|
64
|
+
const allInputPorts = $derived([...props.data.metadata.inputs, ...dynamicInputs]);
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Combined output ports: static metadata outputs + dynamic config outputs
|
|
68
|
+
*/
|
|
69
|
+
const allOutputPorts = $derived([...props.data.metadata.outputs, ...dynamicOutputs]);
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Check if a port should be visible based on connection state and settings
|
|
73
|
+
* @param port - The port to check
|
|
74
|
+
* @param type - Whether this is an 'input' or 'output' port
|
|
75
|
+
* @returns true if the port should be visible
|
|
76
|
+
*/
|
|
77
|
+
function isPortVisible(port: NodePort, type: 'input' | 'output'): boolean {
|
|
78
|
+
// Always show if hideUnconnectedHandles is disabled
|
|
79
|
+
if (!hideUnconnectedHandles()) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Always show required ports
|
|
84
|
+
if (port.required) {
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Check if port is connected
|
|
89
|
+
const handleId = `${props.data.nodeId}-${type}-${port.id}`;
|
|
90
|
+
return $connectedHandles.has(handleId);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Derived list of visible input ports based on hideUnconnectedHandles setting
|
|
95
|
+
* Now includes both static and dynamic inputs
|
|
96
|
+
*/
|
|
97
|
+
const visibleInputPorts = $derived(
|
|
98
|
+
allInputPorts.filter((port) => isPortVisible(port, 'input'))
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Derived list of visible output ports based on hideUnconnectedHandles setting
|
|
103
|
+
* Now includes both static and dynamic outputs
|
|
104
|
+
*/
|
|
105
|
+
const visibleOutputPorts = $derived(
|
|
106
|
+
allOutputPorts.filter((port) => isPortVisible(port, 'output'))
|
|
107
|
+
);
|
|
108
|
+
|
|
26
109
|
/**
|
|
27
110
|
* Handle configuration value changes - now handled by global ConfigSidebar
|
|
28
111
|
*/
|
|
@@ -110,13 +193,13 @@
|
|
|
110
193
|
</div>
|
|
111
194
|
|
|
112
195
|
<!-- Input Ports Container -->
|
|
113
|
-
{#if
|
|
196
|
+
{#if visibleInputPorts.length > 0}
|
|
114
197
|
<div class="flowdrop-workflow-node__ports">
|
|
115
198
|
<div class="flowdrop-workflow-node__ports-header">
|
|
116
199
|
<h5 class="flowdrop-workflow-node__ports-title">Inputs</h5>
|
|
117
200
|
</div>
|
|
118
201
|
<div class="flowdrop-workflow-node__ports-list">
|
|
119
|
-
{#each
|
|
202
|
+
{#each visibleInputPorts as port (port.id)}
|
|
120
203
|
<div class="flowdrop-workflow-node__port">
|
|
121
204
|
<!-- Input Handle -->
|
|
122
205
|
<Handle
|
|
@@ -161,13 +244,13 @@
|
|
|
161
244
|
{/if}
|
|
162
245
|
|
|
163
246
|
<!-- Output Ports Container -->
|
|
164
|
-
{#if
|
|
247
|
+
{#if visibleOutputPorts.length > 0}
|
|
165
248
|
<div class="flowdrop-workflow-node__ports">
|
|
166
249
|
<div class="flowdrop-workflow-node__ports-header">
|
|
167
250
|
<h5 class="flowdrop-workflow-node__ports-title">Outputs</h5>
|
|
168
251
|
</div>
|
|
169
252
|
<div class="flowdrop-workflow-node__ports-list">
|
|
170
|
-
{#each
|
|
253
|
+
{#each visibleOutputPorts as port (port.id)}
|
|
171
254
|
<div class="flowdrop-workflow-node__port">
|
|
172
255
|
<!-- Port Info -->
|
|
173
256
|
<div class="flowdrop-flex--1 flowdrop-min-w--0 flowdrop-text--right">
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import './styles/base.css';
|
|
6
6
|
import './registry/builtinNodes.js';
|
|
7
|
-
export type { NodeCategory, NodeDataType, NodePort, NodeMetadata, ConfigValues, WorkflowNode, WorkflowEdge, Workflow, ApiResponse, NodesResponse, WorkflowResponse, WorkflowsResponse, ExecutionStatus, ExecutionResult, FlowDropConfig, WorkflowEvents, BuiltinNodeType } from './types/index.js';
|
|
7
|
+
export type { NodeCategory, NodeDataType, NodePort, DynamicPort, Branch, NodeMetadata, NodeExtensions, NodeUIExtensions, ConfigValues, WorkflowNode, WorkflowEdge, Workflow, ApiResponse, NodesResponse, WorkflowResponse, WorkflowsResponse, ExecutionStatus, ExecutionResult, FlowDropConfig, WorkflowEvents, BuiltinNodeType } from './types/index.js';
|
|
8
8
|
export type { WorkflowEditorConfig, EditorFeatures, UIConfig, APIConfig, ExecutionConfig, StorageConfig } from './types/config.js';
|
|
9
9
|
export type { AuthProvider, StaticAuthConfig, CallbackAuthConfig } from './types/auth.js';
|
|
10
10
|
export { StaticAuthProvider, CallbackAuthProvider, NoAuthProvider } from './types/auth.js';
|
|
@@ -36,7 +36,6 @@ export { default as LogsSidebar } from './components/LogsSidebar.svelte';
|
|
|
36
36
|
export { default as PipelineStatus } from './components/PipelineStatus.svelte';
|
|
37
37
|
export { default as Navbar } from './components/Navbar.svelte';
|
|
38
38
|
export { default as Logo } from './components/Logo.svelte';
|
|
39
|
-
export { sampleNodes, sampleWorkflow } from './data/samples.js';
|
|
40
39
|
export * from './utils/icons.js';
|
|
41
40
|
export * from './utils/colors.js';
|
|
42
41
|
export * from './utils/connections.js';
|
|
@@ -56,7 +55,7 @@ export { globalSaveWorkflow, globalExportWorkflow, initializeGlobalSave } from '
|
|
|
56
55
|
export { fetchPortConfig, validatePortConfig } from './services/portConfigApi.js';
|
|
57
56
|
export { getDraftStorageKey, saveDraft, loadDraft, deleteDraft, hasDraft, getDraftMetadata, DraftAutoSaveManager } from './services/draftStorage.js';
|
|
58
57
|
export { EdgeStylingHelper, NodeOperationsHelper, WorkflowOperationsHelper, ConfigurationHelper } from './helpers/workflowEditorHelper.js';
|
|
59
|
-
export { workflowStore, workflowActions, workflowId, workflowName, workflowNodes, workflowEdges, workflowMetadata, workflowChanged, workflowValidation, workflowMetadataChanged, isDirtyStore, isDirty, markAsSaved, getWorkflow as getWorkflowFromStore, setOnDirtyStateChange, setOnWorkflowChange } from './stores/workflowStore.js';
|
|
58
|
+
export { workflowStore, workflowActions, workflowId, workflowName, workflowNodes, workflowEdges, workflowMetadata, workflowChanged, workflowValidation, workflowMetadataChanged, connectedHandles, isDirtyStore, isDirty, markAsSaved, getWorkflow as getWorkflowFromStore, setOnDirtyStateChange, setOnWorkflowChange } from './stores/workflowStore.js';
|
|
60
59
|
export * from './config/endpoints.js';
|
|
61
60
|
export { DEFAULT_PORT_CONFIG } from './config/defaultPortConfig.js';
|
|
62
61
|
export * from './config/runtimeConfig.js';
|
package/dist/index.js
CHANGED
|
@@ -37,8 +37,6 @@ export { default as LogsSidebar } from './components/LogsSidebar.svelte';
|
|
|
37
37
|
export { default as PipelineStatus } from './components/PipelineStatus.svelte';
|
|
38
38
|
export { default as Navbar } from './components/Navbar.svelte';
|
|
39
39
|
export { default as Logo } from './components/Logo.svelte';
|
|
40
|
-
// Export sample data for development
|
|
41
|
-
export { sampleNodes, sampleWorkflow } from './data/samples.js';
|
|
42
40
|
// Export utilities
|
|
43
41
|
export * from './utils/icons.js';
|
|
44
42
|
export * from './utils/colors.js';
|
|
@@ -67,7 +65,7 @@ export { getDraftStorageKey, saveDraft, loadDraft, deleteDraft, hasDraft, getDra
|
|
|
67
65
|
// Export helpers
|
|
68
66
|
export { EdgeStylingHelper, NodeOperationsHelper, WorkflowOperationsHelper, ConfigurationHelper } from './helpers/workflowEditorHelper.js';
|
|
69
67
|
// Export stores
|
|
70
|
-
export { workflowStore, workflowActions, workflowId, workflowName, workflowNodes, workflowEdges, workflowMetadata, workflowChanged, workflowValidation, workflowMetadataChanged,
|
|
68
|
+
export { workflowStore, workflowActions, workflowId, workflowName, workflowNodes, workflowEdges, workflowMetadata, workflowChanged, workflowValidation, workflowMetadataChanged, connectedHandles,
|
|
71
69
|
// Dirty state tracking
|
|
72
70
|
isDirtyStore, isDirty, markAsSaved, getWorkflow as getWorkflowFromStore, setOnDirtyStateChange, setOnWorkflowChange } from './stores/workflowStore.js';
|
|
73
71
|
// Export endpoint configuration
|
|
@@ -154,3 +154,18 @@ export declare const workflowMetadataChanged: import("svelte/store").Readable<{
|
|
|
154
154
|
updatedAt: string;
|
|
155
155
|
version: string;
|
|
156
156
|
}>;
|
|
157
|
+
/**
|
|
158
|
+
* Derived store for connected handles
|
|
159
|
+
*
|
|
160
|
+
* Provides a Set of all handle IDs that are currently connected to edges.
|
|
161
|
+
* Used by node components to implement hideUnconnectedHandles functionality.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```typescript
|
|
165
|
+
* import { connectedHandles } from './workflowStore.js';
|
|
166
|
+
*
|
|
167
|
+
* // Check if a specific handle is connected
|
|
168
|
+
* const isConnected = $connectedHandles.has('node-1-input-data');
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
171
|
+
export declare const connectedHandles: import("svelte/store").Readable<Set<string>>;
|
|
@@ -470,3 +470,31 @@ export const workflowMetadataChanged = derived(workflowMetadata, (metadata) => (
|
|
|
470
470
|
updatedAt: metadata.updatedAt,
|
|
471
471
|
version: metadata.version ?? '1.0.0'
|
|
472
472
|
}));
|
|
473
|
+
/**
|
|
474
|
+
* Derived store for connected handles
|
|
475
|
+
*
|
|
476
|
+
* Provides a Set of all handle IDs that are currently connected to edges.
|
|
477
|
+
* Used by node components to implement hideUnconnectedHandles functionality.
|
|
478
|
+
*
|
|
479
|
+
* @example
|
|
480
|
+
* ```typescript
|
|
481
|
+
* import { connectedHandles } from './workflowStore.js';
|
|
482
|
+
*
|
|
483
|
+
* // Check if a specific handle is connected
|
|
484
|
+
* const isConnected = $connectedHandles.has('node-1-input-data');
|
|
485
|
+
* ```
|
|
486
|
+
*/
|
|
487
|
+
export const connectedHandles = derived(workflowEdges, (edges) => {
|
|
488
|
+
const handles = new Set();
|
|
489
|
+
edges.forEach((edge) => {
|
|
490
|
+
// Add source handle (output port)
|
|
491
|
+
if (edge.sourceHandle) {
|
|
492
|
+
handles.add(edge.sourceHandle);
|
|
493
|
+
}
|
|
494
|
+
// Add target handle (input port)
|
|
495
|
+
if (edge.targetHandle) {
|
|
496
|
+
handles.add(edge.targetHandle);
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
return handles;
|
|
500
|
+
});
|