@d34dman/flowdrop 0.0.1 → 0.0.3

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 (120) hide show
  1. package/README.md +307 -215
  2. package/dist/adapters/WorkflowAdapter.d.ts +1 -1
  3. package/dist/adapters/WorkflowAdapter.js +30 -30
  4. package/dist/api/client.d.ts +24 -1
  5. package/dist/api/client.js +55 -38
  6. package/dist/api/enhanced-client.d.ts +46 -0
  7. package/dist/api/enhanced-client.js +211 -0
  8. package/dist/clients/ApiClient.d.ts +19 -23
  9. package/dist/clients/ApiClient.js +36 -34
  10. package/dist/components/App.svelte +1299 -230
  11. package/dist/components/App.svelte.d.ts +21 -1
  12. package/dist/components/CanvasBanner.svelte +50 -44
  13. package/dist/components/CanvasBanner.svelte.d.ts +5 -19
  14. package/dist/components/ConfigForm.svelte +555 -0
  15. package/dist/components/ConfigForm.svelte.d.ts +32 -0
  16. package/dist/components/ConfigModal.svelte +261 -0
  17. package/dist/components/ConfigModal.svelte.d.ts +31 -0
  18. package/dist/components/ConfigSidebar.svelte +934 -0
  19. package/dist/components/ConfigSidebar.svelte.d.ts +51 -0
  20. package/dist/components/ConnectionLine.svelte +32 -0
  21. package/dist/components/ConnectionLine.svelte.d.ts +3 -0
  22. package/dist/components/GatewayNode.svelte +471 -0
  23. package/dist/components/GatewayNode.svelte.d.ts +15 -0
  24. package/dist/components/LoadingSpinner.svelte +23 -23
  25. package/dist/components/LoadingSpinner.svelte.d.ts +1 -1
  26. package/dist/components/Logo.svelte +82 -0
  27. package/dist/components/Logo.svelte.d.ts +26 -0
  28. package/dist/components/LogsSidebar.svelte +565 -0
  29. package/dist/components/LogsSidebar.svelte.d.ts +34 -0
  30. package/dist/components/MarkdownDisplay.svelte +28 -0
  31. package/dist/components/MarkdownDisplay.svelte.d.ts +7 -0
  32. package/dist/components/Navbar.svelte +663 -0
  33. package/dist/components/Navbar.svelte.d.ts +21 -0
  34. package/dist/components/NodeSidebar.svelte +629 -488
  35. package/dist/components/NodeSidebar.svelte.d.ts +1 -2
  36. package/dist/components/NodeStatusOverlay.svelte +327 -0
  37. package/dist/components/NodeStatusOverlay.svelte.d.ts +11 -0
  38. package/dist/components/NotesNode.svelte +566 -0
  39. package/dist/components/NotesNode.svelte.d.ts +43 -0
  40. package/dist/components/PipelineStatus.svelte +331 -0
  41. package/dist/components/PipelineStatus.svelte.d.ts +18 -0
  42. package/dist/components/SimpleNode.svelte +447 -0
  43. package/dist/components/SimpleNode.svelte.d.ts +24 -0
  44. package/dist/components/SquareNode.svelte +346 -0
  45. package/dist/components/SquareNode.svelte.d.ts +24 -0
  46. package/dist/components/StatusIcon.svelte +112 -0
  47. package/dist/components/StatusIcon.svelte.d.ts +10 -0
  48. package/dist/components/StatusLabel.svelte +33 -0
  49. package/dist/components/StatusLabel.svelte.d.ts +7 -0
  50. package/dist/components/ToolNode.svelte +385 -0
  51. package/dist/components/ToolNode.svelte.d.ts +36 -0
  52. package/dist/components/UniversalNode.svelte +126 -0
  53. package/dist/components/UniversalNode.svelte.d.ts +15 -0
  54. package/dist/components/WorkflowEditor.svelte +871 -528
  55. package/dist/components/WorkflowEditor.svelte.d.ts +15 -5
  56. package/dist/components/WorkflowNode.svelte +428 -542
  57. package/dist/components/WorkflowNode.svelte.d.ts +7 -3
  58. package/dist/config/apiConfig.d.ts +33 -0
  59. package/dist/config/apiConfig.js +39 -0
  60. package/dist/config/defaultPortConfig.d.ts +6 -0
  61. package/dist/config/defaultPortConfig.js +192 -0
  62. package/dist/config/demo.d.ts +58 -0
  63. package/dist/config/demo.js +142 -0
  64. package/dist/config/endpoints.d.ts +106 -0
  65. package/dist/config/endpoints.js +128 -0
  66. package/dist/data/samples.d.ts +38 -4
  67. package/dist/data/samples.js +2789 -737
  68. package/dist/examples/adapter-usage.d.ts +4 -4
  69. package/dist/examples/adapter-usage.js +21 -26
  70. package/dist/examples/api-client-usage.d.ts +6 -6
  71. package/dist/examples/api-client-usage.js +55 -54
  72. package/dist/index.d.ts +23 -15
  73. package/dist/index.js +23 -15
  74. package/dist/mocks/app-environment.d.ts +8 -0
  75. package/dist/mocks/app-environment.js +16 -0
  76. package/dist/mocks/app-forms.d.ts +2 -0
  77. package/dist/mocks/app-forms.js +21 -0
  78. package/dist/mocks/app-navigation.d.ts +5 -0
  79. package/dist/mocks/app-navigation.js +34 -0
  80. package/dist/mocks/app-stores.d.ts +14 -0
  81. package/dist/mocks/app-stores.js +26 -0
  82. package/dist/services/api.d.ts +13 -3
  83. package/dist/services/api.js +91 -36
  84. package/dist/services/globalSave.d.ts +20 -0
  85. package/dist/services/globalSave.js +165 -0
  86. package/dist/services/nodeExecutionService.d.ts +63 -0
  87. package/dist/services/nodeExecutionService.js +261 -0
  88. package/dist/services/portConfigApi.d.ts +14 -0
  89. package/dist/services/portConfigApi.js +69 -0
  90. package/dist/services/toastService.d.ts +147 -0
  91. package/dist/services/toastService.js +235 -0
  92. package/dist/services/workflowStorage.d.ts +2 -2
  93. package/dist/services/workflowStorage.js +10 -10
  94. package/dist/stores/workflowStore.d.ts +53 -0
  95. package/dist/stores/workflowStore.js +264 -0
  96. package/dist/styles/base.css +896 -363
  97. package/dist/svelte-app.d.ts +52 -5
  98. package/dist/svelte-app.js +128 -6
  99. package/dist/types/config.d.ts +291 -0
  100. package/dist/types/config.js +4 -0
  101. package/dist/types/index.d.ts +231 -19
  102. package/dist/types/index.js +1 -1
  103. package/dist/utils/colors.d.ts +67 -33
  104. package/dist/utils/colors.js +183 -118
  105. package/dist/utils/config.d.ts +41 -0
  106. package/dist/utils/config.js +248 -0
  107. package/dist/utils/connections.d.ts +40 -3
  108. package/dist/utils/connections.js +115 -44
  109. package/dist/utils/icons.d.ts +1 -1
  110. package/dist/utils/icons.js +71 -70
  111. package/dist/utils/nodeStatus.d.ts +53 -0
  112. package/dist/utils/nodeStatus.js +183 -0
  113. package/dist/utils/nodeTypes.d.ts +57 -0
  114. package/dist/utils/nodeTypes.js +109 -0
  115. package/dist/utils/nodeWrapper.d.ts +39 -0
  116. package/dist/utils/nodeWrapper.js +62 -0
  117. package/package.json +132 -97
  118. package/dist/app.css +0 -0
  119. package/dist/components/Node.svelte +0 -38
  120. package/dist/components/Node.svelte.d.ts +0 -4
