@d34dman/flowdrop 0.0.16 → 0.0.18
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 +106 -0
- package/dist/api/enhanced-client.d.ts +3 -3
- package/dist/api/enhanced-client.js +57 -57
- package/dist/components/FlowDropZone.svelte +4 -5
- package/dist/components/FlowDropZone.svelte.d.ts +1 -1
- package/dist/components/TerminalNode.svelte +565 -0
- package/dist/components/TerminalNode.svelte.d.ts +24 -0
- package/dist/components/UniversalNode.svelte +94 -34
- package/dist/components/WorkflowEditor.svelte +63 -3
- package/dist/config/runtimeConfig.d.ts +2 -2
- package/dist/config/runtimeConfig.js +7 -7
- package/dist/helpers/workflowEditorHelper.d.ts +44 -4
- package/dist/helpers/workflowEditorHelper.js +161 -30
- package/dist/index.d.ts +16 -13
- package/dist/index.js +19 -8
- package/dist/registry/builtinNodes.d.ts +77 -0
- package/dist/registry/builtinNodes.js +194 -0
- package/dist/registry/index.d.ts +7 -0
- package/dist/registry/index.js +10 -0
- package/dist/registry/nodeComponentRegistry.d.ts +307 -0
- package/dist/registry/nodeComponentRegistry.js +315 -0
- package/dist/registry/plugin.d.ts +215 -0
- package/dist/registry/plugin.js +249 -0
- package/dist/services/draftStorage.d.ts +1 -1
- package/dist/services/draftStorage.js +5 -5
- package/dist/stores/workflowStore.d.ts +2 -2
- package/dist/stores/workflowStore.js +16 -16
- package/dist/styles/base.css +15 -0
- package/dist/svelte-app.d.ts +6 -6
- package/dist/svelte-app.js +25 -25
- package/dist/types/auth.d.ts +2 -2
- package/dist/types/auth.js +7 -7
- package/dist/types/events.d.ts +2 -2
- package/dist/types/index.d.ts +38 -3
- package/dist/utils/nodeTypes.d.ts +76 -21
- package/dist/utils/nodeTypes.js +182 -32
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -14,6 +14,14 @@ A visual workflow editor component library built with Svelte 5 and @xyflow/svelt
|
|
|
14
14
|
- **TypeScript Support**: Full type definitions included
|
|
15
15
|
- **Docker Ready**: Production-ready Dockerfile and Docker Compose configuration
|
|
16
16
|
|
|
17
|
+
### Enterprise Features (v0.0.16+)
|
|
18
|
+
|
|
19
|
+
- **Pluggable Authentication**: AuthProvider interface for OAuth, JWT, SSO integration
|
|
20
|
+
- **Workflow Lifecycle Events**: Hooks for save, load, change, and unmount events
|
|
21
|
+
- **Dirty State Tracking**: Monitor unsaved changes with reactive stores
|
|
22
|
+
- **Draft Auto-Save**: Automatic localStorage drafts with configurable intervals
|
|
23
|
+
- **Feature Flags**: Customize behavior for security and UX requirements
|
|
24
|
+
|
|
17
25
|
## 📦 Installation
|
|
18
26
|
|
|
19
27
|
```bash
|
|
@@ -117,6 +125,52 @@ const editor = mountWorkflowEditor(container, {
|
|
|
117
125
|
editor.destroy();
|
|
118
126
|
```
|
|
119
127
|
|
|
128
|
+
#### 3. Enterprise Integration (v0.0.16+)
|
|
129
|
+
|
|
130
|
+
```javascript
|
|
131
|
+
import { mountFlowDropApp, createEndpointConfig, CallbackAuthProvider } from '@d34dman/flowdrop';
|
|
132
|
+
|
|
133
|
+
const app = await mountFlowDropApp(container, {
|
|
134
|
+
workflow: myWorkflow,
|
|
135
|
+
endpointConfig: createEndpointConfig('/api/flowdrop'),
|
|
136
|
+
|
|
137
|
+
// Dynamic authentication with token refresh
|
|
138
|
+
authProvider: new CallbackAuthProvider({
|
|
139
|
+
getToken: () => authService.getAccessToken(),
|
|
140
|
+
onUnauthorized: () => authService.refreshToken()
|
|
141
|
+
}),
|
|
142
|
+
|
|
143
|
+
// Workflow lifecycle hooks
|
|
144
|
+
eventHandlers: {
|
|
145
|
+
onDirtyStateChange: (isDirty) => updateSaveButton(isDirty),
|
|
146
|
+
onAfterSave: (workflow) => showSuccess('Saved!'),
|
|
147
|
+
onBeforeUnmount: (workflow, isDirty) => {
|
|
148
|
+
if (isDirty) saveDraft(workflow);
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
|
|
152
|
+
// Feature configuration
|
|
153
|
+
features: {
|
|
154
|
+
autoSaveDraft: true,
|
|
155
|
+
autoSaveDraftInterval: 30000,
|
|
156
|
+
showToasts: true
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// Access instance methods
|
|
161
|
+
if (app.isDirty()) {
|
|
162
|
+
await app.save();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Get current workflow data
|
|
166
|
+
const workflow = app.getWorkflow();
|
|
167
|
+
|
|
168
|
+
// Cleanup
|
|
169
|
+
app.destroy();
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
See the [Enterprise Integration Guide](./docs/enterprise-integration.md) for React, Vue, Angular, and Drupal examples.
|
|
173
|
+
|
|
120
174
|
#### 3. Integration with Backend Frameworks
|
|
121
175
|
|
|
122
176
|
##### Drupal Example
|
|
@@ -218,6 +272,48 @@ Override CSS custom properties:
|
|
|
218
272
|
|
|
219
273
|
### Node Types
|
|
220
274
|
|
|
275
|
+
FlowDrop includes 7 built-in visual node types that control how nodes are rendered:
|
|
276
|
+
|
|
277
|
+
| Type | Description | Use Case |
|
|
278
|
+
| ---------- | ------------------------------------------------------- | ------------------------ |
|
|
279
|
+
| `default` | Full-featured workflow node with inputs/outputs display | Standard nodes |
|
|
280
|
+
| `simple` | Compact layout with header, icon, and description | Space-efficient nodes |
|
|
281
|
+
| `square` | Minimal square node showing only an icon | Icon-only representation |
|
|
282
|
+
| `tool` | Specialized node for agent tools with tool metadata | AI agent tools |
|
|
283
|
+
| `gateway` | Branching control flow with multiple output branches | Conditional logic |
|
|
284
|
+
| `terminal` | Circular node for workflow start/end/exit points | Workflow boundaries |
|
|
285
|
+
| `note` | Documentation note with markdown support | Comments/documentation |
|
|
286
|
+
|
|
287
|
+
#### Terminal Nodes
|
|
288
|
+
|
|
289
|
+
Terminal nodes are special circular nodes for workflow boundaries:
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
// Start node - output only
|
|
293
|
+
const startNode: NodeMetadata = {
|
|
294
|
+
id: 'workflow-start',
|
|
295
|
+
name: 'Start',
|
|
296
|
+
type: 'terminal',
|
|
297
|
+
tags: ['start'],
|
|
298
|
+
inputs: [],
|
|
299
|
+
outputs: [{ id: 'trigger', name: 'Go', type: 'output', dataType: 'trigger' }]
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
// End node - input only
|
|
303
|
+
const endNode: NodeMetadata = {
|
|
304
|
+
id: 'workflow-end',
|
|
305
|
+
name: 'End',
|
|
306
|
+
type: 'terminal',
|
|
307
|
+
tags: ['end'],
|
|
308
|
+
inputs: [{ id: 'done', name: 'Done', type: 'input', dataType: 'trigger' }],
|
|
309
|
+
outputs: []
|
|
310
|
+
};
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Terminal variants are auto-detected from `id`, `name`, or `tags` containing: `start`, `end`, `exit`, `abort`, `entry`, `finish`, `complete`.
|
|
314
|
+
|
|
315
|
+
#### Custom Node Types
|
|
316
|
+
|
|
221
317
|
Define custom node types:
|
|
222
318
|
|
|
223
319
|
```typescript
|
|
@@ -313,6 +409,13 @@ npm run format
|
|
|
313
409
|
- **CHANGELOG.md** - Version history
|
|
314
410
|
- **Storybook** - Component documentation (run `npm run storybook`)
|
|
315
411
|
|
|
412
|
+
### Enterprise Features (v0.0.16+)
|
|
413
|
+
|
|
414
|
+
- **[Enterprise Integration Guide](./docs/enterprise-integration.md)** - Complete integration patterns for React, Vue, Angular, Drupal
|
|
415
|
+
- **[Authentication Guide](./docs/authentication-guide.md)** - OAuth, JWT, SSO, and custom auth providers
|
|
416
|
+
- **[Event Handlers](./docs/event-handlers.md)** - Workflow lifecycle events and hooks
|
|
417
|
+
- **[Features Configuration](./docs/features-configuration.md)** - Feature flags, draft auto-save, and customization
|
|
418
|
+
|
|
316
419
|
## 🤝 Contributing
|
|
317
420
|
|
|
318
421
|
Not accepting contributions until the library stabilizes. Stay tuned.
|
|
@@ -347,6 +450,7 @@ docker-compose up -d
|
|
|
347
450
|
### Environment Variables
|
|
348
451
|
|
|
349
452
|
**Production (Runtime):**
|
|
453
|
+
|
|
350
454
|
- `FLOWDROP_API_BASE_URL` - Backend API URL
|
|
351
455
|
- `FLOWDROP_THEME` - UI theme (light/dark/auto)
|
|
352
456
|
- `FLOWDROP_TIMEOUT` - Request timeout in milliseconds
|
|
@@ -354,6 +458,7 @@ docker-compose up -d
|
|
|
354
458
|
- `FLOWDROP_AUTH_TOKEN` - Authentication token
|
|
355
459
|
|
|
356
460
|
**Development (Build-time):**
|
|
461
|
+
|
|
357
462
|
- `VITE_API_BASE_URL` - Dev API URL (used only during `npm run dev`)
|
|
358
463
|
|
|
359
464
|
### Build for Production
|
|
@@ -371,6 +476,7 @@ node build
|
|
|
371
476
|
```
|
|
372
477
|
|
|
373
478
|
For detailed deployment instructions, see:
|
|
479
|
+
|
|
374
480
|
- [DOCKER.md](./DOCKER.md) - Docker quick start
|
|
375
481
|
|
|
376
482
|
---
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module api/enhanced-client
|
|
7
7
|
*/
|
|
8
|
-
import type { NodeMetadata, Workflow, ExecutionResult } from
|
|
9
|
-
import type { EndpointConfig } from
|
|
10
|
-
import type { AuthProvider } from
|
|
8
|
+
import type { NodeMetadata, Workflow, ExecutionResult } from '../types/index.js';
|
|
9
|
+
import type { EndpointConfig } from '../config/endpoints.js';
|
|
10
|
+
import type { AuthProvider } from '../types/auth.js';
|
|
11
11
|
/**
|
|
12
12
|
* API error with additional context
|
|
13
13
|
*/
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module api/enhanced-client
|
|
7
7
|
*/
|
|
8
|
-
import { buildEndpointUrl, getEndpointMethod, getEndpointHeaders } from
|
|
9
|
-
import { createAuthProviderFromLegacyConfig } from
|
|
8
|
+
import { buildEndpointUrl, getEndpointMethod, getEndpointHeaders } from '../config/endpoints.js';
|
|
9
|
+
import { createAuthProviderFromLegacyConfig } from '../types/auth.js';
|
|
10
10
|
/**
|
|
11
11
|
* API error with additional context
|
|
12
12
|
*/
|
|
@@ -19,7 +19,7 @@ export class ApiError extends Error {
|
|
|
19
19
|
operation;
|
|
20
20
|
constructor(message, status, operation, errorData = {}) {
|
|
21
21
|
super(message);
|
|
22
|
-
this.name =
|
|
22
|
+
this.name = 'ApiError';
|
|
23
23
|
this.status = status;
|
|
24
24
|
this.operation = operation;
|
|
25
25
|
this.errorData = errorData;
|
|
@@ -62,7 +62,7 @@ export class EnhancedFlowDropApiClient {
|
|
|
62
62
|
* @param options - Additional fetch options
|
|
63
63
|
* @param operation - Description of the operation (for error messages)
|
|
64
64
|
*/
|
|
65
|
-
async request(endpointKey, endpointPath, params, options = {}, operation =
|
|
65
|
+
async request(endpointKey, endpointPath, params, options = {}, operation = 'API request') {
|
|
66
66
|
const url = buildEndpointUrl(this.config, endpointPath, params);
|
|
67
67
|
const method = options.method ?? getEndpointMethod(this.config, endpointKey);
|
|
68
68
|
const configHeaders = getEndpointHeaders(this.config, endpointKey);
|
|
@@ -99,14 +99,14 @@ export class EnhancedFlowDropApiClient {
|
|
|
99
99
|
continue; // Retry with new headers
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
|
-
throw new ApiError(
|
|
102
|
+
throw new ApiError('Unauthorized', 401, operation, {});
|
|
103
103
|
}
|
|
104
104
|
// Handle 403 Forbidden
|
|
105
105
|
if (response.status === 403) {
|
|
106
106
|
if (this.authProvider.onForbidden) {
|
|
107
107
|
await this.authProvider.onForbidden();
|
|
108
108
|
}
|
|
109
|
-
throw new ApiError(
|
|
109
|
+
throw new ApiError('Forbidden', 403, operation, {});
|
|
110
110
|
}
|
|
111
111
|
// Handle other errors
|
|
112
112
|
if (!response.ok) {
|
|
@@ -133,7 +133,7 @@ export class EnhancedFlowDropApiClient {
|
|
|
133
133
|
}
|
|
134
134
|
// Wait before retry
|
|
135
135
|
const delay = this.config.retry?.delay ?? 1000;
|
|
136
|
-
const backoffDelay = this.config.retry?.backoff ===
|
|
136
|
+
const backoffDelay = this.config.retry?.backoff === 'exponential' ? delay * Math.pow(2, attempt - 1) : delay;
|
|
137
137
|
await new Promise((resolve) => setTimeout(resolve, backoffDelay));
|
|
138
138
|
}
|
|
139
139
|
}
|
|
@@ -166,9 +166,9 @@ export class EnhancedFlowDropApiClient {
|
|
|
166
166
|
* Fetch all available node types
|
|
167
167
|
*/
|
|
168
168
|
async getAvailableNodes() {
|
|
169
|
-
const response = await this.request(
|
|
169
|
+
const response = await this.request('nodes.list', this.config.endpoints.nodes.list, undefined, {}, 'fetch available nodes');
|
|
170
170
|
if (!response.success || !response.data) {
|
|
171
|
-
throw new Error(response.error ??
|
|
171
|
+
throw new Error(response.error ?? 'Failed to fetch available nodes');
|
|
172
172
|
}
|
|
173
173
|
return response.data;
|
|
174
174
|
}
|
|
@@ -176,9 +176,9 @@ export class EnhancedFlowDropApiClient {
|
|
|
176
176
|
* Fetch nodes filtered by category
|
|
177
177
|
*/
|
|
178
178
|
async getNodesByCategory(category) {
|
|
179
|
-
const response = await this.request(
|
|
179
|
+
const response = await this.request('nodes.byCategory', this.config.endpoints.nodes.byCategory, { category }, {}, 'fetch nodes by category');
|
|
180
180
|
if (!response.success || !response.data) {
|
|
181
|
-
throw new Error(response.error ??
|
|
181
|
+
throw new Error(response.error ?? 'Failed to fetch nodes by category');
|
|
182
182
|
}
|
|
183
183
|
return response.data;
|
|
184
184
|
}
|
|
@@ -186,9 +186,9 @@ export class EnhancedFlowDropApiClient {
|
|
|
186
186
|
* Fetch metadata for a specific node type
|
|
187
187
|
*/
|
|
188
188
|
async getNodeMetadata(nodeId) {
|
|
189
|
-
const response = await this.request(
|
|
189
|
+
const response = await this.request('nodes.metadata', this.config.endpoints.nodes.metadata, { id: nodeId }, {}, 'fetch node metadata');
|
|
190
190
|
if (!response.success || !response.data) {
|
|
191
|
-
throw new Error(response.error ??
|
|
191
|
+
throw new Error(response.error ?? 'Failed to fetch node metadata');
|
|
192
192
|
}
|
|
193
193
|
return response.data;
|
|
194
194
|
}
|
|
@@ -199,12 +199,12 @@ export class EnhancedFlowDropApiClient {
|
|
|
199
199
|
* Save a new workflow
|
|
200
200
|
*/
|
|
201
201
|
async saveWorkflow(workflow) {
|
|
202
|
-
const response = await this.request(
|
|
203
|
-
method:
|
|
202
|
+
const response = await this.request('workflows.create', this.config.endpoints.workflows.create, undefined, {
|
|
203
|
+
method: 'POST',
|
|
204
204
|
body: JSON.stringify(workflow)
|
|
205
|
-
},
|
|
205
|
+
}, 'save workflow');
|
|
206
206
|
if (!response.success || !response.data) {
|
|
207
|
-
throw new Error(response.error ??
|
|
207
|
+
throw new Error(response.error ?? 'Failed to save workflow');
|
|
208
208
|
}
|
|
209
209
|
return response.data;
|
|
210
210
|
}
|
|
@@ -212,12 +212,12 @@ export class EnhancedFlowDropApiClient {
|
|
|
212
212
|
* Update an existing workflow
|
|
213
213
|
*/
|
|
214
214
|
async updateWorkflow(workflowId, workflow) {
|
|
215
|
-
const response = await this.request(
|
|
216
|
-
method:
|
|
215
|
+
const response = await this.request('workflows.update', this.config.endpoints.workflows.update, { id: workflowId }, {
|
|
216
|
+
method: 'PUT',
|
|
217
217
|
body: JSON.stringify(workflow)
|
|
218
|
-
},
|
|
218
|
+
}, 'update workflow');
|
|
219
219
|
if (!response.success || !response.data) {
|
|
220
|
-
throw new Error(response.error ??
|
|
220
|
+
throw new Error(response.error ?? 'Failed to update workflow');
|
|
221
221
|
}
|
|
222
222
|
return response.data;
|
|
223
223
|
}
|
|
@@ -225,9 +225,9 @@ export class EnhancedFlowDropApiClient {
|
|
|
225
225
|
* Load a workflow by ID
|
|
226
226
|
*/
|
|
227
227
|
async loadWorkflow(workflowId) {
|
|
228
|
-
const response = await this.request(
|
|
228
|
+
const response = await this.request('workflows.get', this.config.endpoints.workflows.get, { id: workflowId }, {}, 'load workflow');
|
|
229
229
|
if (!response.success || !response.data) {
|
|
230
|
-
throw new Error(response.error ??
|
|
230
|
+
throw new Error(response.error ?? 'Failed to load workflow');
|
|
231
231
|
}
|
|
232
232
|
return response.data;
|
|
233
233
|
}
|
|
@@ -235,9 +235,9 @@ export class EnhancedFlowDropApiClient {
|
|
|
235
235
|
* List all workflows
|
|
236
236
|
*/
|
|
237
237
|
async listWorkflows() {
|
|
238
|
-
const response = await this.request(
|
|
238
|
+
const response = await this.request('workflows.list', this.config.endpoints.workflows.list, undefined, {}, 'list workflows');
|
|
239
239
|
if (!response.success || !response.data) {
|
|
240
|
-
throw new Error(response.error ??
|
|
240
|
+
throw new Error(response.error ?? 'Failed to list workflows');
|
|
241
241
|
}
|
|
242
242
|
return response.data;
|
|
243
243
|
}
|
|
@@ -245,21 +245,21 @@ export class EnhancedFlowDropApiClient {
|
|
|
245
245
|
* Delete a workflow
|
|
246
246
|
*/
|
|
247
247
|
async deleteWorkflow(workflowId) {
|
|
248
|
-
const response = await this.request(
|
|
248
|
+
const response = await this.request('workflows.delete', this.config.endpoints.workflows.delete, { id: workflowId }, { method: 'DELETE' }, 'delete workflow');
|
|
249
249
|
if (!response.success) {
|
|
250
|
-
throw new Error(response.error ??
|
|
250
|
+
throw new Error(response.error ?? 'Failed to delete workflow');
|
|
251
251
|
}
|
|
252
252
|
}
|
|
253
253
|
/**
|
|
254
254
|
* Validate a workflow
|
|
255
255
|
*/
|
|
256
256
|
async validateWorkflow(workflow) {
|
|
257
|
-
const response = await this.request(
|
|
258
|
-
method:
|
|
257
|
+
const response = await this.request('workflows.validate', this.config.endpoints.workflows.validate, undefined, {
|
|
258
|
+
method: 'POST',
|
|
259
259
|
body: JSON.stringify(workflow)
|
|
260
|
-
},
|
|
260
|
+
}, 'validate workflow');
|
|
261
261
|
if (!response.success || !response.data) {
|
|
262
|
-
throw new Error(response.error ??
|
|
262
|
+
throw new Error(response.error ?? 'Failed to validate workflow');
|
|
263
263
|
}
|
|
264
264
|
return response.data;
|
|
265
265
|
}
|
|
@@ -267,9 +267,9 @@ export class EnhancedFlowDropApiClient {
|
|
|
267
267
|
* Export a workflow as JSON string
|
|
268
268
|
*/
|
|
269
269
|
async exportWorkflow(workflowId) {
|
|
270
|
-
const response = await this.request(
|
|
270
|
+
const response = await this.request('workflows.export', this.config.endpoints.workflows.export, { id: workflowId }, {}, 'export workflow');
|
|
271
271
|
if (!response.success || !response.data) {
|
|
272
|
-
throw new Error(response.error ??
|
|
272
|
+
throw new Error(response.error ?? 'Failed to export workflow');
|
|
273
273
|
}
|
|
274
274
|
return response.data;
|
|
275
275
|
}
|
|
@@ -277,12 +277,12 @@ export class EnhancedFlowDropApiClient {
|
|
|
277
277
|
* Import a workflow from JSON
|
|
278
278
|
*/
|
|
279
279
|
async importWorkflow(workflowJson) {
|
|
280
|
-
const response = await this.request(
|
|
281
|
-
method:
|
|
280
|
+
const response = await this.request('workflows.import', this.config.endpoints.workflows.import, undefined, {
|
|
281
|
+
method: 'POST',
|
|
282
282
|
body: JSON.stringify({ workflow: workflowJson })
|
|
283
|
-
},
|
|
283
|
+
}, 'import workflow');
|
|
284
284
|
if (!response.success || !response.data) {
|
|
285
|
-
throw new Error(response.error ??
|
|
285
|
+
throw new Error(response.error ?? 'Failed to import workflow');
|
|
286
286
|
}
|
|
287
287
|
return response.data;
|
|
288
288
|
}
|
|
@@ -293,12 +293,12 @@ export class EnhancedFlowDropApiClient {
|
|
|
293
293
|
* Execute a workflow
|
|
294
294
|
*/
|
|
295
295
|
async executeWorkflow(workflowId, inputs) {
|
|
296
|
-
const response = await this.request(
|
|
297
|
-
method:
|
|
296
|
+
const response = await this.request('executions.execute', this.config.endpoints.executions.execute, { id: workflowId }, {
|
|
297
|
+
method: 'POST',
|
|
298
298
|
body: JSON.stringify({ inputs })
|
|
299
|
-
},
|
|
299
|
+
}, 'execute workflow');
|
|
300
300
|
if (!response.success || !response.data) {
|
|
301
|
-
throw new Error(response.error ??
|
|
301
|
+
throw new Error(response.error ?? 'Failed to execute workflow');
|
|
302
302
|
}
|
|
303
303
|
return response.data;
|
|
304
304
|
}
|
|
@@ -306,9 +306,9 @@ export class EnhancedFlowDropApiClient {
|
|
|
306
306
|
* Get execution status
|
|
307
307
|
*/
|
|
308
308
|
async getExecutionStatus(executionId) {
|
|
309
|
-
const response = await this.request(
|
|
309
|
+
const response = await this.request('executions.status', this.config.endpoints.executions.status, { id: executionId }, {}, 'get execution status');
|
|
310
310
|
if (!response.success || !response.data) {
|
|
311
|
-
throw new Error(response.error ??
|
|
311
|
+
throw new Error(response.error ?? 'Failed to get execution status');
|
|
312
312
|
}
|
|
313
313
|
return response.data;
|
|
314
314
|
}
|
|
@@ -316,18 +316,18 @@ export class EnhancedFlowDropApiClient {
|
|
|
316
316
|
* Cancel a running execution
|
|
317
317
|
*/
|
|
318
318
|
async cancelExecution(executionId) {
|
|
319
|
-
const response = await this.request(
|
|
319
|
+
const response = await this.request('executions.cancel', this.config.endpoints.executions.cancel, { id: executionId }, { method: 'POST' }, 'cancel execution');
|
|
320
320
|
if (!response.success) {
|
|
321
|
-
throw new Error(response.error ??
|
|
321
|
+
throw new Error(response.error ?? 'Failed to cancel execution');
|
|
322
322
|
}
|
|
323
323
|
}
|
|
324
324
|
/**
|
|
325
325
|
* Get execution logs
|
|
326
326
|
*/
|
|
327
327
|
async getExecutionLogs(executionId) {
|
|
328
|
-
const response = await this.request(
|
|
328
|
+
const response = await this.request('executions.logs', this.config.endpoints.executions.logs, { id: executionId }, {}, 'get execution logs');
|
|
329
329
|
if (!response.success || !response.data) {
|
|
330
|
-
throw new Error(response.error ??
|
|
330
|
+
throw new Error(response.error ?? 'Failed to get execution logs');
|
|
331
331
|
}
|
|
332
332
|
return response.data;
|
|
333
333
|
}
|
|
@@ -338,9 +338,9 @@ export class EnhancedFlowDropApiClient {
|
|
|
338
338
|
* List available templates
|
|
339
339
|
*/
|
|
340
340
|
async listTemplates() {
|
|
341
|
-
const response = await this.request(
|
|
341
|
+
const response = await this.request('templates.list', this.config.endpoints.templates.list, undefined, {}, 'list templates');
|
|
342
342
|
if (!response.success || !response.data) {
|
|
343
|
-
throw new Error(response.error ??
|
|
343
|
+
throw new Error(response.error ?? 'Failed to list templates');
|
|
344
344
|
}
|
|
345
345
|
return response.data;
|
|
346
346
|
}
|
|
@@ -348,9 +348,9 @@ export class EnhancedFlowDropApiClient {
|
|
|
348
348
|
* Get a template by ID
|
|
349
349
|
*/
|
|
350
350
|
async getTemplate(templateId) {
|
|
351
|
-
const response = await this.request(
|
|
351
|
+
const response = await this.request('templates.get', this.config.endpoints.templates.get, { id: templateId }, {}, 'get template');
|
|
352
352
|
if (!response.success || !response.data) {
|
|
353
|
-
throw new Error(response.error ??
|
|
353
|
+
throw new Error(response.error ?? 'Failed to get template');
|
|
354
354
|
}
|
|
355
355
|
return response.data;
|
|
356
356
|
}
|
|
@@ -361,9 +361,9 @@ export class EnhancedFlowDropApiClient {
|
|
|
361
361
|
* Get system health status
|
|
362
362
|
*/
|
|
363
363
|
async getSystemHealth() {
|
|
364
|
-
const response = await this.request(
|
|
364
|
+
const response = await this.request('system.health', this.config.endpoints.system.health, undefined, {}, 'get system health');
|
|
365
365
|
if (!response.success || !response.data) {
|
|
366
|
-
throw new Error(response.error ??
|
|
366
|
+
throw new Error(response.error ?? 'Failed to get system health');
|
|
367
367
|
}
|
|
368
368
|
return response.data;
|
|
369
369
|
}
|
|
@@ -371,9 +371,9 @@ export class EnhancedFlowDropApiClient {
|
|
|
371
371
|
* Get system configuration
|
|
372
372
|
*/
|
|
373
373
|
async getSystemConfig() {
|
|
374
|
-
const response = await this.request(
|
|
374
|
+
const response = await this.request('system.config', this.config.endpoints.system.config, undefined, {}, 'get system config');
|
|
375
375
|
if (!response.success || !response.data) {
|
|
376
|
-
throw new Error(response.error ??
|
|
376
|
+
throw new Error(response.error ?? 'Failed to get system config');
|
|
377
377
|
}
|
|
378
378
|
return response.data;
|
|
379
379
|
}
|
|
@@ -381,9 +381,9 @@ export class EnhancedFlowDropApiClient {
|
|
|
381
381
|
* Get system version information
|
|
382
382
|
*/
|
|
383
383
|
async getSystemVersion() {
|
|
384
|
-
const response = await this.request(
|
|
384
|
+
const response = await this.request('system.version', this.config.endpoints.system.version, undefined, {}, 'get system version');
|
|
385
385
|
if (!response.success || !response.data) {
|
|
386
|
-
throw new Error(response.error ??
|
|
386
|
+
throw new Error(response.error ?? 'Failed to get system version');
|
|
387
387
|
}
|
|
388
388
|
return response.data;
|
|
389
389
|
}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
-->
|
|
6
6
|
|
|
7
7
|
<script lang="ts">
|
|
8
|
-
import { useSvelteFlow } from
|
|
9
|
-
import type { Snippet } from
|
|
8
|
+
import { useSvelteFlow } from '@xyflow/svelte';
|
|
9
|
+
import type { Snippet } from 'svelte';
|
|
10
10
|
|
|
11
11
|
interface Props {
|
|
12
12
|
ondrop: (nodeTypeData: string, position: { x: number; y: number }) => void;
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
function handleDragOver(e: DragEvent): void {
|
|
25
25
|
e.preventDefault();
|
|
26
26
|
if (e.dataTransfer) {
|
|
27
|
-
e.dataTransfer.dropEffect =
|
|
27
|
+
e.dataTransfer.dropEffect = 'copy';
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
e.preventDefault();
|
|
36
36
|
|
|
37
37
|
// Get the data from the drag event
|
|
38
|
-
const nodeTypeData = e.dataTransfer?.getData(
|
|
38
|
+
const nodeTypeData = e.dataTransfer?.getData('application/json');
|
|
39
39
|
if (nodeTypeData) {
|
|
40
40
|
// Convert screen coordinates to flow coordinates (accounts for zoom and pan)
|
|
41
41
|
const position = screenToFlowPosition({
|
|
@@ -65,4 +65,3 @@
|
|
|
65
65
|
height: 100%;
|
|
66
66
|
}
|
|
67
67
|
</style>
|
|
68
|
-
|