mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-26 08:01:38 +00:00
remove lightweightschemaform
This commit is contained in:
@@ -4,12 +4,13 @@
|
||||
import { base } from '$lib/base'
|
||||
import { emptySchema, emptyString } from '$lib/utils'
|
||||
import SchemaForm from './SchemaForm.svelte'
|
||||
import SimpleEditor from './SimpleEditor.svelte'
|
||||
import type SimpleEditor from './SimpleEditor.svelte'
|
||||
import Toggle from './Toggle.svelte'
|
||||
import TestConnection from './TestConnection.svelte'
|
||||
import SupabaseIcon from './icons/SupabaseIcon.svelte'
|
||||
import Popup from './common/popup/Popup.svelte'
|
||||
import Button from './common/button/Button.svelte'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
|
||||
export let resourceType: string
|
||||
export let resourceTypeInfo: ResourceType | undefined
|
||||
@@ -195,13 +196,17 @@
|
||||
>{error}</span
|
||||
>{:else}<div class="py-2" />{/if}
|
||||
<div class="h-full w-full border p-1 rounded">
|
||||
<SimpleEditor
|
||||
bind:this={rawCodeEditor}
|
||||
autoHeight
|
||||
lang="json"
|
||||
bind:code={rawCode}
|
||||
fixedOverflowWidgets={false}
|
||||
/>
|
||||
{#await import('$lib/components/SimpleEditor.svelte')}
|
||||
<Loader2 class="animate-spin" />
|
||||
{:then Module}
|
||||
<Module.default
|
||||
bind:this={rawCodeEditor}
|
||||
autoHeight
|
||||
lang="json"
|
||||
bind:code={rawCode}
|
||||
fixedOverflowWidgets={false}
|
||||
/>
|
||||
{/await}
|
||||
</div>
|
||||
{:else if resourceTypeInfo?.format_extension}
|
||||
<h5 class="mt-4 inline-flex items-center gap-4">
|
||||
@@ -209,13 +214,17 @@
|
||||
</h5>
|
||||
<div class="py-2" />
|
||||
<div class="h-full w-full border p-1 rounded">
|
||||
<SimpleEditor
|
||||
bind:this={rawCodeEditor}
|
||||
autoHeight
|
||||
lang={resourceTypeInfo.format_extension}
|
||||
bind:code={textFileContent}
|
||||
fixedOverflowWidgets={false}
|
||||
/>
|
||||
{#await import('$lib/components/SimpleEditor.svelte')}
|
||||
<Loader2 class="animate-spin" />
|
||||
{:then Module}
|
||||
<Module.default
|
||||
bind:this={rawCodeEditor}
|
||||
autoHeight
|
||||
lang={resourceTypeInfo.format_extension}
|
||||
bind:code={textFileContent}
|
||||
fixedOverflowWidgets={false}
|
||||
/>
|
||||
{/await}
|
||||
</div>
|
||||
{:else}
|
||||
<SchemaForm
|
||||
|
||||
@@ -6,18 +6,17 @@
|
||||
emptyString,
|
||||
getSchemaFromProperties
|
||||
} from '$lib/utils'
|
||||
import { DollarSign, Pipette, Plus, X, Check } from 'lucide-svelte'
|
||||
import { DollarSign, Pipette, Plus, X, Check, Loader2 } from 'lucide-svelte'
|
||||
import { createEventDispatcher, onMount, tick } from 'svelte'
|
||||
import Multiselect from 'svelte-multiselect'
|
||||
import { fade } from 'svelte/transition'
|
||||
import JsonEditor from './apps/editor/settingsPanel/inputEditor/JsonEditor.svelte'
|
||||
import { Button, SecondsInput } from './common'
|
||||
import FieldHeader from './FieldHeader.svelte'
|
||||
import type ItemPicker from './ItemPicker.svelte'
|
||||
import ObjectResourceInput from './ObjectResourceInput.svelte'
|
||||
import Range from './Range.svelte'
|
||||
import ResourcePicker from './ResourcePicker.svelte'
|
||||
import SimpleEditor from './SimpleEditor.svelte'
|
||||
import type SimpleEditor from './SimpleEditor.svelte'
|
||||
import Toggle from './Toggle.svelte'
|
||||
import type VariableEditor from './VariableEditor.svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
@@ -38,6 +37,7 @@
|
||||
import DynSelect from './DynSelect.svelte'
|
||||
import type { Script } from '$lib/gen'
|
||||
import type { SchemaDiff } from '$lib/components/schema/schemaUtils'
|
||||
import type { ComponentCustomCSS } from './apps/types'
|
||||
|
||||
export let label: string = ''
|
||||
export let value: any
|
||||
@@ -101,6 +101,20 @@
|
||||
export let hideNested = false
|
||||
export let nestedParent: { label: string; nestedParent: any | undefined } | undefined = undefined
|
||||
export let nestedClasses = ''
|
||||
export let displayType = true
|
||||
export let css: ComponentCustomCSS<'schemaformcomponent'> | undefined = undefined
|
||||
export let appPath: string | undefined = undefined
|
||||
export let computeS3ForceViewerPolicies:
|
||||
| (() =>
|
||||
| {
|
||||
allowed_resources: string[]
|
||||
allow_user_resources: boolean
|
||||
allow_workspace_resource: boolean
|
||||
file_key_regex: string
|
||||
}
|
||||
| undefined)
|
||||
| undefined = undefined
|
||||
export let workspace: string | undefined = undefined
|
||||
|
||||
$: inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncoding)
|
||||
|
||||
@@ -402,11 +416,13 @@
|
||||
{format}
|
||||
{simpleTooltip}
|
||||
{lightHeader}
|
||||
{displayType}
|
||||
labelClass={css?.label?.class}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if description}
|
||||
<div class="text-xs italic pb-1 text-secondary">
|
||||
<div class={twMerge('text-xs italic pb-1 text-secondary', css?.description?.class)}>
|
||||
<pre class="font-main whitespace-normal">{description}</pre>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -512,7 +528,11 @@
|
||||
multiple={false}
|
||||
/>
|
||||
{:else if itemsType?.type == 'object' && itemsType?.resourceType === undefined && itemsType?.properties === undefined}
|
||||
<JsonEditor code={JSON.stringify(v, null, 2)} bind:value={v} />
|
||||
{#await import('$lib/components/JsonEditor.svelte')}
|
||||
<Loader2 class="animate-spin" />
|
||||
{:then Module}
|
||||
<Module.default code={JSON.stringify(v, null, 2)} bind:value={v} />
|
||||
{/await}
|
||||
{:else if Array.isArray(itemsType?.enum)}
|
||||
<ArgEnum
|
||||
required
|
||||
@@ -539,17 +559,21 @@
|
||||
defaultValue={undefined}
|
||||
/>
|
||||
{:else if itemsType?.type == 'resource'}
|
||||
<JsonEditor
|
||||
bind:editor
|
||||
on:focus={(e) => {
|
||||
dispatch('focus')
|
||||
}}
|
||||
on:blur={(e) => {
|
||||
dispatch('blur')
|
||||
}}
|
||||
code={JSON.stringify(v, null, 2)}
|
||||
bind:value={v}
|
||||
/>
|
||||
{#await import('$lib/components/JsonEditor.svelte')}
|
||||
<Loader2 class="animate-spin" />
|
||||
{:then Module}
|
||||
<Module.default
|
||||
bind:editor
|
||||
on:focus={(e) => {
|
||||
dispatch('focus')
|
||||
}}
|
||||
on:blur={(e) => {
|
||||
dispatch('blur')
|
||||
}}
|
||||
code={JSON.stringify(v, null, 2)}
|
||||
bind:value={v}
|
||||
/>
|
||||
{/await}
|
||||
{:else if itemsType?.type === 'object' && itemsType?.properties}
|
||||
<div class="p-8 border rounded-md w-full">
|
||||
<SchemaForm
|
||||
@@ -670,17 +694,21 @@
|
||||
options={{ left: 'Raw S3 object input' }}
|
||||
/>
|
||||
{#if s3FileUploadRawMode}
|
||||
<JsonEditor
|
||||
bind:editor
|
||||
on:focus={(e) => {
|
||||
dispatch('focus')
|
||||
}}
|
||||
on:blur={(e) => {
|
||||
dispatch('blur')
|
||||
}}
|
||||
code={JSON.stringify(value ?? defaultValue ?? { s3: '' }, null, 2)}
|
||||
bind:value
|
||||
/>
|
||||
{#await import('$lib/components/JsonEditor.svelte')}
|
||||
<Loader2 class="animate-spin" />
|
||||
{:then Module}
|
||||
<Module.default
|
||||
bind:editor
|
||||
on:focus={(e) => {
|
||||
dispatch('focus')
|
||||
}}
|
||||
on:blur={(e) => {
|
||||
dispatch('blur')
|
||||
}}
|
||||
code={JSON.stringify(value ?? defaultValue ?? { s3: '' }, null, 2)}
|
||||
bind:value
|
||||
/>
|
||||
{/await}
|
||||
<Button
|
||||
variant="border"
|
||||
color="light"
|
||||
@@ -695,6 +723,9 @@
|
||||
</Button>
|
||||
{:else}
|
||||
<FileUpload
|
||||
{appPath}
|
||||
computeForceViewerPolicies={computeS3ForceViewerPolicies}
|
||||
{workspace}
|
||||
allowMultiple={false}
|
||||
randomFileKey={true}
|
||||
on:addition={(evt) => {
|
||||
@@ -788,33 +819,41 @@
|
||||
{:else if disabled}
|
||||
<textarea disabled />
|
||||
{:else}
|
||||
<JsonEditor
|
||||
bind:editor
|
||||
on:focus={(e) => {
|
||||
dispatch('focus')
|
||||
}}
|
||||
on:blur={(e) => {
|
||||
dispatch('blur')
|
||||
}}
|
||||
code={rawValue}
|
||||
bind:value
|
||||
/>
|
||||
{#await import('$lib/components/JsonEditor.svelte')}
|
||||
<Loader2 class="animate-spin" />
|
||||
{:then Module}
|
||||
<Module.default
|
||||
bind:editor
|
||||
on:focus={(e) => {
|
||||
dispatch('focus')
|
||||
}}
|
||||
on:blur={(e) => {
|
||||
dispatch('blur')
|
||||
}}
|
||||
code={rawValue}
|
||||
bind:value
|
||||
/>
|
||||
{/await}
|
||||
{/if}
|
||||
{/if}
|
||||
{:else if disabled}
|
||||
<textarea disabled />
|
||||
{:else}
|
||||
<JsonEditor
|
||||
bind:editor
|
||||
on:focus={(e) => {
|
||||
dispatch('focus')
|
||||
}}
|
||||
on:blur={(e) => {
|
||||
dispatch('blur')
|
||||
}}
|
||||
code={rawValue}
|
||||
bind:value
|
||||
/>
|
||||
{#await import('$lib/components/JsonEditor.svelte')}
|
||||
<Loader2 class="animate-spin" />
|
||||
{:then Module}
|
||||
<Module.default
|
||||
bind:editor
|
||||
on:focus={(e) => {
|
||||
dispatch('focus')
|
||||
}}
|
||||
on:blur={(e) => {
|
||||
dispatch('blur')
|
||||
}}
|
||||
code={rawValue}
|
||||
bind:value
|
||||
/>
|
||||
{/await}
|
||||
{/if}
|
||||
</div>
|
||||
{:else if properties && Object.keys(properties).length > 0 && inputCat !== 'list'}
|
||||
@@ -885,17 +924,21 @@
|
||||
{:else if disabled}
|
||||
<textarea disabled />
|
||||
{:else}
|
||||
<JsonEditor
|
||||
bind:editor
|
||||
on:focus={(e) => {
|
||||
dispatch('focus')
|
||||
}}
|
||||
on:blur={(e) => {
|
||||
dispatch('blur')
|
||||
}}
|
||||
code={rawValue}
|
||||
bind:value
|
||||
/>
|
||||
{#await import('$lib/components/JsonEditor.svelte')}
|
||||
<Loader2 class="animate-spin" />
|
||||
{:then Module}
|
||||
<Module.default
|
||||
bind:editor
|
||||
on:focus={(e) => {
|
||||
dispatch('focus')
|
||||
}}
|
||||
on:blur={(e) => {
|
||||
dispatch('blur')
|
||||
}}
|
||||
code={rawValue}
|
||||
bind:value
|
||||
/>
|
||||
{/await}
|
||||
{/if}
|
||||
{#if inputCat == 'list'}
|
||||
<div class="block">
|
||||
@@ -938,18 +981,22 @@
|
||||
{/if}
|
||||
{:else if inputCat == 'sql' || inputCat == 'yaml'}
|
||||
<div class="border my-1 mb-4 w-full border-primary">
|
||||
<SimpleEditor
|
||||
on:focus={(e) => {
|
||||
dispatch('focus')
|
||||
}}
|
||||
on:blur={(e) => {
|
||||
dispatch('blur')
|
||||
}}
|
||||
bind:this={editor}
|
||||
lang={inputCat}
|
||||
bind:code={value}
|
||||
autoHeight
|
||||
/>
|
||||
{#await import('$lib/components/SimpleEditor.svelte')}
|
||||
<Loader2 class="animate-spin" />
|
||||
{:then Module}
|
||||
<Module.default
|
||||
on:focus={(e) => {
|
||||
dispatch('focus')
|
||||
}}
|
||||
on:blur={(e) => {
|
||||
dispatch('blur')
|
||||
}}
|
||||
bind:this={editor}
|
||||
lang={inputCat}
|
||||
bind:code={value}
|
||||
autoHeight
|
||||
/>
|
||||
{/await}
|
||||
</div>
|
||||
{:else if inputCat == 'base64'}
|
||||
<div class="flex flex-col my-6 w-full">
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
import { sendUserToast } from '$lib/utils'
|
||||
import ToggleButton from './common/toggleButton-v2/ToggleButton.svelte'
|
||||
import ToggleButtonGroup from './common/toggleButton-v2/ToggleButtonGroup.svelte'
|
||||
import GraphqlSchemaViewer from './GraphqlSchemaViewer.svelte'
|
||||
import { Loader2, RefreshCcw } from 'lucide-svelte'
|
||||
import {
|
||||
formatGraphqlSchema,
|
||||
@@ -93,7 +92,11 @@
|
||||
</ToggleButtonGroup>
|
||||
{/if}
|
||||
{#if dbSchema.lang === 'graphql'}
|
||||
<GraphqlSchemaViewer code={formatGraphqlSchema(dbSchema.schema)} class="h-full" />
|
||||
{#await import('$lib/components/GraphqlSchemaViewer.svelte')}
|
||||
<Loader2 class="animate-spin" />
|
||||
{:then Module}
|
||||
<Module.default code={formatGraphqlSchema(dbSchema.schema)} class="h-full" />
|
||||
{/await}
|
||||
{:else}
|
||||
<ObjectViewer json={formatSchema(dbSchema)} pureViewer collapseLevel={1} />
|
||||
{/if}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import DarkModeObserver from './DarkModeObserver.svelte'
|
||||
import ResultJobLoader from './ResultJobLoader.svelte'
|
||||
import Tooltip from './Tooltip.svelte'
|
||||
import JsonEditor from './apps/editor/settingsPanel/inputEditor/JsonEditor.svelte'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
|
||||
export let value: any = undefined
|
||||
export let helperScript:
|
||||
@@ -149,6 +149,10 @@
|
||||
<div class="text-xs text-tertiary"
|
||||
>Dynamic Select is not available in this mode, write value directly</div
|
||||
>
|
||||
<JsonEditor code={rawCode} bind:value />
|
||||
{#await import('$lib/components/JsonEditor.svelte')}
|
||||
<Loader2 class="animate-spin" />
|
||||
{:then Module}
|
||||
<Module.default code={rawCode} bind:value />
|
||||
{/await}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
export let noPreview: boolean = false
|
||||
export let jsonEnabled: boolean = true
|
||||
export let isAppInput: boolean = false
|
||||
export let lightweightMode: boolean = false
|
||||
export let displayWebhookWarning: boolean = false
|
||||
export let dndType: string | undefined = undefined
|
||||
export let editTab:
|
||||
@@ -295,7 +294,6 @@
|
||||
schema = schema
|
||||
dispatch('change', schema)
|
||||
}}
|
||||
{lightweightMode}
|
||||
prettifyHeader={isAppInput}
|
||||
disabled={!!previewSchema}
|
||||
{diff}
|
||||
@@ -557,7 +555,6 @@
|
||||
bind:defaultValue={schema.properties[argName].default}
|
||||
{variableEditor}
|
||||
{itemPicker}
|
||||
{lightweightMode}
|
||||
bind:nullable={schema.properties[argName].nullable}
|
||||
bind:disabled={schema.properties[argName].disabled}
|
||||
type={schema.properties[argName].type}
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import { X } from 'lucide-svelte'
|
||||
import DisplayResult from './DisplayResult.svelte'
|
||||
import LightweightSchemaForm from './LightweightSchemaForm.svelte'
|
||||
import Tooltip from './Tooltip.svelte'
|
||||
import { Button } from './common'
|
||||
import SchemaForm from './SchemaForm.svelte'
|
||||
|
||||
export let isOwner: boolean
|
||||
export let workspaceId: string | undefined
|
||||
@@ -145,7 +145,7 @@
|
||||
|
||||
{#if job?.raw_flow?.modules?.[approvalStep]?.suspend?.resume_form?.schema}
|
||||
<div class="w-full border rounded-lg p-2">
|
||||
<LightweightSchemaForm bind:args={default_payload} {defaultValues} {schema} />
|
||||
<SchemaForm bind:args={default_payload} {defaultValues} {schema} />
|
||||
</div>
|
||||
{/if}
|
||||
<Tooltip
|
||||
|
||||
@@ -922,7 +922,9 @@
|
||||
bind:seconds={$values[setting.key]}
|
||||
/>
|
||||
</div>
|
||||
{:else if setting.fieldType == 'select'}{/if}
|
||||
{:else if setting.fieldType == 'select'}
|
||||
TODO
|
||||
{/if}
|
||||
{#if hasError}
|
||||
<span class="text-red-500 dark:text-red-400 text-sm">
|
||||
{setting.error ?? ''}
|
||||
|
||||
@@ -1,659 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { setInputCat as computeInputCat, emptyString, getSchemaFromProperties } from '$lib/utils'
|
||||
import { Button } from './common'
|
||||
import { createEventDispatcher, tick } from 'svelte'
|
||||
import FieldHeader from './FieldHeader.svelte'
|
||||
import type { EnumType, SchemaProperty } from '$lib/common'
|
||||
import autosize from '$lib/autosize'
|
||||
import Toggle from './Toggle.svelte'
|
||||
import Range from './Range.svelte'
|
||||
import LightweightSchemaForm from './LightweightSchemaForm.svelte'
|
||||
import type { ComponentCustomCSS } from './apps/types'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { fade } from 'svelte/transition'
|
||||
import { Plus, X } from 'lucide-svelte'
|
||||
import LightweightResourcePicker from './LightweightResourcePicker.svelte'
|
||||
import LightweightObjectResourceInput from './LightweightObjectResourceInput.svelte'
|
||||
import DateTimeInput from './DateTimeInput.svelte'
|
||||
import DateInput from './DateInput.svelte'
|
||||
import CurrencyInput from './apps/components/inputs/currency/CurrencyInput.svelte'
|
||||
import Multiselect from 'svelte-multiselect'
|
||||
import Password from './Password.svelte'
|
||||
import ToggleButton from './common/toggleButton-v2/ToggleButton.svelte'
|
||||
import ToggleButtonGroup from './common/toggleButton-v2/ToggleButtonGroup.svelte'
|
||||
import FileUpload from './common/fileUpload/FileUpload.svelte'
|
||||
import { deepEqual } from 'fast-equals'
|
||||
|
||||
export let css: ComponentCustomCSS<'schemaformcomponent'> | undefined = undefined
|
||||
export let label: string = ''
|
||||
export let value: any
|
||||
|
||||
export let defaultValue: any = undefined
|
||||
|
||||
export let description: string = ''
|
||||
export let format: string = ''
|
||||
export let contentEncoding: 'base64' | 'binary' | undefined = undefined
|
||||
export let type: string | undefined = undefined
|
||||
export let oneOf: SchemaProperty[] | undefined = undefined
|
||||
export let required = false
|
||||
//todo
|
||||
// export let nullable = false
|
||||
export let disabled: boolean = false
|
||||
export let pattern: undefined | string = undefined
|
||||
export let valid = required ? false : true
|
||||
export let enum_: EnumType = undefined
|
||||
export let itemsType:
|
||||
| {
|
||||
type?: 'string' | 'number' | 'bytes' | 'object' | 'resource'
|
||||
contentEncoding?: 'base64'
|
||||
enum?: string[]
|
||||
multiselect?: string[]
|
||||
resourceType?: string
|
||||
properties?: { [name: string]: SchemaProperty }
|
||||
}
|
||||
| undefined = undefined
|
||||
export let displayHeader = true
|
||||
export let properties: { [name: string]: SchemaProperty } | undefined = undefined
|
||||
export let nestedRequired: string[] | undefined = undefined
|
||||
export let extra: Record<string, any> = {}
|
||||
export let displayType: boolean = true
|
||||
export let customErrorMessage: string | undefined = undefined
|
||||
export let render = true
|
||||
export let title: string | undefined = undefined
|
||||
export let placeholder: string | undefined = undefined
|
||||
export let appPath: string | undefined = undefined
|
||||
export let computeS3ForceViewerPolicies:
|
||||
| (() =>
|
||||
| {
|
||||
allowed_resources: string[]
|
||||
allow_user_resources: boolean
|
||||
allow_workspace_resource: boolean
|
||||
file_key_regex: string
|
||||
}
|
||||
| undefined)
|
||||
| undefined = undefined
|
||||
export let workspace: string | undefined = undefined
|
||||
|
||||
let oneOfSelected: string | undefined = undefined
|
||||
async function updateOneOfSelected(oneOf: SchemaProperty[] | undefined) {
|
||||
if (
|
||||
oneOf &&
|
||||
oneOf.length >= 2 &&
|
||||
(!oneOfSelected || !oneOf.some((o) => o.title === oneOfSelected))
|
||||
) {
|
||||
if (value && value['label'] && oneOf.some((o) => o.title === value['label'])) {
|
||||
const existingValue = JSON.parse(JSON.stringify(value))
|
||||
oneOfSelected = value['label']
|
||||
await tick()
|
||||
value = existingValue
|
||||
} else {
|
||||
oneOfSelected = oneOf[0]['title']
|
||||
}
|
||||
}
|
||||
}
|
||||
$: updateOneOfSelected(oneOf)
|
||||
function updateOneOfSelectedValue(oneOfSelected) {
|
||||
if (oneOfSelected) {
|
||||
value = { label: oneOfSelected }
|
||||
}
|
||||
}
|
||||
$: updateOneOfSelectedValue(oneOfSelected)
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
export let error: string = ''
|
||||
|
||||
let el: HTMLTextAreaElement | undefined = undefined
|
||||
|
||||
let rawValue: string | undefined = undefined
|
||||
|
||||
$: inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncoding)
|
||||
|
||||
$: render && changeDefaultValue(inputCat, defaultValue)
|
||||
|
||||
$: (rawValue || inputCat === 'object') && evalRawValueToValue()
|
||||
|
||||
$: validateInput(pattern, value, required)
|
||||
|
||||
function evalRawValueToValue() {
|
||||
if (!rawValue || rawValue === '') {
|
||||
value = undefined
|
||||
error = ''
|
||||
} else {
|
||||
try {
|
||||
value = JSON.parse(rawValue)
|
||||
error = ''
|
||||
} catch (err) {
|
||||
error = err.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only used for object inputCat
|
||||
export function evalValueToRaw() {
|
||||
if (value) {
|
||||
rawValue = JSON.stringify(value, null, 4)
|
||||
} else {
|
||||
// If value is undefined, set rawValue to empty object
|
||||
// This is to prevent the textarea from being empty
|
||||
rawValue = ''
|
||||
}
|
||||
}
|
||||
|
||||
function fileChanged(e: any, cb: (v: string | undefined) => void) {
|
||||
let t = e.target
|
||||
if (t && 'files' in t && t.files.length > 0) {
|
||||
let reader = new FileReader()
|
||||
reader.onload = (e: any) => {
|
||||
cb(e.target.result.split('base64,')[1])
|
||||
}
|
||||
reader.readAsDataURL(t.files[0])
|
||||
} else {
|
||||
cb(undefined)
|
||||
}
|
||||
}
|
||||
|
||||
export function focus() {
|
||||
el?.focus()
|
||||
if (el) {
|
||||
el.style.height = '5px'
|
||||
el.style.height = el.scrollHeight + 50 + 'px'
|
||||
}
|
||||
}
|
||||
|
||||
function validateInput(pattern: string | undefined, v: any, required: boolean): void {
|
||||
if (!render) {
|
||||
error = ''
|
||||
value = true
|
||||
}
|
||||
if (required && (v == undefined || v == null || v === '')) {
|
||||
error = 'Required'
|
||||
valid && (valid = false)
|
||||
} else {
|
||||
if (!required && (v == undefined || v == null || v === '')) {
|
||||
error = ''
|
||||
!valid && (valid = true)
|
||||
} else {
|
||||
if (pattern && !testRegex(pattern, v)) {
|
||||
if (!emptyString(customErrorMessage)) {
|
||||
error = customErrorMessage ?? ''
|
||||
} else if (format == 'email') {
|
||||
error = 'invalid email address'
|
||||
} else {
|
||||
error = `should match ${pattern}`
|
||||
}
|
||||
valid && (valid = false)
|
||||
} else {
|
||||
error = ''
|
||||
!valid && (valid = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testRegex(pattern: string, value: any): boolean {
|
||||
try {
|
||||
const regex = new RegExp(pattern)
|
||||
return regex.test(value)
|
||||
} catch (err) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
let prevDefaultValue: any = undefined
|
||||
let defaultChange = 0
|
||||
|
||||
async function changeDefaultValue(inputCat, defaultValue) {
|
||||
if (
|
||||
value == null ||
|
||||
value == undefined ||
|
||||
deepEqual(value, prevDefaultValue) ||
|
||||
(prevDefaultValue != undefined && !deepEqual(defaultValue, prevDefaultValue))
|
||||
) {
|
||||
value = defaultValue
|
||||
defaultChange += 1
|
||||
}
|
||||
prevDefaultValue = structuredClone(defaultValue)
|
||||
|
||||
if (value == null || value == undefined) {
|
||||
if (defaultValue === undefined || defaultValue === null) {
|
||||
if (inputCat === 'string') {
|
||||
value = ''
|
||||
} else if (inputCat == 'enum' && required) {
|
||||
value = enum_?.[0]
|
||||
} else if (inputCat == 'boolean') {
|
||||
value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inputCat === 'object') {
|
||||
evalValueToRaw()
|
||||
}
|
||||
}
|
||||
|
||||
$: render == false && onRenderFalse()
|
||||
|
||||
function onRenderFalse() {
|
||||
value = undefined
|
||||
valid = true
|
||||
error = ''
|
||||
}
|
||||
|
||||
function addItemByItemsType() {
|
||||
if (value == undefined || !Array.isArray(value)) {
|
||||
value = []
|
||||
}
|
||||
|
||||
if (itemsType?.type === 'object') {
|
||||
value = value.concat({})
|
||||
} else {
|
||||
value = value.concat('')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if render}
|
||||
<div class="flex flex-col w-full min-w-[250px]">
|
||||
<div>
|
||||
{#if displayHeader}
|
||||
<FieldHeader
|
||||
prettify={emptyString(title)}
|
||||
label={title && !emptyString(title) ? title : label}
|
||||
{required}
|
||||
{type}
|
||||
{contentEncoding}
|
||||
{format}
|
||||
{displayType}
|
||||
labelClass={css?.label?.class}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if description}
|
||||
<div class={twMerge('text-xs italic pb-1', css?.description?.class)}>
|
||||
<pre class="font-main whitespace-normal">{description}</pre>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="flex space-x-1">
|
||||
{#if inputCat == 'number'}
|
||||
{#if extra['min'] != undefined && extra['max'] != undefined}
|
||||
<Range bind:value min={extra['min']} max={extra['max']} {defaultValue} {disabled} />
|
||||
{:else if extra?.currency}
|
||||
<CurrencyInput
|
||||
inputClasses={{
|
||||
formatted: 'px-2 w-full py-1.5 text-black dark:text-white',
|
||||
wrapper: 'w-full windmillapp',
|
||||
formattedZero: 'text-black dark:text-white'
|
||||
}}
|
||||
noColor
|
||||
bind:value
|
||||
currency={extra?.currency}
|
||||
locale={extra?.currencyLocale ?? 'en-US'}
|
||||
{disabled}
|
||||
/>
|
||||
{:else}
|
||||
<input
|
||||
on:focus={(e) => {
|
||||
dispatch('focus')
|
||||
}}
|
||||
type="number"
|
||||
class={valid && error == ''
|
||||
? ''
|
||||
: 'border !border-red-700 !border-opacity-70 focus:!border-red-700 focus:!border-opacity-30'}
|
||||
placeholder={placeholder ?? defaultValue ?? ''}
|
||||
bind:value
|
||||
min={extra['min']}
|
||||
max={extra['max']}
|
||||
{disabled}
|
||||
/>
|
||||
{/if}
|
||||
{:else if inputCat == 'boolean'}
|
||||
<div class="w-full">
|
||||
<Toggle
|
||||
on:pointerdown={(e) => {
|
||||
e?.stopPropagation()
|
||||
}}
|
||||
class={valid && error == ''
|
||||
? ''
|
||||
: 'border !border-red-700 !border-opacity-70 focus:!border-red-700 focus:!border-opacity-30'}
|
||||
bind:checked={value}
|
||||
{disabled}
|
||||
/>
|
||||
{#if type == 'boolean' && value == undefined}
|
||||
<span> Not set</span>
|
||||
{/if}
|
||||
</div>
|
||||
{:else if inputCat == 'list'}
|
||||
<div class="w-full">
|
||||
{#if Array.isArray(itemsType?.multiselect) && Array.isArray(value)}
|
||||
<div class="items-start">
|
||||
<Multiselect
|
||||
ulOptionsClass={'!bg-surface-secondary'}
|
||||
bind:selected={value}
|
||||
options={itemsType?.multiselect ?? []}
|
||||
selectedOptionsDraggable={true}
|
||||
{disabled}
|
||||
--sms-open-z-index={20}
|
||||
/>
|
||||
</div>
|
||||
{:else if Array.isArray(itemsType?.enum) && Array.isArray(value)}
|
||||
<div class="items-start">
|
||||
<Multiselect
|
||||
ulOptionsClass={'!bg-surface-secondary'}
|
||||
bind:selected={value}
|
||||
options={itemsType?.enum ?? []}
|
||||
selectedOptionsDraggable={true}
|
||||
{disabled}
|
||||
--sms-open-z-index={20}
|
||||
/>
|
||||
</div>
|
||||
{:else if Array.isArray(enum_) && Array.isArray(value)}
|
||||
<div class="items-start">
|
||||
<Multiselect
|
||||
ulOptionsClass={'!bg-surface-secondary'}
|
||||
bind:selected={value}
|
||||
options={enum_ ?? []}
|
||||
selectedOptionsDraggable={true}
|
||||
{disabled}
|
||||
--sms-open-z-index={20}
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="w-full">
|
||||
{#if Array.isArray(value)}
|
||||
{#each value ?? [] as v, i}
|
||||
<div class="flex flex-row max-w-md mt-1 w-full">
|
||||
{#if itemsType?.type == 'number'}
|
||||
<input type="number" bind:value={v} {disabled} />
|
||||
{:else if itemsType?.type == 'string' && itemsType?.contentEncoding == 'base64'}
|
||||
<input
|
||||
type="file"
|
||||
class="my-6"
|
||||
on:change={(x) => fileChanged(x, (val) => (value[i] = val))}
|
||||
multiple={false}
|
||||
{disabled}
|
||||
/>
|
||||
{:else if Array.isArray(itemsType?.enum)}
|
||||
<select
|
||||
on:focus={(e) => {
|
||||
dispatch('focus')
|
||||
}}
|
||||
class="px-6"
|
||||
bind:value={v}
|
||||
{disabled}
|
||||
>
|
||||
{#each itemsType?.enum ?? [] as e}
|
||||
<option>{e}</option>
|
||||
{/each}
|
||||
</select>
|
||||
{:else if itemsType?.type == 'resource' && itemsType?.resourceType}
|
||||
<LightweightResourcePicker
|
||||
bind:value={v}
|
||||
resourceType={itemsType?.resourceType}
|
||||
{disabled}
|
||||
/>
|
||||
{:else if itemsType?.type === 'object' && itemsType?.properties}
|
||||
<div class="p-8 border rounded-md w-full">
|
||||
<LightweightSchemaForm
|
||||
schema={getSchemaFromProperties(itemsType?.properties)}
|
||||
bind:args={v}
|
||||
{disabled}
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<input type="text" bind:value={v} {disabled} />
|
||||
{/if}
|
||||
<button
|
||||
transition:fade|local={{ duration: 100 }}
|
||||
class="rounded-full p-1 bg-surface-secondary duration-200 hover:bg-surface-hover ml-2 flex items-center h-6"
|
||||
aria-label="Clear"
|
||||
on:click={() => {
|
||||
value = value.filter((el) => el != v)
|
||||
if (value.length == 0) {
|
||||
value = undefined
|
||||
}
|
||||
}}
|
||||
{disabled}
|
||||
>
|
||||
<X size={14} />
|
||||
</button>
|
||||
</div>
|
||||
{/each}
|
||||
{:else if value != undefined}
|
||||
List is not an array
|
||||
{/if}
|
||||
</div>
|
||||
<div class="flex my-2">
|
||||
<Button
|
||||
variant="border"
|
||||
color="light"
|
||||
size="sm"
|
||||
btnClasses="mt-1"
|
||||
on:click={() => {
|
||||
addItemByItemsType()
|
||||
}}
|
||||
startIcon={{ icon: Plus }}
|
||||
{disabled}
|
||||
>
|
||||
Add
|
||||
</Button>
|
||||
</div>
|
||||
<span class="ml-2">
|
||||
{(value ?? []).length} item{(value ?? []).length != 1 ? 's' : ''}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
{:else if inputCat == 'resource-object' && format.split('-').length > 1 && format
|
||||
.replace('resource-', '')
|
||||
.replace('_', '')
|
||||
.toLowerCase() == 's3object'}
|
||||
<div class="flex flex-col w-full gap-1">
|
||||
<FileUpload
|
||||
{appPath}
|
||||
computeForceViewerPolicies={computeS3ForceViewerPolicies}
|
||||
{workspace}
|
||||
allowMultiple={false}
|
||||
randomFileKey={true}
|
||||
on:addition={(evt) => {
|
||||
value = {
|
||||
s3: evt.detail?.path ?? '',
|
||||
filename: evt.detail?.filename ?? ''
|
||||
}
|
||||
}}
|
||||
on:deletion={(evt) => {
|
||||
value = {
|
||||
s3: ''
|
||||
}
|
||||
}}
|
||||
defaultValue={defaultValue?.s3}
|
||||
/>
|
||||
</div>
|
||||
{:else if inputCat == 'resource-object'}
|
||||
<LightweightObjectResourceInput {format} bind:value {disabled} />
|
||||
{:else if inputCat == 'object' && oneOf && oneOf.length >= 2}
|
||||
<div class="flex flex-col gap-2 w-full">
|
||||
{#if oneOf && oneOf.length >= 2}
|
||||
<ToggleButtonGroup bind:selected={oneOfSelected} {disabled}>
|
||||
{#each oneOf as obj}
|
||||
<ToggleButton value={obj.title} label={obj.title} {disabled} />
|
||||
{/each}
|
||||
</ToggleButtonGroup>
|
||||
|
||||
{#if oneOfSelected}
|
||||
{@const objIdx = oneOf.findIndex((o) => o.title === oneOfSelected)}
|
||||
{@const obj = oneOf[objIdx]}
|
||||
{#if obj && obj.properties && Object.keys(obj.properties).length > 0}
|
||||
<div class="p-4 pl-8 border rounded w-full">
|
||||
<LightweightSchemaForm
|
||||
schema={{
|
||||
...obj,
|
||||
properties: Object.fromEntries(
|
||||
Object.entries(obj.properties).filter(([k, v]) => k !== 'label')
|
||||
),
|
||||
$schema: '',
|
||||
required: obj.required ?? [],
|
||||
type: 'object',
|
||||
order: obj.order ?? []
|
||||
}}
|
||||
bind:args={value}
|
||||
{disabled}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
{:else if inputCat == 'object'}
|
||||
{#if properties && Object.keys(properties).length > 0}
|
||||
<div class="p-4 pl-8 border rounded w-full">
|
||||
<LightweightSchemaForm
|
||||
schema={{
|
||||
properties,
|
||||
$schema: '',
|
||||
required: nestedRequired ?? [],
|
||||
type: 'object'
|
||||
}}
|
||||
bind:args={value}
|
||||
{disabled}
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<textarea
|
||||
bind:this={el}
|
||||
on:focus={(e) => {
|
||||
dispatch('focus')
|
||||
}}
|
||||
use:autosize
|
||||
style="min-height: 5px;"
|
||||
class="col-span-10 !leading-tight !text-2xs {valid && error == ''
|
||||
? ''
|
||||
: '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}
|
||||
{disabled}
|
||||
/>
|
||||
{/if}
|
||||
{:else if inputCat == 'enum'}
|
||||
<select
|
||||
on:focus={(e) => {
|
||||
dispatch('focus')
|
||||
}}
|
||||
class="px-6"
|
||||
bind:value
|
||||
{disabled}
|
||||
>
|
||||
{#each enum_ ?? [] as e}
|
||||
<option value={e}>{extra?.['enumLabels']?.[e] ?? e}</option>
|
||||
{/each}
|
||||
</select>
|
||||
{:else if inputCat == 'date'}
|
||||
{#key defaultChange}
|
||||
{#if format === 'date'}
|
||||
<DateInput bind:value dateFormat={extra['dateFormat']} {disabled} />
|
||||
{:else}
|
||||
<DateTimeInput useDropdown bind:value {disabled} />
|
||||
{/if}
|
||||
{/key}
|
||||
{:else if inputCat == 'base64'}
|
||||
<div class="flex flex-col my-6 w-full">
|
||||
<input
|
||||
type="file"
|
||||
on:change={(x) => fileChanged(x, (val) => (value = val))}
|
||||
multiple={false}
|
||||
{disabled}
|
||||
/>
|
||||
{#if value?.length}
|
||||
<div class="text-2xs text-tertiary mt-1"
|
||||
>File length: {value.length} base64 chars ({(value.length / 1024 / 1024).toFixed(
|
||||
2
|
||||
)}MB)</div
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
{:else if inputCat == 'resource-string'}
|
||||
<div class="flex flex-row gap-x-1 w-full">
|
||||
<LightweightResourcePicker
|
||||
bind:value
|
||||
resourceType={format.split('-').length > 1
|
||||
? format.substring('resource-'.length)
|
||||
: undefined}
|
||||
{disabled}
|
||||
/>
|
||||
</div>
|
||||
{:else if inputCat == 'email'}
|
||||
<input
|
||||
on:focus
|
||||
type="email"
|
||||
class={valid
|
||||
? ''
|
||||
: 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-3'}
|
||||
placeholder={placeholder ?? defaultValue ?? ''}
|
||||
bind:value
|
||||
{disabled}
|
||||
/>
|
||||
{:else if inputCat == 'currency'}
|
||||
<input
|
||||
type="number"
|
||||
class={valid
|
||||
? ''
|
||||
: 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-3'}
|
||||
placeholder={placeholder ?? defaultValue ?? ''}
|
||||
bind:value
|
||||
{disabled}
|
||||
/>
|
||||
{:else if inputCat == 'string'}
|
||||
<div class="flex flex-col w-full">
|
||||
<div class="flex flex-row w-full items-center justify-between">
|
||||
{#if extra?.['password'] == true}
|
||||
<Password bind:password={value} {disabled} />
|
||||
{:else}
|
||||
<textarea
|
||||
rows={extra?.['minRows'] || 1}
|
||||
bind:this={el}
|
||||
on:focus={(e) => {
|
||||
dispatch('focus')
|
||||
}}
|
||||
use:autosize
|
||||
class="col-span-10 {valid && error == ''
|
||||
? ''
|
||||
: 'border !border-red-700 !border-opacity-70 focus:!border-red-700 focus:!border-opacity-30'}"
|
||||
placeholder={placeholder ?? defaultValue ?? ''}
|
||||
bind:value
|
||||
on:pointerdown|stopPropagation={(e) => {
|
||||
dispatch('inputClicked', e)
|
||||
}}
|
||||
{disabled}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<slot name="actions" />
|
||||
</div>
|
||||
{#if error && error != ''}
|
||||
<div class="text-right text-xs text-red-600 dark:text-red-400">
|
||||
{#if error === ''}
|
||||
|
||||
{:else}
|
||||
{error}
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
input::-webkit-outer-spin-button,
|
||||
input::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none !important;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Firefox */
|
||||
input[type='number'] {
|
||||
-moz-appearance: textfield !important;
|
||||
appearance: textfield !important;
|
||||
}
|
||||
</style>
|
||||
@@ -1,46 +0,0 @@
|
||||
<script lang="ts">
|
||||
import LightweightResourcePicker from './LightweightResourcePicker.svelte'
|
||||
|
||||
export let format: string
|
||||
export let value: any
|
||||
export let disablePortal = false
|
||||
export let disabled: boolean = false
|
||||
function isString(value: any) {
|
||||
return typeof value === 'string' || value instanceof String
|
||||
}
|
||||
|
||||
let path: string = ''
|
||||
|
||||
function resourceToValue() {
|
||||
if (path) {
|
||||
value = `$res:${path}`
|
||||
} else {
|
||||
value = undefined
|
||||
}
|
||||
}
|
||||
|
||||
function isResource() {
|
||||
return isString(value) && value.length >= '$res:'.length
|
||||
}
|
||||
|
||||
function valueToPath() {
|
||||
if (isResource()) {
|
||||
path = value.substr('$res:'.length)
|
||||
}
|
||||
}
|
||||
|
||||
$: value && valueToPath()
|
||||
</script>
|
||||
|
||||
<div class="flex flex-row w-full flex-wrap gap-x-2 gap-y-0.5">
|
||||
<LightweightResourcePicker
|
||||
{disabled}
|
||||
{disablePortal}
|
||||
on:change={(e) => {
|
||||
path = e.detail
|
||||
resourceToValue()
|
||||
}}
|
||||
bind:value={path}
|
||||
resourceType={format.split('-').length > 1 ? format.substring('resource-'.length) : undefined}
|
||||
/>
|
||||
</div>
|
||||
@@ -1,125 +0,0 @@
|
||||
<script lang="ts">
|
||||
import type { Schema } from '$lib/common'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import LightweightArgInput from './LightweightArgInput.svelte'
|
||||
import type { ComponentCustomCSS } from './apps/types'
|
||||
import { allTrue, computeShow } from '$lib/utils'
|
||||
import { deepEqual } from 'fast-equals'
|
||||
|
||||
export let css: ComponentCustomCSS<'schemaformcomponent'> | undefined = undefined
|
||||
|
||||
export let schema: Schema | Record<string, any>
|
||||
export let args: Record<string, any> | undefined = undefined
|
||||
export let displayType: boolean = true
|
||||
export let largeGap: boolean = false
|
||||
export let isValid: boolean = true
|
||||
export let defaultValues: Record<string, any> = {}
|
||||
export let dynamicEnums: Record<string, any> = {}
|
||||
export let disabled: boolean = false
|
||||
export let appPath: string | undefined = undefined
|
||||
export let computeS3ForceViewerPolicies:
|
||||
| (() =>
|
||||
| {
|
||||
allowed_resources: string[]
|
||||
allow_user_resources: boolean
|
||||
allow_workspace_resource: boolean
|
||||
file_key_regex: string
|
||||
}
|
||||
| undefined)
|
||||
| undefined = undefined
|
||||
export let workspace: string | undefined = undefined
|
||||
|
||||
let inputCheck: { [id: string]: boolean } = {}
|
||||
let errors: { [id: string]: string } = {}
|
||||
|
||||
$: isValid = allTrue(inputCheck) ?? false
|
||||
|
||||
$: if (args === undefined) {
|
||||
args = {}
|
||||
}
|
||||
|
||||
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], '']))
|
||||
}
|
||||
|
||||
let keys: string[] = Array.isArray(schema?.order)
|
||||
? schema?.order
|
||||
: Object.keys(schema?.properties ?? {})
|
||||
|
||||
$: schema && reorder()
|
||||
|
||||
function reorder() {
|
||||
let lkeys = Object.keys(schema?.properties ?? {})
|
||||
if (!deepEqual(schema?.order, lkeys) || !deepEqual(keys, lkeys)) {
|
||||
console.debug('reorder')
|
||||
if (schema?.order && Array.isArray(schema.order)) {
|
||||
const n = {}
|
||||
|
||||
;(schema.order as string[]).forEach((x) => {
|
||||
if (schema.properties && schema.properties[x] != undefined) {
|
||||
n[x] = schema.properties[x]
|
||||
}
|
||||
})
|
||||
|
||||
Object.keys(schema.properties ?? {})
|
||||
.filter((x) => !schema.order?.includes(x))
|
||||
.forEach((x) => {
|
||||
n[x] = schema.properties[x]
|
||||
})
|
||||
schema.properties = n
|
||||
}
|
||||
keys = Object.keys(schema.properties ?? {})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={twMerge('w-full flex flex-col px-0.5 pb-2', largeGap ? 'gap-8' : 'gap-2')}
|
||||
on:pointerdown
|
||||
>
|
||||
{#each keys as argName (argName)}
|
||||
{#if typeof args == 'object' && schema?.properties[argName] && args}
|
||||
<LightweightArgInput
|
||||
render={computeShow(argName, schema?.properties[argName].showExpr, args)}
|
||||
label={argName}
|
||||
description={schema.properties[argName].description}
|
||||
bind:value={args[argName]}
|
||||
bind:valid={inputCheck[argName]}
|
||||
bind:error={errors[argName]}
|
||||
type={schema.properties[argName].type}
|
||||
oneOf={schema.properties[argName].oneOf}
|
||||
required={schema.required?.includes(argName) ?? false}
|
||||
pattern={schema.properties[argName].pattern}
|
||||
defaultValue={defaultValues?.[argName] ?? schema.properties[argName].default}
|
||||
enum_={dynamicEnums?.[argName] ?? schema.properties[argName].enum}
|
||||
format={schema.properties[argName].format}
|
||||
contentEncoding={schema.properties[argName].contentEncoding}
|
||||
customErrorMessage={schema.properties[argName].customErrorMessage}
|
||||
properties={schema.properties[argName].properties}
|
||||
nestedRequired={schema.properties[argName].required}
|
||||
itemsType={schema.properties[argName].items}
|
||||
extra={schema.properties[argName]}
|
||||
title={schema.properties[argName].title}
|
||||
placeholder={schema.properties[argName].placeholder}
|
||||
on:inputClicked
|
||||
{displayType}
|
||||
{css}
|
||||
disabled={disabled || schema.properties[argName].disabled}
|
||||
{appPath}
|
||||
{computeS3ForceViewerPolicies}
|
||||
{workspace}
|
||||
/>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
@@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
import JsonEditor from './apps/editor/settingsPanel/inputEditor/JsonEditor.svelte'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
import ResourcePicker from './ResourcePicker.svelte'
|
||||
import S3ObjectPicker from './S3ObjectPicker.svelte'
|
||||
import SimpleEditor from './SimpleEditor.svelte'
|
||||
import type SimpleEditor from './SimpleEditor.svelte'
|
||||
|
||||
export let format: string
|
||||
export let value: any
|
||||
@@ -58,6 +58,10 @@
|
||||
{showSchemaExplorer}
|
||||
/>
|
||||
{:else}
|
||||
<JsonEditor bind:editor code={JSON.stringify(value, null, 2)} bind:value />
|
||||
{#await import('$lib/components/JsonEditor.svelte')}
|
||||
<Loader2 class="animate-spin" />
|
||||
{:then Module}
|
||||
<Module.default bind:editor code={JSON.stringify(value, null, 2)} bind:value />
|
||||
{/await}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
import Select from './apps/svelte-select/lib/index'
|
||||
import { SELECT_INPUT_DEFAULT_STYLE } from '../defaults'
|
||||
import AppConnect from './AppConnectDrawer.svelte'
|
||||
import ResourceEditorDrawer from './ResourceEditorDrawer.svelte'
|
||||
|
||||
import { Button } from './common'
|
||||
import DBSchemaExplorer from './DBSchemaExplorer.svelte'
|
||||
import DarkModeObserver from './DarkModeObserver.svelte'
|
||||
import { Pen, Plus, RotateCw } from 'lucide-svelte'
|
||||
import ResourceEditorDrawer from './ResourceEditorDrawer.svelte'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
@@ -120,7 +121,6 @@
|
||||
bind:this={appConnect}
|
||||
{expressOAuthSetup}
|
||||
/>
|
||||
|
||||
<ResourceEditorDrawer
|
||||
bind:this={resourceEditor}
|
||||
on:refresh={async (e) => {
|
||||
@@ -195,7 +195,7 @@
|
||||
{disabled}
|
||||
color="light"
|
||||
variant="border"
|
||||
size="xs"
|
||||
size="sm"
|
||||
on:click={() => appConnect?.open?.(resourceType)}
|
||||
startIcon={{ icon: Plus }}
|
||||
iconOnly={collection?.length > 0}
|
||||
@@ -203,6 +203,7 @@
|
||||
Add a {resourceType} resource
|
||||
{/if}</Button
|
||||
>
|
||||
<div class="mx-0.5" />
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { Pipette } from 'lucide-svelte'
|
||||
import { Loader2, Pipette } from 'lucide-svelte'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
// @ts-ignore
|
||||
import SimpleEditor from './SimpleEditor.svelte'
|
||||
import type SimpleEditor from './SimpleEditor.svelte'
|
||||
|
||||
import JsonEditor from './apps/editor/settingsPanel/inputEditor/JsonEditor.svelte'
|
||||
import { Button } from './common'
|
||||
|
||||
import Toggle from './Toggle.svelte'
|
||||
@@ -55,14 +54,18 @@
|
||||
options={{ left: 'Raw S3 object input' }}
|
||||
/>
|
||||
{#if s3FileUploadRawMode}
|
||||
<JsonEditor
|
||||
bind:editor
|
||||
on:focus={(e) => {
|
||||
dispatch('focus')
|
||||
}}
|
||||
code={JSON.stringify(value ?? { s3: '' }, null, 2)}
|
||||
bind:value
|
||||
/>
|
||||
{#await import('$lib/components/JsonEditor.svelte')}
|
||||
<Loader2 class="animate-spin" />
|
||||
{:then Module}
|
||||
<Module.default
|
||||
bind:editor
|
||||
on:focus={(e) => {
|
||||
dispatch('focus')
|
||||
}}
|
||||
code={JSON.stringify(value ?? { s3: '' }, null, 2)}
|
||||
bind:value
|
||||
/>
|
||||
{/await}
|
||||
<Button
|
||||
variant="border"
|
||||
color="light"
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
import { Plus } from 'lucide-svelte'
|
||||
import ArgInput from './ArgInput.svelte'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import LightweightArgInput from './LightweightArgInput.svelte'
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import { dragHandleZone, type Options as DndOptions } from '@windmill-labs/svelte-dnd-action'
|
||||
import type { SchemaDiff } from '$lib/components/schema/schemaUtils'
|
||||
import type { ComponentCustomCSS } from './apps/types'
|
||||
|
||||
export let schema: Schema | any
|
||||
export let schemaSkippedValues: string[] = []
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
export let isValid: boolean = true
|
||||
export let autofocus = false
|
||||
export let defaultValues: Record<string, any> = {}
|
||||
|
||||
export let shouldHideNoInputs: boolean = false
|
||||
export let compact = false
|
||||
@@ -39,7 +40,6 @@
|
||||
export let showSchemaExplorer = false
|
||||
export let showReset = false
|
||||
export let onlyMaskPassword = false
|
||||
export let lightweightMode: boolean = false
|
||||
export let dndConfig: DndOptions | undefined = undefined
|
||||
export let items: { id: string; value: string }[] | undefined = undefined
|
||||
export let helperScript:
|
||||
@@ -51,6 +51,24 @@
|
||||
export let nestedParent: { label: string; nestedParent: any | undefined } | undefined = undefined
|
||||
export let shouldDispatchChanges = false
|
||||
export let nestedClasses = ''
|
||||
export let dynamicEnums: Record<string, any> = {}
|
||||
export let largeGap: boolean = false
|
||||
export let css: ComponentCustomCSS<'schemaformcomponent'> | undefined = undefined
|
||||
export let displayType: boolean = true
|
||||
|
||||
export let appPath: string | undefined = undefined
|
||||
|
||||
export let computeS3ForceViewerPolicies:
|
||||
| (() =>
|
||||
| {
|
||||
allowed_resources: string[]
|
||||
allow_user_resources: boolean
|
||||
allow_workspace_resource: boolean
|
||||
file_key_regex: string
|
||||
}
|
||||
| undefined)
|
||||
| undefined = undefined
|
||||
export let workspace: string | undefined = undefined
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
@@ -61,7 +79,7 @@
|
||||
}
|
||||
|
||||
export function setDefaults() {
|
||||
const nargs = {}
|
||||
const nargs = structuredClone(defaultValues)
|
||||
|
||||
Object.keys(schema?.properties ?? {}).forEach((key) => {
|
||||
if (schema?.properties[key].default != undefined && args[key] == undefined) {
|
||||
@@ -204,8 +222,8 @@
|
||||
required={formerProperty?.required}
|
||||
pattern={formerProperty?.pattern}
|
||||
valid={inputCheck[argName]}
|
||||
defaultValue={structuredClone(formerProperty?.default)}
|
||||
enum_={formerProperty?.enum}
|
||||
defaultValue={defaultValues?.[argName] ?? structuredClone(formerProperty?.default)}
|
||||
enum_={dynamicEnums?.[argName] ?? formerProperty?.enum}
|
||||
format={formerProperty?.format}
|
||||
contentEncoding={formerProperty?.contentEncoding}
|
||||
customErrorMessage={formerProperty?.customErrorMessage}
|
||||
@@ -232,164 +250,117 @@
|
||||
{lightHeader}
|
||||
hideNested={typeof diff[argName].diff === 'object'}
|
||||
diffStatus={undefined}
|
||||
{appPath}
|
||||
{computeS3ForceViewerPolicies}
|
||||
{workspace}
|
||||
{css}
|
||||
{displayType}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<div
|
||||
class="flex flex-row items-center"
|
||||
class="flex flex-row items-center {largeGap ? 'pb-4' : ''} "
|
||||
on:click={() => {
|
||||
dispatch('click', argName)
|
||||
}}
|
||||
>
|
||||
{#if typeof args == 'object' && schema?.properties[argName]}
|
||||
{#if !hidden[argName]}
|
||||
{#if lightweightMode}
|
||||
<LightweightArgInput
|
||||
label={argName}
|
||||
description={schema.properties[argName].description}
|
||||
bind:value={args[argName]}
|
||||
type={schema.properties[argName].type}
|
||||
oneOf={schema.properties[argName].oneOf}
|
||||
required={schema?.required?.includes(argName)}
|
||||
pattern={schema.properties[argName].pattern}
|
||||
bind:valid={inputCheck[argName]}
|
||||
defaultValue={structuredClone(schema.properties[argName].default)}
|
||||
enum_={schema.properties[argName].enum}
|
||||
format={schema.properties[argName].format}
|
||||
contentEncoding={schema.properties[argName].contentEncoding}
|
||||
customErrorMessage={schema.properties[argName].customErrorMessage}
|
||||
bind:properties={schema.properties[argName].properties}
|
||||
nestedRequired={schema.properties[argName]?.required}
|
||||
itemsType={schema.properties[argName].items}
|
||||
extra={schema.properties[argName]}
|
||||
title={schema.properties[argName].title}
|
||||
placeholder={schema.properties[argName].placeholder}
|
||||
disabled={disabledArgs.includes(argName) ||
|
||||
disabled ||
|
||||
schema.properties[argName].disabled}
|
||||
<ArgInput
|
||||
on:change={() => {
|
||||
dispatch('change')
|
||||
}}
|
||||
on:nestedChange={() => {
|
||||
dispatch('nestedChange')
|
||||
}}
|
||||
on:acceptChange={(e) => dispatch('acceptChange', e.detail)}
|
||||
on:rejectChange={(e) => dispatch('rejectChange', e.detail)}
|
||||
{disablePortal}
|
||||
{resourceTypes}
|
||||
{prettifyHeader}
|
||||
autofocus={i == 0 && autofocus ? true : null}
|
||||
label={argName}
|
||||
description={schema.properties[argName].description}
|
||||
bind:value={args[argName]}
|
||||
type={schema.properties[argName].type}
|
||||
oneOf={schema.properties[argName].oneOf}
|
||||
required={schema?.required?.includes(argName)}
|
||||
pattern={schema.properties[argName].pattern}
|
||||
bind:valid={inputCheck[argName]}
|
||||
defaultValue={defaultValues?.[argName] ??
|
||||
structuredClone(schema.properties[argName].default)}
|
||||
enum_={dynamicEnums?.[argName] ?? schema.properties[argName].enum}
|
||||
format={schema.properties[argName].format}
|
||||
contentEncoding={schema.properties[argName].contentEncoding}
|
||||
customErrorMessage={schema.properties[argName].customErrorMessage}
|
||||
bind:properties={schema.properties[argName].properties}
|
||||
bind:order={schema.properties[argName].order}
|
||||
nestedRequired={schema.properties[argName]?.required}
|
||||
itemsType={schema.properties[argName].items}
|
||||
disabled={disabledArgs.includes(argName) ||
|
||||
disabled ||
|
||||
schema.properties[argName].disabled}
|
||||
{compact}
|
||||
{variableEditor}
|
||||
{itemPicker}
|
||||
bind:pickForField
|
||||
password={linkedSecret == argName}
|
||||
extra={schema.properties[argName]}
|
||||
{showSchemaExplorer}
|
||||
simpleTooltip={schemaFieldTooltip[argName]}
|
||||
{onlyMaskPassword}
|
||||
nullable={schema.properties[argName].nullable}
|
||||
title={schema.properties[argName].title}
|
||||
placeholder={schema.properties[argName].placeholder}
|
||||
orderEditable={dndConfig != undefined}
|
||||
otherArgs={args}
|
||||
{helperScript}
|
||||
{lightHeader}
|
||||
diffStatus={diff[argName] ?? undefined}
|
||||
{nestedParent}
|
||||
{shouldDispatchChanges}
|
||||
{nestedClasses}
|
||||
{appPath}
|
||||
{computeS3ForceViewerPolicies}
|
||||
{workspace}
|
||||
{css}
|
||||
{displayType}
|
||||
>
|
||||
<svelte:fragment slot="actions">
|
||||
<slot name="actions" />
|
||||
{#if linkedSecretCandidates?.includes(argName)}
|
||||
<div>
|
||||
<ToggleButtonGroup
|
||||
selected={linkedSecret == argName}
|
||||
on:selected={(e) => {
|
||||
if (e.detail) {
|
||||
linkedSecret = argName
|
||||
} else if (linkedSecret == argName) {
|
||||
linkedSecret = undefined
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ToggleButton
|
||||
value={false}
|
||||
size="sm"
|
||||
label="Inlined"
|
||||
tooltip="The value is inlined in the resource and thus has no special treatment."
|
||||
/>
|
||||
<ToggleButton
|
||||
position="right"
|
||||
value={true}
|
||||
size="sm"
|
||||
label="Secret"
|
||||
tooltip="The value will be stored in a newly created linked secret variable at the same path. That variable can be permissioned differently, will be treated as a secret the UI, operators will not be able to load it and every access will generate a corresponding audit log."
|
||||
/>
|
||||
</ToggleButtonGroup>
|
||||
</div>{/if}</svelte:fragment
|
||||
>
|
||||
<svelte:fragment slot="actions">
|
||||
<slot name="actions" />
|
||||
{#if linkedSecretCandidates?.includes(argName)}
|
||||
<div>
|
||||
<ToggleButtonGroup
|
||||
selected={linkedSecret == argName}
|
||||
on:selected={(e) => {
|
||||
if (e.detail) {
|
||||
linkedSecret = argName
|
||||
} else if (linkedSecret == argName) {
|
||||
linkedSecret = undefined
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ToggleButton
|
||||
value={false}
|
||||
size="sm"
|
||||
label="Inlined"
|
||||
tooltip="The value is inlined in the resource and thus has no special treatment."
|
||||
/>
|
||||
<ToggleButton
|
||||
position="right"
|
||||
value={true}
|
||||
size="sm"
|
||||
label="Secret"
|
||||
tooltip="The value will be stored in a newly created linked secret variable at the same path. That variable can be permissioned differently, will be treated as a secret the UI, operators will not be able to load it and every access will generate a corresponding audit log."
|
||||
/>
|
||||
</ToggleButtonGroup>
|
||||
</div>{/if}
|
||||
</svelte:fragment>
|
||||
</LightweightArgInput>
|
||||
{:else}
|
||||
<ArgInput
|
||||
on:change={() => {
|
||||
dispatch('change')
|
||||
}}
|
||||
on:nestedChange={() => {
|
||||
dispatch('nestedChange')
|
||||
}}
|
||||
on:acceptChange={(e) => dispatch('acceptChange', e.detail)}
|
||||
on:rejectChange={(e) => dispatch('rejectChange', e.detail)}
|
||||
{disablePortal}
|
||||
{resourceTypes}
|
||||
{prettifyHeader}
|
||||
autofocus={i == 0 && autofocus ? true : null}
|
||||
label={argName}
|
||||
description={schema.properties[argName].description}
|
||||
bind:value={args[argName]}
|
||||
type={schema.properties[argName].type}
|
||||
oneOf={schema.properties[argName].oneOf}
|
||||
required={schema?.required?.includes(argName)}
|
||||
pattern={schema.properties[argName].pattern}
|
||||
bind:valid={inputCheck[argName]}
|
||||
defaultValue={structuredClone(schema.properties[argName].default)}
|
||||
enum_={schema.properties[argName].enum}
|
||||
format={schema.properties[argName].format}
|
||||
contentEncoding={schema.properties[argName].contentEncoding}
|
||||
customErrorMessage={schema.properties[argName].customErrorMessage}
|
||||
bind:properties={schema.properties[argName].properties}
|
||||
bind:order={schema.properties[argName].order}
|
||||
nestedRequired={schema.properties[argName]?.required}
|
||||
itemsType={schema.properties[argName].items}
|
||||
disabled={disabledArgs.includes(argName) ||
|
||||
disabled ||
|
||||
schema.properties[argName].disabled}
|
||||
{compact}
|
||||
{variableEditor}
|
||||
{itemPicker}
|
||||
bind:pickForField
|
||||
password={linkedSecret == argName}
|
||||
extra={schema.properties[argName]}
|
||||
{showSchemaExplorer}
|
||||
simpleTooltip={schemaFieldTooltip[argName]}
|
||||
{onlyMaskPassword}
|
||||
nullable={schema.properties[argName].nullable}
|
||||
title={schema.properties[argName].title}
|
||||
placeholder={schema.properties[argName].placeholder}
|
||||
orderEditable={dndConfig != undefined}
|
||||
otherArgs={args}
|
||||
{helperScript}
|
||||
{lightHeader}
|
||||
diffStatus={diff[argName] ?? undefined}
|
||||
{nestedParent}
|
||||
{shouldDispatchChanges}
|
||||
{nestedClasses}
|
||||
>
|
||||
<svelte:fragment slot="actions">
|
||||
<slot name="actions" />
|
||||
{#if linkedSecretCandidates?.includes(argName)}
|
||||
<div>
|
||||
<ToggleButtonGroup
|
||||
selected={linkedSecret == argName}
|
||||
on:selected={(e) => {
|
||||
if (e.detail) {
|
||||
linkedSecret = argName
|
||||
} else if (linkedSecret == argName) {
|
||||
linkedSecret = undefined
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ToggleButton
|
||||
value={false}
|
||||
size="sm"
|
||||
label="Inlined"
|
||||
tooltip="The value is inlined in the resource and thus has no special treatment."
|
||||
/>
|
||||
<ToggleButton
|
||||
position="right"
|
||||
value={true}
|
||||
size="sm"
|
||||
label="Secret"
|
||||
tooltip="The value will be stored in a newly created linked secret variable at the same path. That variable can be permissioned differently, will be treated as a secret the UI, operators will not be able to load it and every access will generate a corresponding audit log."
|
||||
/>
|
||||
</ToggleButtonGroup>
|
||||
</div>{/if}</svelte:fragment
|
||||
>
|
||||
</ArgInput>
|
||||
{/if}
|
||||
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
</ArgInput>
|
||||
{/if}
|
||||
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
import DrawerContent from './common/drawer/DrawerContent.svelte'
|
||||
import Alert from './common/alert/Alert.svelte'
|
||||
import Toggle from './Toggle.svelte'
|
||||
import SimpleEditor from './SimpleEditor.svelte'
|
||||
import type SimpleEditor from './SimpleEditor.svelte'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import { canWrite, isOwner } from '$lib/utils'
|
||||
import ToggleButtonGroup from './common/toggleButton-v2/ToggleButtonGroup.svelte'
|
||||
import ToggleButton from './common/toggleButton-v2/ToggleButton.svelte'
|
||||
import Section from './Section.svelte'
|
||||
import { Save } from 'lucide-svelte'
|
||||
import { Loader2, Save } from 'lucide-svelte'
|
||||
import autosize from '$lib/autosize'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
@@ -198,23 +198,31 @@
|
||||
/>
|
||||
{:else if editorKind == 'json'}
|
||||
<div class="border rounded mb-4 w-full">
|
||||
<SimpleEditor
|
||||
bind:this={editor}
|
||||
autoHeight
|
||||
lang="json"
|
||||
bind:code={variable.value}
|
||||
fixedOverflowWidgets={false}
|
||||
/>
|
||||
{#await import('$lib/components/SimpleEditor.svelte')}
|
||||
<Loader2 class="animate-spin" />
|
||||
{:then Module}
|
||||
<Module.default
|
||||
bind:this={editor}
|
||||
autoHeight
|
||||
lang="json"
|
||||
bind:code={variable.value}
|
||||
fixedOverflowWidgets={false}
|
||||
/>
|
||||
{/await}
|
||||
</div>
|
||||
{:else if editorKind == 'yaml'}
|
||||
<div class="border rounded mb-4 w-full">
|
||||
<SimpleEditor
|
||||
bind:this={editor}
|
||||
autoHeight
|
||||
lang="yaml"
|
||||
bind:code={variable.value}
|
||||
fixedOverflowWidgets={false}
|
||||
/>
|
||||
{#await import('$lib/components/SimpleEditor.svelte')}
|
||||
<Loader2 class="animate-spin" />
|
||||
{:then Module}
|
||||
<Module.default
|
||||
bind:this={editor}
|
||||
autoHeight
|
||||
lang="yaml"
|
||||
bind:code={variable.value}
|
||||
fixedOverflowWidgets={false}
|
||||
/>
|
||||
{/await}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
RichConfigurations
|
||||
} from '../../types'
|
||||
import RunnableWrapper from '../helpers/RunnableWrapper.svelte'
|
||||
import LightweightSchemaForm from '$lib/components/LightweightSchemaForm.svelte'
|
||||
import type { Schema } from '$lib/common'
|
||||
import { initCss } from '../../utils'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
@@ -21,6 +20,7 @@
|
||||
import { computeWorkspaceS3FileInputPolicy } from '../../editor/appUtilsS3'
|
||||
import { defaultIfEmptyString } from '$lib/utils'
|
||||
import { userStore } from '$lib/stores'
|
||||
import SchemaForm from '$lib/components/SchemaForm.svelte'
|
||||
|
||||
export let id: string
|
||||
export let componentInput: AppInput | undefined
|
||||
@@ -71,7 +71,7 @@
|
||||
listInputs?.remove(id)
|
||||
})
|
||||
|
||||
let schemaForm: LightweightSchemaForm
|
||||
let schemaForm: SchemaForm
|
||||
|
||||
$componentControl[id] = {
|
||||
setValue(nvalue: any) {
|
||||
@@ -150,7 +150,7 @@
|
||||
on:pointerdown|stopPropagation={(e) =>
|
||||
!$connectingInput.opened && selectId(e, id, selectedComponent, $app)}
|
||||
>
|
||||
<LightweightSchemaForm
|
||||
<SchemaForm
|
||||
defaultValues={resolvedConfig.defaultValues}
|
||||
dynamicEnums={resolvedConfig.dynamicEnums}
|
||||
schema={result}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script lang="ts">
|
||||
import type { Schema, SchemaProperty } from '$lib/common'
|
||||
import LightweightSchemaForm from '$lib/components/LightweightSchemaForm.svelte'
|
||||
import { ColumnIdentity, type ColumnMetadata, type DbType, type ColumnDef } from './utils'
|
||||
|
||||
import init, {
|
||||
@@ -15,6 +14,7 @@
|
||||
init(wasmUrl)
|
||||
|
||||
import { argSigToJsonSchemaType } from '$lib/inferArgSig'
|
||||
import SchemaForm from '$lib/components/SchemaForm.svelte'
|
||||
|
||||
export let args: Record<string, any> = {}
|
||||
export let dbType: DbType = 'postgresql'
|
||||
@@ -156,5 +156,5 @@
|
||||
</script>
|
||||
|
||||
{#if schema}
|
||||
<LightweightSchemaForm {schema} bind:args />
|
||||
<SchemaForm {schema} bind:args />
|
||||
{/if}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type { Schema } from '$lib/common'
|
||||
import Alert from '$lib/components/common/alert/Alert.svelte'
|
||||
import LightweightSchemaForm from '$lib/components/LightweightSchemaForm.svelte'
|
||||
import Popover from '$lib/components/Popover.svelte'
|
||||
import { AppService, type ExecuteComponentData } from '$lib/gen'
|
||||
import { classNames, defaultIfEmptyString, emptySchema, sendUserToast } from '$lib/utils'
|
||||
@@ -27,6 +26,7 @@
|
||||
import RefreshButton from '$lib/components/apps/components/helpers/RefreshButton.svelte'
|
||||
import { ctxRegex } from '../../utils'
|
||||
import { computeWorkspaceS3FileInputPolicy } from '../../editor/appUtilsS3'
|
||||
import SchemaForm from '$lib/components/SchemaForm.svelte'
|
||||
|
||||
// Component props
|
||||
export let id: string
|
||||
@@ -166,7 +166,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
let schemaForm: LightweightSchemaForm
|
||||
let schemaForm: SchemaForm
|
||||
|
||||
export function invalidate(key: string, error: string) {
|
||||
schemaForm?.invalidate(key, error)
|
||||
@@ -768,7 +768,7 @@
|
||||
<!-- {Object.keys(schemaStripped?.properties ?? {}).length > 0} -->
|
||||
{#if render && (autoRefresh || forceSchemaDisplay) && schemaStripped && Object.keys(schemaStripped?.properties ?? {}).length > 0}
|
||||
<div class="px-2 h-fit min-h-0">
|
||||
<LightweightSchemaForm
|
||||
<SchemaForm
|
||||
schema={schemaStripped}
|
||||
appPath={defaultIfEmptyString($appPath, `u/${$userStore?.username ?? 'unknown'}/newapp`)}
|
||||
{computeS3ForceViewerPolicies}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import Drawer from '$lib/components/common/drawer/Drawer.svelte'
|
||||
import DrawerContent from '$lib/components/common/drawer/DrawerContent.svelte'
|
||||
|
||||
import JsonEditor from './settingsPanel/inputEditor/JsonEditor.svelte'
|
||||
import JsonEditor from '../../JsonEditor.svelte'
|
||||
import { AppService, DraftService } from '$lib/gen'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
|
||||
+1
-1
@@ -2,7 +2,6 @@
|
||||
import type { InputType, StaticInput, StaticOptions } from '../../../inputType'
|
||||
import ArrayStaticInputEditor from '../ArrayStaticInputEditor.svelte'
|
||||
import ResourcePicker from '$lib/components/ResourcePicker.svelte'
|
||||
import JsonEditor from './JsonEditor.svelte'
|
||||
import { getContext } from 'svelte'
|
||||
import type { AppViewerContext } from '$lib/components/apps/types'
|
||||
import IconSelectInput from './IconSelectInput.svelte'
|
||||
@@ -23,6 +22,7 @@
|
||||
import DBTableSelect from './DBTableSelect.svelte'
|
||||
import EditableSchemaDrawer from '$lib/components/schema/EditableSchemaDrawer.svelte'
|
||||
import AppPicker from '$lib/components/wizards/AppPicker.svelte'
|
||||
import JsonEditor from '$lib/components/JsonEditor.svelte'
|
||||
|
||||
export let componentInput: StaticInput<any> | undefined
|
||||
export let fieldType: InputType | undefined = undefined
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import Tooltip from '$lib/components/Tooltip.svelte'
|
||||
import type { FlowModule } from '$lib/gen'
|
||||
|
||||
import JsonEditor from '$lib/components/apps/editor/settingsPanel/inputEditor/JsonEditor.svelte'
|
||||
import JsonEditor from '$lib/components/JsonEditor.svelte'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
|
||||
export let flowModule: FlowModule
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
PlayCircle,
|
||||
X
|
||||
} from 'lucide-svelte'
|
||||
import JsonEditor from '../apps/editor/settingsPanel/inputEditor/JsonEditor.svelte'
|
||||
import JsonEditor from '../JsonEditor.svelte'
|
||||
import Toggle from '../Toggle.svelte'
|
||||
import Label from '../Label.svelte'
|
||||
import Section from '../Section.svelte'
|
||||
@@ -271,8 +271,10 @@
|
||||
|
||||
<span class="text-xs absolute -top-4"
|
||||
>Label <Tooltip
|
||||
><a href="https://www.windmill.dev/docs/core_concepts/monitor_past_and_future_runs#jobs-labels" target="_blank">Job Labels</a> are string values in the array at the result field 'wm_labels' to easily
|
||||
filter them.</Tooltip
|
||||
><a
|
||||
href="https://www.windmill.dev/docs/core_concepts/monitor_past_and_future_runs#jobs-labels"
|
||||
target="_blank">Job Labels</a
|
||||
> are string values in the array at the result field 'wm_labels' to easily filter them.</Tooltip
|
||||
></span
|
||||
>
|
||||
|
||||
|
||||
@@ -185,7 +185,6 @@
|
||||
on:delete={(e) => {
|
||||
addProperty?.handleDeleteArgument([e.detail])
|
||||
}}
|
||||
lightweightMode
|
||||
dndType="drawer"
|
||||
editTab="inputEditor"
|
||||
>
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
export let uiOnly: boolean = false
|
||||
export let noPreview: boolean = false
|
||||
export let fullHeight: boolean = true
|
||||
export let lightweightMode: boolean = false
|
||||
export let formatExtension: string | undefined = undefined
|
||||
|
||||
let resourceIsTextFile: boolean = false
|
||||
@@ -117,7 +116,6 @@
|
||||
}}
|
||||
{uiOnly}
|
||||
{noPreview}
|
||||
{lightweightMode}
|
||||
editTab="inputEditor"
|
||||
>
|
||||
<svelte:fragment slot="addProperty">
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
import ObjectTypeNarrowing from '../ObjectTypeNarrowing.svelte'
|
||||
import Tabs from '../common/tabs/Tabs.svelte'
|
||||
import { Tab, TabContent } from '../common'
|
||||
import LightweightArgInput from '../LightweightArgInput.svelte'
|
||||
import EditableSchemaDrawer from './EditableSchemaDrawer.svelte'
|
||||
import type { SchemaProperty } from '$lib/common'
|
||||
import ToggleButtonGroup from '../common/toggleButton-v2/ToggleButtonGroup.svelte'
|
||||
@@ -48,7 +47,6 @@
|
||||
export let order: string[] | undefined = undefined
|
||||
export let requiredProperty: string[] | undefined = undefined
|
||||
export let displayWebhookWarning: boolean = true
|
||||
export let lightweightMode: boolean = false
|
||||
|
||||
function getOneOfWithoutLabel(oneOf: SchemaProperty[]) {
|
||||
return oneOf.map((v) => ({
|
||||
@@ -331,40 +329,25 @@
|
||||
|
||||
{#if !(type === 'object' && oneOf && oneOf.length >= 2)}
|
||||
<Label label="Default">
|
||||
{#if lightweightMode}
|
||||
<LightweightArgInput
|
||||
bind:value={defaultValue}
|
||||
type={password ? 'string' : type}
|
||||
displayHeader={false}
|
||||
{pattern}
|
||||
{customErrorMessage}
|
||||
{itemsType}
|
||||
{contentEncoding}
|
||||
{format}
|
||||
{extra}
|
||||
{disabled}
|
||||
/>
|
||||
{:else}
|
||||
<ArgInput
|
||||
noDefaultOnSelectFirst
|
||||
{itemPicker}
|
||||
resourceTypes={getResourceTypesFromFormat(format)}
|
||||
bind:value={defaultValue}
|
||||
type={password ? 'string' : type}
|
||||
displayHeader={false}
|
||||
{pattern}
|
||||
{customErrorMessage}
|
||||
{itemsType}
|
||||
{contentEncoding}
|
||||
{format}
|
||||
{extra}
|
||||
{disabled}
|
||||
{nullable}
|
||||
{variableEditor}
|
||||
compact
|
||||
noMargin
|
||||
/>
|
||||
{/if}
|
||||
<ArgInput
|
||||
noDefaultOnSelectFirst
|
||||
{itemPicker}
|
||||
resourceTypes={getResourceTypesFromFormat(format)}
|
||||
bind:value={defaultValue}
|
||||
type={password ? 'string' : type}
|
||||
displayHeader={false}
|
||||
{pattern}
|
||||
{customErrorMessage}
|
||||
{itemsType}
|
||||
{contentEncoding}
|
||||
{format}
|
||||
{extra}
|
||||
{disabled}
|
||||
{nullable}
|
||||
{variableEditor}
|
||||
compact
|
||||
noMargin
|
||||
/>
|
||||
</Label>
|
||||
{/if}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
export let schema: Schema
|
||||
export let args: Record<string, any> = {}
|
||||
export let prettifyHeader: boolean = false
|
||||
export let lightweightMode: boolean = false
|
||||
export let onlyMaskPassword: boolean = false
|
||||
export let disablePortal: boolean = false
|
||||
export let disabled: boolean = false
|
||||
@@ -81,7 +80,6 @@
|
||||
on:acceptChange
|
||||
on:rejectChange
|
||||
on:nestedChange
|
||||
{lightweightMode}
|
||||
bind:args
|
||||
{prettifyHeader}
|
||||
{onlyMaskPassword}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
import Label from '$lib/components/Label.svelte'
|
||||
import { json } from 'svelte-highlight/languages'
|
||||
import { Highlight } from 'svelte-highlight'
|
||||
import JsonEditor from '$lib/components/apps/editor/settingsPanel/inputEditor/JsonEditor.svelte'
|
||||
import JsonEditor from '$lib/components/JsonEditor.svelte'
|
||||
import FileUpload from '$lib/components/common/fileUpload/FileUpload.svelte'
|
||||
import ToggleButton from '$lib/components/common/toggleButton-v2/ToggleButton.svelte'
|
||||
import ToggleButtonGroup from '$lib/components/common/toggleButton-v2/ToggleButtonGroup.svelte'
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import Label from '$lib/components/Label.svelte'
|
||||
import { fade } from 'svelte/transition'
|
||||
import type { Schema } from '$lib/common'
|
||||
import JsonEditor from '$lib/components/apps/editor/settingsPanel/inputEditor/JsonEditor.svelte'
|
||||
import JsonEditor from '$lib/components/JsonEditor.svelte'
|
||||
import Toggle from '$lib/components/Toggle.svelte'
|
||||
import WebsocketEditorConfigSection from './WebsocketEditorConfigSection.svelte'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user