diff --git a/frontend/src/lib/components/LightweightArgInput.svelte b/frontend/src/lib/components/LightweightArgInput.svelte index 8997de2285..0f63e88a11 100644 --- a/frontend/src/lib/components/LightweightArgInput.svelte +++ b/frontend/src/lib/components/LightweightArgInput.svelte @@ -52,7 +52,7 @@ $: validateInput(pattern, value) - let error: string = '' + export let error: string = '' let el: HTMLTextAreaElement | undefined = undefined @@ -185,9 +185,9 @@ }} type="number" class={twMerge( - valid + valid && error == '' ? '' - : 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100' + : 'border !border-red-700 !border-opacity-70 focus:!border-red-700 focus:!border-opacity-30' )} placeholder={defaultValue ?? ''} bind:value @@ -200,9 +200,9 @@ on:pointerdown={(e) => { e?.stopPropagation() }} - class={valid + class={valid && error == '' ? '' - : 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'} + : 'border !border-red-700 !border-opacity-70 focus:!border-red-700 focus:!border-opacity-30'} bind:checked={value} /> {#if type == 'boolean' && value == undefined} @@ -292,9 +292,9 @@ }} use:autosize style="max-height: {maxHeight}" - class="col-span-10 {valid + class="col-span-10 {valid && error == '' ? '' - : 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'}" + : 'border !border-red-700 !border-opacity-70 focus:!border-red-700 focus:!border-opacity-30'}" placeholder={defaultValue ? JSON.stringify(defaultValue, null, 4) : ''} bind:value={rawValue} /> @@ -340,9 +340,9 @@ }} use:autosize type="text" - class="col-span-10 {valid + class="col-span-10 {valid && error == '' ? '' - : 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'}" + : 'border !border-red-700 !border-opacity-70 focus:!border-red-700 focus:!border-opacity-30'}" placeholder={defaultValue ?? ''} bind:value on:pointerdown|stopPropagation={(e) => { diff --git a/frontend/src/lib/components/LightweightSchemaForm.svelte b/frontend/src/lib/components/LightweightSchemaForm.svelte index 11d0e66ce3..81b10cc1fe 100644 --- a/frontend/src/lib/components/LightweightSchemaForm.svelte +++ b/frontend/src/lib/components/LightweightSchemaForm.svelte @@ -14,6 +14,8 @@ export let isValid: boolean = true let inputCheck: { [id: string]: boolean } = {} + let errors: { [id: string]: string } = {} + $: isValid = allTrue(inputCheck) ?? false $: if (args === undefined) { @@ -22,6 +24,21 @@ reorder() + export function invalidate(key: string, error: string) { + inputCheck[key] = false + errors[key] = error + } + + export function validate(key: string) { + inputCheck[key] = true + errors[key] = '' + } + + export function validateAll() { + inputCheck = Object.fromEntries(Object.entries(inputCheck).map((x) => [x[0], true])) + errors = Object.fromEntries(Object.entries(errors).map((x) => [x[0], ''])) + } + function reorder() { if (schema.order && Array.isArray(schema.order)) { const n = {} @@ -50,6 +67,7 @@ description={schema.properties[argName].description} bind:value={args[argName]} bind:valid={inputCheck[argName]} + bind:error={errors[argName]} type={schema.properties[argName].type} required={schema.required?.includes(argName) ?? false} pattern={schema.properties[argName].pattern} diff --git a/frontend/src/lib/components/apps/components/buttons/AppForm.svelte b/frontend/src/lib/components/apps/components/buttons/AppForm.svelte index 7aa9fed9f7..661961c734 100644 --- a/frontend/src/lib/components/apps/components/buttons/AppForm.svelte +++ b/frontend/src/lib/components/apps/components/buttons/AppForm.svelte @@ -46,6 +46,15 @@ $componentControl[id] = { setValue(nvalue: string) { wrapper?.setArgs(nvalue) + }, + invalidate(key: string, error: string) { + runnableComponent?.invalidate(key, error) + }, + validateAll() { + runnableComponent?.validateAll() + }, + validate(key: string) { + runnableComponent?.validate(key) } } diff --git a/frontend/src/lib/components/apps/components/buttons/AppFormButton.svelte b/frontend/src/lib/components/apps/components/buttons/AppFormButton.svelte index d81990a897..eabebe0d8b 100644 --- a/frontend/src/lib/components/apps/components/buttons/AppFormButton.svelte +++ b/frontend/src/lib/components/apps/components/buttons/AppFormButton.svelte @@ -35,6 +35,15 @@ $componentControl[id] = { onDelete: () => { modal?.close() + }, + invalidate(key: string, error: string) { + runnableComponent?.invalidate(key, error) + }, + validateAll() { + runnableComponent?.validateAll() + }, + validate(key: string) { + runnableComponent?.validate(key) } } diff --git a/frontend/src/lib/components/apps/components/buttons/AppSchemaForm.svelte b/frontend/src/lib/components/apps/components/buttons/AppSchemaForm.svelte index 410d46acd8..5b5a956520 100644 --- a/frontend/src/lib/components/apps/components/buttons/AppSchemaForm.svelte +++ b/frontend/src/lib/components/apps/components/buttons/AppSchemaForm.svelte @@ -55,9 +55,20 @@ } } + let schemaForm: LightweightSchemaForm + $componentControl[id] = { setValue(nvalue: any) { args = nvalue + }, + invalidate(key: string, error: string) { + schemaForm?.invalidate(key, error) + }, + validateAll() { + schemaForm?.validateAll() + }, + validate(key: string) { + schemaForm?.validate(key) } } @@ -106,6 +117,7 @@ schema={result} bind:isValid={valid} bind:args + bind:this={schemaForm} displayType={Boolean(resolvedConfig.displayType)} largeGap={Boolean(resolvedConfig.largeGap)} {css} diff --git a/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte b/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte index 4d40b23d19..96a7447264 100644 --- a/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte +++ b/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte @@ -131,6 +131,20 @@ } } + let schemaForm: LightweightSchemaForm + + export function invalidate(key: string, error: string) { + schemaForm?.invalidate(key, error) + } + + export function validate(key: string) { + schemaForm?.validate(key) + } + + export function validateAll() { + schemaForm?.validateAll() + } + // Test job internal state let resultJobLoader: ResultJobLoader | undefined = undefined @@ -568,6 +582,7 @@