remove lightweightschemaform

This commit is contained in:
Ruben Fiszel
2025-01-27 21:35:38 +01:00
parent b85b3fb2d3
commit bb691d68ae
29 changed files with 366 additions and 1167 deletions
@@ -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
+119 -72
View File
@@ -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 -2
View File
@@ -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>&nbsp; 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 === ''}
&nbsp;
{: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"
+121 -150
View File
@@ -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'
@@ -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'