diff --git a/frontend/src/lib/components/AIProviderPicker.svelte b/frontend/src/lib/components/AIProviderPicker.svelte index b32453aa8f..c9336f8627 100644 --- a/frontend/src/lib/components/AIProviderPicker.svelte +++ b/frontend/src/lib/components/AIProviderPicker.svelte @@ -8,6 +8,7 @@ import ToggleButtonGroup from './common/toggleButton-v2/ToggleButtonGroup.svelte' import ToggleButton from './common/toggleButton-v2/ToggleButton.svelte' import ResourcePicker from './ResourcePicker.svelte' + import ToggleButtonMore from './common/toggleButton-v2/ToggleButtonMore.svelte' interface ProviderValue { kind?: AIProvider @@ -154,22 +155,36 @@ } -
+
-
- +
+ {#snippet children({ item })} - {#each providerOptions as option} - + {#each providerOptions.slice(0, 3) as option} + {/each} + value?.kind, (v) => v && onProviderChange(v)} + /> {/snippet}
-
+
-

resource

+

resource

resourceValueToPath(value?.resource), @@ -183,12 +198,13 @@ disabled={disabled || !value?.kind} placeholder="Select resource" selectFirst={true} + selectInputClass="!bg-surface" />
-

model

+

model

dispatch('focus')} onBlur={() => dispatch('blur')} + inputClass={selectClass} />
diff --git a/frontend/src/lib/components/ArgInput.svelte b/frontend/src/lib/components/ArgInput.svelte index 843281774f..ace4f6cbed 100644 --- a/frontend/src/lib/components/ArgInput.svelte +++ b/frontend/src/lib/components/ArgInput.svelte @@ -46,6 +46,7 @@ import { workspaceStore } from '$lib/stores' import { getJsonSchemaFromResource } from './schema/jsonSchemaResource.svelte' import AIProviderPicker from './AIProviderPicker.svelte' + import TextInput, { inputBaseClass, inputBorderClass } from './text_input/TextInput.svelte' interface Props { label?: string @@ -71,6 +72,7 @@ properties?: { [name: string]: SchemaProperty } } | undefined + lightHeaderFont?: boolean displayHeader?: boolean properties?: { [name: string]: SchemaProperty } | undefined nestedRequired?: string[] | undefined @@ -120,6 +122,8 @@ | undefined workspace?: string | undefined actions?: import('svelte').Snippet + innerBottomSnippet?: import('svelte').Snippet + fieldHeaderActions?: import('svelte').Snippet } let { @@ -133,7 +137,7 @@ oneOf = $bindable(undefined), required = false, pattern = $bindable(undefined), - valid = $bindable(undefined), + valid = $bindable(undefined), // Note : this should not exist, valid and error should be one coherent state enum_ = $bindable(undefined), disabled = false, itemsType = $bindable(undefined), @@ -176,7 +180,10 @@ appPath = undefined, computeS3ForceViewerPolicies = undefined, workspace = undefined, - actions + actions, + innerBottomSnippet, + fieldHeaderActions, + lightHeaderFont = false }: Props = $props() $effect(() => { @@ -468,6 +475,11 @@ let { debounced, clearDebounce } = debounce(() => compareValues(value), 50) let inputCat = $derived(computeInputCat(type, format, itemsType?.type, enum_, contentEncoding)) + let displayJsonToggleHeader = $derived( + displayHeader && + inputCat === 'list' && + !(itemsType?.resourceType === 's3_object' || itemsType?.resourceType === 's3object') + ) $effect(() => { oneOf && untrack(() => updateOneOfSelected(oneOf)) }) @@ -518,10 +530,10 @@ {#snippet variableInput()} {#if variableEditor} -
+
{#if value && typeof value == 'string' && value?.startsWith('$var:')} Linked to variable {/if} @@ -587,24 +599,43 @@
{/if} {#if displayHeader} - - {/if} +
+ +
+ {#if displayJsonToggleHeader} + { + // Once the user has changed the input type, we should not change it back automatically + if (!hasIsListJsonChanged) { + hasIsListJsonChanged = true + } - {#if description} -
-
{description}
+ evalValueToRaw() + isListJson = !isListJson + }} + checked={isListJson} + textClass="text-secondary" + size="xs" + options={{ left: 'json' }} + /> + {/if} + {@render fieldHeaderActions?.()} +
{/if} @@ -629,7 +660,22 @@ /> {:else}
- (ignoreValueUndefined = true), + placeholder: placeholder ?? defaultValue ?? '', + min: extra['min'], + max: extra['max'] + }} + {error} + bind:value + /> +
{/if} {:else if inputCat == 'boolean'} @@ -679,6 +725,7 @@ bind:editor {appPath} {computeS3ForceViewerPolicies} + bottom={innerBottomSnippet} /> {:else if inputCat == 'object' && format == 'json-schema'} {#await import('$lib/components/EditableSchemaForm.svelte')} @@ -722,8 +769,9 @@ {/await} {:else} -
+
{:else} -
+
{#key redraw} {#if Array.isArray(value)} {#each value ?? [] as v, i} {#if i < itemsLimit} -
+
+ {#snippet deleteItemBtn()} + + {/snippet} {#if itemsType?.type == 'number'} - + +
+ {@render deleteItemBtn()} +
{:else if itemsType?.type == 'string' && itemsType?.contentEncoding == 'base64'} fileChanged(x, (val) => (value[i] = val))} multiple={false} /> + {@render deleteItemBtn()} {:else if itemsType?.type == 'object' && itemsType?.resourceType === undefined && itemsType?.properties === undefined && !(format?.startsWith('resource-') && resourceTypes?.includes(format.split('-')[1]))} {#await import('$lib/components/JsonEditor.svelte')} @@ -792,6 +861,7 @@ bind:value={value[i]} /> {/await} + {@render deleteItemBtn()} {:else if Array.isArray(itemsType?.enum)} + {@render deleteItemBtn()} {:else if (itemsType?.type == 'resource' && itemsType?.resourceType && resourceTypes?.includes(itemsType.resourceType)) || (format?.startsWith('resource-') && resourceTypes?.includes(format.split('-')[1]))} {@const resourceFormat = itemsType?.type == 'resource' && @@ -821,6 +892,7 @@ format={resourceFormat} defaultValue={undefined} /> + {@render deleteItemBtn()} {:else if itemsType?.type == 'resource'} {#await import('$lib/components/JsonEditor.svelte')} @@ -837,9 +909,11 @@ bind:value={value[i]} /> {/await} + {@render deleteItemBtn()} {:else if itemsType?.type === 'object' && itemsType?.properties}
+ {@render deleteItemBtn()} {:else} - + +
+ {@render deleteItemBtn()} +
{/if} -
{/if} {/each} @@ -874,7 +945,7 @@ {#if value.startsWith('$res:')} {@render resourceInput()} {:else} -
+
Invalid string value: "{value}", expected array. Click add item to turn it into an array.
@@ -882,59 +953,58 @@ {/if} {/key}
-
- -
+ {/if}
-
- { - // Once the user has changed the input type, we should not change it back automatically - if (!hasIsListJsonChanged) { - hasIsListJsonChanged = true - } + {#if !displayHeader} +
+ { + // Once the user has changed the input type, we should not change it back automatically + if (!hasIsListJsonChanged) { + hasIsListJsonChanged = true + } - evalValueToRaw() - isListJson = !isListJson - }} - checked={isListJson} - textClass="text-secondary" - size="xs" - options={{ right: 'json' }} - /> -
+ evalValueToRaw() + isListJson = !isListJson + }} + checked={isListJson} + textClass="text-secondary" + size="xs" + options={{ left: 'json' }} + /> +
+ {/if}
{:else if inputCat == 'dynamic'} @@ -957,7 +1027,7 @@ /> {:else if inputCat == 'object' || inputCat == 'resource-object' || isListJson} {#if oneOf && oneOf.length >= 2} -
+
{#if oneOf && oneOf.length >= 2} 0} {#key redraw} -
- {#if orderEditable} - ({ - properties: obj.properties ?? {}, - order: obj.order, - $schema: '', - required: obj.required ?? [], - type: 'object' - }), - () => { - dispatch('nestedChange') - } - } - bind:args={value} - hiddenArgs={[ - oneOf?.find((o) => Object.keys(o.properties ?? {}).includes('kind')) - ? 'kind' - : 'label' - ]} - on:reorder={(e) => { - if (oneOf && oneOf[objIdx]) { - const keys = e.detail - oneOf[objIdx].order = keys - } - }} - on:nestedChange - {shouldDispatchChanges} - /> - {:else} - ({ + properties: obj.properties ?? {}, order: obj.order, $schema: '', required: obj.required ?? [], type: 'object' - }} - bind:args={ - () => value, - (v) => { - value = { ...v, [tagKey]: oneOfSelected } - } - } - {shouldDispatchChanges} - on:change={() => { + }), + () => { dispatch('nestedChange') - }} - on:nestedChange - /> - {/if} -
+ } + } + bind:args={value} + hiddenArgs={[ + oneOf?.find((o) => Object.keys(o.properties ?? {}).includes('kind')) + ? 'kind' + : 'label' + ]} + on:reorder={(e) => { + if (oneOf && oneOf[objIdx]) { + const keys = e.detail + oneOf[objIdx].order = keys + } + }} + on:nestedChange + {shouldDispatchChanges} + /> + {:else} + value, + (v) => { + value = { ...v, [tagKey]: oneOfSelected } + } + } + {shouldDispatchChanges} + on:change={() => { + dispatch('nestedChange') + }} + on:nestedChange + /> + {/if} {/key} {:else if disabled} @@ -1107,9 +1177,10 @@ {/if}
{:else if properties && Object.keys(properties).length > 0 && inputCat !== 'list'} -
+
{#if orderEditable} {:else} {/await} {/if} - {#if inputCat == 'list'} -
+ {#if inputCat == 'list' && !displayHeader} +
{ isListJson = !isListJson @@ -1199,7 +1271,7 @@ checked={isListJson} textClass="text-secondary" size="xs" - options={{ right: 'json' }} + options={{ left: 'json' }} />
{/if} @@ -1220,6 +1292,7 @@ dispatch('blur') }} enumLabels={extra['enumLabels']} + selectClass="min-h-10" />
{:else if inputCat == 'date'} @@ -1328,12 +1401,7 @@ use:autosize onkeydown={onKeyDown} {disabled} - class={twMerge( - 'w-full', - valid - ? '' - : 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-3' - )} + class={twMerge('w-full', inputBaseClass, inputBorderClass({ error: !!error }))} placeholder={placeholder ?? defaultValue ?? ''} bind:value > @@ -1344,7 +1412,7 @@
- {#if !compact || (error && error != '')} -
- {#if disabled || error === ''} -   - {:else} - {error} - {/if} + {#if description} +
+
{description}
+ {/if} + + {#if !compact || (error && error != '')} + {#if disabled || error === ''} +   + {:else} +
+ {error} +
+ {/if} {:else if !noMargin}
{/if} @@ -1381,10 +1455,4 @@ -webkit-appearance: none !important; margin: 0; } - - /* Firefox */ - input[type='number'] { - -moz-appearance: textfield !important; - appearance: textfield !important; - } diff --git a/frontend/src/lib/components/ArrayTypeNarrowing.svelte b/frontend/src/lib/components/ArrayTypeNarrowing.svelte index 86b4fb6c10..0a27ddf228 100644 --- a/frontend/src/lib/components/ArrayTypeNarrowing.svelte +++ b/frontend/src/lib/components/ArrayTypeNarrowing.svelte @@ -10,6 +10,7 @@ import type { SchemaProperty } from '$lib/common' import Toggle from './Toggle.svelte' import { tick } from 'svelte' + import Select from './select/Select.svelte' interface Props { canEditResourceType?: boolean @@ -54,39 +55,44 @@ {#if canEditResourceType || originalType == 'string[]' || originalType == 'object[]'} {:else if itemsType?.resourceType}