@d34dman/flowdrop 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +307 -215
- package/dist/adapters/WorkflowAdapter.d.ts +1 -1
- package/dist/adapters/WorkflowAdapter.js +30 -30
- package/dist/api/client.d.ts +24 -1
- package/dist/api/client.js +55 -38
- package/dist/api/enhanced-client.d.ts +46 -0
- package/dist/api/enhanced-client.js +211 -0
- package/dist/clients/ApiClient.d.ts +19 -23
- package/dist/clients/ApiClient.js +36 -34
- package/dist/components/App.svelte +1299 -230
- package/dist/components/App.svelte.d.ts +21 -1
- package/dist/components/CanvasBanner.svelte +50 -44
- package/dist/components/CanvasBanner.svelte.d.ts +5 -19
- package/dist/components/ConfigForm.svelte +555 -0
- package/dist/components/ConfigForm.svelte.d.ts +32 -0
- package/dist/components/ConfigModal.svelte +261 -0
- package/dist/components/ConfigModal.svelte.d.ts +31 -0
- package/dist/components/ConfigSidebar.svelte +934 -0
- package/dist/components/ConfigSidebar.svelte.d.ts +51 -0
- package/dist/components/ConnectionLine.svelte +32 -0
- package/dist/components/ConnectionLine.svelte.d.ts +3 -0
- package/dist/components/GatewayNode.svelte +471 -0
- package/dist/components/GatewayNode.svelte.d.ts +15 -0
- package/dist/components/LoadingSpinner.svelte +23 -23
- package/dist/components/LoadingSpinner.svelte.d.ts +1 -1
- package/dist/components/Logo.svelte +82 -0
- package/dist/components/Logo.svelte.d.ts +26 -0
- package/dist/components/LogsSidebar.svelte +565 -0
- package/dist/components/LogsSidebar.svelte.d.ts +34 -0
- package/dist/components/MarkdownDisplay.svelte +28 -0
- package/dist/components/MarkdownDisplay.svelte.d.ts +7 -0
- package/dist/components/Navbar.svelte +663 -0
- package/dist/components/Navbar.svelte.d.ts +21 -0
- package/dist/components/NodeSidebar.svelte +629 -488
- package/dist/components/NodeSidebar.svelte.d.ts +1 -2
- package/dist/components/NodeStatusOverlay.svelte +327 -0
- package/dist/components/NodeStatusOverlay.svelte.d.ts +11 -0
- package/dist/components/NotesNode.svelte +566 -0
- package/dist/components/NotesNode.svelte.d.ts +43 -0
- package/dist/components/PipelineStatus.svelte +331 -0
- package/dist/components/PipelineStatus.svelte.d.ts +18 -0
- package/dist/components/SimpleNode.svelte +447 -0
- package/dist/components/SimpleNode.svelte.d.ts +24 -0
- package/dist/components/SquareNode.svelte +346 -0
- package/dist/components/SquareNode.svelte.d.ts +24 -0
- package/dist/components/StatusIcon.svelte +112 -0
- package/dist/components/StatusIcon.svelte.d.ts +10 -0
- package/dist/components/StatusLabel.svelte +33 -0
- package/dist/components/StatusLabel.svelte.d.ts +7 -0
- package/dist/components/ToolNode.svelte +385 -0
- package/dist/components/ToolNode.svelte.d.ts +36 -0
- package/dist/components/UniversalNode.svelte +126 -0
- package/dist/components/UniversalNode.svelte.d.ts +15 -0
- package/dist/components/WorkflowEditor.svelte +871 -528
- package/dist/components/WorkflowEditor.svelte.d.ts +15 -5
- package/dist/components/WorkflowNode.svelte +428 -542
- package/dist/components/WorkflowNode.svelte.d.ts +7 -3
- package/dist/config/apiConfig.d.ts +33 -0
- package/dist/config/apiConfig.js +39 -0
- package/dist/config/defaultPortConfig.d.ts +6 -0
- package/dist/config/defaultPortConfig.js +192 -0
- package/dist/config/demo.d.ts +58 -0
- package/dist/config/demo.js +142 -0
- package/dist/config/endpoints.d.ts +106 -0
- package/dist/config/endpoints.js +128 -0
- package/dist/data/samples.d.ts +38 -4
- package/dist/data/samples.js +2789 -737
- package/dist/examples/adapter-usage.d.ts +4 -4
- package/dist/examples/adapter-usage.js +21 -26
- package/dist/examples/api-client-usage.d.ts +6 -6
- package/dist/examples/api-client-usage.js +55 -54
- package/dist/index.d.ts +23 -15
- package/dist/index.js +23 -15
- package/dist/mocks/app-environment.d.ts +8 -0
- package/dist/mocks/app-environment.js +16 -0
- package/dist/mocks/app-forms.d.ts +2 -0
- package/dist/mocks/app-forms.js +21 -0
- package/dist/mocks/app-navigation.d.ts +5 -0
- package/dist/mocks/app-navigation.js +34 -0
- package/dist/mocks/app-stores.d.ts +14 -0
- package/dist/mocks/app-stores.js +26 -0
- package/dist/services/api.d.ts +13 -3
- package/dist/services/api.js +91 -36
- package/dist/services/globalSave.d.ts +20 -0
- package/dist/services/globalSave.js +165 -0
- package/dist/services/nodeExecutionService.d.ts +63 -0
- package/dist/services/nodeExecutionService.js +261 -0
- package/dist/services/portConfigApi.d.ts +14 -0
- package/dist/services/portConfigApi.js +69 -0
- package/dist/services/toastService.d.ts +147 -0
- package/dist/services/toastService.js +235 -0
- package/dist/services/workflowStorage.d.ts +2 -2
- package/dist/services/workflowStorage.js +10 -10
- package/dist/stores/workflowStore.d.ts +53 -0
- package/dist/stores/workflowStore.js +264 -0
- package/dist/styles/base.css +896 -363
- package/dist/svelte-app.d.ts +52 -5
- package/dist/svelte-app.js +128 -6
- package/dist/types/config.d.ts +291 -0
- package/dist/types/config.js +4 -0
- package/dist/types/index.d.ts +231 -19
- package/dist/types/index.js +1 -1
- package/dist/utils/colors.d.ts +67 -33
- package/dist/utils/colors.js +183 -118
- package/dist/utils/config.d.ts +41 -0
- package/dist/utils/config.js +248 -0
- package/dist/utils/connections.d.ts +40 -3
- package/dist/utils/connections.js +115 -44
- package/dist/utils/icons.d.ts +1 -1
- package/dist/utils/icons.js +71 -70
- package/dist/utils/nodeStatus.d.ts +53 -0
- package/dist/utils/nodeStatus.js +183 -0
- package/dist/utils/nodeTypes.d.ts +57 -0
- package/dist/utils/nodeTypes.js +109 -0
- package/dist/utils/nodeWrapper.d.ts +39 -0
- package/dist/utils/nodeWrapper.js +62 -0
- package/package.json +129 -97
- package/dist/components/Node.svelte +0 -38
- package/dist/components/Node.svelte.d.ts +0 -4
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Square Node Component
|
|
3
|
+
A simple square node with optional input and output ports
|
|
4
|
+
Styled with BEM syntax
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
<script lang="ts">
|
|
8
|
+
import { Position, Handle } from '@xyflow/svelte';
|
|
9
|
+
import type { NodeConfig, NodeMetadata } from '../types/index.js';
|
|
10
|
+
import Icon from '@iconify/svelte';
|
|
11
|
+
import { getDataTypeColor } from '../utils/colors.js';
|
|
12
|
+
|
|
13
|
+
const props = $props<{
|
|
14
|
+
data: {
|
|
15
|
+
label: string;
|
|
16
|
+
config: NodeConfig;
|
|
17
|
+
metadata: NodeMetadata;
|
|
18
|
+
nodeId?: string;
|
|
19
|
+
onConfigOpen?: (node: {
|
|
20
|
+
id: string;
|
|
21
|
+
type: string;
|
|
22
|
+
data: { label: string; config: NodeConfig; metadata: NodeMetadata };
|
|
23
|
+
}) => void;
|
|
24
|
+
};
|
|
25
|
+
selected?: boolean;
|
|
26
|
+
isProcessing?: boolean;
|
|
27
|
+
isError?: boolean;
|
|
28
|
+
}>();
|
|
29
|
+
|
|
30
|
+
// Removed local config state - now using global ConfigSidebar
|
|
31
|
+
|
|
32
|
+
// Prioritize metadata icon over config icon for square nodes (metadata is the node definition)
|
|
33
|
+
let squareIcon = $derived(
|
|
34
|
+
(props.data.metadata?.icon as string) || (props.data.config?.icon as string) || 'mdi:square'
|
|
35
|
+
);
|
|
36
|
+
let squareColor = $derived(
|
|
37
|
+
(props.data.metadata?.color as string) || (props.data.config?.color as string) || '#6366f1'
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
// Layout configuration for square nodes (always compact)
|
|
41
|
+
const currentLayout = {
|
|
42
|
+
width: '80px',
|
|
43
|
+
height: '80px',
|
|
44
|
+
iconSize: '2rem',
|
|
45
|
+
showHeader: false
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// Handle configuration sidebar - now using global ConfigSidebar
|
|
49
|
+
function openConfigSidebar(): void {
|
|
50
|
+
if (props.data.onConfigOpen) {
|
|
51
|
+
// Create a WorkflowNodeType-like object for the global ConfigSidebar
|
|
52
|
+
const nodeForConfig = {
|
|
53
|
+
id: props.data.nodeId || 'unknown',
|
|
54
|
+
type: 'square',
|
|
55
|
+
data: props.data
|
|
56
|
+
};
|
|
57
|
+
props.data.onConfigOpen(nodeForConfig);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Handle double-click to open config
|
|
62
|
+
function handleDoubleClick(): void {
|
|
63
|
+
openConfigSidebar();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Handle single click to open config
|
|
67
|
+
function handleClick(): void {
|
|
68
|
+
openConfigSidebar();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Handle keyboard events
|
|
72
|
+
function handleKeydown(event: KeyboardEvent): void {
|
|
73
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
74
|
+
event.preventDefault();
|
|
75
|
+
openConfigSidebar();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Get first input/output ports for square node representation
|
|
80
|
+
// Special handling for trigger ports - they should always be shown if present
|
|
81
|
+
let triggerInputPort = $derived(
|
|
82
|
+
props.data.metadata?.inputs?.find((port) => port.dataType === 'trigger')
|
|
83
|
+
);
|
|
84
|
+
let triggerOutputPort = $derived(
|
|
85
|
+
props.data.metadata?.outputs?.find((port) => port.dataType === 'trigger')
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
// Get first non-trigger ports for data connections
|
|
89
|
+
let firstDataInputPort = $derived(
|
|
90
|
+
props.data.metadata?.inputs?.find((port) => port.dataType !== 'trigger')
|
|
91
|
+
);
|
|
92
|
+
let firstDataOutputPort = $derived(
|
|
93
|
+
props.data.metadata?.outputs?.find((port) => port.dataType !== 'trigger')
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
// Use trigger port if present, otherwise use first data port
|
|
97
|
+
let firstInputPort = $derived(triggerInputPort || firstDataInputPort);
|
|
98
|
+
let firstOutputPort = $derived(triggerOutputPort || firstDataOutputPort);
|
|
99
|
+
|
|
100
|
+
let hasInput = $derived(!!firstInputPort);
|
|
101
|
+
let hasOutput = $derived(!!firstOutputPort);
|
|
102
|
+
|
|
103
|
+
// Check if we need to show both trigger and data ports
|
|
104
|
+
let hasBothInputTypes = $derived(!!triggerInputPort && !!firstDataInputPort);
|
|
105
|
+
let hasBothOutputTypes = $derived(!!triggerOutputPort && !!firstDataOutputPort);
|
|
106
|
+
</script>
|
|
107
|
+
|
|
108
|
+
<!-- Input Handles -->
|
|
109
|
+
{#if firstDataInputPort}
|
|
110
|
+
<!-- Data Input - positioned at top-left if both types exist, otherwise center -->
|
|
111
|
+
<Handle
|
|
112
|
+
type="target"
|
|
113
|
+
position={Position.Left}
|
|
114
|
+
style="background-color: {getDataTypeColor(
|
|
115
|
+
firstDataInputPort.dataType
|
|
116
|
+
)}; border-color: '#ffffff'; top: {hasBothInputTypes ? '25%' : '50%'}; z-index: 30;"
|
|
117
|
+
id={`${props.data.nodeId}-input-${firstDataInputPort.id}`}
|
|
118
|
+
/>
|
|
119
|
+
{/if}
|
|
120
|
+
{#if triggerInputPort}
|
|
121
|
+
<!-- Trigger Input - positioned at bottom-left -->
|
|
122
|
+
<Handle
|
|
123
|
+
type="target"
|
|
124
|
+
position={Position.Left}
|
|
125
|
+
style="background-color: {getDataTypeColor(
|
|
126
|
+
triggerInputPort.dataType
|
|
127
|
+
)}; border-color: '#ffffff'; top: {hasBothInputTypes ? '75%' : '50%'}; z-index: 30;"
|
|
128
|
+
id={`${props.data.nodeId}-input-${triggerInputPort.id}`}
|
|
129
|
+
/>
|
|
130
|
+
{/if}
|
|
131
|
+
|
|
132
|
+
<!-- Square Node -->
|
|
133
|
+
<div
|
|
134
|
+
class="flowdrop-square-node flowdrop-square-node--compact"
|
|
135
|
+
class:flowdrop-square-node--selected={props.selected}
|
|
136
|
+
class:flowdrop-square-node--processing={props.isProcessing}
|
|
137
|
+
class:flowdrop-square-node--error={props.isError}
|
|
138
|
+
onclick={handleClick}
|
|
139
|
+
ondblclick={handleDoubleClick}
|
|
140
|
+
onkeydown={handleKeydown}
|
|
141
|
+
role="button"
|
|
142
|
+
tabindex="0"
|
|
143
|
+
>
|
|
144
|
+
<!-- Square Layout: Always compact with centered icon -->
|
|
145
|
+
<div class="flowdrop-square-node__compact-content">
|
|
146
|
+
<Icon
|
|
147
|
+
icon={squareIcon}
|
|
148
|
+
class="flowdrop-square-node__compact-icon"
|
|
149
|
+
style="color: {squareColor}; font-size: {currentLayout.iconSize};"
|
|
150
|
+
/>
|
|
151
|
+
</div>
|
|
152
|
+
|
|
153
|
+
<!-- Processing indicator -->
|
|
154
|
+
{#if props.isProcessing}
|
|
155
|
+
<div class="flowdrop-square-node__processing">
|
|
156
|
+
<div class="flowdrop-square-node__spinner"></div>
|
|
157
|
+
</div>
|
|
158
|
+
{/if}
|
|
159
|
+
|
|
160
|
+
<!-- Error indicator -->
|
|
161
|
+
{#if props.isError}
|
|
162
|
+
<div class="flowdrop-square-node__error">
|
|
163
|
+
<Icon icon="mdi:alert-circle" class="flowdrop-square-node__error-icon" />
|
|
164
|
+
</div>
|
|
165
|
+
{/if}
|
|
166
|
+
|
|
167
|
+
<!-- Config button -->
|
|
168
|
+
<button
|
|
169
|
+
class="flowdrop-square-node__config-btn"
|
|
170
|
+
onclick={openConfigSidebar}
|
|
171
|
+
title="Configure node"
|
|
172
|
+
>
|
|
173
|
+
<Icon icon="mdi:cog" />
|
|
174
|
+
</button>
|
|
175
|
+
</div>
|
|
176
|
+
|
|
177
|
+
<!-- Output Handles -->
|
|
178
|
+
{#if firstDataOutputPort}
|
|
179
|
+
<!-- Data Output - positioned at top-right if both types exist, otherwise center -->
|
|
180
|
+
<Handle
|
|
181
|
+
type="source"
|
|
182
|
+
position={Position.Right}
|
|
183
|
+
id={`${props.data.nodeId}-output-${firstDataOutputPort.id}`}
|
|
184
|
+
style="background-color: {getDataTypeColor(
|
|
185
|
+
firstDataOutputPort.dataType
|
|
186
|
+
)}; border-color: '#ffffff'; top: {hasBothOutputTypes ? '25%' : '50%'}; z-index: 30;"
|
|
187
|
+
/>
|
|
188
|
+
{/if}
|
|
189
|
+
{#if triggerOutputPort}
|
|
190
|
+
<!-- Trigger Output - positioned at bottom-right -->
|
|
191
|
+
<Handle
|
|
192
|
+
type="source"
|
|
193
|
+
position={Position.Right}
|
|
194
|
+
id={`${props.data.nodeId}-output-${triggerOutputPort.id}`}
|
|
195
|
+
style="background-color: {getDataTypeColor(
|
|
196
|
+
triggerOutputPort.dataType
|
|
197
|
+
)}; border-color: '#ffffff'; top: {hasBothOutputTypes ? '75%' : '50%'}; z-index: 30;"
|
|
198
|
+
/>
|
|
199
|
+
{/if}
|
|
200
|
+
|
|
201
|
+
<!-- ConfigSidebar removed - now using global ConfigSidebar in WorkflowEditor -->
|
|
202
|
+
|
|
203
|
+
<style>
|
|
204
|
+
.flowdrop-square-node {
|
|
205
|
+
position: relative;
|
|
206
|
+
background-color: #ffffff;
|
|
207
|
+
border: 2px solid #e5e7eb;
|
|
208
|
+
border-radius: 0.75rem;
|
|
209
|
+
display: flex;
|
|
210
|
+
flex-direction: column;
|
|
211
|
+
cursor: pointer;
|
|
212
|
+
transition: all 0.2s ease-in-out;
|
|
213
|
+
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
|
214
|
+
overflow: visible; /* Changed from hidden to visible to allow handles to be properly accessible */
|
|
215
|
+
z-index: 10;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/* Square layout (always compact) */
|
|
219
|
+
.flowdrop-square-node--compact {
|
|
220
|
+
width: 80px;
|
|
221
|
+
height: 80px;
|
|
222
|
+
justify-content: center;
|
|
223
|
+
align-items: center;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.flowdrop-square-node:hover {
|
|
227
|
+
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.flowdrop-square-node--selected {
|
|
231
|
+
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
|
|
232
|
+
border: 2px solid #3b82f6;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.flowdrop-square-node--processing {
|
|
236
|
+
opacity: 0.7;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.flowdrop-square-node--error {
|
|
240
|
+
border-color: #ef4444 !important;
|
|
241
|
+
background-color: #fef2f2 !important;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/* Compact layout styles */
|
|
245
|
+
.flowdrop-square-node__compact-content {
|
|
246
|
+
display: flex;
|
|
247
|
+
align-items: center;
|
|
248
|
+
justify-content: center;
|
|
249
|
+
width: 100%;
|
|
250
|
+
height: 100%;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
:global(.flowdrop-square-node__compact-icon) {
|
|
254
|
+
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.2));
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/* Label styling removed - now using header title */
|
|
258
|
+
|
|
259
|
+
.flowdrop-square-node__processing {
|
|
260
|
+
position: absolute;
|
|
261
|
+
top: 4px;
|
|
262
|
+
right: 4px;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.flowdrop-square-node__spinner {
|
|
266
|
+
width: 12px;
|
|
267
|
+
height: 12px;
|
|
268
|
+
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
269
|
+
border-top: 1px solid white;
|
|
270
|
+
border-radius: 50%;
|
|
271
|
+
animation: spin 1s linear infinite;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.flowdrop-square-node__error {
|
|
275
|
+
position: absolute;
|
|
276
|
+
top: 4px;
|
|
277
|
+
right: 4px;
|
|
278
|
+
color: #ef4444;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
:global(.flowdrop-square-node__error-icon) {
|
|
282
|
+
width: 12px;
|
|
283
|
+
height: 12px;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.flowdrop-square-node__config-btn {
|
|
287
|
+
position: absolute;
|
|
288
|
+
top: 0.5rem;
|
|
289
|
+
right: 0.5rem;
|
|
290
|
+
width: 1.5rem;
|
|
291
|
+
height: 1.5rem;
|
|
292
|
+
background-color: rgba(255, 255, 255, 0.9);
|
|
293
|
+
border: 1px solid #e5e7eb;
|
|
294
|
+
border-radius: 0.25rem;
|
|
295
|
+
color: #6b7280;
|
|
296
|
+
cursor: pointer;
|
|
297
|
+
display: flex;
|
|
298
|
+
align-items: center;
|
|
299
|
+
justify-content: center;
|
|
300
|
+
opacity: 0;
|
|
301
|
+
transition: all 0.2s ease-in-out;
|
|
302
|
+
backdrop-filter: blur(4px);
|
|
303
|
+
z-index: 15;
|
|
304
|
+
font-size: 0.875rem;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.flowdrop-square-node:hover .flowdrop-square-node__config-btn {
|
|
308
|
+
opacity: 1;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.flowdrop-square-node__config-btn:hover {
|
|
312
|
+
background-color: #f9fafb;
|
|
313
|
+
border-color: #d1d5db;
|
|
314
|
+
color: #374151;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
@keyframes spin {
|
|
318
|
+
to {
|
|
319
|
+
transform: rotate(360deg);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/* Handle styles - matching WorkflowNode exactly */
|
|
324
|
+
:global(.svelte-flow__node-square .svelte-flow__handle) {
|
|
325
|
+
width: 18px !important;
|
|
326
|
+
height: 18px !important;
|
|
327
|
+
border-radius: 50% !important;
|
|
328
|
+
transition: all 0.2s ease-in-out !important;
|
|
329
|
+
cursor: pointer !important;
|
|
330
|
+
z-index: 20 !important;
|
|
331
|
+
pointer-events: auto !important;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
:global(.svelte-flow__node-square .svelte-flow__handle-left) {
|
|
335
|
+
left: -6px !important;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
:global(.svelte-flow__node-square .svelte-flow__handle-right) {
|
|
339
|
+
right: -6px !important;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
:global(.svelte-flow__node-square .svelte-flow__handle:focus) {
|
|
343
|
+
outline: 2px solid #3b82f6 !important;
|
|
344
|
+
outline-offset: 2px !important;
|
|
345
|
+
}
|
|
346
|
+
</style>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { NodeConfig, NodeMetadata } from '../types/index.js';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
data: {
|
|
4
|
+
label: string;
|
|
5
|
+
config: NodeConfig;
|
|
6
|
+
metadata: NodeMetadata;
|
|
7
|
+
nodeId?: string;
|
|
8
|
+
onConfigOpen?: (node: {
|
|
9
|
+
id: string;
|
|
10
|
+
type: string;
|
|
11
|
+
data: {
|
|
12
|
+
label: string;
|
|
13
|
+
config: NodeConfig;
|
|
14
|
+
metadata: NodeMetadata;
|
|
15
|
+
};
|
|
16
|
+
}) => void;
|
|
17
|
+
};
|
|
18
|
+
selected?: boolean;
|
|
19
|
+
isProcessing?: boolean;
|
|
20
|
+
isError?: boolean;
|
|
21
|
+
};
|
|
22
|
+
declare const SquareNode: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
23
|
+
type SquareNode = ReturnType<typeof SquareNode>;
|
|
24
|
+
export default SquareNode;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Status Icon Component
|
|
3
|
+
Reusable status icon that can be used anywhere in the application
|
|
4
|
+
Displays status with appropriate icon, color, and styling
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
<script lang="ts">
|
|
8
|
+
import type { NodeExecutionStatus } from '../types/index.js';
|
|
9
|
+
import Icon from '@iconify/svelte';
|
|
10
|
+
import { getStatusColor, getStatusIcon } from '../utils/nodeStatus.js';
|
|
11
|
+
|
|
12
|
+
interface Props {
|
|
13
|
+
status: NodeExecutionStatus;
|
|
14
|
+
size?: 'sm' | 'md' | 'lg' | 'xl';
|
|
15
|
+
showBackground?: boolean;
|
|
16
|
+
class?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let props: Props = $props();
|
|
20
|
+
|
|
21
|
+
// Size configurations
|
|
22
|
+
const sizeConfig = {
|
|
23
|
+
sm: {
|
|
24
|
+
iconSize: '12px',
|
|
25
|
+
backgroundSize: '20px',
|
|
26
|
+
backgroundRadius: '0.25rem'
|
|
27
|
+
},
|
|
28
|
+
md: {
|
|
29
|
+
iconSize: '16px',
|
|
30
|
+
backgroundSize: '24px',
|
|
31
|
+
backgroundRadius: '0.375rem'
|
|
32
|
+
},
|
|
33
|
+
lg: {
|
|
34
|
+
iconSize: '24px',
|
|
35
|
+
backgroundSize: '48px',
|
|
36
|
+
backgroundRadius: '0.5rem'
|
|
37
|
+
},
|
|
38
|
+
xl: {
|
|
39
|
+
iconSize: '28px',
|
|
40
|
+
backgroundSize: '56px',
|
|
41
|
+
backgroundRadius: '0.75rem'
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const config = sizeConfig[props.size || 'md'];
|
|
46
|
+
const statusColor = $derived(getStatusColor(props.status));
|
|
47
|
+
const statusIcon = $derived(getStatusIcon(props.status));
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
{#if props.showBackground}
|
|
51
|
+
<div
|
|
52
|
+
class="status-icon status-icon--with-background {props.class || ''}"
|
|
53
|
+
style="
|
|
54
|
+
--icon-size: {config.iconSize};
|
|
55
|
+
--background-size: {config.backgroundSize};
|
|
56
|
+
--background-radius: {config.backgroundRadius};
|
|
57
|
+
--status-color: {statusColor};
|
|
58
|
+
"
|
|
59
|
+
title={props.status}
|
|
60
|
+
>
|
|
61
|
+
<Icon icon={statusIcon} class="status-icon__icon" />
|
|
62
|
+
</div>
|
|
63
|
+
{:else}
|
|
64
|
+
<Icon
|
|
65
|
+
icon={statusIcon}
|
|
66
|
+
class="status-icon status-icon--icon-only {props.class || ''}"
|
|
67
|
+
style="
|
|
68
|
+
--icon-size: {config.iconSize};
|
|
69
|
+
--status-color: {statusColor};
|
|
70
|
+
"
|
|
71
|
+
/>
|
|
72
|
+
{/if}
|
|
73
|
+
|
|
74
|
+
<style>
|
|
75
|
+
.status-icon {
|
|
76
|
+
display: inline-flex;
|
|
77
|
+
align-items: center;
|
|
78
|
+
justify-content: center;
|
|
79
|
+
color: var(--status-color);
|
|
80
|
+
transition: all 0.2s ease-in-out;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.status-icon--with-background {
|
|
84
|
+
width: var(--background-size);
|
|
85
|
+
height: var(--background-size);
|
|
86
|
+
background-color: var(--status-color);
|
|
87
|
+
border-radius: var(--background-radius);
|
|
88
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
89
|
+
position: relative;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.status-icon--icon-only {
|
|
93
|
+
width: var(--icon-size);
|
|
94
|
+
height: var(--icon-size);
|
|
95
|
+
font-size: var(--icon-size);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* Animation for running status */
|
|
99
|
+
.status-icon--with-background[title='running'] {
|
|
100
|
+
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@keyframes pulse {
|
|
104
|
+
0%,
|
|
105
|
+
100% {
|
|
106
|
+
opacity: 1;
|
|
107
|
+
}
|
|
108
|
+
50% {
|
|
109
|
+
opacity: 0.7;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
</style>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { NodeExecutionStatus } from '../types/index.js';
|
|
2
|
+
interface Props {
|
|
3
|
+
status: NodeExecutionStatus;
|
|
4
|
+
size?: 'sm' | 'md' | 'lg' | 'xl';
|
|
5
|
+
showBackground?: boolean;
|
|
6
|
+
class?: string;
|
|
7
|
+
}
|
|
8
|
+
declare const StatusIcon: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type StatusIcon = ReturnType<typeof StatusIcon>;
|
|
10
|
+
export default StatusIcon;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Status Label Component
|
|
3
|
+
Dedicated component for displaying status labels with consistent styling
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
<script lang="ts">
|
|
7
|
+
interface Props {
|
|
8
|
+
label: string;
|
|
9
|
+
class?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let props: Props = $props();
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<span class="status-label {props.class || ''}">
|
|
16
|
+
{props.label}
|
|
17
|
+
</span>
|
|
18
|
+
|
|
19
|
+
<style>
|
|
20
|
+
.status-label {
|
|
21
|
+
font-size: 16px;
|
|
22
|
+
font-weight: 600;
|
|
23
|
+
color: #000000;
|
|
24
|
+
white-space: nowrap;
|
|
25
|
+
line-height: 1.2;
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
text-overflow: ellipsis;
|
|
28
|
+
text-shadow: 0 1px 2px rgba(255, 255, 255, 0.3);
|
|
29
|
+
letter-spacing: 0.025em;
|
|
30
|
+
display: flex;
|
|
31
|
+
align-items: center;
|
|
32
|
+
}
|
|
33
|
+
</style>
|