@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,331 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Pipeline Status Component
|
|
3
|
+
Displays workflow execution status using the App component in read-only mode
|
|
4
|
+
Styled with BEM syntax
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
<script lang="ts">
|
|
8
|
+
import { onMount } from 'svelte';
|
|
9
|
+
import App from './App.svelte';
|
|
10
|
+
import LogsSidebar from './LogsSidebar.svelte';
|
|
11
|
+
import { FlowDropApiClient } from '../api/client.js';
|
|
12
|
+
import type { Workflow } from '../types/index.js';
|
|
13
|
+
|
|
14
|
+
interface Props {
|
|
15
|
+
pipelineId: string;
|
|
16
|
+
workflow: Workflow;
|
|
17
|
+
apiClient?: FlowDropApiClient;
|
|
18
|
+
baseUrl?: string;
|
|
19
|
+
onActionsReady?: (
|
|
20
|
+
actions: Array<{
|
|
21
|
+
label: string;
|
|
22
|
+
href: string;
|
|
23
|
+
icon?: string;
|
|
24
|
+
variant?: 'primary' | 'secondary' | 'outline';
|
|
25
|
+
onclick?: (event: Event) => void;
|
|
26
|
+
}>
|
|
27
|
+
) => void;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
let { pipelineId, workflow, apiClient, baseUrl, onActionsReady }: Props = $props();
|
|
31
|
+
|
|
32
|
+
// Initialize API client if not provided
|
|
33
|
+
const client = apiClient || new FlowDropApiClient(baseUrl || window.location.origin);
|
|
34
|
+
|
|
35
|
+
// Pipeline status and job data
|
|
36
|
+
let pipelineStatus = $state<string>('unknown');
|
|
37
|
+
let jobStatusData = $state<{
|
|
38
|
+
jobs: any[];
|
|
39
|
+
node_statuses: Record<string, any>;
|
|
40
|
+
status_summary: {
|
|
41
|
+
total: number;
|
|
42
|
+
pending: number;
|
|
43
|
+
running: number;
|
|
44
|
+
completed: number;
|
|
45
|
+
failed: number;
|
|
46
|
+
cancelled: number;
|
|
47
|
+
};
|
|
48
|
+
}>({
|
|
49
|
+
jobs: [],
|
|
50
|
+
node_statuses: {},
|
|
51
|
+
status_summary: {
|
|
52
|
+
total: 0,
|
|
53
|
+
pending: 0,
|
|
54
|
+
running: 0,
|
|
55
|
+
completed: 0,
|
|
56
|
+
failed: 0,
|
|
57
|
+
cancelled: 0
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Node statuses for visual indicators
|
|
62
|
+
let nodeStatuses = $state<Record<string, 'pending' | 'running' | 'completed' | 'error'>>({});
|
|
63
|
+
|
|
64
|
+
// Loading and error states
|
|
65
|
+
let isLoadingJobStatus = $state(false);
|
|
66
|
+
let error = $state<string | null>(null);
|
|
67
|
+
|
|
68
|
+
// Logs sidebar state
|
|
69
|
+
let isLogsSidebarOpen = $state(false);
|
|
70
|
+
let logs = $state<Array<{ level: string; message: string; timestamp: string }>>([]);
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Fetch pipeline data including job information
|
|
74
|
+
*/
|
|
75
|
+
async function fetchPipelineData(): Promise<void> {
|
|
76
|
+
if (!pipelineId) return;
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
isLoadingJobStatus = true;
|
|
80
|
+
const pipelineData = await client.getPipelineData(pipelineId);
|
|
81
|
+
|
|
82
|
+
pipelineStatus = pipelineData.status;
|
|
83
|
+
jobStatusData = {
|
|
84
|
+
jobs: pipelineData.jobs || [],
|
|
85
|
+
node_statuses: pipelineData.node_statuses || {},
|
|
86
|
+
status_summary: pipelineData.job_status_summary || {
|
|
87
|
+
total: 0,
|
|
88
|
+
pending: 0,
|
|
89
|
+
running: 0,
|
|
90
|
+
completed: 0,
|
|
91
|
+
failed: 0,
|
|
92
|
+
cancelled: 0
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
// Update node statuses based on job data
|
|
97
|
+
if (jobStatusData.node_statuses) {
|
|
98
|
+
const newNodeStatuses: Record<string, 'pending' | 'running' | 'completed' | 'error'> = {};
|
|
99
|
+
|
|
100
|
+
// Initialize all nodes as pending
|
|
101
|
+
if (workflow && workflow.nodes) {
|
|
102
|
+
workflow.nodes.forEach((node) => {
|
|
103
|
+
newNodeStatuses[node.id] = 'pending';
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Override with actual job statuses
|
|
108
|
+
for (const nodeId in jobStatusData.node_statuses) {
|
|
109
|
+
const status = jobStatusData.node_statuses[nodeId].status;
|
|
110
|
+
if (['pending', 'running', 'completed', 'failed', 'cancelled'].includes(status)) {
|
|
111
|
+
newNodeStatuses[nodeId] = status === 'failed' ? 'error' : status;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
nodeStatuses = newNodeStatuses;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
addLog('info', `Job status updated: ${jobStatusData.status_summary.total} total jobs`);
|
|
118
|
+
} catch (error) {
|
|
119
|
+
console.error('Failed to fetch pipeline data:', error);
|
|
120
|
+
addLog(
|
|
121
|
+
'error',
|
|
122
|
+
`Failed to fetch pipeline data: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
123
|
+
);
|
|
124
|
+
} finally {
|
|
125
|
+
isLoadingJobStatus = false;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Add a log entry
|
|
131
|
+
*/
|
|
132
|
+
function addLog(level: string, message: string): void {
|
|
133
|
+
logs = [
|
|
134
|
+
...logs,
|
|
135
|
+
{
|
|
136
|
+
level,
|
|
137
|
+
message,
|
|
138
|
+
timestamp: new Date().toISOString()
|
|
139
|
+
}
|
|
140
|
+
];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Toggle logs sidebar
|
|
145
|
+
*/
|
|
146
|
+
function toggleLogsSidebar(): void {
|
|
147
|
+
isLogsSidebarOpen = !isLogsSidebarOpen;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Get status color for visual indicators
|
|
152
|
+
*/
|
|
153
|
+
function getStatusColor(status: string): string {
|
|
154
|
+
switch (status) {
|
|
155
|
+
case 'completed':
|
|
156
|
+
return '#10b981'; // green
|
|
157
|
+
case 'running':
|
|
158
|
+
return '#3b82f6'; // blue
|
|
159
|
+
case 'error':
|
|
160
|
+
case 'failed':
|
|
161
|
+
return '#ef4444'; // red
|
|
162
|
+
case 'pending':
|
|
163
|
+
default:
|
|
164
|
+
return '#6b7280'; // gray
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Get status icon for visual indicators
|
|
170
|
+
*/
|
|
171
|
+
function getStatusIcon(status: string): string {
|
|
172
|
+
switch (status) {
|
|
173
|
+
case 'completed':
|
|
174
|
+
return 'mdi:check-circle';
|
|
175
|
+
case 'running':
|
|
176
|
+
return 'mdi:loading';
|
|
177
|
+
case 'error':
|
|
178
|
+
case 'failed':
|
|
179
|
+
return 'mdi:alert-circle';
|
|
180
|
+
case 'pending':
|
|
181
|
+
default:
|
|
182
|
+
return 'mdi:clock-outline';
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Get pipeline actions for the parent navbar
|
|
188
|
+
*/
|
|
189
|
+
function getPipelineActions() {
|
|
190
|
+
return [
|
|
191
|
+
{
|
|
192
|
+
label: isLoadingJobStatus ? 'Refreshing...' : 'Refresh Status',
|
|
193
|
+
href: '#refresh',
|
|
194
|
+
icon: isLoadingJobStatus ? 'mdi:loading' : 'mdi:refresh',
|
|
195
|
+
variant: 'outline' as const,
|
|
196
|
+
onclick: (e: Event) => {
|
|
197
|
+
e.preventDefault();
|
|
198
|
+
fetchPipelineData();
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
label: 'View Logs',
|
|
203
|
+
href: '#logs',
|
|
204
|
+
icon: 'mdi:file-document-outline',
|
|
205
|
+
variant: 'outline' as const,
|
|
206
|
+
onclick: (e: Event) => {
|
|
207
|
+
e.preventDefault();
|
|
208
|
+
toggleLogsSidebar();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
];
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Fetch pipeline data on mount
|
|
215
|
+
onMount(() => {
|
|
216
|
+
fetchPipelineData();
|
|
217
|
+
// Expose actions to parent
|
|
218
|
+
if (onActionsReady) {
|
|
219
|
+
onActionsReady(getPipelineActions());
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Listen for custom events from the layout navbar
|
|
223
|
+
const handleRefresh = () => fetchPipelineData();
|
|
224
|
+
const handleViewLogs = () => toggleLogsSidebar();
|
|
225
|
+
|
|
226
|
+
window.addEventListener('pipeline-refresh', handleRefresh);
|
|
227
|
+
window.addEventListener('pipeline-view-logs', handleViewLogs);
|
|
228
|
+
|
|
229
|
+
return () => {
|
|
230
|
+
window.removeEventListener('pipeline-refresh', handleRefresh);
|
|
231
|
+
window.removeEventListener('pipeline-view-logs', handleViewLogs);
|
|
232
|
+
};
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
// Send pipeline breadcrumbs to layout when they change
|
|
236
|
+
$effect(() => {
|
|
237
|
+
if (pipelineStatus && pipelineId && workflow) {
|
|
238
|
+
const breadcrumbs = [
|
|
239
|
+
{
|
|
240
|
+
label: 'Workflows',
|
|
241
|
+
href: '/',
|
|
242
|
+
icon: 'mdi:view-list'
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
label: workflow.name || 'Workflow',
|
|
246
|
+
href: `/workflow/${workflow.id}/edit`,
|
|
247
|
+
icon: 'mdi:workflow'
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
label: 'Pipelines',
|
|
251
|
+
href: `/workflow/${workflow.id}/pipelines`,
|
|
252
|
+
icon: 'mdi:source-branch'
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
label: `Pipeline ${pipelineId} - ${pipelineStatus}`,
|
|
256
|
+
icon: 'mdi:play-circle'
|
|
257
|
+
}
|
|
258
|
+
];
|
|
259
|
+
|
|
260
|
+
window.dispatchEvent(
|
|
261
|
+
new CustomEvent('page-breadcrumbs-update', {
|
|
262
|
+
detail: { breadcrumbs }
|
|
263
|
+
})
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
// Update actions when loading state changes
|
|
269
|
+
$effect(() => {
|
|
270
|
+
if (onActionsReady) {
|
|
271
|
+
onActionsReady(getPipelineActions());
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
// Auto-refresh pipeline data every 5 seconds when pipeline is running
|
|
276
|
+
let refreshInterval: NodeJS.Timeout | null = null;
|
|
277
|
+
|
|
278
|
+
$effect(() => {
|
|
279
|
+
// Clear existing interval
|
|
280
|
+
if (refreshInterval) {
|
|
281
|
+
clearInterval(refreshInterval);
|
|
282
|
+
refreshInterval = null;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Only start polling if pipeline is running
|
|
286
|
+
if (pipelineStatus === 'running' && pipelineId) {
|
|
287
|
+
refreshInterval = setInterval(() => {
|
|
288
|
+
fetchPipelineData();
|
|
289
|
+
}, 5000);
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
// Cleanup on unmount
|
|
294
|
+
onMount(() => {
|
|
295
|
+
return () => {
|
|
296
|
+
if (refreshInterval) {
|
|
297
|
+
clearInterval(refreshInterval);
|
|
298
|
+
refreshInterval = null;
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
});
|
|
302
|
+
</script>
|
|
303
|
+
|
|
304
|
+
<div class="pipeline-status-container">
|
|
305
|
+
<!-- Workflow Visualization using App component -->
|
|
306
|
+
<App
|
|
307
|
+
{workflow}
|
|
308
|
+
height="100vh"
|
|
309
|
+
width="100%"
|
|
310
|
+
showNavbar={false}
|
|
311
|
+
disableSidebar={true}
|
|
312
|
+
lockWorkflow={true}
|
|
313
|
+
readOnly={true}
|
|
314
|
+
{nodeStatuses}
|
|
315
|
+
{pipelineId}
|
|
316
|
+
/>
|
|
317
|
+
|
|
318
|
+
<!-- Logs Sidebar -->
|
|
319
|
+
{#if isLogsSidebarOpen}
|
|
320
|
+
<LogsSidebar {logs} isOpen={isLogsSidebarOpen} onClose={() => (isLogsSidebarOpen = false)} />
|
|
321
|
+
{/if}
|
|
322
|
+
</div>
|
|
323
|
+
|
|
324
|
+
<style>
|
|
325
|
+
.pipeline-status-container {
|
|
326
|
+
display: flex;
|
|
327
|
+
flex-direction: column;
|
|
328
|
+
height: 100vh;
|
|
329
|
+
background: #f3f4f6;
|
|
330
|
+
}
|
|
331
|
+
</style>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { FlowDropApiClient } from '../api/client.js';
|
|
2
|
+
import type { Workflow } from '../types/index.js';
|
|
3
|
+
interface Props {
|
|
4
|
+
pipelineId: string;
|
|
5
|
+
workflow: Workflow;
|
|
6
|
+
apiClient?: FlowDropApiClient;
|
|
7
|
+
baseUrl?: string;
|
|
8
|
+
onActionsReady?: (actions: Array<{
|
|
9
|
+
label: string;
|
|
10
|
+
href: string;
|
|
11
|
+
icon?: string;
|
|
12
|
+
variant?: 'primary' | 'secondary' | 'outline';
|
|
13
|
+
onclick?: (event: Event) => void;
|
|
14
|
+
}>) => void;
|
|
15
|
+
}
|
|
16
|
+
declare const PipelineStatus: import("svelte").Component<Props, {}, "">;
|
|
17
|
+
type PipelineStatus = ReturnType<typeof PipelineStatus>;
|
|
18
|
+
export default PipelineStatus;
|