windmill-components 1.447.7 → 1.448.1
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/autosize.js +3 -8
- package/package/components/AppConnectInner.svelte +7 -1
- package/package/components/ArgInput.svelte +673 -596
- package/package/components/ArgInput.svelte.d.ts +11 -0
- package/package/components/AssignableTags.svelte +2 -1
- package/package/components/AssignableTags.svelte.d.ts +1 -0
- package/package/components/AssignableTagsInner.svelte +5 -1
- package/package/components/AssignableTagsInner.svelte.d.ts +3 -1
- package/package/components/AuthSettings.svelte +1 -1
- package/package/components/AuthSettings.svelte.d.ts +1 -0
- package/package/components/EditableSchemaForm.svelte +61 -29
- package/package/components/EditableSchemaForm.svelte.d.ts +9 -0
- package/package/components/FirstStepInputs.svelte +3 -1
- package/package/components/FlowPreviewContent.svelte +46 -45
- package/package/components/HistoricInputs.svelte +2 -0
- package/package/components/InstanceSettings.svelte +5 -1
- package/package/components/Range.svelte +5 -4
- package/package/components/Range.svelte.d.ts +2 -0
- package/package/components/RunFormAdvancedPopup.svelte +2 -2
- package/package/components/SavedInputsPicker.svelte +6 -0
- package/package/components/SchemaForm.svelte +70 -4
- package/package/components/SchemaForm.svelte.d.ts +11 -0
- package/package/components/ScriptBuilder.svelte +9 -1
- package/package/components/ScriptEditor.svelte.d.ts +2 -2
- package/package/components/ScriptPicker.svelte.d.ts +1 -1
- package/package/components/SimpleEditor.svelte +3 -1
- package/package/components/TestConnection.svelte +1 -1
- package/package/components/WorkerGroup.svelte +21 -0
- package/package/components/WorkerTagPicker.svelte +2 -2
- package/package/components/WorkerTagSelect.svelte +2 -2
- package/package/components/apps/components/display/table/AppAggridTable.svelte +3 -1
- package/package/components/apps/editor/component/components.d.ts +79 -79
- package/package/components/details/EmailTriggerConfigSection.svelte.d.ts +1 -1
- package/package/components/flows/content/FlowEditorPanel.svelte +2 -2
- package/package/components/flows/content/FlowInput.svelte +193 -130
- package/package/components/flows/content/FlowInputEditor.svelte +12 -36
- package/package/components/flows/content/FlowInputEditor.svelte.d.ts +1 -5
- package/package/components/flows/content/FlowInputsQuick.svelte.d.ts +1 -1
- package/package/components/flows/content/FlowModuleWorkerTagSelect.svelte +2 -2
- package/package/components/flows/flowStateUtils.d.ts +1 -2
- package/package/components/flows/flowStateUtils.js +1 -1
- package/package/components/flows/pickers/WorkspaceScriptPickerQuick.svelte.d.ts +1 -1
- package/package/components/meltComponents/SideBarTab.svelte +60 -0
- package/package/components/meltComponents/SideBarTab.svelte.d.ts +24 -0
- package/package/components/runs/NoWorkerWithTagWarning.svelte +5 -1
- package/package/components/schema/AddProperty.svelte +3 -1
- package/package/components/schema/AddPropertyV2.svelte +5 -8
- package/package/components/schema/AddPropertyV2.svelte.d.ts +3 -0
- package/package/components/schema/EditableSchemaDrawer.svelte +12 -3
- package/package/components/schema/EditableSchemaWrapper.svelte +5 -0
- package/package/components/schema/SchemaFormDND.svelte +25 -9
- package/package/components/schema/SchemaFormDND.svelte.d.ts +12 -0
- package/package/components/schema/schemaUtils.d.ts +26 -0
- package/package/components/schema/schemaUtils.js +185 -0
- package/package/components/settings/PremiumInfo.svelte +212 -30
- package/package/components/triggers/CaptureSection.svelte.d.ts +1 -1
- package/package/components/triggers/CaptureTable.svelte +10 -2
- package/package/components/triggers/CaptureWrapper.svelte +2 -1
- package/package/components/triggers/KafkaTriggersConfigSection.svelte.d.ts +1 -1
- package/package/components/triggers/NatsTriggersConfigSection.svelte.d.ts +1 -1
- package/package/components/triggers/RouteEditorConfigSection.svelte +3 -2
- package/package/components/triggers/RouteEditorConfigSection.svelte.d.ts +2 -1
- package/package/components/triggers/RoutesPanel.svelte +2 -0
- package/package/components/triggers/RoutesPanel.svelte.d.ts +1 -0
- package/package/components/triggers/TriggersEditor.svelte +3 -1
- package/package/components/triggers/TriggersEditor.svelte.d.ts +1 -0
- package/package/components/triggers/TriggersEditorSection.svelte +0 -1
- package/package/components/triggers/TriggersWrapper.svelte +1 -1
- package/package/components/triggers/WebhooksConfigSection.svelte +9 -9
- package/package/components/triggers/WebhooksConfigSection.svelte.d.ts +2 -2
- package/package/components/triggers/WebhooksPanel.svelte +2 -2
- package/package/components/triggers/WebhooksPanel.svelte.d.ts +1 -1
- package/package/components/triggers/WebsocketEditorConfigSection.svelte.d.ts +1 -1
- package/package/gen/core/OpenAPI.js +1 -1
- package/package/gen/schemas.gen.d.ts +2 -2
- package/package/gen/schemas.gen.js +2 -2
- package/package/gen/services.gen.d.ts +22 -2
- package/package/gen/services.gen.js +44 -2
- package/package/gen/types.gen.d.ts +62 -2
- package/package/script_helpers.d.ts +1 -1
- package/package/script_helpers.js +7 -7
- package/package.json +11 -3
|
@@ -11,7 +11,7 @@ export declare function pickScript(path: string, summary: string, id: string, ha
|
|
|
11
11
|
export declare function pickFlow(path: string, summary: string, id: string): Promise<[FlowModule & {
|
|
12
12
|
value: PathFlow;
|
|
13
13
|
}, FlowModuleState]>;
|
|
14
|
-
export declare function createInlineScriptModule(language: RawScript['language'], kind: Script['kind'], subkind: 'pgsql' | 'flow' |
|
|
14
|
+
export declare function createInlineScriptModule(language: RawScript['language'], kind: Script['kind'], subkind: 'pgsql' | 'flow' | undefined, id: string, summary?: string): Promise<[FlowModule, FlowModuleState]>;
|
|
15
15
|
export declare function createLoop(id: string, enabledAi: boolean): Promise<[FlowModule, FlowModuleState]>;
|
|
16
16
|
export declare function createWhileLoop(id: string): Promise<[FlowModule, FlowModuleState]>;
|
|
17
17
|
export declare function createBranches(id: string): Promise<[FlowModule, FlowModuleState]>;
|
|
@@ -28,7 +28,6 @@ export declare function deleteFlowStateById(id: string, flowStateStore: Writable
|
|
|
28
28
|
export declare function sliceModules(modules: FlowModule[], upTo: number, idOrders: string[]): FlowModule[];
|
|
29
29
|
export declare function insertNewPreprocessorModule(flowStore: Writable<ExtendedOpenFlow>, flowStateStore: Writable<FlowState>, inlineScript?: {
|
|
30
30
|
language: RawScript['language'];
|
|
31
|
-
subkind: 'preprocessor';
|
|
32
31
|
}, wsScript?: {
|
|
33
32
|
path: string;
|
|
34
33
|
summary: string;
|
|
@@ -219,7 +219,7 @@ export async function insertNewPreprocessorModule(flowStore, flowStateStore, inl
|
|
|
219
219
|
var state = emptyFlowModuleState();
|
|
220
220
|
if (inlineScript) {
|
|
221
221
|
;
|
|
222
|
-
[module, state] = await createInlineScriptModule(inlineScript.language, '
|
|
222
|
+
[module, state] = await createInlineScriptModule(inlineScript.language, 'preprocessor', undefined, 'preprocessor');
|
|
223
223
|
}
|
|
224
224
|
else if (wsScript) {
|
|
225
225
|
;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
2
|
declare const __propDef: {
|
|
3
3
|
props: {
|
|
4
|
-
kind?: "script" | "failure" | "trigger" | "approval" | "
|
|
4
|
+
kind?: "script" | "failure" | "trigger" | "approval" | "preprocessor" | "flow" | undefined;
|
|
5
5
|
isTemplate?: boolean | undefined;
|
|
6
6
|
selected?: number | undefined;
|
|
7
7
|
displayPath?: boolean | undefined;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<script>export let dropdownItems = [];
|
|
2
|
+
export let fullMenu = false;
|
|
3
|
+
let open = false;
|
|
4
|
+
let timeout = null;
|
|
5
|
+
function handleMouseEnter() {
|
|
6
|
+
if (!fullMenu)
|
|
7
|
+
return;
|
|
8
|
+
timeout = setTimeout(() => {
|
|
9
|
+
open = true;
|
|
10
|
+
}, 500);
|
|
11
|
+
}
|
|
12
|
+
function handleMouseLeave() {
|
|
13
|
+
if (timeout) {
|
|
14
|
+
clearTimeout(timeout);
|
|
15
|
+
timeout = null;
|
|
16
|
+
}
|
|
17
|
+
open = false;
|
|
18
|
+
}
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
22
|
+
<div
|
|
23
|
+
class="flex flex-col relative !overflow-visible"
|
|
24
|
+
on:mouseenter={handleMouseEnter}
|
|
25
|
+
on:mouseleave={handleMouseLeave}
|
|
26
|
+
>
|
|
27
|
+
<slot name="close button" />
|
|
28
|
+
|
|
29
|
+
{#if fullMenu}
|
|
30
|
+
<div
|
|
31
|
+
class="absolute flex-col top-[30px] left-0 z-50 bg-surface border-l border-b {open
|
|
32
|
+
? 'rounded-md rounded-tl-none overflow-hidden shadow-md'
|
|
33
|
+
: 'rounded-bl-md'}"
|
|
34
|
+
>
|
|
35
|
+
{#each dropdownItems as item}
|
|
36
|
+
<button
|
|
37
|
+
class="hover:bg-surface-hover p-2 transition-colors duration-150 w-full {item.selected
|
|
38
|
+
? 'bg-surface-selected'
|
|
39
|
+
: 'text-secondary'}"
|
|
40
|
+
on:click={() => {
|
|
41
|
+
item.onClick()
|
|
42
|
+
open = false
|
|
43
|
+
}}
|
|
44
|
+
>
|
|
45
|
+
<div class="flex flex-row items-center gap-2 min-h-[20px]">
|
|
46
|
+
{#if item.icon}
|
|
47
|
+
<svelte:component this={item.icon} size={14} />
|
|
48
|
+
{/if}
|
|
49
|
+
|
|
50
|
+
{#if open}
|
|
51
|
+
<p class="text-xs text-secondary whitespace-nowrap text-left">
|
|
52
|
+
{item.label}
|
|
53
|
+
</p>
|
|
54
|
+
{/if}
|
|
55
|
+
</div>
|
|
56
|
+
</button>
|
|
57
|
+
{/each}
|
|
58
|
+
</div>
|
|
59
|
+
{/if}
|
|
60
|
+
</div>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
dropdownItems?: {
|
|
5
|
+
label: string;
|
|
6
|
+
onClick: () => void;
|
|
7
|
+
icon?: any;
|
|
8
|
+
selected?: boolean | undefined;
|
|
9
|
+
}[] | undefined;
|
|
10
|
+
fullMenu?: boolean | undefined;
|
|
11
|
+
};
|
|
12
|
+
events: {
|
|
13
|
+
[evt: string]: CustomEvent<any>;
|
|
14
|
+
};
|
|
15
|
+
slots: {
|
|
16
|
+
'close button': {};
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
export type SideBarTabProps = typeof __propDef.props;
|
|
20
|
+
export type SideBarTabEvents = typeof __propDef.events;
|
|
21
|
+
export type SideBarTabSlots = typeof __propDef.slots;
|
|
22
|
+
export default class SideBarTab extends SvelteComponent<SideBarTabProps, SideBarTabEvents, SideBarTabSlots> {
|
|
23
|
+
}
|
|
24
|
+
export {};
|
|
@@ -5,13 +5,16 @@ import { onDestroy } from 'svelte';
|
|
|
5
5
|
export let tag;
|
|
6
6
|
let noWorkerWithTag = false;
|
|
7
7
|
let timeout = undefined;
|
|
8
|
+
let visible = true;
|
|
8
9
|
async function lookForTag() {
|
|
9
10
|
try {
|
|
10
11
|
const existsWorkerWithTag = await WorkerService.existsWorkerWithTag({ tag });
|
|
11
12
|
noWorkerWithTag = !existsWorkerWithTag;
|
|
12
13
|
if (noWorkerWithTag) {
|
|
13
14
|
timeout = setTimeout(() => {
|
|
14
|
-
|
|
15
|
+
if (visible) {
|
|
16
|
+
lookForTag();
|
|
17
|
+
}
|
|
15
18
|
}, 1000);
|
|
16
19
|
}
|
|
17
20
|
}
|
|
@@ -21,6 +24,7 @@ async function lookForTag() {
|
|
|
21
24
|
}
|
|
22
25
|
lookForTag();
|
|
23
26
|
onDestroy(() => {
|
|
27
|
+
visible = false;
|
|
24
28
|
if (timeout) {
|
|
25
29
|
clearTimeout(timeout);
|
|
26
30
|
}
|
|
@@ -112,7 +112,9 @@ export function handleDeleteArgument(argPath) {
|
|
|
112
112
|
});
|
|
113
113
|
if (Object.keys(modifiedProperties).includes(argName)) {
|
|
114
114
|
delete modifiedProperties[argName];
|
|
115
|
-
modifiedObject.required
|
|
115
|
+
if (modifiedObject.required) {
|
|
116
|
+
modifiedObject.required = schema.required.filter((arg) => arg !== argName);
|
|
117
|
+
}
|
|
116
118
|
if (modifiedObject.order) {
|
|
117
119
|
modifiedObject.order = modifiedObject.order.filter((arg) => arg !== argName);
|
|
118
120
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<script>import { modalToSchema } from '../../common';
|
|
2
2
|
import { emptySchema, sendUserToast } from '../../utils';
|
|
3
3
|
import { createEventDispatcher } from 'svelte';
|
|
4
|
-
import SimpleEditor from '../SimpleEditor.svelte';
|
|
5
4
|
import AddPropertyFormV2 from './AddPropertyFormV2.svelte';
|
|
6
5
|
export let schema = emptySchema();
|
|
7
6
|
export const DEFAULT_PROPERTY = {
|
|
@@ -14,12 +13,10 @@ const dispatch = createEventDispatcher();
|
|
|
14
13
|
if (!schema) {
|
|
15
14
|
schema = emptySchema();
|
|
16
15
|
}
|
|
17
|
-
let schemaString = '';
|
|
18
16
|
// Internal state: bound to args builder modal
|
|
19
17
|
let argError = '';
|
|
20
18
|
let editing = false;
|
|
21
19
|
let oldArgName; // when editing argument and changing name
|
|
22
|
-
let jsonEditor;
|
|
23
20
|
reorder();
|
|
24
21
|
function reorder() {
|
|
25
22
|
if (schema.order && Array.isArray(schema.order)) {
|
|
@@ -42,7 +39,7 @@ function syncOrders() {
|
|
|
42
39
|
schema.order = Object.keys(schema.properties ?? {});
|
|
43
40
|
}
|
|
44
41
|
}
|
|
45
|
-
function handleAddOrEditArgument(modalProperty) {
|
|
42
|
+
export function handleAddOrEditArgument(modalProperty) {
|
|
46
43
|
// If editing the arg's name, oldName containing the old argument name must be provided
|
|
47
44
|
argError = '';
|
|
48
45
|
modalProperty.name = modalProperty.name.trim();
|
|
@@ -89,8 +86,6 @@ function handleAddOrEditArgument(modalProperty) {
|
|
|
89
86
|
oldArgName = undefined;
|
|
90
87
|
}
|
|
91
88
|
schema = schema;
|
|
92
|
-
schemaString = JSON.stringify(schema, null, '\t');
|
|
93
|
-
jsonEditor?.setCode(schemaString);
|
|
94
89
|
if (argError !== '') {
|
|
95
90
|
sendUserToast(argError, true);
|
|
96
91
|
}
|
|
@@ -112,12 +107,13 @@ export function handleDeleteArgument(argPath) {
|
|
|
112
107
|
});
|
|
113
108
|
if (Object.keys(modifiedProperties).includes(argName)) {
|
|
114
109
|
delete modifiedProperties[argName];
|
|
115
|
-
modifiedObject.required
|
|
110
|
+
if (modifiedObject.required) {
|
|
111
|
+
modifiedObject.required = schema.required.filter((arg) => arg !== argName);
|
|
112
|
+
}
|
|
116
113
|
if (modifiedObject.order) {
|
|
117
114
|
modifiedObject.order = modifiedObject.order.filter((arg) => arg !== argName);
|
|
118
115
|
}
|
|
119
116
|
schema = schema;
|
|
120
|
-
schemaString = JSON.stringify(schema, null, '\t');
|
|
121
117
|
dispatch('change', schema);
|
|
122
118
|
}
|
|
123
119
|
else {
|
|
@@ -140,6 +136,7 @@ export function handleDeleteArgument(argPath) {
|
|
|
140
136
|
selectedType: 'string',
|
|
141
137
|
name: e.detail.name
|
|
142
138
|
})
|
|
139
|
+
dispatch('addNew', e.detail.name)
|
|
143
140
|
} catch (err) {
|
|
144
141
|
sendUserToast(`Could not add argument: ${err}`, true)
|
|
145
142
|
}
|
|
@@ -4,9 +4,11 @@ declare const __propDef: {
|
|
|
4
4
|
props: {
|
|
5
5
|
schema?: Schema | any;
|
|
6
6
|
DEFAULT_PROPERTY?: ModalSchemaProperty | undefined;
|
|
7
|
+
handleAddOrEditArgument?: ((modalProperty: ModalSchemaProperty) => void) | undefined;
|
|
7
8
|
handleDeleteArgument?: ((argPath: string[]) => void) | undefined;
|
|
8
9
|
};
|
|
9
10
|
events: {
|
|
11
|
+
addNew: CustomEvent<any>;
|
|
10
12
|
change: CustomEvent<any>;
|
|
11
13
|
} & {
|
|
12
14
|
[evt: string]: CustomEvent<any>;
|
|
@@ -20,6 +22,7 @@ export type AddPropertyV2Events = typeof __propDef.events;
|
|
|
20
22
|
export type AddPropertyV2Slots = typeof __propDef.slots;
|
|
21
23
|
export default class AddPropertyV2 extends SvelteComponent<AddPropertyV2Props, AddPropertyV2Events, AddPropertyV2Slots> {
|
|
22
24
|
get DEFAULT_PROPERTY(): ModalSchemaProperty;
|
|
25
|
+
get handleAddOrEditArgument(): (modalProperty: ModalSchemaProperty) => void;
|
|
23
26
|
get handleDeleteArgument(): (argPath: string[]) => void;
|
|
24
27
|
}
|
|
25
28
|
export {};
|
|
@@ -135,8 +135,11 @@ let error = undefined;
|
|
|
135
135
|
<div class="flex flex-col w-full mt-2">
|
|
136
136
|
<Label label="Nested properties">
|
|
137
137
|
<svelte:self
|
|
138
|
-
on:change={() =>
|
|
139
|
-
|
|
138
|
+
on:change={() => {
|
|
139
|
+
schema = schema
|
|
140
|
+
dispatch('change', schema)
|
|
141
|
+
}}
|
|
142
|
+
bind:schema={schema.properties[item.value]}
|
|
140
143
|
parentId={item.value}
|
|
141
144
|
/>
|
|
142
145
|
</Label>
|
|
@@ -168,7 +171,13 @@ let error = undefined;
|
|
|
168
171
|
editTab="inputEditor"
|
|
169
172
|
>
|
|
170
173
|
<svelte:fragment slot="addProperty">
|
|
171
|
-
<AddPropertyV2
|
|
174
|
+
<AddPropertyV2
|
|
175
|
+
bind:schema
|
|
176
|
+
on:change
|
|
177
|
+
on:addNew={(e) => {
|
|
178
|
+
editableSchemaForm?.openField(e.detail)
|
|
179
|
+
}}
|
|
180
|
+
>
|
|
172
181
|
<svelte:fragment slot="trigger">
|
|
173
182
|
<div
|
|
174
183
|
class="w-full py-2 flex justify-center items-center border border-dashed rounded-md hover:bg-surface-hover"
|
|
@@ -15,6 +15,7 @@ export let lightweightMode = false;
|
|
|
15
15
|
export let formatExtension = undefined;
|
|
16
16
|
let resourceIsTextFile = false;
|
|
17
17
|
let addProperty = undefined;
|
|
18
|
+
let editableSchemaForm = undefined;
|
|
18
19
|
const dispatch = createEventDispatcher();
|
|
19
20
|
$: !resourceIsTextFile && (formatExtension = undefined);
|
|
20
21
|
$: invalidExtension =
|
|
@@ -80,6 +81,9 @@ let autocompleteExtension = true;
|
|
|
80
81
|
bind:schema
|
|
81
82
|
bind:this={addProperty}
|
|
82
83
|
on:change={() => dispatch('change', schema)}
|
|
84
|
+
on:addNew={(e) => {
|
|
85
|
+
editableSchemaForm?.openField(e.detail)
|
|
86
|
+
}}
|
|
83
87
|
>
|
|
84
88
|
<svelte:fragment slot="trigger">
|
|
85
89
|
<div
|
|
@@ -91,6 +95,7 @@ let autocompleteExtension = true;
|
|
|
91
95
|
</AddPropertyV2>
|
|
92
96
|
{/if}
|
|
93
97
|
<EditableSchemaForm
|
|
98
|
+
bind:this={editableSchemaForm}
|
|
94
99
|
bind:schema
|
|
95
100
|
on:change={() => dispatch('change', schema)}
|
|
96
101
|
isFlowInput
|
|
@@ -12,6 +12,11 @@ export let onlyMaskPassword = false;
|
|
|
12
12
|
export let disablePortal = false;
|
|
13
13
|
export let disabled = false;
|
|
14
14
|
export let schemaSkippedValues = [];
|
|
15
|
+
export let nestedParent = undefined;
|
|
16
|
+
export let disableDnd = false;
|
|
17
|
+
export let shouldDispatchChanges = false;
|
|
18
|
+
export let diff = {};
|
|
19
|
+
export let nestedClasses = '';
|
|
15
20
|
const dispatch = createEventDispatcher();
|
|
16
21
|
const flipDurationMs = 200;
|
|
17
22
|
let items = computeItems();
|
|
@@ -48,12 +53,16 @@ function handleFinalize(e) {
|
|
|
48
53
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
49
54
|
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
|
50
55
|
<SchemaForm
|
|
56
|
+
{nestedClasses}
|
|
51
57
|
{schemaSkippedValues}
|
|
52
58
|
on:click
|
|
53
59
|
on:change
|
|
54
60
|
on:reorder
|
|
55
61
|
on:consider={handleConsider}
|
|
56
62
|
on:finalize={handleFinalize}
|
|
63
|
+
on:acceptChange
|
|
64
|
+
on:rejectChange
|
|
65
|
+
on:nestedChange
|
|
57
66
|
{lightweightMode}
|
|
58
67
|
bind:args
|
|
59
68
|
{prettifyHeader}
|
|
@@ -61,17 +70,24 @@ function handleFinalize(e) {
|
|
|
61
70
|
{disablePortal}
|
|
62
71
|
{disabled}
|
|
63
72
|
bind:schema
|
|
64
|
-
dndConfig={
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
73
|
+
dndConfig={disableDnd
|
|
74
|
+
? undefined
|
|
75
|
+
: {
|
|
76
|
+
items,
|
|
77
|
+
flipDurationMs,
|
|
78
|
+
dropTargetStyle: {},
|
|
79
|
+
type: dndType ?? 'top-level'
|
|
80
|
+
}}
|
|
70
81
|
{items}
|
|
82
|
+
{diff}
|
|
83
|
+
{nestedParent}
|
|
84
|
+
{shouldDispatchChanges}
|
|
71
85
|
>
|
|
72
86
|
<svelte:fragment slot="actions">
|
|
73
|
-
|
|
74
|
-
<
|
|
75
|
-
|
|
87
|
+
{#if !disableDnd}
|
|
88
|
+
<div class="w-4 h-8 cursor-move ml-2 handle" aria-label="drag-handle" use:dragHandle>
|
|
89
|
+
<GripVertical size={16} />
|
|
90
|
+
</div>
|
|
91
|
+
{/if}
|
|
76
92
|
</svelte:fragment>
|
|
77
93
|
</SchemaForm>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
2
|
import type { Schema } from '../../common';
|
|
3
|
+
import type { SchemaDiff } from './schemaUtils';
|
|
3
4
|
declare const __propDef: {
|
|
4
5
|
props: {
|
|
5
6
|
dndType?: string | undefined;
|
|
@@ -11,11 +12,22 @@ declare const __propDef: {
|
|
|
11
12
|
disablePortal?: boolean | undefined;
|
|
12
13
|
disabled?: boolean | undefined;
|
|
13
14
|
schemaSkippedValues?: string[] | undefined;
|
|
15
|
+
nestedParent?: {
|
|
16
|
+
label: string;
|
|
17
|
+
nestedParent: any | undefined;
|
|
18
|
+
} | undefined;
|
|
19
|
+
disableDnd?: boolean | undefined;
|
|
20
|
+
shouldDispatchChanges?: boolean | undefined;
|
|
21
|
+
diff?: Record<string, SchemaDiff> | undefined;
|
|
22
|
+
nestedClasses?: string | undefined;
|
|
14
23
|
};
|
|
15
24
|
events: {
|
|
16
25
|
click: CustomEvent<any>;
|
|
17
26
|
change: CustomEvent<any>;
|
|
18
27
|
reorder: CustomEvent<any>;
|
|
28
|
+
acceptChange: CustomEvent<any>;
|
|
29
|
+
rejectChange: CustomEvent<any>;
|
|
30
|
+
nestedChange: CustomEvent<any>;
|
|
19
31
|
} & {
|
|
20
32
|
[evt: string]: CustomEvent<any>;
|
|
21
33
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type SchemaDiff = {
|
|
2
|
+
diff: 'same' | 'added' | 'removed' | 'modified' | Record<string, SchemaDiff>;
|
|
3
|
+
fullSchema: {
|
|
4
|
+
[key: string]: any;
|
|
5
|
+
} | undefined;
|
|
6
|
+
oldSchema?: {
|
|
7
|
+
[key: string]: any;
|
|
8
|
+
} | undefined;
|
|
9
|
+
};
|
|
10
|
+
export declare function computeDiff(previewSchema: {
|
|
11
|
+
[key: string]: any;
|
|
12
|
+
} | undefined, currentSchema: {
|
|
13
|
+
[key: string]: any;
|
|
14
|
+
} | undefined): Record<string, SchemaDiff>;
|
|
15
|
+
export declare function schemaFromDiff(diff: Record<string, SchemaDiff>, schema: {
|
|
16
|
+
[key: string]: any;
|
|
17
|
+
} | undefined): {
|
|
18
|
+
[key: string]: any;
|
|
19
|
+
} | undefined;
|
|
20
|
+
export declare function getFullPath(arg: {
|
|
21
|
+
label: string;
|
|
22
|
+
nestedParent: any | undefined;
|
|
23
|
+
}): string[];
|
|
24
|
+
export declare function getNestedProperty(obj: any, path: string[], field?: string): any;
|
|
25
|
+
export declare function setNestedProperty(obj: any, path: string[], value: any, field?: string): void;
|
|
26
|
+
export declare function applyDiff(schema: Record<string, any> | undefined, diff: Record<string, SchemaDiff> | undefined): Record<string, any> | undefined;
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
function isCompatible(diff) {
|
|
2
|
+
let compatible = true;
|
|
3
|
+
Object.values(diff).forEach((diff) => {
|
|
4
|
+
if (diff.diff === 'added' || diff.diff === 'modified' || diff.diff === 'removed') {
|
|
5
|
+
compatible = false;
|
|
6
|
+
}
|
|
7
|
+
else if (isRecordSchemaDiff(diff.diff)) {
|
|
8
|
+
compatible = isCompatible(diff.diff);
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
return compatible;
|
|
12
|
+
}
|
|
13
|
+
function isCompatibleObject(a, b) {
|
|
14
|
+
if (!a || !b) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
if (a.type === 'null' || b.type === 'null') {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
if (a.type !== b.type) {
|
|
21
|
+
if ((a.type === 'number' || a.type === 'integer') &&
|
|
22
|
+
(b.type === 'number' || b.type === 'integer')) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
switch (a.type) {
|
|
28
|
+
case 'object':
|
|
29
|
+
if (a.oneOf || b.oneOf) {
|
|
30
|
+
//TODO: handle oneOf compatibility. here we assume that only b is oneOf
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
return a.format === b.format;
|
|
34
|
+
case 'array':
|
|
35
|
+
return !a.items || !b.items || a.items?.type === b.items?.type;
|
|
36
|
+
case 'string':
|
|
37
|
+
return a.format === b.format;
|
|
38
|
+
case 'boolean':
|
|
39
|
+
case 'number':
|
|
40
|
+
case 'integer':
|
|
41
|
+
return true;
|
|
42
|
+
default:
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export function computeDiff(previewSchema, currentSchema) {
|
|
47
|
+
if (!previewSchema || !currentSchema) {
|
|
48
|
+
return {};
|
|
49
|
+
}
|
|
50
|
+
const diff = {};
|
|
51
|
+
if (previewSchema?.properties) {
|
|
52
|
+
Object.keys(previewSchema.properties).forEach((key) => {
|
|
53
|
+
if (!currentSchema?.properties?.[key]) {
|
|
54
|
+
diff[key] = {
|
|
55
|
+
diff: 'added',
|
|
56
|
+
fullSchema: previewSchema.properties[key]
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
const previewProp = previewSchema.properties[key];
|
|
61
|
+
const currentProp = currentSchema.properties[key];
|
|
62
|
+
if (previewProp.type === 'object' && currentProp.type === 'object') {
|
|
63
|
+
if (JSON.stringify(previewProp) === JSON.stringify(currentProp)) {
|
|
64
|
+
diff[key] = { diff: 'same', fullSchema: undefined };
|
|
65
|
+
}
|
|
66
|
+
else if (previewProp.oneOf || currentProp.oneOf) {
|
|
67
|
+
if (isCompatibleObject(previewProp, currentProp)) {
|
|
68
|
+
diff[key] = { diff: 'same', fullSchema: undefined };
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
diff[key] = { diff: 'modified', fullSchema: previewProp, oldSchema: currentProp };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else if (previewProp.format || currentProp.format) {
|
|
75
|
+
//TODO: handle s3 object compatibility
|
|
76
|
+
diff[key] = { diff: 'modified', fullSchema: previewProp, oldSchema: currentProp };
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
const diffProp = computeDiff(previewProp, currentProp);
|
|
80
|
+
const checkIfSame = isCompatible(diffProp);
|
|
81
|
+
if (checkIfSame) {
|
|
82
|
+
diff[key] = { diff: 'same', fullSchema: undefined };
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
diff[key] = {
|
|
86
|
+
diff: diffProp,
|
|
87
|
+
fullSchema: previewProp,
|
|
88
|
+
oldSchema: currentProp
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else if (isCompatibleObject(previewProp, currentProp)) {
|
|
94
|
+
diff[key] = { diff: 'same', fullSchema: undefined };
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
diff[key] = { diff: 'modified', fullSchema: previewProp, oldSchema: currentProp };
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
if (currentSchema?.properties) {
|
|
103
|
+
Object.keys(currentSchema.properties).forEach((key) => {
|
|
104
|
+
if (!previewSchema?.properties?.[key]) {
|
|
105
|
+
diff[key] = { diff: 'removed', fullSchema: undefined };
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return diff;
|
|
110
|
+
}
|
|
111
|
+
export function schemaFromDiff(diff, schema) {
|
|
112
|
+
if (!schema) {
|
|
113
|
+
return undefined;
|
|
114
|
+
}
|
|
115
|
+
const newSchema = structuredClone(schema);
|
|
116
|
+
Object.keys(diff).forEach((key) => {
|
|
117
|
+
const diffValue = diff[key].diff;
|
|
118
|
+
if (diffValue === 'added' || diffValue === 'modified') {
|
|
119
|
+
newSchema.properties[key] = diff[key].fullSchema;
|
|
120
|
+
if (newSchema.order && !newSchema.order.includes(key)) {
|
|
121
|
+
newSchema.order.push(key);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else if (isRecordSchemaDiff(diffValue)) {
|
|
125
|
+
// Handle nested diffs
|
|
126
|
+
newSchema.properties[key] = schemaFromDiff(diffValue, schema.properties[key]);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
return newSchema;
|
|
130
|
+
}
|
|
131
|
+
export function getFullPath(arg) {
|
|
132
|
+
const getPath = (current) => {
|
|
133
|
+
if (!current.nestedParent) {
|
|
134
|
+
return [current.label];
|
|
135
|
+
}
|
|
136
|
+
return [...getPath(current.nestedParent), current.label];
|
|
137
|
+
};
|
|
138
|
+
return getPath(arg);
|
|
139
|
+
}
|
|
140
|
+
export function getNestedProperty(obj, path, field = 'properties') {
|
|
141
|
+
return path.reduce((curr, key) => curr?.[field]?.[key], obj);
|
|
142
|
+
}
|
|
143
|
+
export function setNestedProperty(obj, path, value, field = 'properties') {
|
|
144
|
+
const pathCopy = [...path];
|
|
145
|
+
const lastKey = pathCopy.pop();
|
|
146
|
+
const target = pathCopy.reduce((curr, key) => {
|
|
147
|
+
if (!(key in curr[field])) {
|
|
148
|
+
curr[field][key] = { [field]: {} };
|
|
149
|
+
}
|
|
150
|
+
return curr[field][key];
|
|
151
|
+
}, obj);
|
|
152
|
+
if (lastKey && value) {
|
|
153
|
+
const newValue = structuredClone(value);
|
|
154
|
+
target[field][lastKey] = newValue;
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
else if (lastKey && !value) {
|
|
158
|
+
delete target[field][lastKey];
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function isRecordSchemaDiff(value) {
|
|
162
|
+
return typeof value === 'object' && value !== null;
|
|
163
|
+
}
|
|
164
|
+
export function applyDiff(schema, diff) {
|
|
165
|
+
if (!diff || !schema) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
let newSchema = structuredClone(schema);
|
|
169
|
+
Object.keys(diff).forEach((key) => {
|
|
170
|
+
const diffValue = diff[key].diff;
|
|
171
|
+
if (diffValue === 'removed') {
|
|
172
|
+
delete newSchema.properties[key];
|
|
173
|
+
if (newSchema.order) {
|
|
174
|
+
newSchema.order = newSchema.order.filter((x) => x !== key);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
else if (diffValue === 'added' || diffValue === 'modified' || isRecordSchemaDiff(diffValue)) {
|
|
178
|
+
newSchema.properties[key] = diff[key].fullSchema;
|
|
179
|
+
if (newSchema.order && !newSchema.order.includes(key)) {
|
|
180
|
+
newSchema.order.push(key);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
return newSchema;
|
|
185
|
+
}
|