@@ -0,0 +1,51 @@
1
+ import type { ConfigSchema, ConfigValues } from '../types/index.js';
2
+ interface Props {
3
+ isOpen: boolean;
4
+ title: string;
5
+ configSchema?: ConfigSchema;
6
+ configValues: ConfigValues;
7
+ nodeDetails?: {
8
+ type: string;
9
+ category: string;
10
+ description: string;
11
+ version?: string;
12
+ tags?: string[];
13
+ inputs?: Array<{
14
+ id: string;
15
+ name: string;
16
+ type: string;
17
+ dataType?: string;
18
+ }>;
19
+ outputs?: Array<{
20
+ id: string;
21
+ name: string;
22
+ type: string;
23
+ dataType?: string;
24
+ }>;
25
+ };
26
+ onSave?: (config: ConfigValues) => void;
27
+ onCancel?: () => void;
28
+ onClose?: () => void;
29
+ }
30
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
31
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
32
+ $$bindings?: Bindings;
33
+ } & Exports;
34
+ (internal: unknown, props: Props & {
35
+ $$events?: Events;
36
+ $$slots?: Slots;
37
+ }): Exports & {
38
+ $set?: any;
39
+ $on?: any;
40
+ };
41
+ z_$$bindings?: Bindings;
42
+ }
43
+ declare const ConfigSidebar: $$__sveltets_2_IsomorphicComponent<Props, {
44
+ save: CustomEvent<any>;
45
+ cancel: CustomEvent<any>;
46
+ close: CustomEvent<any>;
47
+ } & {
48
+ [evt: string]: CustomEvent<any>;
49
+ }, {}, {}, "">;
50
+ type ConfigSidebar = InstanceType<typeof ConfigSidebar>;
51
+ export default ConfigSidebar;
@@ -0,0 +1,32 @@
1
+ <script lang="ts">
2
+ import { getDataTypeColor } from '../utils/colors';
3
+ import { useConnection } from '@xyflow/svelte';
4
+
5
+ const connection = useConnection();
6
+
7
+ let path: string | null = $derived.by(() => {
8
+ if (connection.current.inProgress) {
9
+ const { from, to } = connection.current;
10
+ return `M${from.x},${from.y} C ${from.x} ${to.y} ${from.x} ${to.y} ${to.x},${to.y}`;
11
+ }
12
+ return null;
13
+ });
14
+ </script>
15
+
16
+ {#if connection.current.inProgress}
17
+ <path
18
+ fill="none"
19
+ stroke-width={1.5}
20
+ class="animated"
21
+ stroke={getDataTypeColor(connection.current.fromHandle.id)}
22
+ d={path}
23
+ />
24
+ <circle
25
+ cx={connection.current.to.x}
26
+ cy={connection.current.to.y}
27
+ fill="#fff"
28
+ r={3}
29
+ stroke={getDataTypeColor(connection.current.fromHandle.id)}
30
+ stroke-width={1.5}
31
+ />
32
+ {/if}
@@ -0,0 +1,3 @@
1
+ declare const ConnectionLine: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type ConnectionLine = ReturnType<typeof ConnectionLine>;
3
+ export default ConnectionLine;
@@ -0,0 +1,471 @@
1
+ <!--
2
+ Gateway Node Component
3
+ Visual representation of gateway/branch nodes with branching flow indicators
4
+ Shows active branches and execution paths
5
+ Styled with BEM syntax following WorkflowNode pattern
6
+ -->
7
+
8
+ <script lang="ts">
9
+ import { Position, Handle } from '@xyflow/svelte';
10
+ import type { WorkflowNode } from '../types/index.js';
11
+ import Icon from '@iconify/svelte';
12
+ import { getNodeIcon } from '../utils/icons.js';
13
+ 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
+ }
20
+
21
+ interface Props {
22
+ data: WorkflowNode['data'] & {
23
+ nodeId?: string;
24
+ onConfigOpen?: (node: { id: string; type: string; data: WorkflowNode['data'] }) => void;
25
+ };
26
+ selected?: boolean;
27
+ }
28
+
29
+ let props: Props = $props();
30
+
31
+ // Gateway-specific data - branches are calculated at runtime from config
32
+ let branches = $derived((props.data.config?.branches as Branch[]) || []);
33
+ let activeBranches = $derived((props.data.executionInfo as any)?.output?.active_branches || []);
34
+
35
+ /**
36
+ * Handle node click - only handle selection, no config opening
37
+ */
38
+ function handleNodeClick(): void {
39
+ // Node selection is handled by Svelte Flow
40
+ }
41
+
42
+ /**
43
+ * Handle double-click to open config
44
+ */
45
+ function handleNodeDoubleClick(): void {
46
+ if (props.data.onConfigOpen) {
47
+ props.data.onConfigOpen({
48
+ id: props.data.nodeId || '',
49
+ type: 'gateway',
50
+ data: props.data
51
+ });
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Handle keyboard events for accessibility
57
+ */
58
+ function handleKeydown(event: KeyboardEvent): void {
59
+ if (event.key === 'Enter' || event.key === ' ') {
60
+ event.preventDefault();
61
+ handleNodeClick();
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Check if a branch is active
67
+ */
68
+ function isBranchActive(branchName: string): boolean {
69
+ return activeBranches.includes(branchName);
70
+ }
71
+ </script>
72
+
73
+ <!-- Node Container -->
74
+ <div
75
+ class="flowdrop-workflow-node flowdrop-workflow-node--gateway"
76
+ class:flowdrop-workflow-node--selected={props.selected}
77
+ onclick={handleNodeClick}
78
+ ondblclick={handleNodeDoubleClick}
79
+ onkeydown={handleKeydown}
80
+ role="button"
81
+ tabindex="0"
82
+ aria-label="Gateway node: {props.data.metadata.name}"
83
+ aria-describedby="node-description-{props.data.nodeId || 'unknown'}"
84
+ >
85
+ <!-- Node Header -->
86
+ <div class="flowdrop-workflow-node__header">
87
+ <div class="flowdrop-flex flowdrop-gap--3 flowdrop-items--center">
88
+ <!-- Node Icon -->
89
+ <div
90
+ class="flowdrop-workflow-node__icon"
91
+ style="background-color: {getCategoryColorToken(props.data.metadata.category)}"
92
+ >
93
+ <Icon icon={getNodeIcon(props.data.metadata.icon, props.data.metadata.category)} />
94
+ </div>
95
+
96
+ <!-- Node Title -->
97
+ <h3 class="flowdrop-text--sm flowdrop-font--medium flowdrop-truncate flowdrop-flex--1">
98
+ {props.data.label}
99
+ </h3>
100
+ </div>
101
+ <!-- Node Description -->
102
+ <p
103
+ class="flowdrop-text--xs flowdrop-text--gray flowdrop-truncate flowdrop-mt--1"
104
+ id="node-description-{props.data.nodeId || 'unknown'}"
105
+ >
106
+ {props.data.metadata.description}
107
+ </p>
108
+ </div>
109
+
110
+ <!-- Input Ports Container -->
111
+ {#if props.data.metadata.inputs.length > 0}
112
+ <div class="flowdrop-workflow-node__ports">
113
+ <div class="flowdrop-workflow-node__ports-header">
114
+ <h5 class="flowdrop-workflow-node__ports-title">Inputs</h5>
115
+ </div>
116
+ <div class="flowdrop-workflow-node__ports-list">
117
+ {#each props.data.metadata.inputs as port (port.id)}
118
+ <div class="flowdrop-workflow-node__port">
119
+ <!-- Input Handle -->
120
+ <Handle
121
+ type="target"
122
+ position={Position.Left}
123
+ id={`${props.data.nodeId}-input-${port.id}`}
124
+ class="flowdrop-workflow-node__handle"
125
+ style="top: 50%; transform: translateY(-50%); margin-left: -32px; background-color: {getDataTypeColorToken(
126
+ port.dataType
127
+ )}; border-color: '#ffffff';"
128
+ role="button"
129
+ tabindex={0}
130
+ aria-label="Connect to {port.name} input port"
131
+ />
132
+
133
+ <!-- Port Info -->
134
+ <div class="flowdrop-flex--1 flowdrop-min-w--0">
135
+ <div class="flowdrop-flex flowdrop-gap--2">
136
+ <span class="flowdrop-text--xs flowdrop-font--medium">{port.name}</span>
137
+ <span
138
+ class="flowdrop-badge flowdrop-badge--sm"
139
+ style="background-color: {getDataTypeColorToken(port.dataType)}; color: #fff;"
140
+ >
141
+ {port.dataType}
142
+ </span>
143
+ {#if port.required}
144
+ <span class="flowdrop-badge flowdrop-badge--error flowdrop-badge--sm"
145
+ >Required</span
146
+ >
147
+ {/if}
148
+ </div>
149
+ {#if port.description}
150
+ <p class="flowdrop-text--xs flowdrop-text--gray flowdrop-truncate">
151
+ {port.description}
152
+ </p>
153
+ {/if}
154
+ </div>
155
+ </div>
156
+ {/each}
157
+ </div>
158
+ </div>
159
+ {/if}
160
+
161
+ <!-- Branches Section (Output Ports) -->
162
+ {#if branches.length > 0}
163
+ <div class="flowdrop-workflow-node__ports">
164
+ <div class="flowdrop-workflow-node__ports-header">
165
+ <h5 class="flowdrop-workflow-node__ports-title">
166
+ <Icon icon="mdi:source-branch" />
167
+ <span>Branches ({branches.length})</span>
168
+ </h5>
169
+ </div>
170
+ <div class="flowdrop-workflow-node__ports-list">
171
+ {#each branches as branch (branch.name)}
172
+ {@const isActive = isBranchActive(branch.name)}
173
+ <div class="flowdrop-workflow-node__port">
174
+ <!-- Port Info -->
175
+ <div class="flowdrop-flex--1 flowdrop-min-w--0 flowdrop-text--right">
176
+ <div
177
+ class="flowdrop-flex flowdrop-gap--2 flowdrop-justify--end flowdrop-items--center"
178
+ >
179
+ {#if isActive}
180
+ <span style="color: {getDataTypeColorToken('trigger')};">
181
+ <Icon icon="mdi:check-circle" />
182
+ </span>
183
+ {/if}
184
+ <span
185
+ class="flowdrop-text--xs flowdrop-font--medium"
186
+ class:flowdrop-text--active={isActive}
187
+ >
188
+ {branch.name}
189
+ </span>
190
+ <span
191
+ class="flowdrop-badge flowdrop-badge--sm"
192
+ style="background-color: {getDataTypeColorToken('trigger')}; color: #fff;"
193
+ >
194
+ trigger
195
+ </span>
196
+ </div>
197
+ </div>
198
+
199
+ <!-- Output Handle - Generated from branch name -->
200
+ <Handle
201
+ type="source"
202
+ position={Position.Right}
203
+ id={`${props.data.nodeId}-output-${branch.name}`}
204
+ class={`flowdrop-workflow-node__handle ${isActive ? 'flowdrop-workflow-node__handle--active' : ''}`}
205
+ style="top: 50%; transform: translateY(-50%); margin-right: -32px; background-color: {isActive
206
+ ? getDataTypeColorToken('trigger')
207
+ : getDataTypeColorToken('trigger')}; border-color: '#ffffff';"
208
+ role="button"
209
+ tabindex={0}
210
+ aria-label="Connect from {branch.name} branch"
211
+ />
212
+ </div>
213
+ {/each}
214
+ </div>
215
+ </div>
216
+ {:else}
217
+ <div class="flowdrop-workflow-node__ports">
218
+ <div class="workflow-node__no-branches">
219
+ <Icon icon="mdi:alert-circle-outline" />
220
+ <span>No branches configured</span>
221
+ </div>
222
+ </div>
223
+ {/if}
224
+
225
+ <!-- Config button -->
226
+ <button
227
+ class="flowdrop-workflow-node__config-btn"
228
+ onclick={handleNodeDoubleClick}
229
+ title="Configure node"
230
+ >
231
+ <Icon icon="mdi:cog" />
232
+ </button>
233
+ </div>
234
+
235
+ <style>
236
+ .flowdrop-workflow-node {
237
+ position: relative;
238
+ background-color: #ffffff;
239
+ border: 2px solid #e5e7eb;
240
+ border-radius: 0.75rem;
241
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
242
+ width: 18rem;
243
+ z-index: 10;
244
+ }
245
+
246
+ .flowdrop-workflow-node--gateway {
247
+ min-width: 18rem;
248
+ }
249
+
250
+ .flowdrop-workflow-node--selected {
251
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
252
+ border: 2px solid #3b82f6;
253
+ }
254
+
255
+ .flowdrop-workflow-node__header {
256
+ padding: 1rem;
257
+ border-bottom: 1px solid #e5e7eb;
258
+ background-color: #f9fafb;
259
+ border-top-left-radius: 0.75rem;
260
+ border-top-right-radius: 0.75rem;
261
+ }
262
+
263
+ .flowdrop-workflow-node__icon {
264
+ width: 2rem;
265
+ height: 2rem;
266
+ border-radius: 0.5rem;
267
+ color: #ffffff;
268
+ font-size: 0.875rem;
269
+ font-weight: 500;
270
+ display: flex;
271
+ align-items: center;
272
+ justify-content: center;
273
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
274
+ }
275
+
276
+ .flowdrop-workflow-node__header h3 {
277
+ margin: 0;
278
+ line-height: 1;
279
+ }
280
+
281
+ .flowdrop-workflow-node__ports {
282
+ padding: 0.75rem 1rem;
283
+ }
284
+
285
+ .flowdrop-workflow-node__ports-header {
286
+ margin-bottom: 0.5rem;
287
+ display: flex;
288
+ align-items: center;
289
+ gap: 0.25rem;
290
+ }
291
+
292
+ .flowdrop-workflow-node__ports-title {
293
+ margin: 0;
294
+ font-size: 0.75rem;
295
+ font-weight: 600;
296
+ color: #374151;
297
+ text-transform: uppercase;
298
+ letter-spacing: 0.05em;
299
+ display: flex;
300
+ align-items: center;
301
+ gap: 0.5rem;
302
+ }
303
+
304
+ .flowdrop-workflow-node__ports-list {
305
+ display: flex;
306
+ flex-direction: column;
307
+ gap: 0.5rem;
308
+ }
309
+
310
+ .flowdrop-workflow-node__port {
311
+ display: flex;
312
+ align-items: center;
313
+ gap: 0.5rem;
314
+ padding: 0.25rem 0;
315
+ position: relative;
316
+ }
317
+
318
+ .flowdrop-badge {
319
+ padding: 0.125rem 0.375rem;
320
+ border-radius: 0.25rem;
321
+ font-size: 0.625rem;
322
+ font-weight: 500;
323
+ text-transform: uppercase;
324
+ letter-spacing: 0.05em;
325
+ }
326
+
327
+ .flowdrop-badge--error {
328
+ background-color: #ef4444;
329
+ color: #ffffff;
330
+ }
331
+
332
+ .flowdrop-badge--sm {
333
+ font-size: 0.625rem;
334
+ padding: 0.125rem 0.25rem;
335
+ }
336
+
337
+ .workflow-node__no-branches {
338
+ display: flex;
339
+ align-items: center;
340
+ gap: 0.5rem;
341
+ padding: 0.75rem;
342
+ background: #fef3c7;
343
+ border: 1px solid #f59e0b;
344
+ border-radius: 0.5rem;
345
+ color: #92400e;
346
+ font-size: 0.875rem;
347
+ }
348
+
349
+ /* Handle styles */
350
+ :global(.flowdrop-workflow-node__handle) {
351
+ width: 0.75rem;
352
+ height: 0.75rem;
353
+ background-color: #6b7280;
354
+ border: 2px solid #ffffff;
355
+ border-radius: 50%;
356
+ transition: all 0.2s ease-in-out;
357
+ cursor: pointer;
358
+ }
359
+
360
+ :global(.flowdrop-workflow-node__handle:hover) {
361
+ background-color: #3b82f6;
362
+ transform: scale(1.2);
363
+ }
364
+
365
+ :global(.flowdrop-workflow-node__handle:focus) {
366
+ outline: 2px solid #3b82f6;
367
+ outline-offset: 2px;
368
+ }
369
+
370
+ :global(.flowdrop-workflow-node__handle--active) {
371
+ transform: scale(1.15);
372
+ box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.2);
373
+ }
374
+
375
+ /* Utility classes */
376
+ .flowdrop-flex {
377
+ display: flex;
378
+ }
379
+
380
+ .flowdrop-flex--1 {
381
+ flex: 1;
382
+ }
383
+
384
+ .flowdrop-gap--2 {
385
+ gap: 0.5rem;
386
+ }
387
+
388
+ .flowdrop-gap--3 {
389
+ gap: 0.75rem;
390
+ }
391
+
392
+ .flowdrop-items--center {
393
+ align-items: center;
394
+ }
395
+
396
+ .flowdrop-justify--end {
397
+ justify-content: flex-end;
398
+ }
399
+
400
+ .flowdrop-min-w--0 {
401
+ min-width: 0;
402
+ }
403
+
404
+ .flowdrop-text--xs {
405
+ font-size: 0.75rem;
406
+ line-height: 1rem;
407
+ }
408
+
409
+ .flowdrop-text--sm {
410
+ font-size: 0.875rem;
411
+ line-height: 1.25rem;
412
+ }
413
+
414
+ .flowdrop-text--gray {
415
+ color: #6b7280;
416
+ }
417
+
418
+ .flowdrop-text--active {
419
+ color: #10b981;
420
+ font-weight: 600;
421
+ }
422
+
423
+ .flowdrop-font--medium {
424
+ font-weight: 500;
425
+ }
426
+
427
+ .flowdrop-truncate {
428
+ overflow: hidden;
429
+ text-overflow: ellipsis;
430
+ white-space: nowrap;
431
+ }
432
+
433
+ .flowdrop-mt--1 {
434
+ margin-top: 0.25rem;
435
+ }
436
+
437
+ .flowdrop-text--right {
438
+ text-align: right;
439
+ }
440
+
441
+ .flowdrop-workflow-node__config-btn {
442
+ position: absolute;
443
+ top: 0.5rem;
444
+ right: 0.5rem;
445
+ width: 1.5rem;
446
+ height: 1.5rem;
447
+ background-color: rgba(255, 255, 255, 0.9);
448
+ border: 1px solid #e5e7eb;
449
+ border-radius: 0.25rem;
450
+ color: #6b7280;
451
+ cursor: pointer;
452
+ display: flex;
453
+ align-items: center;
454
+ justify-content: center;
455
+ opacity: 0;
456
+ transition: all 0.2s ease-in-out;
457
+ backdrop-filter: blur(4px);
458
+ z-index: 15;
459
+ font-size: 0.875rem;
460
+ }
461
+
462
+ .flowdrop-workflow-node:hover .flowdrop-workflow-node__config-btn {
463
+ opacity: 1;
464
+ }
465
+
466
+ .flowdrop-workflow-node__config-btn:hover {
467
+ background-color: #f9fafb;
468
+ border-color: #d1d5db;
469
+ color: #374151;
470
+ }
471
+ </style>
@@ -0,0 +1,15 @@
1
+ import type { WorkflowNode } from '../types/index.js';
2
+ interface Props {
3
+ data: WorkflowNode['data'] & {
4
+ nodeId?: string;
5
+ onConfigOpen?: (node: {
6
+ id: string;
7
+ type: string;
8
+ data: WorkflowNode['data'];
9
+ }) => void;
10
+ };
11
+ selected?: boolean;
12
+ }
13
+ declare const GatewayNode: import("svelte").Component<Props, {}, "">;
14
+ type GatewayNode = ReturnType<typeof GatewayNode>;
15
+ export default GatewayNode;
@@ -4,33 +4,33 @@
4
4
  -->
5
5
 
6
6
  <script lang="ts">
7
- interface Props {
8
- size?: "xs" | "sm" | "md" | "lg";
9
- text?: string;
10
- showText?: boolean;
11
- }
7
+ interface Props {
8
+ size?: 'xs' | 'sm' | 'md' | 'lg';
9
+ text?: string;
10
+ showText?: boolean;
11
+ }
12
12
 
13
- let props: Props = $props();
14
-
15
- // Default values
16
- let size = $derived(props.size || "md");
17
- let text = $derived(props.text || "Loading...");
18
- let showText = $derived(props.showText !== false);
13
+ let props: Props = $props();
14
+
15
+ // Default values
16
+ let size = $derived(props.size || 'md');
17
+ let text = $derived(props.text || 'Loading...');
18
+ let showText = $derived(props.showText !== false);
19
19
  </script>
20
20
 
21
21
  <div class="flowdrop-loading">
22
- <div class="flowdrop-spinner flowdrop-spinner--{size}"></div>
23
- {#if showText}
24
- <p class="flowdrop-text--xs flowdrop-text--gray">{text}</p>
25
- {/if}
22
+ <div class="flowdrop-spinner flowdrop-spinner--{size}"></div>
23
+ {#if showText}
24
+ <p class="flowdrop-text--xs flowdrop-text--gray">{text}</p>
25
+ {/if}
26
26
  </div>
27
27
 
28
28
  <style>
29
- .flowdrop-loading {
30
- display: flex;
31
- flex-direction: column;
32
- align-items: center;
33
- justify-content: center;
34
- gap: 0.5rem;
35
- }
36
- </style>
29
+ .flowdrop-loading {
30
+ display: flex;
31
+ flex-direction: column;
32
+ align-items: center;
33
+ justify-content: center;
34
+ gap: 0.5rem;
35
+ }
36
+ </style>
@@ -1,5 +1,5 @@
1
1
  interface Props {
2
- size?: "xs" | "sm" | "md" | "lg";
2
+ size?: 'xs' | 'sm' | 'md' | 'lg';
3
3
  text?: string;
4
4
  showText?: boolean;
5
5
  }