mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-21 16:02:28 +00:00
feat(frontend): array of resources (#4095)
* feat(frontend): wip * feat(frontend): wip * feat(frontend): add support for array of resources * feat(frontend): improve code * feat(frontend): add support for array of resources in the flow and app editors * feat(frontend): improve code * feat(frontend): display the detected resource type * fix(frontend): Fix PR comments + add warning on the value format * fix(frontend): improve code
This commit is contained in:
@@ -26,9 +26,10 @@ export interface SchemaProperty {
|
||||
contentEncoding?: 'base64' | 'binary'
|
||||
format?: string
|
||||
items?: {
|
||||
type?: 'string' | 'number' | 'bytes' | 'object'
|
||||
type?: 'string' | 'number' | 'bytes' | 'object' | 'resource'
|
||||
contentEncoding?: 'base64'
|
||||
enum?: string[]
|
||||
resourceType?: string
|
||||
}
|
||||
min?: number
|
||||
max?: number
|
||||
|
||||
@@ -47,12 +47,14 @@
|
||||
export let disabled = false
|
||||
export let itemsType:
|
||||
| {
|
||||
type?: 'string' | 'number' | 'bytes' | 'object'
|
||||
type?: 'string' | 'number' | 'bytes' | 'object' | 'resource'
|
||||
contentEncoding?: 'base64'
|
||||
enum?: string[]
|
||||
multiselect?: string[]
|
||||
resourceType?: string
|
||||
}
|
||||
| undefined = undefined
|
||||
|
||||
export let displayHeader = true
|
||||
export let properties: { [name: string]: SchemaProperty } | undefined = undefined
|
||||
export let nestedRequired: string[] | undefined = undefined
|
||||
@@ -372,7 +374,7 @@
|
||||
on:change={(x) => fileChanged(x, (val) => (value[i] = val))}
|
||||
multiple={false}
|
||||
/>
|
||||
{:else if itemsType?.type == 'object'}
|
||||
{:else if itemsType?.type == 'object' && itemsType?.resourceType === undefined}
|
||||
<JsonEditor code={JSON.stringify(v, null, 2)} bind:value={v} />
|
||||
{:else if Array.isArray(itemsType?.enum)}
|
||||
<ArgEnum
|
||||
@@ -392,6 +394,8 @@
|
||||
enum_={itemsType?.enum ?? []}
|
||||
enumLabels={extra['enumLabels']}
|
||||
/>
|
||||
{:else if itemsType?.type == 'resource' && itemsType?.resourceType}
|
||||
<ResourcePicker bind:value={v} resourceType={itemsType?.resourceType} />
|
||||
{:else}
|
||||
<input type="text" bind:value={v} id="arg-input-array" />
|
||||
{/if}
|
||||
|
||||
@@ -3,16 +3,21 @@
|
||||
import { Button } from './common'
|
||||
import { fade } from 'svelte/transition'
|
||||
import Label from './Label.svelte'
|
||||
import ResourceTypePicker from './ResourceTypePicker.svelte'
|
||||
import Badge from './common/badge/Badge.svelte'
|
||||
import Alert from './common/alert/Alert.svelte'
|
||||
|
||||
export let canEditResourceType: boolean = false
|
||||
export let itemsType:
|
||||
| {
|
||||
type?: 'string' | 'number' | 'bytes' | 'object'
|
||||
type?: 'string' | 'number' | 'bytes' | 'object' | 'resource'
|
||||
contentEncoding?: 'base64'
|
||||
enum?: string[]
|
||||
resourceType?: string
|
||||
}
|
||||
| undefined
|
||||
|
||||
let selected: 'string' | 'number' | 'object' | 'bytes' | 'enum' | undefined =
|
||||
let selected: 'string' | 'number' | 'object' | 'bytes' | 'enum' | 'resource' | undefined =
|
||||
itemsType?.type != 'string'
|
||||
? itemsType?.type
|
||||
: Array.isArray(itemsType?.enum)
|
||||
@@ -20,33 +25,62 @@
|
||||
: 'string'
|
||||
</script>
|
||||
|
||||
<Label label="Items type">
|
||||
<select
|
||||
bind:value={selected}
|
||||
on:change={() => {
|
||||
if (selected == 'enum') {
|
||||
itemsType = { type: 'string', enum: [] }
|
||||
} else if (selected == 'string') {
|
||||
itemsType = { type: 'string' }
|
||||
} else if (selected == 'number') {
|
||||
itemsType = { type: 'number' }
|
||||
} else if (selected == 'object') {
|
||||
itemsType = { type: 'object' }
|
||||
} else if (selected == 'bytes') {
|
||||
itemsType = { type: 'string', contentEncoding: 'base64' }
|
||||
} else {
|
||||
itemsType = undefined
|
||||
}
|
||||
}}
|
||||
id="array-type-narrowing"
|
||||
{#if canEditResourceType}
|
||||
<Label label="Items type">
|
||||
<select
|
||||
bind:value={selected}
|
||||
on:change={() => {
|
||||
if (selected == 'enum') {
|
||||
itemsType = { type: 'string', enum: [] }
|
||||
} else if (selected == 'string') {
|
||||
itemsType = { type: 'string' }
|
||||
} else if (selected == 'number') {
|
||||
itemsType = { type: 'number' }
|
||||
} else if (selected == 'object') {
|
||||
itemsType = { type: 'object' }
|
||||
} else if (selected == 'bytes') {
|
||||
itemsType = { type: 'string', contentEncoding: 'base64' }
|
||||
} else if (selected == 'resource') {
|
||||
itemsType = { type: 'resource', resourceType: itemsType?.resourceType }
|
||||
} else {
|
||||
itemsType = undefined
|
||||
}
|
||||
}}
|
||||
id="array-type-narrowing"
|
||||
>
|
||||
<option value="string"> Items are strings</option>
|
||||
<option value="enum">Items are strings from an enum</option>
|
||||
<option value="object"> Items are objects (JSON)</option>
|
||||
<option value="resource"> Items are resources</option>
|
||||
<option value="number">Items are numbers</option>
|
||||
<option value="bytes">Items are bytes</option>
|
||||
</select>
|
||||
</Label>
|
||||
{:else}
|
||||
<Label label="Resource type">
|
||||
<Badge color="blue">
|
||||
{itemsType?.resourceType}
|
||||
</Badge>
|
||||
</Label>
|
||||
{/if}
|
||||
|
||||
{#if itemsType?.type === 'resource'}
|
||||
<Alert
|
||||
type="warning"
|
||||
title="Value"
|
||||
size="xs"
|
||||
tooltip="Learn how to use the SDK to get the resource by using the path."
|
||||
documentationLink="https://www.windmill.dev/docs/code_editor/add_variables_resources#fetching-them-from-within-a-script-by-using-the-wmill-client-in-the-respective-language"
|
||||
>
|
||||
<option value="string"> Items are strings</option>
|
||||
<option value="enum">Items are strings from an enum</option>
|
||||
<option value="object"> Items are objects (JSON)</option>
|
||||
<option value="number">Items are numbers</option>
|
||||
<option value="bytes">Items are bytes</option>
|
||||
</select>
|
||||
</Label>
|
||||
The value passed is the path of the resource, not the resource itself. You can use the SDK to
|
||||
get the resource by using the path.
|
||||
</Alert>
|
||||
{/if}
|
||||
|
||||
{#if canEditResourceType && itemsType?.type == 'resource'}
|
||||
<ResourceTypePicker bind:value={itemsType.resourceType} />
|
||||
{/if}
|
||||
|
||||
{#if Array.isArray(itemsType?.enum)}
|
||||
<label for="input" class="text-secondary text-xs">
|
||||
Enums
|
||||
|
||||
@@ -40,10 +40,11 @@
|
||||
export let enum_: EnumType = undefined
|
||||
export let itemsType:
|
||||
| {
|
||||
type?: 'string' | 'number' | 'bytes' | 'object'
|
||||
type?: 'string' | 'number' | 'bytes' | 'object' | 'resource'
|
||||
contentEncoding?: 'base64'
|
||||
enum?: string[]
|
||||
multiselect?: string[]
|
||||
resourceType?: string
|
||||
}
|
||||
| undefined = undefined
|
||||
export let displayHeader = true
|
||||
@@ -329,6 +330,11 @@
|
||||
<option>{e}</option>
|
||||
{/each}
|
||||
</select>
|
||||
{:else if itemsType?.type == 'resource' && itemsType?.resourceType}
|
||||
<LightweightResourcePicker
|
||||
bind:value={v}
|
||||
resourceType={itemsType?.resourceType}
|
||||
/>
|
||||
{:else}
|
||||
<input type="text" bind:value={v} />
|
||||
{/if}
|
||||
|
||||
@@ -34,9 +34,10 @@
|
||||
export let order: string[] | undefined = undefined
|
||||
export let itemsType:
|
||||
| {
|
||||
type?: 'string' | 'number' | 'bytes' | 'object'
|
||||
type?: 'string' | 'number' | 'bytes' | 'object' | 'resource'
|
||||
contentEncoding?: 'base64'
|
||||
enum?: string[]
|
||||
resourceType?: string
|
||||
multiselect?: string[]
|
||||
}
|
||||
| undefined = undefined
|
||||
@@ -157,7 +158,7 @@
|
||||
</Label>
|
||||
|
||||
{#if type == 'array'}
|
||||
<ArrayTypeNarrowing bind:itemsType />
|
||||
<ArrayTypeNarrowing bind:itemsType canEditResourceType={isFlowInput || isAppInput} />
|
||||
{:else if type == 'string' || ['number', 'integer', 'object'].includes(type ?? '')}
|
||||
<div>
|
||||
<Label label="Field settings">
|
||||
|
||||
@@ -101,6 +101,8 @@ export function argSigToJsonSchemaType(
|
||||
newS.items = { type: 'string' }
|
||||
} else if (t.list && typeof t.list == 'object' && 'str' in t.list) {
|
||||
newS.items = { type: 'string', enum: t.list.str }
|
||||
} else if (t.list && typeof t.list == 'object' && 'resource' in t.list && t.list.resource) {
|
||||
newS.items = { type: 'resource', resourceType: t.list.resource as string }
|
||||
} else {
|
||||
newS.items = { type: 'object' }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user