windmill-components 1.504.1 → 1.504.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.
- package/package/components/AppWrapper.svelte +0 -3
- package/package/components/{DBManagerDrawerButton.svelte → DBManagerDrawer.svelte} +38 -38
- package/package/components/DBManagerDrawer.svelte.d.ts +7 -0
- package/package/components/DarkModeObserver.svelte +30 -16
- package/package/components/DarkModeObserver.svelte.d.ts +9 -4
- package/package/components/Dev.svelte +1 -1
- package/package/components/EditorBar.svelte +108 -67
- package/package/components/ExploreAssetButton.svelte +40 -0
- package/package/components/ExploreAssetButton.svelte.d.ts +23 -0
- package/package/components/FlowBuilder.svelte +2 -3
- package/package/components/FlowStatusViewerInner.svelte +19 -0
- package/package/components/ItemPicker.svelte +1 -1
- package/package/components/ItemPicker.svelte.d.ts +1 -1
- package/package/components/MoveDrawer.svelte.d.ts +2 -2
- package/package/components/ResourcePicker.svelte +11 -4
- package/package/components/S3FilePicker.svelte +10 -3
- package/package/components/S3FilePicker.svelte.d.ts +6 -4
- package/package/components/ScriptBuilder.svelte +3 -1
- package/package/components/ScriptEditor.svelte +31 -3
- package/package/components/ScriptEditor.svelte.d.ts +3 -1
- package/package/components/ScriptWrapper.svelte +0 -3
- package/package/components/ShareModal.svelte.d.ts +1 -1
- package/package/components/apps/editor/AppEditor.svelte +1 -1
- package/package/components/apps/editor/AppEditorHeader.svelte +1 -1
- package/package/components/apps/editor/GridEditor.svelte +1 -1
- package/package/components/apps/editor/SubGridEditor.svelte +1 -1
- package/package/components/apps/editor/component/componentCallbacks.svelte.js +1 -1
- package/package/components/apps/editor/componentsPanel/ComponentList.svelte +1 -1
- package/package/components/apps/editor/settingsPanel/ComponentPanel.svelte +1 -1
- package/package/components/apps/editor/settingsPanel/DeleteComponent.svelte +1 -1
- package/package/components/apps/types.d.ts +2 -2
- package/package/components/assets/AssetsDropdownButton.svelte +178 -0
- package/package/components/assets/AssetsDropdownButton.svelte.d.ts +16 -0
- package/package/components/assets/AssetsUsageDrawer.svelte +43 -0
- package/package/components/assets/AssetsUsageDrawer.svelte.d.ts +12 -0
- package/package/components/assets/lib.d.ts +16 -0
- package/package/components/assets/lib.js +60 -0
- package/package/components/auditLogs/AuditLogsFilters.svelte.d.ts +1 -1
- package/package/components/common/OnChange.svelte +18 -0
- package/package/components/common/OnChange.svelte.d.ts +21 -0
- package/package/components/common/button/UndoRedo.svelte +2 -2
- package/package/components/common/button/UndoRedo.svelte.d.ts +5 -6
- package/package/components/copilot/chat/script/core.js +4 -4
- package/package/components/custom_ui.d.ts +1 -0
- package/package/components/flows/content/FlowModuleComponent.svelte +20 -1
- package/package/components/flows/types.d.ts +15 -1
- package/package/components/graph/FlowGraphV2.svelte +111 -8
- package/package/components/graph/FlowGraphV2.svelte.d.ts +2 -0
- package/package/components/graph/graphBuilder.svelte.d.ts +14 -1
- package/package/components/graph/renderers/edges/BaseEdge.svelte +10 -1
- package/package/components/graph/renderers/edges/EmptyEdge.svelte +7 -1
- package/package/components/graph/renderers/edges/EmptyEdge.svelte.d.ts +3 -0
- package/package/components/graph/renderers/nodes/AssetNode.svelte +257 -0
- package/package/components/graph/renderers/nodes/AssetNode.svelte.d.ts +21 -0
- package/package/components/graph/renderers/nodes/AssetsOverflowedNode.svelte +55 -0
- package/package/components/graph/renderers/nodes/AssetsOverflowedNode.svelte.d.ts +7 -0
- package/package/components/icons/AssetGenericIcon.svelte +16 -0
- package/package/components/icons/AssetGenericIcon.svelte.d.ts +10 -0
- package/package/components/icons/AssetResIcon.svelte +32 -0
- package/package/components/icons/AssetResIcon.svelte.d.ts +9 -0
- package/package/components/icons/AssetS3Icon.svelte +30 -0
- package/package/components/icons/AssetS3Icon.svelte.d.ts +9 -0
- package/package/components/icons/AssetVarIcon.svelte +31 -0
- package/package/components/icons/AssetVarIcon.svelte.d.ts +9 -0
- package/package/components/meltComponents/Popover.svelte +2 -0
- package/package/components/meltComponents/Popover.svelte.d.ts +2 -0
- package/package/components/schema/EditableSchemaSdkWrapper.svelte +1 -4
- package/package/components/script_builder.d.ts +2 -0
- package/package/components/settings/WorkspaceOperatorSettings.svelte +20 -17
- package/package/components/sidebar/OperatorMenu.svelte +5 -0
- package/package/components/sidebar/SidebarContent.svelte +9 -1
- package/package/components/tutorials/app/AppTutorial.svelte +1 -1
- package/package/components/tutorials/app/ConnectionTutorial.svelte +1 -1
- package/package/gen/schemas.gen.d.ts +69 -1
- package/package/gen/schemas.gen.js +69 -1
- package/package/gen/services.gen.d.ts +20 -1
- package/package/gen/services.gen.js +37 -0
- package/package/gen/types.gen.d.ts +103 -0
- package/package/history.svelte.d.ts +2 -2
- package/package/history.svelte.js +6 -6
- package/package/infer.d.ts +2 -0
- package/package/infer.js +31 -5
- package/package/svelte5Utils.svelte.d.ts +2 -1
- package/package/svelte5Utils.svelte.js +3 -2
- package/package/utils.d.ts +12 -0
- package/package/utils.js +22 -0
- package/package.json +5 -5
- package/package/components/DBManagerDrawerButton.svelte.d.ts +0 -9
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { capitalize } from '../../utils';
|
|
2
|
+
export function formatAsset(asset) {
|
|
3
|
+
switch (asset.kind) {
|
|
4
|
+
case 'resource':
|
|
5
|
+
return `res://${asset.path}`;
|
|
6
|
+
case 's3object':
|
|
7
|
+
return `s3://${asset.path}`;
|
|
8
|
+
case 'variable':
|
|
9
|
+
return `var://${asset.path}`;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export function getAssetUsagePageUri(usage) {
|
|
13
|
+
if (usage.kind === 'script') {
|
|
14
|
+
return `/scripts/get/${usage.path}`;
|
|
15
|
+
}
|
|
16
|
+
else if (usage.kind === 'flow') {
|
|
17
|
+
return `/flows/get/${usage.path}`;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function assetEq(a, b) {
|
|
21
|
+
if (!a || !b)
|
|
22
|
+
return a === b;
|
|
23
|
+
return a.kind === b.kind && a.path === b.path;
|
|
24
|
+
}
|
|
25
|
+
export function parseAssetFromString(s) {
|
|
26
|
+
if (s.startsWith('res://')) {
|
|
27
|
+
return { kind: 'resource', path: s.slice(6) };
|
|
28
|
+
}
|
|
29
|
+
else if (s.startsWith('$res:')) {
|
|
30
|
+
return { kind: 'resource', path: s.slice(5) };
|
|
31
|
+
}
|
|
32
|
+
else if (s.startsWith('s3://')) {
|
|
33
|
+
return { kind: 's3object', path: s.slice(5) };
|
|
34
|
+
}
|
|
35
|
+
else if (s.startsWith('var://')) {
|
|
36
|
+
return { kind: 'variable', path: s.slice(6) };
|
|
37
|
+
}
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
export function formatAssetKind(asset) {
|
|
41
|
+
switch (asset.kind) {
|
|
42
|
+
case 'resource':
|
|
43
|
+
if (asset.metadata?.resource_type) {
|
|
44
|
+
if (asset.metadata.resource_type === 'state')
|
|
45
|
+
return 'State';
|
|
46
|
+
if (asset.metadata.resource_type === 'cache')
|
|
47
|
+
return 'Cache';
|
|
48
|
+
if (asset.metadata.resource_type === 'app_theme')
|
|
49
|
+
return 'App Theme';
|
|
50
|
+
return `${capitalize(asset.metadata.resource_type)} resource`;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
return 'metadata' in asset ? 'Invalid resource' : 'Resource';
|
|
54
|
+
}
|
|
55
|
+
case 's3object':
|
|
56
|
+
return 'S3 Object';
|
|
57
|
+
case 'variable':
|
|
58
|
+
return 'Variable';
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -13,6 +13,6 @@ interface Props {
|
|
|
13
13
|
actionKind?: ActionKind | 'all';
|
|
14
14
|
scope?: undefined | 'all_workspaces' | 'instance';
|
|
15
15
|
}
|
|
16
|
-
declare const AuditLogsFilters: import("svelte").Component<Props, {}, "
|
|
16
|
+
declare const AuditLogsFilters: import("svelte").Component<Props, {}, "resource" | "username" | "operation" | "before" | "after" | "perPage" | "hasMore" | "logs" | "pageIndex" | "actionKind" | "scope">;
|
|
17
17
|
type AuditLogsFilters = ReturnType<typeof AuditLogsFilters>;
|
|
18
18
|
export default AuditLogsFilters;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Useful to listen to changes on a list without recomputing the whole list
|
|
3
|
+
when a single item changes
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
<script lang="ts" generics="T">import { untrack } from 'svelte';
|
|
7
|
+
let { key, onChange, runFirstEffect = false } = $props();
|
|
8
|
+
let isFirstRun = true;
|
|
9
|
+
$effect(() => {
|
|
10
|
+
key;
|
|
11
|
+
if (isFirstRun) {
|
|
12
|
+
isFirstRun = false;
|
|
13
|
+
if (!runFirstEffect)
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
untrack(() => onChange());
|
|
17
|
+
});
|
|
18
|
+
</script>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
declare class __sveltets_Render<T> {
|
|
2
|
+
props(): {
|
|
3
|
+
key: T;
|
|
4
|
+
onChange: () => void;
|
|
5
|
+
runFirstEffect?: boolean;
|
|
6
|
+
};
|
|
7
|
+
events(): {};
|
|
8
|
+
slots(): {};
|
|
9
|
+
bindings(): "";
|
|
10
|
+
exports(): {};
|
|
11
|
+
}
|
|
12
|
+
interface $$IsomorphicComponent {
|
|
13
|
+
new <T>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
|
|
14
|
+
$$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
|
|
15
|
+
} & ReturnType<__sveltets_Render<T>['exports']>;
|
|
16
|
+
<T>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
|
|
17
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
18
|
+
}
|
|
19
|
+
declare const OnChange: $$IsomorphicComponent;
|
|
20
|
+
type OnChange<T> = InstanceType<typeof OnChange<T>>;
|
|
21
|
+
export default OnChange;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<script lang="ts">import { Redo, Undo } from 'lucide-svelte';
|
|
2
2
|
import { createEventDispatcher } from 'svelte';
|
|
3
3
|
import { Button } from '..';
|
|
4
|
-
let
|
|
4
|
+
export let undoProps = {};
|
|
5
|
+
export let redoProps = {};
|
|
5
6
|
const dispatch = createEventDispatcher();
|
|
6
7
|
</script>
|
|
7
8
|
|
|
@@ -28,5 +29,4 @@ const dispatch = createEventDispatcher();
|
|
|
28
29
|
>
|
|
29
30
|
<Redo size={14} />
|
|
30
31
|
</Button>
|
|
31
|
-
|
|
32
32
|
</div>
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
interface Props {
|
|
2
|
-
undoProps?: Record<string, any>;
|
|
3
|
-
redoProps?: Record<string, any>;
|
|
4
|
-
}
|
|
5
1
|
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> {
|
|
6
2
|
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
7
3
|
$$bindings?: Bindings;
|
|
@@ -15,11 +11,14 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
|
|
|
15
11
|
};
|
|
16
12
|
z_$$bindings?: Bindings;
|
|
17
13
|
}
|
|
18
|
-
declare const UndoRedo: $$__sveltets_2_IsomorphicComponent<
|
|
14
|
+
declare const UndoRedo: $$__sveltets_2_IsomorphicComponent<{
|
|
15
|
+
undoProps?: Record<string, any>;
|
|
16
|
+
redoProps?: Record<string, any>;
|
|
17
|
+
}, {
|
|
19
18
|
undo: CustomEvent<any>;
|
|
20
19
|
redo: CustomEvent<any>;
|
|
21
20
|
} & {
|
|
22
21
|
[evt: string]: CustomEvent<any>;
|
|
23
|
-
}, {}, {},
|
|
22
|
+
}, {}, {}, string>;
|
|
24
23
|
type UndoRedo = InstanceType<typeof UndoRedo>;
|
|
25
24
|
export default UndoRedo;
|
|
@@ -62,8 +62,8 @@ wmill.runScriptAsync(path: string, args?: Record<string, any>): Promise<string>
|
|
|
62
62
|
wmill.waitJob(jobId: string): Promise<any> // Wait for job completion and get result
|
|
63
63
|
|
|
64
64
|
// S3 file operations (if S3 is configured)
|
|
65
|
-
wmill.loadS3File(s3object: S3Object): Promise<Uint8Array> // Load file content from S3
|
|
66
|
-
wmill.writeS3File(s3object: S3Object, content: string | Blob): Promise<S3Object> // Write file to S3
|
|
65
|
+
wmill.loadS3File(s3object: S3Object | string): Promise<Uint8Array> // Load file content from S3
|
|
66
|
+
wmill.writeS3File(s3object: S3Object | string, content: string | Blob): Promise<S3Object> // Write file to S3
|
|
67
67
|
|
|
68
68
|
// Flow operations
|
|
69
69
|
wmill.setFlowUserState(key: string, value: any): Promise<void> // Set flow user state
|
|
@@ -97,8 +97,8 @@ wmill.run_script_async(path: str, args: dict = None, scheduled_in_secs: int = No
|
|
|
97
97
|
wmill.wait_job(job_id: str, timeout = None) -> Any // Wait for job completion and get result
|
|
98
98
|
|
|
99
99
|
// S3 file operations (if S3 is configured)
|
|
100
|
-
wmill.load_s3_file(s3object: S3Object, s3_resource_path: str = None) -> bytes // Load file content from S3
|
|
101
|
-
wmill.write_s3_file(s3object: S3Object, file_content: bytes, s3_resource_path: str = None) -> S3Object // Write file to S3
|
|
100
|
+
wmill.load_s3_file(s3object: S3Object | str, s3_resource_path: str = None) -> bytes // Load file content from S3
|
|
101
|
+
wmill.write_s3_file(s3object: S3Object | str, file_content: bytes, s3_resource_path: str = None) -> S3Object // Write file to S3
|
|
102
102
|
|
|
103
103
|
// Flow operations
|
|
104
104
|
wmill.run_flow_async(path: str, args: dict = None) -> str // Run flow asynchronously
|
|
@@ -45,8 +45,10 @@ import { JobService } from '../../../gen';
|
|
|
45
45
|
import { workspaceStore } from '../../../stores';
|
|
46
46
|
import { checkIfParentLoop } from '../utils';
|
|
47
47
|
import ModulePreviewResultViewer from '../../ModulePreviewResultViewer.svelte';
|
|
48
|
-
import { refreshStateStore } from '../../../svelte5Utils.svelte';
|
|
48
|
+
import { refreshStateStore, usePromise } from '../../../svelte5Utils.svelte';
|
|
49
49
|
import { getStepHistoryLoaderContext } from '../../stepHistoryLoader.svelte';
|
|
50
|
+
import AssetsDropdownButton from '../../assets/AssetsDropdownButton.svelte';
|
|
51
|
+
import { inferAssets } from '../../../infer';
|
|
50
52
|
const { selectedId, currentEditor, previewArgs, flowStateStore, flowStore, pathStore, saveDraft, customUi, executionCount } = getContext('FlowEditorContext');
|
|
51
53
|
let { flowModule = $bindable(), failureModule = false, preprocessorModule = false, parentModule = $bindable(), previousModule, scriptKind = 'script', scriptTemplate = 'script', noEditor, enableAi, savedModule = undefined, forceTestTab = false, highlightArg = undefined } = $props();
|
|
52
54
|
let workspaceScriptTag = $state(undefined);
|
|
@@ -220,6 +222,15 @@ $effect(() => {
|
|
|
220
222
|
}, 100);
|
|
221
223
|
}
|
|
222
224
|
});
|
|
225
|
+
let assets = usePromise(async () => flowModule.value.type === 'rawscript'
|
|
226
|
+
? await inferAssets(flowModule.value.language, flowModule.value.content)
|
|
227
|
+
: undefined, { clearValueOnRefresh: false, loadInit: false });
|
|
228
|
+
$effect(() => {
|
|
229
|
+
if (flowModule.value.type !== 'rawscript')
|
|
230
|
+
return;
|
|
231
|
+
[flowModule.value.content, flowModule.value.language];
|
|
232
|
+
untrack(() => assets.refresh());
|
|
233
|
+
});
|
|
223
234
|
let rawScriptLang = $derived(flowModule.value.type == 'rawscript' ? flowModule.value.language : undefined);
|
|
224
235
|
</script>
|
|
225
236
|
|
|
@@ -327,6 +338,14 @@ let rawScriptLang = $derived(flowModule.value.type == 'rawscript' ? flowModule.v
|
|
|
327
338
|
{#if flowModule.value.type === 'rawscript'}
|
|
328
339
|
{#if !noEditor}
|
|
329
340
|
{#key flowModule.id}
|
|
341
|
+
<div class="absolute top-2 right-4 z-10 flex flex-row gap-2">
|
|
342
|
+
{#if assets.value?.length}
|
|
343
|
+
<AssetsDropdownButton
|
|
344
|
+
assets={assets.value}
|
|
345
|
+
bind:fallbackAccessTypes={flowModule.value.asset_fallback_access_types}
|
|
346
|
+
/>
|
|
347
|
+
{/if}
|
|
348
|
+
</div>
|
|
330
349
|
<Editor
|
|
331
350
|
loadAsync
|
|
332
351
|
folding
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { OpenFlow } from '../../gen';
|
|
2
|
-
import type { History } from '../../history';
|
|
2
|
+
import type { History } from '../../history.svelte';
|
|
3
3
|
import type { Writable } from 'svelte/store';
|
|
4
4
|
import type ScriptEditorDrawer from './content/ScriptEditorDrawer.svelte';
|
|
5
5
|
import type { FlowState } from './flowState';
|
|
@@ -8,6 +8,10 @@ import type Editor from '../Editor.svelte';
|
|
|
8
8
|
import type SimpleEditor from '../SimpleEditor.svelte';
|
|
9
9
|
import type { StateStore } from '../../utils';
|
|
10
10
|
import type { TestSteps } from './testSteps.svelte';
|
|
11
|
+
import type { Asset, AssetWithAccessType } from '../assets/lib';
|
|
12
|
+
import type S3FilePicker from '../S3FilePicker.svelte';
|
|
13
|
+
import type DbManagerDrawer from '../DBManagerDrawer.svelte';
|
|
14
|
+
import type ResourceEditorDrawer from '../ResourceEditorDrawer.svelte';
|
|
11
15
|
import type { ModulesTestStates } from '../modulesTest.svelte';
|
|
12
16
|
export type FlowInput = Record<string, {
|
|
13
17
|
flowStepWarnings?: Record<string, {
|
|
@@ -64,3 +68,13 @@ export type FlowEditorContext = {
|
|
|
64
68
|
modulesTestStates: ModulesTestStates;
|
|
65
69
|
outputPickerOpenFns: Record<string, () => void>;
|
|
66
70
|
};
|
|
71
|
+
export type FlowGraphAssetContext = StateStore<{
|
|
72
|
+
selectedAsset: Asset | undefined;
|
|
73
|
+
assetsMap: Record<string, AssetWithAccessType[]>;
|
|
74
|
+
s3FilePicker: S3FilePicker | undefined;
|
|
75
|
+
dbManagerDrawer: DbManagerDrawer | undefined;
|
|
76
|
+
resourceEditorDrawer: ResourceEditorDrawer | undefined;
|
|
77
|
+
resourceMetadataCache: Record<string, {
|
|
78
|
+
resource_type?: string;
|
|
79
|
+
} | undefined>;
|
|
80
|
+
}>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<script lang="ts">import { FlowService } from '../../gen';
|
|
1
|
+
<script lang="ts">import { AssetService, FlowService, ResourceService } from '../../gen';
|
|
2
2
|
import { NODE } from '.';
|
|
3
3
|
import { getContext, onDestroy, setContext, tick, untrack } from 'svelte';
|
|
4
4
|
import { get, writable } from 'svelte/store';
|
|
@@ -18,7 +18,7 @@ import { sugiyama, dagStratify, coordCenter, decrossTwoLayer, decrossOpt } from
|
|
|
18
18
|
import { Expand } from 'lucide-svelte';
|
|
19
19
|
import Toggle from '../Toggle.svelte';
|
|
20
20
|
import DataflowEdge from './renderers/edges/DataflowEdge.svelte';
|
|
21
|
-
import { encodeState } from '../../utils';
|
|
21
|
+
import { encodeState, readFieldsRecursively } from '../../utils';
|
|
22
22
|
import BranchOneStart from './renderers/nodes/BranchOneStart.svelte';
|
|
23
23
|
import NoBranchNode from './renderers/nodes/NoBranchNode.svelte';
|
|
24
24
|
import HiddenBaseEdge from './renderers/edges/HiddenBaseEdge.svelte';
|
|
@@ -31,12 +31,21 @@ import { workspaceStore } from '../../stores';
|
|
|
31
31
|
import SubflowBound from './renderers/nodes/SubflowBound.svelte';
|
|
32
32
|
import { deepEqual } from 'fast-equals';
|
|
33
33
|
import ViewportResizer from './ViewportResizer.svelte';
|
|
34
|
+
import AssetNode, { computeAssetNodes } from './renderers/nodes/AssetNode.svelte';
|
|
35
|
+
import { getAllModules } from '../flows/flowExplorer';
|
|
36
|
+
import { inferAssets } from '../../infer';
|
|
37
|
+
import OnChange from '../common/OnChange.svelte';
|
|
38
|
+
import S3FilePicker from '../S3FilePicker.svelte';
|
|
39
|
+
import DbManagerDrawer from '../DBManagerDrawer.svelte';
|
|
40
|
+
import ResourceEditorDrawer from '../ResourceEditorDrawer.svelte';
|
|
41
|
+
import { assetEq } from '../assets/lib';
|
|
42
|
+
import AssetsOverflowedNode from './renderers/nodes/AssetsOverflowedNode.svelte';
|
|
34
43
|
let useDataflow = writable(false);
|
|
35
44
|
const triggerContext = getContext('TriggerContext');
|
|
36
45
|
let fullWidth = 0;
|
|
37
46
|
let width = $state(0);
|
|
38
47
|
let simplifiableFlow = $state(undefined);
|
|
39
|
-
let { onInsert = undefined, onDelete = undefined, onMove = undefined, onDeleteBranch = undefined, onNewBranch = undefined, onSelect = undefined, onChangeId = undefined, onUpdateMock = undefined, onSelectedIteration = undefined, success = undefined, modules = [], failureModule = undefined, preprocessorModule = undefined, minHeight = 0, maxHeight = undefined, notSelectable = false, flowModuleStates = undefined, selectedId = writable(undefined), path = undefined, newFlow = false, insertable = false, earlyStop = false, cache = false, scroll = false, moving = undefined, download = false, fullSize = false, disableAi = false, triggerNode = false, workspace = $workspaceStore ?? 'NO_WORKSPACE', editMode = false, allowSimplifiedPoll = true, expandedSubflows = $bindable({}), onTestUpTo = undefined, onEditInput = undefined, isOwner = false, onTestFlow = undefined, isRunning = false, onCancelTestFlow = undefined, onOpenPreview = undefined, onHideJobStatus = undefined, individualStepTests = false, flowJob = undefined, showJobStatus = false, suspendStatus = writable({}), flowHasChanged = false } = $props();
|
|
48
|
+
let { onInsert = undefined, onDelete = undefined, onMove = undefined, onDeleteBranch = undefined, onNewBranch = undefined, onSelect = undefined, onChangeId = undefined, onUpdateMock = undefined, onSelectedIteration = undefined, success = undefined, modules = [], failureModule = undefined, preprocessorModule = undefined, minHeight = 0, maxHeight = undefined, notSelectable = false, flowModuleStates = undefined, selectedId = writable(undefined), path = undefined, newFlow = false, insertable = false, earlyStop = false, cache = false, scroll = false, moving = undefined, download = false, fullSize = false, disableAi = false, triggerNode = false, workspace = $workspaceStore ?? 'NO_WORKSPACE', editMode = false, allowSimplifiedPoll = true, expandedSubflows = $bindable({}), inputAssets, onTestUpTo = undefined, onEditInput = undefined, isOwner = false, onTestFlow = undefined, isRunning = false, onCancelTestFlow = undefined, onOpenPreview = undefined, onHideJobStatus = undefined, individualStepTests = false, flowJob = undefined, showJobStatus = false, suspendStatus = writable({}), flowHasChanged = false } = $props();
|
|
40
49
|
setContext('FlowGraphContext', { selectedId, useDataflow });
|
|
41
50
|
if (triggerContext && allowSimplifiedPoll) {
|
|
42
51
|
if (isSimplifiable(modules)) {
|
|
@@ -46,6 +55,66 @@ if (triggerContext && allowSimplifiedPoll) {
|
|
|
46
55
|
computeSimplifiableFlow(modules ?? [], value ?? false);
|
|
47
56
|
});
|
|
48
57
|
}
|
|
58
|
+
const flowGraphAssetsCtx = $state({
|
|
59
|
+
val: {
|
|
60
|
+
assetsMap: inputAssets ? { Input: inputAssets } : {},
|
|
61
|
+
selectedAsset: undefined,
|
|
62
|
+
dbManagerDrawer: undefined,
|
|
63
|
+
s3FilePicker: undefined,
|
|
64
|
+
resourceEditorDrawer: undefined,
|
|
65
|
+
resourceMetadataCache: {}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
setContext('FlowGraphAssetContext', flowGraphAssetsCtx);
|
|
69
|
+
const assetsMap = $derived(flowGraphAssetsCtx.val.assetsMap);
|
|
70
|
+
$effect(() => {
|
|
71
|
+
if (inputAssets)
|
|
72
|
+
flowGraphAssetsCtx.val.assetsMap.Input = inputAssets;
|
|
73
|
+
});
|
|
74
|
+
// Fetch resource metadata for the ExploreAssetButton
|
|
75
|
+
const resMetadataCache = $derived(flowGraphAssetsCtx.val.resourceMetadataCache);
|
|
76
|
+
$effect(() => {
|
|
77
|
+
for (const asset of Object.values(assetsMap ?? []).flatMap((x) => x)) {
|
|
78
|
+
if (asset.kind !== 'resource' || asset.path in resMetadataCache)
|
|
79
|
+
continue;
|
|
80
|
+
resMetadataCache[asset.path] = undefined; // avoid fetching multiple times because of async
|
|
81
|
+
ResourceService.getResource({ path: asset.path, workspace: $workspaceStore }).then((r) => (resMetadataCache[asset.path] = { resource_type: r.resource_type }));
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
// Fetch transitive assets (path scripts and flows)
|
|
85
|
+
$effect(() => {
|
|
86
|
+
if (!$workspaceStore)
|
|
87
|
+
return;
|
|
88
|
+
let usages = [];
|
|
89
|
+
let modIds = [];
|
|
90
|
+
for (const mod of getAllModules(modules)) {
|
|
91
|
+
if (mod.id in assetsMap)
|
|
92
|
+
continue;
|
|
93
|
+
assetsMap[mod.id] = []; // avoid fetching multiple times because of async
|
|
94
|
+
if (mod.value.type === 'flow' || mod.value.type === 'script') {
|
|
95
|
+
usages.push({ path: mod.value.path, kind: mod.value.type });
|
|
96
|
+
modIds.push(mod.id);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (usages.length) {
|
|
100
|
+
AssetService.listAssetsByUsage({
|
|
101
|
+
workspace: $workspaceStore,
|
|
102
|
+
requestBody: { usages }
|
|
103
|
+
}).then((result) => {
|
|
104
|
+
result.forEach((assets, idx) => {
|
|
105
|
+
assetsMap[modIds[idx]] = assets;
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
// Prune assetsMap to only contain assets that are actually used
|
|
111
|
+
$effect(() => {
|
|
112
|
+
const allModules = new Set(getAllModules(modules).map((mod) => mod.id));
|
|
113
|
+
for (const modId in assetsMap) {
|
|
114
|
+
if (modId !== 'Input' && !allModules.has(modId))
|
|
115
|
+
delete assetsMap[modId];
|
|
116
|
+
}
|
|
117
|
+
});
|
|
49
118
|
function computeSimplifiableFlow(modules, simplifiedFlow) {
|
|
50
119
|
const isSimplif = isSimplifiable(modules);
|
|
51
120
|
simplifiableFlow = isSimplif ? { simplifiedFlow } : undefined;
|
|
@@ -61,7 +130,7 @@ function onModulesChange(modules) {
|
|
|
61
130
|
let lastNodes = undefined;
|
|
62
131
|
function layoutNodes(nodes) {
|
|
63
132
|
let lastResult = lastNodes?.[1];
|
|
64
|
-
if (lastResult &&
|
|
133
|
+
if (lastResult && nodes === lastNodes?.[0]) {
|
|
65
134
|
return lastResult;
|
|
66
135
|
}
|
|
67
136
|
let seenId = [];
|
|
@@ -220,8 +289,11 @@ async function updateStores() {
|
|
|
220
289
|
}
|
|
221
290
|
let newGraph = graph;
|
|
222
291
|
newGraph.nodes.sort((a, b) => b.id.localeCompare(a.id));
|
|
223
|
-
nodes = layoutNodes(newGraph.nodes)
|
|
224
|
-
|
|
292
|
+
[nodes, edges] = computeAssetNodes(layoutNodes(newGraph.nodes), newGraph.edges, assetsMap, {
|
|
293
|
+
moving,
|
|
294
|
+
eventHandlers: eventHandler,
|
|
295
|
+
disableAi
|
|
296
|
+
});
|
|
225
297
|
await tick();
|
|
226
298
|
height = Math.max(...nodes.map((n) => n.position.y + NODE.height + 100), minHeight);
|
|
227
299
|
}
|
|
@@ -239,7 +311,9 @@ const nodeTypes = {
|
|
|
239
311
|
branchOneEnd: BranchOneEndNode,
|
|
240
312
|
subflowBound: SubflowBound,
|
|
241
313
|
noBranch: NoBranchNode,
|
|
242
|
-
trigger: TriggersNode
|
|
314
|
+
trigger: TriggersNode,
|
|
315
|
+
asset: AssetNode,
|
|
316
|
+
assetsOverflowed: AssetsOverflowedNode
|
|
243
317
|
};
|
|
244
318
|
const edgeTypes = {
|
|
245
319
|
edge: BaseEdge,
|
|
@@ -281,7 +355,9 @@ let graph = $derived.by(() => {
|
|
|
281
355
|
});
|
|
282
356
|
$effect(() => {
|
|
283
357
|
;
|
|
284
|
-
|
|
358
|
+
[graph, allowSimplifiedPoll];
|
|
359
|
+
readFieldsRecursively(assetsMap);
|
|
360
|
+
untrack(() => updateStores());
|
|
285
361
|
});
|
|
286
362
|
let showDataflow = $derived($selectedId != undefined &&
|
|
287
363
|
!$selectedId.startsWith('constants') &&
|
|
@@ -405,6 +481,33 @@ export function isNodeVisible(nodeId) {
|
|
|
405
481
|
{/if}
|
|
406
482
|
</div>
|
|
407
483
|
|
|
484
|
+
{#each getAllModules(modules) as mod (mod.id)}
|
|
485
|
+
{#if mod.value.type === 'rawscript'}
|
|
486
|
+
{@const v = mod.value}
|
|
487
|
+
<OnChange
|
|
488
|
+
key={[v.content, v.asset_fallback_access_types]}
|
|
489
|
+
runFirstEffect
|
|
490
|
+
onChange={() =>
|
|
491
|
+
inferAssets(v.language, v.content)
|
|
492
|
+
.then((assets) => {
|
|
493
|
+
for (const override of v.asset_fallback_access_types ?? []) {
|
|
494
|
+
assets = assets.map((asset) => {
|
|
495
|
+
if (assetEq(asset, override) && !asset.access_type)
|
|
496
|
+
return { ...asset, access_type: override.access_type }
|
|
497
|
+
return asset
|
|
498
|
+
})
|
|
499
|
+
}
|
|
500
|
+
if (assetsMap && !deepEqual(assetsMap[mod.id], assets)) assetsMap[mod.id] = assets
|
|
501
|
+
})
|
|
502
|
+
.catch((e) => {})}
|
|
503
|
+
/>
|
|
504
|
+
{/if}
|
|
505
|
+
{/each}
|
|
506
|
+
|
|
507
|
+
<S3FilePicker bind:this={flowGraphAssetsCtx.val.s3FilePicker} readOnlyMode />
|
|
508
|
+
<DbManagerDrawer bind:this={flowGraphAssetsCtx.val.dbManagerDrawer} />
|
|
509
|
+
<ResourceEditorDrawer bind:this={flowGraphAssetsCtx.val.resourceEditorDrawer} />
|
|
510
|
+
|
|
408
511
|
<style>
|
|
409
512
|
:global(.svelte-flow__handle) {
|
|
410
513
|
opacity: 0;
|
|
@@ -3,6 +3,7 @@ import { type GraphModuleState } from '.';
|
|
|
3
3
|
import { type Writable } from 'svelte/store';
|
|
4
4
|
import '@xyflow/svelte/dist/base.css';
|
|
5
5
|
import { type InlineScript, type InsertKind, type onSelectedIteration } from './graphBuilder.svelte';
|
|
6
|
+
import { type AssetWithAccessType } from '../assets/lib';
|
|
6
7
|
interface Props {
|
|
7
8
|
success?: boolean | undefined;
|
|
8
9
|
modules?: FlowModule[] | undefined;
|
|
@@ -28,6 +29,7 @@ interface Props {
|
|
|
28
29
|
editMode?: boolean;
|
|
29
30
|
allowSimplifiedPoll?: boolean;
|
|
30
31
|
expandedSubflows?: Record<string, FlowModule[]>;
|
|
32
|
+
inputAssets?: AssetWithAccessType[];
|
|
31
33
|
isOwner?: boolean;
|
|
32
34
|
isRunning?: boolean;
|
|
33
35
|
individualStepTests?: boolean;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { FlowModule, Job, RawScript, Script } from '../../gen';
|
|
2
2
|
import { type Edge } from '@xyflow/svelte';
|
|
3
3
|
import type { GraphModuleState } from './model';
|
|
4
|
+
import type { AssetWithAccessType } from '../assets/lib';
|
|
4
5
|
import type { Writable } from 'svelte/store';
|
|
5
6
|
export type InsertKind = 'script' | 'forloop' | 'whileloop' | 'branchone' | 'branchall' | 'flow' | 'trigger' | 'approval' | 'end';
|
|
6
7
|
export type InlineScript = {
|
|
@@ -70,7 +71,7 @@ export type NodeLayout = {
|
|
|
70
71
|
id: string;
|
|
71
72
|
parentIds?: string[];
|
|
72
73
|
} & FlowNode;
|
|
73
|
-
export type FlowNode = InputN | ModuleN | BranchAllStartN | BranchAllEndN | ForLoopEndN | ForLoopStartN | ResultN | WhileLoopStartN | WhileLoopEndN | BranchOneStartN | BranchOneEndN | SubflowBoundN | NoBranchN | TriggerN;
|
|
74
|
+
export type FlowNode = InputN | ModuleN | BranchAllStartN | BranchAllEndN | ForLoopEndN | ForLoopStartN | ResultN | WhileLoopStartN | WhileLoopEndN | BranchOneStartN | BranchOneEndN | SubflowBoundN | NoBranchN | TriggerN | AssetN | AssetsOverflowedN;
|
|
74
75
|
export type InputN = {
|
|
75
76
|
type: 'input2';
|
|
76
77
|
data: {
|
|
@@ -232,6 +233,18 @@ export type TriggerN = {
|
|
|
232
233
|
disableAi: boolean;
|
|
233
234
|
};
|
|
234
235
|
};
|
|
236
|
+
export type AssetN = {
|
|
237
|
+
type: 'asset';
|
|
238
|
+
data: {
|
|
239
|
+
asset: AssetWithAccessType;
|
|
240
|
+
};
|
|
241
|
+
};
|
|
242
|
+
export type AssetsOverflowedN = {
|
|
243
|
+
type: 'assetsOverflowed';
|
|
244
|
+
data: {
|
|
245
|
+
overflowedAssets: AssetWithAccessType[];
|
|
246
|
+
};
|
|
247
|
+
};
|
|
235
248
|
export declare function graphBuilder(modules: FlowModule[] | undefined, extra: {
|
|
236
249
|
disableAi: boolean;
|
|
237
250
|
insertable: boolean;
|
|
@@ -4,14 +4,18 @@ import { ClipboardCopy, Hourglass } from 'lucide-svelte';
|
|
|
4
4
|
import { getContext } from 'svelte';
|
|
5
5
|
import { getStraightLinePath } from '../utils';
|
|
6
6
|
import { twMerge } from 'tailwind-merge';
|
|
7
|
+
import {} from '../../../flows/types';
|
|
8
|
+
import { assetDisplaysAsOutputInFlowGraph, NODE_WITH_WRITE_ASSET_Y_OFFSET } from '../nodes/AssetNode.svelte';
|
|
7
9
|
import { workspaceStore } from '../../../../stores';
|
|
8
10
|
import FlowStatusWaitingForEvents from '../../../FlowStatusWaitingForEvents.svelte';
|
|
9
11
|
const { useDataflow } = getContext('FlowGraphContext');
|
|
12
|
+
const flowGraphAssetCtx = getContext('FlowGraphAssetContext');
|
|
10
13
|
let {
|
|
11
14
|
// id,
|
|
12
15
|
sourceX, sourceY, sourcePosition, targetX, targetY, targetPosition, markerEnd,
|
|
13
16
|
// style,
|
|
14
17
|
data } = $props();
|
|
18
|
+
const shouldOffsetInsertButtonDueToAssetNode = flowGraphAssetCtx?.val.assetsMap?.[data.sourceId]?.some(assetDisplaysAsOutputInFlowGraph);
|
|
15
19
|
let [edgePath] = $derived(getBezierPath({
|
|
16
20
|
sourceX,
|
|
17
21
|
sourceY: targetY - sourceY > 100 ? targetY - 100 : sourceY,
|
|
@@ -31,7 +35,12 @@ let waitingForEvents = $derived(data?.flowModuleStates?.[data.targetId]?.type ==
|
|
|
31
35
|
const suspendStatus = $derived(data?.suspendStatus);
|
|
32
36
|
</script>
|
|
33
37
|
|
|
34
|
-
<EdgeLabel
|
|
38
|
+
<EdgeLabel
|
|
39
|
+
x={sourceX}
|
|
40
|
+
y={sourceY + 28 + (shouldOffsetInsertButtonDueToAssetNode ? NODE_WITH_WRITE_ASSET_Y_OFFSET : 0)}
|
|
41
|
+
class="base-edge"
|
|
42
|
+
style=""
|
|
43
|
+
>
|
|
35
44
|
{#if data?.insertable && !$useDataflow && !data?.moving && !waitingForEvents}
|
|
36
45
|
<div
|
|
37
46
|
class={twMerge('edgeButtonContainer nodrag nopan top-0')}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">import { getBezierPath, BaseEdge } from '@xyflow/svelte';
|
|
2
2
|
import { getContext } from 'svelte';
|
|
3
|
+
import { twMerge } from 'tailwind-merge';
|
|
3
4
|
export let sourceX;
|
|
4
5
|
export let sourceY;
|
|
5
6
|
export let sourcePosition;
|
|
@@ -7,6 +8,7 @@ export let targetX;
|
|
|
7
8
|
export let targetY;
|
|
8
9
|
export let targetPosition;
|
|
9
10
|
export let markerEnd = undefined;
|
|
11
|
+
export let data = {};
|
|
10
12
|
const { useDataflow } = getContext('FlowGraphContext');
|
|
11
13
|
$: [edgePath] = getBezierPath({
|
|
12
14
|
sourceX,
|
|
@@ -19,4 +21,8 @@ $: [edgePath] = getBezierPath({
|
|
|
19
21
|
});
|
|
20
22
|
</script>
|
|
21
23
|
|
|
22
|
-
<BaseEdge
|
|
24
|
+
<BaseEdge
|
|
25
|
+
path={edgePath}
|
|
26
|
+
{markerEnd}
|
|
27
|
+
class={twMerge($useDataflow ? 'hidden' : '', data.class ?? '')}
|
|
28
|
+
/>
|