mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-09 08:02:25 +00:00
feat: add dynamic args for input list
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
export let text: string
|
||||
export let tooltip: string | undefined = undefined
|
||||
export let view = false
|
||||
export let size: xs | 'sm' | 'md' | 'lg' = 'md'
|
||||
export let size: 'xs' | 'sm' | 'md' | 'lg' = 'md'
|
||||
</script>
|
||||
|
||||
<Button color="light" on:click={() => (view = !view)} {size} variant="border"
|
||||
|
||||
@@ -2,7 +2,13 @@
|
||||
import { getContext } from 'svelte'
|
||||
import { initConfig, initOutput, selectId } from '../../editor/appUtils'
|
||||
import type { AppInput } from '../../inputType'
|
||||
import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types'
|
||||
import type {
|
||||
AppViewerContext,
|
||||
ComponentCustomCSS,
|
||||
ListContext,
|
||||
ListInputs,
|
||||
RichConfigurations
|
||||
} from '../../types'
|
||||
import RunnableWrapper from '../helpers/RunnableWrapper.svelte'
|
||||
import LightweightSchemaForm from '$lib/components/LightweightSchemaForm.svelte'
|
||||
import type { Schema } from '$lib/common'
|
||||
@@ -20,6 +26,8 @@
|
||||
|
||||
const { worldStore, connectingInput, app, selectedComponent, componentControl } =
|
||||
getContext<AppViewerContext>('AppViewerContext')
|
||||
const iterContext = getContext<ListContext>('ListWrapperContext')
|
||||
const listInputs: ListInputs | undefined = getContext<ListInputs>('ListInputs')
|
||||
|
||||
const outputs = initOutput($worldStore, id, {
|
||||
result: undefined,
|
||||
@@ -41,6 +49,9 @@
|
||||
}
|
||||
|
||||
outputs.values.set(newArgs, true)
|
||||
if (iterContext && listInputs) {
|
||||
listInputs(id, newArgs)
|
||||
}
|
||||
}
|
||||
|
||||
$componentControl[id] = {
|
||||
|
||||
@@ -89,10 +89,24 @@
|
||||
$state &&
|
||||
debounce(debounceTemplate)
|
||||
|
||||
let lastExpr: any = undefined
|
||||
|
||||
const debounceEval = async () => {
|
||||
let nvalue = await evalExpr(lastInput)
|
||||
if (!deepEqual(nvalue, value)) {
|
||||
value = nvalue
|
||||
if (
|
||||
typeof nvalue == 'string' ||
|
||||
typeof nvalue == 'number' ||
|
||||
typeof nvalue == 'boolean' ||
|
||||
typeof nvalue == 'bigint'
|
||||
) {
|
||||
if (nvalue != lastExpr) {
|
||||
lastExpr = nvalue
|
||||
value = nvalue as T
|
||||
}
|
||||
} else {
|
||||
value = nvalue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +131,6 @@
|
||||
|
||||
async function evalExpr(input: EvalAppInput): Promise<any> {
|
||||
if (iterContext && $iterContext.disabled) return
|
||||
|
||||
try {
|
||||
const r = await eval_like(
|
||||
input.expr,
|
||||
|
||||
@@ -2,7 +2,13 @@
|
||||
import Toggle from '$lib/components/Toggle.svelte'
|
||||
import { getContext } from 'svelte'
|
||||
import { initConfig, initOutput } from '../../editor/appUtils'
|
||||
import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types'
|
||||
import type {
|
||||
AppViewerContext,
|
||||
ComponentCustomCSS,
|
||||
ListContext,
|
||||
ListInputs,
|
||||
RichConfigurations
|
||||
} from '../../types'
|
||||
import { concatCustomCss } from '../../utils'
|
||||
import AlignWrapper from '../helpers/AlignWrapper.svelte'
|
||||
import InitializeComponent from '../helpers/InitializeComponent.svelte'
|
||||
@@ -24,6 +30,8 @@
|
||||
|
||||
const { app, worldStore, componentControl, runnableComponents } =
|
||||
getContext<AppViewerContext>('AppViewerContext')
|
||||
const iterContext = getContext<ListContext>('ListWrapperContext')
|
||||
const listInputs: ListInputs | undefined = getContext<ListInputs>('ListInputs')
|
||||
|
||||
let resolvedConfig = initConfig(
|
||||
components['checkboxcomponent'].initialData.configuration,
|
||||
@@ -51,6 +59,9 @@
|
||||
|
||||
function handleInput() {
|
||||
outputs.result.set(value)
|
||||
if (iterContext && listInputs) {
|
||||
listInputs(id, value)
|
||||
}
|
||||
if (recomputeIds) {
|
||||
recomputeIds.forEach((id) => $runnableComponents?.[id]?.cb())
|
||||
}
|
||||
|
||||
@@ -2,7 +2,13 @@
|
||||
import { getContext } from 'svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { initOutput } from '../../editor/appUtils'
|
||||
import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types'
|
||||
import type {
|
||||
AppViewerContext,
|
||||
ComponentCustomCSS,
|
||||
ListContext,
|
||||
ListInputs,
|
||||
RichConfigurations
|
||||
} from '../../types'
|
||||
import { concatCustomCss } from '../../utils'
|
||||
import AlignWrapper from '../helpers/AlignWrapper.svelte'
|
||||
import InputValue from '../helpers/InputValue.svelte'
|
||||
@@ -16,6 +22,8 @@
|
||||
|
||||
const { app, worldStore, selectedComponent, componentControl } =
|
||||
getContext<AppViewerContext>('AppViewerContext')
|
||||
const iterContext = getContext<ListContext>('ListWrapperContext')
|
||||
const listInputs: ListInputs | undefined = getContext<ListInputs>('ListInputs')
|
||||
|
||||
let defaultValue: number | undefined = undefined
|
||||
let placeholder: string | undefined = undefined
|
||||
@@ -37,7 +45,12 @@
|
||||
|
||||
$: handleDefault(defaultValue)
|
||||
|
||||
$: outputs?.result.set(value)
|
||||
$: {
|
||||
outputs?.result.set(value)
|
||||
if (iterContext && listInputs) {
|
||||
listInputs(id, value)
|
||||
}
|
||||
}
|
||||
|
||||
function handleDefault(defaultValue: number | undefined) {
|
||||
value = defaultValue
|
||||
|
||||
@@ -3,7 +3,13 @@
|
||||
import RangeSlider from 'svelte-range-slider-pips'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { initOutput } from '../../editor/appUtils'
|
||||
import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types'
|
||||
import type {
|
||||
AppViewerContext,
|
||||
ComponentCustomCSS,
|
||||
ListContext,
|
||||
ListInputs,
|
||||
RichConfigurations
|
||||
} from '../../types'
|
||||
import { concatCustomCss } from '../../utils'
|
||||
import AlignWrapper from '../helpers/AlignWrapper.svelte'
|
||||
import InputValue from '../helpers/InputValue.svelte'
|
||||
@@ -16,6 +22,9 @@
|
||||
export let render: boolean
|
||||
|
||||
const { app, worldStore, componentControl } = getContext<AppViewerContext>('AppViewerContext')
|
||||
const iterContext = getContext<ListContext>('ListWrapperContext')
|
||||
const listInputs: ListInputs | undefined = getContext<ListInputs>('ListInputs')
|
||||
|
||||
let min = 0
|
||||
let max = 42
|
||||
let step = 1
|
||||
@@ -33,7 +42,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
$: outputs?.result.set(values)
|
||||
$: {
|
||||
outputs?.result.set(values)
|
||||
if (iterContext && listInputs) {
|
||||
listInputs(id, values)
|
||||
}
|
||||
}
|
||||
|
||||
$: css = concatCustomCss($app.css?.rangecomponent, customCss)
|
||||
|
||||
|
||||
@@ -2,7 +2,13 @@
|
||||
import { getContext } from 'svelte'
|
||||
import Select from 'svelte-select'
|
||||
|
||||
import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types'
|
||||
import type {
|
||||
AppViewerContext,
|
||||
ComponentCustomCSS,
|
||||
ListContext,
|
||||
ListInputs,
|
||||
RichConfigurations
|
||||
} from '../../types'
|
||||
import { concatCustomCss } from '../../utils'
|
||||
import AlignWrapper from '../helpers/AlignWrapper.svelte'
|
||||
import { SELECT_INPUT_DEFAULT_STYLE } from '../../../../defaults'
|
||||
@@ -31,6 +37,9 @@
|
||||
componentControl
|
||||
} = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
const iterContext = getContext<ListContext>('ListWrapperContext')
|
||||
const listInputs: ListInputs | undefined = getContext<ListInputs>('ListInputs')
|
||||
|
||||
$componentControl[id] = {
|
||||
setValue(nvalue: string) {
|
||||
setValue(JSON.stringify(nvalue))
|
||||
@@ -75,6 +84,9 @@
|
||||
value = JSON.stringify(rawValue)
|
||||
outputs?.result.set(rawValue)
|
||||
}
|
||||
if (iterContext && listInputs) {
|
||||
listInputs(id, rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
function onChange(e: CustomEvent) {
|
||||
@@ -97,6 +109,9 @@
|
||||
} catch (_) {}
|
||||
value = nvalue
|
||||
outputs?.result.set(result)
|
||||
if (iterContext && listInputs) {
|
||||
listInputs(id, result)
|
||||
}
|
||||
if (recomputeIds) {
|
||||
recomputeIds.forEach((id) => $runnableComponents?.[id]?.cb())
|
||||
}
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
<script lang="ts">
|
||||
import RangeSlider from 'svelte-range-slider-pips'
|
||||
import { getContext } from 'svelte'
|
||||
import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types'
|
||||
import type {
|
||||
ListInputs,
|
||||
AppViewerContext,
|
||||
ComponentCustomCSS,
|
||||
ListContext,
|
||||
RichConfigurations
|
||||
} from '../../types'
|
||||
import AlignWrapper from '../helpers/AlignWrapper.svelte'
|
||||
import InputValue from '../helpers/InputValue.svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
@@ -15,6 +21,9 @@
|
||||
export let customCss: ComponentCustomCSS<'slidercomponent'> | undefined = undefined
|
||||
export let render: boolean
|
||||
|
||||
const iterContext = getContext<ListContext>('ListWrapperContext')
|
||||
const listInputs: ListInputs | undefined = getContext<ListInputs>('ListInputs')
|
||||
|
||||
const { app, worldStore, selectedComponent, componentControl } =
|
||||
getContext<AppViewerContext>('AppViewerContext')
|
||||
let min = 0
|
||||
@@ -44,6 +53,9 @@
|
||||
// }
|
||||
const num = isNaN(+values[0]) ? null : +values[0]
|
||||
outputs?.result.set(num)
|
||||
if (iterContext && listInputs) {
|
||||
listInputs(id, num)
|
||||
}
|
||||
}
|
||||
|
||||
$: css = concatCustomCss($app.css?.slidercomponent, customCss)
|
||||
|
||||
@@ -2,7 +2,13 @@
|
||||
import { getContext } from 'svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { initOutput, selectId } from '../../editor/appUtils'
|
||||
import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types'
|
||||
import type {
|
||||
AppViewerContext,
|
||||
ComponentCustomCSS,
|
||||
ListContext,
|
||||
ListInputs,
|
||||
RichConfigurations
|
||||
} from '../../types'
|
||||
import { concatCustomCss } from '../../utils'
|
||||
import AlignWrapper from '../helpers/AlignWrapper.svelte'
|
||||
import InputValue from '../helpers/InputValue.svelte'
|
||||
@@ -23,6 +29,9 @@
|
||||
const { app, worldStore, selectedComponent, connectingInput, componentControl } =
|
||||
getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
const iterContext = getContext<ListContext>('ListWrapperContext')
|
||||
const listInputs: ListInputs | undefined = getContext<ListInputs>('ListInputs')
|
||||
|
||||
let placeholder: string | undefined = undefined
|
||||
let defaultValue: string | undefined = undefined
|
||||
let value: string | undefined = undefined
|
||||
@@ -39,7 +48,13 @@
|
||||
|
||||
$: handleDefault(defaultValue)
|
||||
|
||||
$: outputs?.result.set(value ?? '')
|
||||
$: {
|
||||
let val = value ?? ''
|
||||
outputs?.result.set(val)
|
||||
if (iterContext && listInputs) {
|
||||
listInputs(id, val)
|
||||
}
|
||||
}
|
||||
|
||||
function handleDefault(defaultValue: string | undefined) {
|
||||
value = defaultValue
|
||||
|
||||
+12
-1
@@ -2,7 +2,13 @@
|
||||
import { initOutput } from '$lib/components/apps/editor/appUtils'
|
||||
import { getContext } from 'svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../../types'
|
||||
import type {
|
||||
AppViewerContext,
|
||||
ComponentCustomCSS,
|
||||
ListContext,
|
||||
ListInputs,
|
||||
RichConfigurations
|
||||
} from '../../../types'
|
||||
import { concatCustomCss } from '../../../utils'
|
||||
import AlignWrapper from '../../helpers/AlignWrapper.svelte'
|
||||
import InputValue from '../../helpers/InputValue.svelte'
|
||||
@@ -17,6 +23,8 @@
|
||||
|
||||
const { app, worldStore, selectedComponent, componentControl } =
|
||||
getContext<AppViewerContext>('AppViewerContext')
|
||||
const iterContext = getContext<ListContext>('ListWrapperContext')
|
||||
const listInputs: ListInputs | undefined = getContext<ListInputs>('ListInputs')
|
||||
|
||||
const outputs = initOutput($worldStore, id, {
|
||||
result: null as number | null
|
||||
@@ -37,6 +45,9 @@
|
||||
|
||||
function handleInput() {
|
||||
outputs?.result.set(value ?? null)
|
||||
if (iterContext && listInputs) {
|
||||
listInputs(id, value ?? null)
|
||||
}
|
||||
}
|
||||
|
||||
function handleDefault() {
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
|
||||
const outputs = initOutput($worldStore, id, {
|
||||
result: undefined,
|
||||
loading: false
|
||||
loading: false,
|
||||
inputs: {}
|
||||
})
|
||||
|
||||
let resolvedConfig = initConfig(
|
||||
@@ -42,6 +43,8 @@
|
||||
let result: any[] | undefined = undefined
|
||||
|
||||
$: isCard = resolvedConfig.width?.selected == 'card'
|
||||
|
||||
let inputs = {}
|
||||
</script>
|
||||
|
||||
{#each Object.keys(components['listcomponent'].initialData.configuration) as key (key)}
|
||||
@@ -81,7 +84,14 @@
|
||||
} max-height: ${resolvedConfig.heightPx}px;`}
|
||||
class="overflow-auto {!isCard ? 'w-full' : 'border'}"
|
||||
>
|
||||
<ListWrapper {value} {index}>
|
||||
<ListWrapper
|
||||
on:inputsChange={() => {
|
||||
outputs?.inputs.set(inputs, true)
|
||||
}}
|
||||
bind:inputs
|
||||
{value}
|
||||
{index}
|
||||
>
|
||||
<SubGridEditor
|
||||
visible={render}
|
||||
{id}
|
||||
|
||||
@@ -1,16 +1,27 @@
|
||||
<script lang="ts">
|
||||
import { setContext } from 'svelte'
|
||||
import type { ListContext } from '../../types'
|
||||
import { createEventDispatcher, setContext } from 'svelte'
|
||||
import type { ListInputs, ListContext } from '../../types'
|
||||
import { writable } from 'svelte/store'
|
||||
|
||||
export let index: number
|
||||
export let value: any
|
||||
export let disabled = false
|
||||
export let inputs: Record<string, Record<number, any>> = {}
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const ctx = writable({ index, value, disabled })
|
||||
|
||||
$: $ctx = { index, value, disabled }
|
||||
setContext<ListContext>('ListWrapperContext', ctx)
|
||||
setContext<ListInputs>('ListInputs', (id: string, value: any) => {
|
||||
if (!inputs[id]) {
|
||||
inputs[id] = { [index]: value }
|
||||
} else {
|
||||
inputs[id][index] = value
|
||||
}
|
||||
console.log('foo')
|
||||
dispatch('inputsChange')
|
||||
})
|
||||
</script>
|
||||
|
||||
<slot />
|
||||
|
||||
@@ -156,6 +156,8 @@ export type ListContext = Writable<{
|
||||
disabled: boolean
|
||||
}>
|
||||
|
||||
export type ListInputs = (id: string, value: any) => void
|
||||
|
||||
export type AppViewerContext = {
|
||||
worldStore: Writable<World>
|
||||
app: Writable<App>
|
||||
|
||||
+7044
-5400
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+4687
-3045
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+6886
-5242
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+6090
-4446
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+101123
-90794
File diff suppressed because one or more lines are too long
+7514
-4467
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user