mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-22 08:02:19 +00:00
feat(frontend): Add label, description, input style + add displayType… (#1540)
* feat(frontend): Add label, description, input style + add displayType prop * feat(frontend): add large gap prop + use ResolveConfig
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import Required from './Required.svelte'
|
||||
|
||||
export let label: string
|
||||
@@ -6,10 +7,12 @@
|
||||
export let contentEncoding = ''
|
||||
export let type: string | undefined = undefined
|
||||
export let required = false
|
||||
export let displayType: boolean = true
|
||||
export let labelClass: string = ''
|
||||
</script>
|
||||
|
||||
<div class="inline-flex flex-row items-center truncated">
|
||||
<span class="font-semibold">
|
||||
<span class={twMerge('font-semibold', labelClass)}>
|
||||
{label}
|
||||
</span>
|
||||
<Required {required} class="!ml-0" />
|
||||
@@ -18,11 +21,11 @@
|
||||
<span class="text-sm italic ml-1 text-indigo-800">
|
||||
({format})
|
||||
</span>
|
||||
{:else}
|
||||
{:else if displayType}
|
||||
<span class="text-sm italic ml-1 text-indigo-800">
|
||||
({type ?? 'any'}{contentEncoding && contentEncoding != ''
|
||||
? `, encoding: ${contentEncoding}`
|
||||
: ''})</span
|
||||
>
|
||||
: ''})
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,10 @@
|
||||
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'
|
||||
|
||||
export let css: ComponentCustomCSS<'schemaformcomponent'> | undefined = undefined
|
||||
export let label: string = ''
|
||||
export let value: any
|
||||
|
||||
@@ -34,6 +37,7 @@
|
||||
export let displayHeader = true
|
||||
export let properties: { [name: string]: SchemaProperty } | undefined = undefined
|
||||
export let extra: Record<string, any> = {}
|
||||
export let displayType: boolean = true
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
@@ -138,11 +142,19 @@
|
||||
<div class="flex flex-col w-full min-w-[250px]">
|
||||
<div>
|
||||
{#if displayHeader}
|
||||
<FieldHeader {label} {required} {type} {contentEncoding} {format} />
|
||||
<FieldHeader
|
||||
{label}
|
||||
{required}
|
||||
{type}
|
||||
{contentEncoding}
|
||||
{format}
|
||||
{displayType}
|
||||
labelClass={css?.label?.class}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if description}
|
||||
<div class="text-sm italic pb-1">
|
||||
<div class={twMerge('text-sm italic pb-1', css?.description?.class)}>
|
||||
{description}
|
||||
</div>
|
||||
{/if}
|
||||
@@ -164,9 +176,11 @@
|
||||
dispatch('focus')
|
||||
}}
|
||||
type="number"
|
||||
class={valid
|
||||
? ''
|
||||
: 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'}
|
||||
class={twMerge(
|
||||
valid
|
||||
? ''
|
||||
: 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'
|
||||
)}
|
||||
placeholder={defaultValue ?? ''}
|
||||
bind:value
|
||||
min={extra['min']}
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
<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'
|
||||
|
||||
export let css: ComponentCustomCSS<'schemaformcomponent'> | undefined = undefined
|
||||
|
||||
export let schema: Schema
|
||||
export let args: Record<string, any> | undefined = undefined
|
||||
export let displayType: boolean = true
|
||||
export let largeGap: boolean = false
|
||||
|
||||
$: if (args === undefined) {
|
||||
args = {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="w-full">
|
||||
<div class={twMerge('w-full flex flex-col overflow-auto', largeGap ? 'gap-8' : 'gap-2')}>
|
||||
{#each Object.keys(schema.properties ?? {}) as argName (argName)}
|
||||
<div>
|
||||
{#if typeof args == 'object' && schema?.properties[argName] && args}
|
||||
@@ -29,6 +35,8 @@
|
||||
itemsType={schema.properties[argName].items}
|
||||
extra={schema.properties[argName]}
|
||||
on:inputClicked
|
||||
{displayType}
|
||||
{css}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from 'svelte'
|
||||
import { initOutput, selectId } from '../../editor/appUtils'
|
||||
import { initConfig, initOutput, selectId } from '../../editor/appUtils'
|
||||
import type { AppInput } from '../../inputType'
|
||||
import type { AppViewerContext } from '../../types'
|
||||
import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types'
|
||||
import RunnableWrapper from '../helpers/RunnableWrapper.svelte'
|
||||
import LightweightSchemaForm from '$lib/components/LightweightSchemaForm.svelte'
|
||||
import type { Schema } from '$lib/common'
|
||||
import { concatCustomCss } from '../../utils'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { components } from '../../editor/component'
|
||||
import ResolveConfig from '../helpers/ResolveConfig.svelte'
|
||||
|
||||
export let id: string
|
||||
export let componentInput: AppInput | undefined
|
||||
export let initializing: boolean | undefined = undefined
|
||||
export let render: boolean
|
||||
export let configuration: RichConfigurations
|
||||
export let customCss: ComponentCustomCSS<'schemaformcomponent'> | undefined = undefined
|
||||
|
||||
const { worldStore, connectingInput, app, selectedComponent } =
|
||||
getContext<AppViewerContext>('AppViewerContext')
|
||||
@@ -37,16 +43,38 @@
|
||||
}
|
||||
|
||||
$: args && handleArgsChange()
|
||||
$: css = concatCustomCss($app.css?.schemaformcomponent, customCss)
|
||||
|
||||
let resolvedConfig = initConfig(
|
||||
components['schemaformcomponent'].initialData.configuration,
|
||||
configuration
|
||||
)
|
||||
</script>
|
||||
|
||||
{#each Object.keys(components['schemaformcomponent'].initialData.configuration) as key (key)}
|
||||
<ResolveConfig
|
||||
{id}
|
||||
{key}
|
||||
bind:resolvedConfig={resolvedConfig[key]}
|
||||
configuration={configuration[key]}
|
||||
/>
|
||||
{/each}
|
||||
|
||||
<RunnableWrapper {outputs} {render} autoRefresh {componentInput} {id} bind:initializing bind:result>
|
||||
{#if result && Object.keys(result.properties).length > 0}
|
||||
<div
|
||||
class="m-2"
|
||||
class={twMerge('m-2', css?.container?.class)}
|
||||
style={css?.container?.style}
|
||||
on:pointerdown|stopPropagation={(e) =>
|
||||
!$connectingInput.opened && selectId(e, id, selectedComponent, $app)}
|
||||
>
|
||||
<LightweightSchemaForm schema={result} bind:args />
|
||||
<LightweightSchemaForm
|
||||
schema={result}
|
||||
bind:args
|
||||
displayType={Boolean(resolvedConfig.displayType)}
|
||||
largeGap={Boolean(resolvedConfig.largeGap)}
|
||||
{css}
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<p class="m-2 italic"> Empty form </p>
|
||||
|
||||
@@ -475,6 +475,8 @@
|
||||
<AppSchemaForm
|
||||
id={component.id}
|
||||
componentInput={component.componentInput}
|
||||
configuration={component.configuration}
|
||||
customCss={component.customCss}
|
||||
{initializing}
|
||||
{render}
|
||||
/>
|
||||
|
||||
@@ -219,7 +219,8 @@ export const selectOptions = {
|
||||
'en-CA'
|
||||
],
|
||||
objectFitOptions: ['contain', 'cover', 'fill'],
|
||||
splitPanelOptions: ['2', '3', '4']
|
||||
splitPanelOptions: ['2', '3', '4'],
|
||||
formorientationOptions: ['Horizontal', 'Vertical']
|
||||
}
|
||||
|
||||
const onSuccessClick = {
|
||||
@@ -1691,7 +1692,9 @@ Hello \${ctx.username}
|
||||
icon: FileText,
|
||||
dims: '3:8-8:12' as AppComponentDimensions,
|
||||
customCss: {
|
||||
container: { class: '', style: '' }
|
||||
container: { class: '', style: '' },
|
||||
label: { class: '', style: '' },
|
||||
description: { class: '', style: '' }
|
||||
},
|
||||
initialData: {
|
||||
componentInput: {
|
||||
@@ -1704,7 +1707,18 @@ Hello \${ctx.username}
|
||||
type: 'object'
|
||||
}
|
||||
},
|
||||
configuration: {}
|
||||
configuration: {
|
||||
displayType: {
|
||||
fieldType: 'boolean',
|
||||
type: 'static',
|
||||
value: false
|
||||
},
|
||||
largeGap: {
|
||||
fieldType: 'boolean',
|
||||
type: 'static',
|
||||
value: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} as const
|
||||
|
||||
Reference in New Issue
Block a user