From cadc758fc7b8d77f6906cd71b819443fdcc8a514 Mon Sep 17 00:00:00 2001 From: Faton Ramadani Date: Wed, 15 May 2024 17:30:40 +0200 Subject: [PATCH] feat(frontend): add nullable arg (#3729) * feat(frontend): add nullable arg * feat(frontend): Limit nullable toggle for strings and numbers * feat(frontend): Limit nullable toggle to strings * feat(frontend): fix validation * feat(frontend): Disable nullable when required + add missing config in script editor --- frontend/src/lib/common.ts | 3 ++ frontend/src/lib/components/ArgInput.svelte | 34 ++++++++++++++++--- .../lib/components/EditableSchemaForm.svelte | 1 + .../lib/components/InputTransformForm.svelte | 1 + .../lib/components/ModulePreviewForm.svelte | 1 + frontend/src/lib/components/SchemaForm.svelte | 1 + .../src/lib/components/SchemaModal.svelte | 32 ++++++++++++++--- 7 files changed, 64 insertions(+), 9 deletions(-) diff --git a/frontend/src/lib/common.ts b/frontend/src/lib/common.ts index fcdaa04524..c1917635ea 100644 --- a/frontend/src/lib/common.ts +++ b/frontend/src/lib/common.ts @@ -39,6 +39,7 @@ export interface SchemaProperty { showExpr?: string password?: boolean order?: string[] + nullable?: boolean dateFormat?: string } @@ -62,6 +63,7 @@ export interface ModalSchemaProperty { customErrorMessage?: string showExpr?: string password?: boolean + nullable?: boolean dateFormat?: string } @@ -85,6 +87,7 @@ export function modalToSchema(schema: ModalSchemaProperty): SchemaProperty { multiselect: schema.multiselect, showExpr: schema.showExpr, password: schema.password, + nullable: schema.nullable, dateFormat: schema.dateFormat } } diff --git a/frontend/src/lib/components/ArgInput.svelte b/frontend/src/lib/components/ArgInput.svelte index 35c4e62ff4..7f013a2360 100644 --- a/frontend/src/lib/components/ArgInput.svelte +++ b/frontend/src/lib/components/ArgInput.svelte @@ -73,6 +73,7 @@ export let simpleTooltip: string | undefined = undefined export let customErrorMessage: string | undefined = undefined export let onlyMaskPassword = false + export let nullable: boolean = false let seeEditable: boolean = enum_ != undefined || pattern != undefined const dispatch = createEventDispatcher() @@ -94,12 +95,17 @@ $: inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncoding) let rawValue: string | undefined = undefined - function computeDefaultValue(nvalue?: any, inputCat?: string, defaultValue?: any) { + function computeDefaultValue( + nvalue?: any, + inputCat?: string, + defaultValue?: any, + nnullable?: boolean + ) { if ((value == undefined || value == null) && !ignoreValueUndefined) { value = defaultValue if (defaultValue === undefined || defaultValue === null) { if (inputCat === 'string') { - value = '' + value = nullable ? null : '' } else if (inputCat == 'enum' && required) { value = enum_?.[0] } else if (inputCat == 'boolean') { @@ -111,11 +117,15 @@ evalValueToRaw() } } + + if (nnullable && type === 'string' && value === '') { + value = null + } } computeDefaultValue() - $: computeDefaultValue(value, inputCat, defaultValue) + $: computeDefaultValue(value, inputCat, defaultValue, nullable) $: defaultValue != undefined && handleDefaultValueChange() @@ -158,7 +168,10 @@ } function validateInput(pattern: string | undefined, v: any, required: boolean): void { - if (required && (v == undefined || v == null || v === '')) { + if (nullable && emptyString(v)) { + error = '' + valid && (valid = true) + } else if (required && (v == undefined || v == null || v === '')) { error = 'Required' valid && (valid = false) } else { @@ -304,6 +317,19 @@ {/if} + {#if !required && type === 'string'} +
+ +
+ {/if} {/if} {/if} diff --git a/frontend/src/lib/components/EditableSchemaForm.svelte b/frontend/src/lib/components/EditableSchemaForm.svelte index b7b5b34fdd..f2fea9ec69 100644 --- a/frontend/src/lib/components/EditableSchemaForm.svelte +++ b/frontend/src/lib/components/EditableSchemaForm.svelte @@ -151,6 +151,7 @@ bind:pickForField bind:extra={schema.properties[argName]} simpleTooltip={schemaFieldTooltip[argName]} + nullable={schema.properties[argName].nullable} /> {/if} {/if} diff --git a/frontend/src/lib/components/InputTransformForm.svelte b/frontend/src/lib/components/InputTransformForm.svelte index 24aad7be94..d5d790f509 100644 --- a/frontend/src/lib/components/InputTransformForm.svelte +++ b/frontend/src/lib/components/InputTransformForm.svelte @@ -406,6 +406,7 @@ {itemPicker} bind:pickForField showSchemaExplorer + nullable={schema.properties[argName].nullable} /> {:else if arg.expr != undefined}
diff --git a/frontend/src/lib/components/ModulePreviewForm.svelte b/frontend/src/lib/components/ModulePreviewForm.svelte index 3d45eb819e..2f1dd60125 100644 --- a/frontend/src/lib/components/ModulePreviewForm.svelte +++ b/frontend/src/lib/components/ModulePreviewForm.svelte @@ -95,6 +95,7 @@ nestedRequired={schema.properties[argName].required} itemsType={schema.properties[argName].items} extra={schema.properties[argName]} + nullable={schema.properties[argName].nullable} /> {/if}
diff --git a/frontend/src/lib/components/SchemaForm.svelte b/frontend/src/lib/components/SchemaForm.svelte index f6847f9e3b..e66896e381 100644 --- a/frontend/src/lib/components/SchemaForm.svelte +++ b/frontend/src/lib/components/SchemaForm.svelte @@ -158,6 +158,7 @@ {showSchemaExplorer} simpleTooltip={schemaFieldTooltip[argName]} {onlyMaskPassword} + nullable={schema.properties[argName].nullable} > {#if linkedSecretCandidates?.includes(argName)} diff --git a/frontend/src/lib/components/SchemaModal.svelte b/frontend/src/lib/components/SchemaModal.svelte index 88b769f8a8..762397135b 100644 --- a/frontend/src/lib/components/SchemaModal.svelte +++ b/frontend/src/lib/components/SchemaModal.svelte @@ -61,6 +61,7 @@ : undefined, showExpr: schema.showExpr, password: schema.password, + nullable: schema.nullable, dateFormat: schema.format } } @@ -135,6 +136,7 @@ property.items = undefined property.showExpr = undefined property.password = undefined + property.nullable = false property.dateFormat = undefined drawer.closeDrawer() } @@ -263,12 +265,32 @@ format={property.format} extra={property} disabled={property.password} + nullable={property.nullable} /> - +
+ { + if (event?.detail) { + property.nullable = false + } + }} + /> + {#if property?.selectedType === 'string'} + + {/if} +
{#if isFlowInput}