@flowdrop/flowdrop 1.10.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/enhanced-client.d.ts +29 -16
- package/dist/api/enhanced-client.js +0 -14
- package/dist/components/Navbar.svelte +1 -10
- package/dist/components/Navbar.svelte.d.ts +1 -9
- package/dist/components/PipelineStatus.svelte +9 -12
- package/dist/components/WorkflowEditor.svelte +3 -0
- package/dist/components/interrupt/ChoicePrompt.svelte +24 -5
- package/dist/components/interrupt/ConfirmationPrompt.svelte +5 -0
- package/dist/components/interrupt/InterruptBubble.svelte +12 -0
- package/dist/components/interrupt/ReviewPrompt.svelte +20 -0
- package/dist/components/interrupt/TextInputPrompt.svelte +5 -0
- package/dist/components/nodes/GatewayNode.svelte +2 -6
- package/dist/components/nodes/WorkflowNode.svelte +2 -6
- package/dist/components/playground/ChatInput.svelte +359 -0
- package/dist/components/playground/ChatInput.svelte.d.ts +14 -0
- package/dist/components/playground/ChatPanel.svelte +100 -724
- package/dist/components/playground/ChatPanel.svelte.d.ts +9 -26
- package/dist/components/playground/ControlPanel.svelte +496 -0
- package/dist/components/playground/ControlPanel.svelte.d.ts +20 -0
- package/dist/components/playground/ExecutionConsole.svelte +163 -0
- package/dist/components/playground/ExecutionConsole.svelte.d.ts +14 -0
- package/dist/components/playground/MessageStream.svelte +283 -0
- package/dist/components/playground/MessageStream.svelte.d.ts +27 -0
- package/dist/components/playground/PipelineKanbanView.svelte +284 -0
- package/dist/components/playground/PipelineKanbanView.svelte.d.ts +11 -0
- package/dist/components/playground/PipelinePanel.svelte +204 -65
- package/dist/components/playground/PipelinePanel.svelte.d.ts +3 -1
- package/dist/components/playground/PipelineTableView.svelte +376 -0
- package/dist/components/playground/PipelineTableView.svelte.d.ts +11 -0
- package/dist/components/playground/Playground.svelte +262 -1200
- package/dist/components/playground/Playground.svelte.d.ts +0 -13
- package/dist/components/playground/PlaygroundApp.svelte +110 -0
- package/dist/components/playground/PlaygroundApp.svelte.d.ts +28 -0
- package/dist/components/playground/PlaygroundStudio.svelte +35 -61
- package/dist/components/playground/PlaygroundStudio.svelte.d.ts +3 -1
- package/dist/components/playground/pipelineViewUtils.svelte.d.ts +22 -0
- package/dist/components/playground/pipelineViewUtils.svelte.js +77 -0
- package/dist/messages/defaults.d.ts +24 -0
- package/dist/messages/defaults.js +24 -0
- package/dist/playground/index.d.ts +8 -2
- package/dist/playground/index.js +8 -1
- package/dist/playground/mount.d.ts +59 -4
- package/dist/playground/mount.js +102 -9
- package/dist/stores/playgroundStore.svelte.d.ts +6 -0
- package/dist/stores/playgroundStore.svelte.js +21 -1
- package/dist/svelte-app.d.ts +2 -10
- package/dist/types/index.d.ts +28 -2
- package/dist/types/navbar.d.ts +14 -0
- package/dist/types/navbar.js +1 -0
- package/dist/types/playground.d.ts +5 -2
- package/dist/types/playground.js +5 -7
- package/dist/utils/nodeStatus.js +15 -5
- package/package.json +1 -1
|
@@ -34,6 +34,34 @@ export declare class ApiError extends Error {
|
|
|
34
34
|
* const client = new EnhancedFlowDropApiClient(config);
|
|
35
35
|
* ```
|
|
36
36
|
*/
|
|
37
|
+
export interface PipelineDataResponse {
|
|
38
|
+
status: string;
|
|
39
|
+
jobs: Array<Record<string, unknown>>;
|
|
40
|
+
node_statuses: Record<string, {
|
|
41
|
+
status: string;
|
|
42
|
+
[key: string]: unknown;
|
|
43
|
+
}>;
|
|
44
|
+
job_status_summary: {
|
|
45
|
+
total: number;
|
|
46
|
+
pending: number;
|
|
47
|
+
running: number;
|
|
48
|
+
completed: number;
|
|
49
|
+
failed: number;
|
|
50
|
+
cancelled: number;
|
|
51
|
+
skipped?: number;
|
|
52
|
+
paused?: number;
|
|
53
|
+
interrupted?: number;
|
|
54
|
+
};
|
|
55
|
+
kanban_config?: {
|
|
56
|
+
columns: Array<{
|
|
57
|
+
key: string;
|
|
58
|
+
label: string;
|
|
59
|
+
statuses: string[];
|
|
60
|
+
icon?: string;
|
|
61
|
+
color?: string;
|
|
62
|
+
}>;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
37
65
|
export declare class EnhancedFlowDropApiClient {
|
|
38
66
|
private config;
|
|
39
67
|
private authProvider;
|
|
@@ -164,20 +192,5 @@ export declare class EnhancedFlowDropApiClient {
|
|
|
164
192
|
/**
|
|
165
193
|
* Fetch pipeline data including job information and status
|
|
166
194
|
*/
|
|
167
|
-
getPipelineData(pipelineId: string): Promise<
|
|
168
|
-
status: string;
|
|
169
|
-
jobs: Array<Record<string, unknown>>;
|
|
170
|
-
node_statuses: Record<string, {
|
|
171
|
-
status: string;
|
|
172
|
-
[key: string]: unknown;
|
|
173
|
-
}>;
|
|
174
|
-
job_status_summary: {
|
|
175
|
-
total: number;
|
|
176
|
-
pending: number;
|
|
177
|
-
running: number;
|
|
178
|
-
completed: number;
|
|
179
|
-
failed: number;
|
|
180
|
-
cancelled: number;
|
|
181
|
-
};
|
|
182
|
-
}>;
|
|
195
|
+
getPipelineData(pipelineId: string): Promise<PipelineDataResponse>;
|
|
183
196
|
}
|
|
@@ -28,20 +28,6 @@ export class ApiError extends Error {
|
|
|
28
28
|
this.errorData = errorData;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
/**
|
|
32
|
-
* Enhanced HTTP API client for FlowDrop with configurable endpoints
|
|
33
|
-
*
|
|
34
|
-
* Supports pluggable authentication via AuthProvider interface.
|
|
35
|
-
*
|
|
36
|
-
* @example
|
|
37
|
-
* ```typescript
|
|
38
|
-
* // With AuthProvider
|
|
39
|
-
* const client = new EnhancedFlowDropApiClient(config, authProvider);
|
|
40
|
-
*
|
|
41
|
-
* // Without authentication
|
|
42
|
-
* const client = new EnhancedFlowDropApiClient(config);
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
31
|
export class EnhancedFlowDropApiClient {
|
|
46
32
|
config;
|
|
47
33
|
authProvider;
|
|
@@ -11,18 +11,9 @@
|
|
|
11
11
|
import Logo from './Logo.svelte';
|
|
12
12
|
import SettingsModal from './SettingsModal.svelte';
|
|
13
13
|
import type { SettingsCategory } from '../types/settings.js';
|
|
14
|
+
import type { NavbarAction } from '../types/navbar.js';
|
|
14
15
|
import { m } from '../messages/index.js';
|
|
15
16
|
|
|
16
|
-
interface NavbarAction {
|
|
17
|
-
label: string;
|
|
18
|
-
href: string;
|
|
19
|
-
icon?: string;
|
|
20
|
-
variant?: 'primary' | 'secondary' | 'outline';
|
|
21
|
-
onclick?: (event: Event) => void;
|
|
22
|
-
/** If true, opens link in new tab with proper security attributes */
|
|
23
|
-
external?: boolean;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
17
|
interface BreadcrumbItem {
|
|
27
18
|
label: string;
|
|
28
19
|
href?: string;
|
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
import type { SettingsCategory } from '../types/settings.js';
|
|
2
|
-
|
|
3
|
-
label: string;
|
|
4
|
-
href: string;
|
|
5
|
-
icon?: string;
|
|
6
|
-
variant?: 'primary' | 'secondary' | 'outline';
|
|
7
|
-
onclick?: (event: Event) => void;
|
|
8
|
-
/** If true, opens link in new tab with proper security attributes */
|
|
9
|
-
external?: boolean;
|
|
10
|
-
}
|
|
2
|
+
import type { NavbarAction } from '../types/navbar.js';
|
|
11
3
|
interface BreadcrumbItem {
|
|
12
4
|
label: string;
|
|
13
5
|
href?: string;
|
|
@@ -117,23 +117,20 @@
|
|
|
117
117
|
}
|
|
118
118
|
};
|
|
119
119
|
|
|
120
|
-
// Update node statuses based on job data
|
|
120
|
+
// Update node statuses based on job data — only set what the server reported
|
|
121
121
|
if (jobStatusData.node_statuses) {
|
|
122
122
|
const newNodeStatuses: Record<string, 'pending' | 'running' | 'completed' | 'error'> = {};
|
|
123
123
|
|
|
124
|
-
// Initialize all nodes as pending
|
|
125
|
-
if (workflow && workflow.nodes) {
|
|
126
|
-
workflow.nodes.forEach((node) => {
|
|
127
|
-
newNodeStatuses[node.id] = 'pending';
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Override with actual job statuses
|
|
132
124
|
for (const nodeId in jobStatusData.node_statuses) {
|
|
133
125
|
const status = jobStatusData.node_statuses[nodeId].status;
|
|
134
|
-
if (
|
|
135
|
-
newNodeStatuses[nodeId] =
|
|
136
|
-
|
|
126
|
+
if (status === 'failed' || status === 'cancelled') {
|
|
127
|
+
newNodeStatuses[nodeId] = 'error';
|
|
128
|
+
} else if (status === 'running' || status === 'paused' || status === 'interrupted') {
|
|
129
|
+
newNodeStatuses[nodeId] = 'running';
|
|
130
|
+
} else if (status === 'completed' || status === 'skipped') {
|
|
131
|
+
newNodeStatuses[nodeId] = 'completed';
|
|
132
|
+
} else if (status === 'pending' || status === 'idle') {
|
|
133
|
+
newNodeStatuses[nodeId] = 'pending';
|
|
137
134
|
}
|
|
138
135
|
}
|
|
139
136
|
nodeStatuses = newNodeStatuses;
|
|
@@ -855,6 +855,9 @@
|
|
|
855
855
|
{initialViewport}
|
|
856
856
|
colorMode={getResolvedTheme() as ColorMode}
|
|
857
857
|
fitView={getEditorSettings().fitViewOnLoad}
|
|
858
|
+
nodesDraggable={!props.lockWorkflow && !props.readOnly}
|
|
859
|
+
nodesConnectable={!props.lockWorkflow && !props.readOnly}
|
|
860
|
+
elementsSelectable={!props.lockWorkflow && !props.readOnly}
|
|
858
861
|
>
|
|
859
862
|
<Controls />
|
|
860
863
|
{#if !props.readOnly && !props.lockWorkflow && props.onToggleConsole}
|
|
@@ -45,6 +45,10 @@
|
|
|
45
45
|
// Hoist the choice branch — counter, min, max, submit reads.
|
|
46
46
|
const t = $derived(m().interrupt.choice);
|
|
47
47
|
|
|
48
|
+
// Unique name for the radio/checkbox group so multiple ChoicePrompts on
|
|
49
|
+
// screen don't share the same HTML group and interfere with each other.
|
|
50
|
+
const groupName = `choice-option-${Math.random().toString(36).slice(2, 8)}`;
|
|
51
|
+
|
|
48
52
|
/** Local state for selected values */
|
|
49
53
|
let selectedValues = $state<Set<string>>(new Set());
|
|
50
54
|
|
|
@@ -131,7 +135,7 @@
|
|
|
131
135
|
{/if}
|
|
132
136
|
|
|
133
137
|
<!-- Options -->
|
|
134
|
-
<div class="choice-prompt__options" role={isMultiple ? 'group' : 'radiogroup'}>
|
|
138
|
+
<div class="choice-prompt__options" role={isMultiple ? 'group' : 'radiogroup'} aria-label={config.message}>
|
|
135
139
|
{#each config.options as option (option.value)}
|
|
136
140
|
{@const isChecked = isResolved ? isOptionResolved(option) : selectedValues.has(option.value)}
|
|
137
141
|
<label
|
|
@@ -141,7 +145,7 @@
|
|
|
141
145
|
>
|
|
142
146
|
<input
|
|
143
147
|
type={isMultiple ? 'checkbox' : 'radio'}
|
|
144
|
-
name=
|
|
148
|
+
name={groupName}
|
|
145
149
|
value={option.value}
|
|
146
150
|
checked={isChecked}
|
|
147
151
|
disabled={isResolved || isSubmitting}
|
|
@@ -295,9 +299,19 @@
|
|
|
295
299
|
|
|
296
300
|
.choice-prompt__input {
|
|
297
301
|
position: absolute;
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
302
|
+
width: 1px;
|
|
303
|
+
height: 1px;
|
|
304
|
+
padding: 0;
|
|
305
|
+
margin: -1px;
|
|
306
|
+
overflow: hidden;
|
|
307
|
+
clip: rect(0, 0, 0, 0);
|
|
308
|
+
white-space: nowrap;
|
|
309
|
+
border: 0;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.choice-prompt__option:focus-within {
|
|
313
|
+
outline: 2px solid var(--fd-ring);
|
|
314
|
+
outline-offset: 2px;
|
|
301
315
|
}
|
|
302
316
|
|
|
303
317
|
.choice-prompt__checkmark {
|
|
@@ -372,6 +386,11 @@
|
|
|
372
386
|
transform: translateY(-1px);
|
|
373
387
|
}
|
|
374
388
|
|
|
389
|
+
.choice-prompt__submit:focus-visible {
|
|
390
|
+
outline: 2px solid var(--fd-ring);
|
|
391
|
+
outline-offset: 2px;
|
|
392
|
+
}
|
|
393
|
+
|
|
375
394
|
.choice-prompt__submit:disabled {
|
|
376
395
|
opacity: 0.5;
|
|
377
396
|
cursor: not-allowed;
|
|
@@ -256,6 +256,8 @@
|
|
|
256
256
|
class:interrupt-bubble--cancelled={currentInterrupt.machineState.status === 'cancelled'}
|
|
257
257
|
class:interrupt-bubble--submitting={isSubmitting}
|
|
258
258
|
class:interrupt-bubble--error={currentInterrupt.machineState.status === 'error'}
|
|
259
|
+
role="group"
|
|
260
|
+
aria-label={getTypeLabel(currentInterrupt.type)}
|
|
259
261
|
>
|
|
260
262
|
<!-- Header -->
|
|
261
263
|
<div class="interrupt-bubble__header">
|
|
@@ -517,6 +519,11 @@
|
|
|
517
519
|
background-color: var(--fd-error-hover);
|
|
518
520
|
}
|
|
519
521
|
|
|
522
|
+
.interrupt-bubble__retry-btn:focus-visible {
|
|
523
|
+
outline: 2px solid var(--fd-ring);
|
|
524
|
+
outline-offset: 2px;
|
|
525
|
+
}
|
|
526
|
+
|
|
520
527
|
/* Body - prompt content area, full width */
|
|
521
528
|
.interrupt-bubble__body {
|
|
522
529
|
padding: var(--fd-space-xl);
|
|
@@ -589,6 +596,11 @@
|
|
|
589
596
|
background-color: var(--fd-error-muted);
|
|
590
597
|
}
|
|
591
598
|
|
|
599
|
+
.interrupt-bubble__cancel-btn:focus-visible {
|
|
600
|
+
outline: 2px solid var(--fd-ring);
|
|
601
|
+
outline-offset: 2px;
|
|
602
|
+
}
|
|
603
|
+
|
|
592
604
|
.interrupt-bubble__cancel-btn:disabled {
|
|
593
605
|
opacity: 0.5;
|
|
594
606
|
cursor: not-allowed;
|
|
@@ -533,6 +533,11 @@
|
|
|
533
533
|
color: var(--fd-error);
|
|
534
534
|
}
|
|
535
535
|
|
|
536
|
+
.review-prompt__bulk-btn:focus-visible {
|
|
537
|
+
outline: 2px solid var(--fd-ring);
|
|
538
|
+
outline-offset: 2px;
|
|
539
|
+
}
|
|
540
|
+
|
|
536
541
|
.review-prompt__bulk-btn:disabled {
|
|
537
542
|
opacity: 0.5;
|
|
538
543
|
cursor: not-allowed;
|
|
@@ -630,6 +635,11 @@
|
|
|
630
635
|
color: var(--fd-error-foreground);
|
|
631
636
|
}
|
|
632
637
|
|
|
638
|
+
.review-prompt__toggle-btn:focus-visible {
|
|
639
|
+
outline: 2px solid var(--fd-ring);
|
|
640
|
+
outline-offset: 2px;
|
|
641
|
+
}
|
|
642
|
+
|
|
633
643
|
.review-prompt__toggle-btn:disabled {
|
|
634
644
|
opacity: 0.5;
|
|
635
645
|
cursor: not-allowed;
|
|
@@ -722,6 +732,11 @@
|
|
|
722
732
|
border-color: var(--fd-border-strong);
|
|
723
733
|
}
|
|
724
734
|
|
|
735
|
+
.review-prompt__html-toggle-btn:focus-visible {
|
|
736
|
+
outline: 2px solid var(--fd-ring);
|
|
737
|
+
outline-offset: 2px;
|
|
738
|
+
}
|
|
739
|
+
|
|
725
740
|
/* Raw HTML code display */
|
|
726
741
|
.review-prompt__raw-html {
|
|
727
742
|
font-family: var(--fd-review-font-mono);
|
|
@@ -820,6 +835,11 @@
|
|
|
820
835
|
transform: translateY(-1px);
|
|
821
836
|
}
|
|
822
837
|
|
|
838
|
+
.review-prompt__submit:focus-visible {
|
|
839
|
+
outline: 2px solid var(--fd-ring);
|
|
840
|
+
outline-offset: 2px;
|
|
841
|
+
}
|
|
842
|
+
|
|
823
843
|
.review-prompt__submit:disabled {
|
|
824
844
|
opacity: 0.5;
|
|
825
845
|
cursor: not-allowed;
|
|
@@ -210,9 +210,7 @@
|
|
|
210
210
|
style="top: 50%; transform: translateY(-50%); --fd-handle-fill: {getDataTypeColorToken(
|
|
211
211
|
port.dataType
|
|
212
212
|
)}; --fd-handle-border-color: var(--fd-handle-border);"
|
|
213
|
-
|
|
214
|
-
tabindex={0}
|
|
215
|
-
aria-label={graph.connectInputPort({ name: port.name })}
|
|
213
|
+
tabindex={-1}
|
|
216
214
|
/>
|
|
217
215
|
|
|
218
216
|
<!-- Port Info: padding lives here so handle position is simple -->
|
|
@@ -298,9 +296,7 @@
|
|
|
298
296
|
: getDataTypeColorToken(
|
|
299
297
|
'trigger'
|
|
300
298
|
)}; --fd-handle-border-color: var(--fd-handle-border);"
|
|
301
|
-
|
|
302
|
-
tabindex={0}
|
|
303
|
-
aria-label={graph.connectBranch({ name: branch.name })}
|
|
299
|
+
tabindex={-1}
|
|
304
300
|
/>
|
|
305
301
|
</div>
|
|
306
302
|
{/each}
|
|
@@ -264,9 +264,7 @@
|
|
|
264
264
|
style="top: 50%; transform: translateY(-50%); --fd-handle-fill: var(--fd-port-skin-color, {getDataTypeColorToken(
|
|
265
265
|
port.dataType
|
|
266
266
|
)}); --fd-handle-border-color: var(--fd-handle-border);"
|
|
267
|
-
|
|
268
|
-
tabindex={0}
|
|
269
|
-
aria-label={graph.connectInputPort({ name: port.name })}
|
|
267
|
+
tabindex={-1}
|
|
270
268
|
/>
|
|
271
269
|
|
|
272
270
|
<!-- Port Info: padding lives here so handle position is simple -->
|
|
@@ -342,9 +340,7 @@
|
|
|
342
340
|
style="top: 50%; transform: translateY(-50%); --fd-handle-fill: var(--fd-port-skin-color, {getDataTypeColorToken(
|
|
343
341
|
port.dataType
|
|
344
342
|
)}); --fd-handle-border-color: var(--fd-handle-border);"
|
|
345
|
-
|
|
346
|
-
tabindex={0}
|
|
347
|
-
aria-label={graph.connectOutputPort({ name: port.name })}
|
|
343
|
+
tabindex={-1}
|
|
348
344
|
/>
|
|
349
345
|
</div>
|
|
350
346
|
{/each}
|