mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-08 00:03:07 +00:00
190 lines
6.4 KiB
Svelte
190 lines
6.4 KiB
Svelte
<script lang="ts">
|
|
import type { Schema } from '$lib/common'
|
|
import { InputTransform } from '$lib/gen'
|
|
import { allTrue, type InputCat } from '$lib/utils'
|
|
import ArgInput from './ArgInput.svelte'
|
|
import Editor from './Editor.svelte'
|
|
import FieldHeader from './FieldHeader.svelte'
|
|
import DynamicInputHelpBox from './flows/DynamicInputHelpBox.svelte'
|
|
import { getCodeInjectionExpr, getDefaultExpr, isCodeInjection } from './flows/utils'
|
|
import OverlayPropertyPicker from './propertyPicker/OverlayPropertyPicker.svelte'
|
|
import Toggle from './Toggle.svelte'
|
|
|
|
export let inputTransform = false
|
|
export let schema: Schema
|
|
export let args: Record<string, InputTransform> = {}
|
|
export let editableSchema = false
|
|
export let extraLib: string = 'missing extraLib'
|
|
export let isValid: boolean = true
|
|
|
|
export let i: number | undefined = undefined
|
|
export let pickableProperties: Object | undefined = undefined
|
|
|
|
let inputCheck: { [id: string]: boolean } = {}
|
|
let overlays: { [id: string]: OverlayPropertyPicker } = {}
|
|
$: isValid = allTrue(inputCheck) ?? false
|
|
|
|
let propertiesTypes: { [id: string]: InputTransform.type } = {}
|
|
let inputCats: { [id: string]: InputCat } = {}
|
|
|
|
function setPropertyType(id: string, rawValue: string, isRaw: boolean) {
|
|
const arg = args[id]
|
|
if (!arg) {
|
|
return
|
|
}
|
|
|
|
if (isCodeInjection(rawValue)) {
|
|
args[id].expr = getCodeInjectionExpr(rawValue, isRaw)
|
|
args[id].type = InputTransform.type.JAVASCRIPT
|
|
propertiesTypes[id] = InputTransform.type.STATIC
|
|
} else {
|
|
if (
|
|
args[id].type === InputTransform.type.JAVASCRIPT &&
|
|
propertiesTypes[id] === InputTransform.type.STATIC
|
|
) {
|
|
args[id].type = InputTransform.type.STATIC
|
|
if (inputCats[id] == 'number') {
|
|
args[id].value = Number(args[id].value)
|
|
}
|
|
}
|
|
if (arg.type) {
|
|
propertiesTypes[id] = arg.type
|
|
}
|
|
}
|
|
}
|
|
|
|
function hasOverlay(inputCat: InputCat) {
|
|
return inputCat === 'string' || inputCat === 'number'
|
|
}
|
|
</script>
|
|
|
|
<div class="w-full">
|
|
{#if Object.keys(schema?.properties ?? {}).length > 0}
|
|
{#each Object.keys(schema?.properties ?? {}) as argName, index}
|
|
{#if inputTransform}
|
|
{#if args[argName] != undefined}
|
|
<div class={index > 0 ? 'mt-8' : ''} />
|
|
<div class="flex justify-between items-center">
|
|
<div class="flex items-center">
|
|
<FieldHeader
|
|
label={argName}
|
|
format={schema.properties[argName].format}
|
|
contentEncoding={schema.properties[argName].contentEncoding}
|
|
required={schema.required.includes(argName)}
|
|
type={schema.properties[argName].type}
|
|
itemsType={schema.properties[argName].items}
|
|
/>
|
|
{#if propertiesTypes[argName] === InputTransform.type.STATIC && args[argName].type === InputTransform.type.JAVASCRIPT}
|
|
<span
|
|
class="bg-blue-100 text-blue-800 text-sm font-medium mr-2 px-2.5 py-0.5 rounded ml-2"
|
|
>
|
|
{'${...}'}
|
|
</span>
|
|
{/if}
|
|
</div>
|
|
<Toggle
|
|
options={{
|
|
left: { label: '', value: InputTransform.type.STATIC },
|
|
right: { label: 'Raw Javascript Editor', value: InputTransform.type.JAVASCRIPT }
|
|
}}
|
|
bind:value={propertiesTypes[argName]}
|
|
on:change={(e) => {
|
|
if (e.detail === InputTransform.type.JAVASCRIPT) {
|
|
args[argName].expr = getDefaultExpr(i ?? -1, argName, args[argName].value)
|
|
args[argName].value = undefined
|
|
} else {
|
|
args[argName].expr = undefined
|
|
args[argName].value = undefined
|
|
}
|
|
|
|
args[argName].type = e.detail
|
|
}}
|
|
/>
|
|
</div>
|
|
<div class="max-w-xs" />
|
|
|
|
{#if propertiesTypes[argName] === undefined || propertiesTypes[argName] === InputTransform.type.STATIC}
|
|
<OverlayPropertyPicker
|
|
bind:this={overlays[argName]}
|
|
bind:pickableProperties
|
|
disabled={!hasOverlay(inputCats[argName])}
|
|
on:select={(event) => {
|
|
const toAppend = `\$\{${event.detail}}`
|
|
args[argName].value = `${args[argName].value ?? ''}${toAppend}`
|
|
setPropertyType(argName, args[argName].value, false)
|
|
}}
|
|
>
|
|
<ArgInput
|
|
on:focus={() => {
|
|
Object.keys(overlays).forEach((k) => {
|
|
if (k == argName) {
|
|
overlays[k].focus()
|
|
} else {
|
|
overlays[k].unfocus()
|
|
}
|
|
})
|
|
}}
|
|
label={argName}
|
|
bind:description={schema.properties[argName].description}
|
|
bind:value={args[argName].value}
|
|
type={schema.properties[argName].type}
|
|
required={schema.required.includes(argName)}
|
|
bind:pattern={schema.properties[argName].pattern}
|
|
bind:valid={inputCheck[argName]}
|
|
defaultValue={schema.properties[argName].default}
|
|
bind:enum_={schema.properties[argName].enum}
|
|
bind:format={schema.properties[argName].format}
|
|
contentEncoding={schema.properties[argName].contentEncoding}
|
|
bind:itemsType={schema.properties[argName].items}
|
|
displayHeader={false}
|
|
bind:inputCat={inputCats[argName]}
|
|
numberAsString={true}
|
|
on:input={(e) => {
|
|
if (hasOverlay(inputCats[argName])) {
|
|
setPropertyType(argName, e.detail.rawValue, e.detail.isRaw)
|
|
}
|
|
}}
|
|
/>
|
|
</OverlayPropertyPicker>
|
|
{:else if propertiesTypes[argName] === InputTransform.type.JAVASCRIPT}
|
|
{#if args[argName].expr != undefined}
|
|
<div class="border rounded p-2 mt-2 border-gray-300">
|
|
<Editor
|
|
bind:code={args[argName].expr}
|
|
lang="javascript"
|
|
class="few-lines-editor"
|
|
{extraLib}
|
|
extraLibPath="file:///node_modules/@types/windmill@{i}/index.d.ts"
|
|
/>
|
|
</div>
|
|
<DynamicInputHelpBox />
|
|
{/if}
|
|
{:else}
|
|
<p>Not recognized arg type {args[argName].type}</p>
|
|
{/if}
|
|
{:else}
|
|
<p>Arg at {argName} is undefined</p>
|
|
{/if}
|
|
{:else}
|
|
<ArgInput
|
|
label={argName}
|
|
bind:description={schema.properties[argName].description}
|
|
bind:value={args[argName]}
|
|
type={schema.properties[argName].type}
|
|
required={schema.required.includes(argName)}
|
|
bind:pattern={schema.properties[argName].pattern}
|
|
bind:valid={inputCheck[argName]}
|
|
defaultValue={schema.properties[argName].default}
|
|
bind:enum_={schema.properties[argName].enum}
|
|
bind:format={schema.properties[argName].format}
|
|
contentEncoding={schema.properties[argName].contentEncoding}
|
|
bind:itemsType={schema.properties[argName].items}
|
|
{editableSchema}
|
|
/>
|
|
{/if}
|
|
{/each}
|
|
{:else}
|
|
<p class="italic text-sm">No settable input</p>
|
|
{/if}
|
|
</div>
|