mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-12 00:06:14 +00:00
add dynamic disabled field to button
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
let color: ButtonType.Color
|
||||
let size: ButtonType.Size
|
||||
let runnableComponent: RunnableComponent
|
||||
let disabled = false
|
||||
|
||||
let isLoading: boolean = false
|
||||
let ownClick: boolean = false
|
||||
@@ -55,6 +56,7 @@
|
||||
<InputValue {id} input={configuration.label} bind:value={labelValue} />
|
||||
<InputValue {id} input={configuration.color} bind:value={color} />
|
||||
<InputValue {id} input={configuration.size} bind:value={size} />
|
||||
<InputValue {id} input={configuration.disabled} bind:value={disabled} />
|
||||
|
||||
<RunnableWrapper
|
||||
flexWrap
|
||||
@@ -66,6 +68,7 @@
|
||||
>
|
||||
<AlignWrapper {noWFull} {horizontalAlignment} {verticalAlignment}>
|
||||
<Button
|
||||
{disabled}
|
||||
on:pointerdown={(e) => {
|
||||
e?.stopPropagation()
|
||||
window.dispatchEvent(new Event('pointerup'))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { isCodeInjection } from '$lib/components/flows/utils'
|
||||
import { createEventDispatcher, getContext, onMount } from 'svelte'
|
||||
import type { AppInput } from '../../inputType'
|
||||
import type { AppInput, EvalAppInput } from '../../inputType'
|
||||
import type { AppEditorContext } from '../../types'
|
||||
import { accessPropertyByPath } from '../../utils'
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
$: state = $worldStore?.state
|
||||
$: input && $worldStore && row && handleConnection()
|
||||
$: input && $state && input.type == 'template' && (value = getValue(input))
|
||||
$: input && input.type == 'template' && $state && (value = getValue(input))
|
||||
$: input && input.type == 'eval' && $state && (value = evalExpr(input))
|
||||
|
||||
function handleConnection() {
|
||||
if (input.type === 'connected') {
|
||||
@@ -25,11 +26,21 @@
|
||||
setTimeout(() => (value = row[input['column']]), 0)
|
||||
} else if (input.type === 'static' || input.type == 'template') {
|
||||
setTimeout(() => (value = getValue(input)), 0)
|
||||
} else if (input.type == 'eval') {
|
||||
setTimeout(() => ((value = evalExpr(input as EvalAppInput)), 0))
|
||||
} else {
|
||||
setTimeout(() => (value = undefined), 0)
|
||||
}
|
||||
}
|
||||
|
||||
function evalExpr(input: EvalAppInput) {
|
||||
try {
|
||||
return eval_like(input.expr, computeGlobalContext())
|
||||
} catch (e) {
|
||||
return e.message
|
||||
}
|
||||
}
|
||||
|
||||
function computeGlobalContext() {
|
||||
return Object.fromEntries(
|
||||
Object.entries($worldStore?.outputsById ?? {})
|
||||
|
||||
@@ -171,6 +171,11 @@ const buttons: ComponentSet = {
|
||||
onlyStatic: true,
|
||||
optionValuesKey: 'buttonSizeOptions',
|
||||
value: 'xs'
|
||||
},
|
||||
disabled: {
|
||||
fieldType: 'boolean',
|
||||
type: 'eval',
|
||||
expr: 'false'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
import ConnectedInputEditor from './inputEditor/ConnectedInputEditor.svelte'
|
||||
import Badge from '$lib/components/common/badge/Badge.svelte'
|
||||
import { capitalize, classNames } from '$lib/utils'
|
||||
import { fieldTypeToTsType } from '../../utils'
|
||||
import { buildExtraLib, fieldTypeToTsType } from '../../utils'
|
||||
import Recompute from './Recompute.svelte'
|
||||
import Tooltip from '$lib/components/Tooltip.svelte'
|
||||
import ComponentInputTypeEditor from './ComponentInputTypeEditor.svelte'
|
||||
@@ -70,23 +70,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
export function buildExtraLib(components: Record<string, Record<string, Output<any>>>): string {
|
||||
return Object.entries(components)
|
||||
.filter(([k, v]) => k != component?.id)
|
||||
.map(([k, v]) => [k, Object.fromEntries(Object.entries(v).map(([k, v]) => [k, v.peak()]))])
|
||||
.map(
|
||||
([k, v]) => `
|
||||
|
||||
declare const ${k} = ${JSON.stringify(v)};
|
||||
|
||||
`
|
||||
)
|
||||
.join('\n')
|
||||
}
|
||||
|
||||
$: extraLib =
|
||||
component?.componentInput?.type === 'template' && $worldStore
|
||||
? buildExtraLib($worldStore?.outputsById ?? {})
|
||||
? buildExtraLib($worldStore?.outputsById ?? {}, component?.id)
|
||||
: undefined
|
||||
</script>
|
||||
|
||||
@@ -150,6 +136,7 @@ declare const ${k} = ${JSON.stringify(v)};
|
||||
</svelte:fragment>
|
||||
|
||||
<InputsSpecsEditor
|
||||
id={component.id}
|
||||
shouldCapitalize={false}
|
||||
bind:inputSpecs={component.componentInput.fields}
|
||||
userInputEnabled={component.type !== 'buttoncomponent'}
|
||||
@@ -163,7 +150,11 @@ declare const ${k} = ${JSON.stringify(v)};
|
||||
|
||||
{#if Object.values(component.configuration).length > 0}
|
||||
<PanelSection title={`Configuration (${Object.values(component.configuration).length})`}>
|
||||
<InputsSpecsEditor bind:inputSpecs={component.configuration} userInputEnabled={false} />
|
||||
<InputsSpecsEditor
|
||||
id={component.id}
|
||||
bind:inputSpecs={component.configuration}
|
||||
userInputEnabled={false}
|
||||
/>
|
||||
</PanelSection>
|
||||
{/if}
|
||||
|
||||
|
||||
@@ -2,15 +2,23 @@
|
||||
import Toggle from '$lib/components/Toggle.svelte'
|
||||
import type {
|
||||
ConnectedAppInput,
|
||||
EvalAppInput,
|
||||
RowAppInput,
|
||||
StaticAppInput,
|
||||
UserAppInput
|
||||
} from '../../inputType'
|
||||
import ConnectedInputEditor from './inputEditor/ConnectedInputEditor.svelte'
|
||||
import EvalInputEditor from './inputEditor/EvalInputEditor.svelte'
|
||||
import RowInputEditor from './inputEditor/RowInputEditor.svelte'
|
||||
import StaticInputEditor from './inputEditor/StaticInputEditor.svelte'
|
||||
|
||||
export let componentInput: StaticAppInput | ConnectedAppInput | UserAppInput | RowAppInput
|
||||
export let id: string
|
||||
export let componentInput:
|
||||
| StaticAppInput
|
||||
| ConnectedAppInput
|
||||
| UserAppInput
|
||||
| RowAppInput
|
||||
| EvalAppInput
|
||||
</script>
|
||||
|
||||
{#if componentInput.type === 'connected'}
|
||||
@@ -19,6 +27,8 @@
|
||||
<RowInputEditor bind:componentInput />
|
||||
{:else if componentInput.type === 'static'}
|
||||
<StaticInputEditor bind:componentInput />
|
||||
{:else if componentInput.type === 'eval'}
|
||||
<EvalInputEditor {id} bind:componentInput />
|
||||
{:else if componentInput.type === 'user'}
|
||||
<span class="text-2xs italic text-gray-6f00">Field's value is set by the user</span>
|
||||
{/if}
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
import Tooltip from '$lib/components/Tooltip.svelte'
|
||||
import Popover from '$lib/components/Popover.svelte'
|
||||
|
||||
export let id: string
|
||||
export let inputSpecs: BaseAppComponent['configuration']
|
||||
export let userInputEnabled: boolean = true
|
||||
export let staticOnly: boolean = false
|
||||
export let shouldCapitalize: boolean = true
|
||||
export let rowColumns = false
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
: capitalize(fieldTypeToTsType(input.fieldType))}
|
||||
</Badge>
|
||||
|
||||
{#if !inputSpecs[inputSpecKey].onlyStatic}
|
||||
{#if !inputSpecs[inputSpecKey].onlyStatic && inputSpecs[inputSpecKey].type != 'eval'}
|
||||
<ToggleButtonGroup
|
||||
bind:selected={inputSpecs[inputSpecKey].type}
|
||||
on:selected={(e) => {
|
||||
@@ -72,7 +72,6 @@
|
||||
value="row"
|
||||
startIcon={{ icon: faTableCells }}
|
||||
size="xs"
|
||||
disabled={staticOnly}
|
||||
>
|
||||
<Tooltip>
|
||||
Use the column name to have the value of the cell be passed to the action
|
||||
@@ -89,7 +88,6 @@
|
||||
startIcon={{ icon: faUser }}
|
||||
size="xs"
|
||||
iconOnly
|
||||
disabled={staticOnly}
|
||||
/>
|
||||
<svelte:fragment slot="text">User Input</svelte:fragment>
|
||||
</Popover>
|
||||
@@ -101,7 +99,6 @@
|
||||
startIcon={{ icon: faArrowRight }}
|
||||
size="xs"
|
||||
iconOnly
|
||||
disabled={staticOnly}
|
||||
/>
|
||||
<svelte:fragment slot="text">Connect</svelte:fragment>
|
||||
</Popover>
|
||||
@@ -110,7 +107,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InputsSpecEditor bind:componentInput={inputSpecs[inputSpecKey]} />
|
||||
<InputsSpecEditor {id} bind:componentInput={inputSpecs[inputSpecKey]} />
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
<script lang="ts">
|
||||
import type { EvalAppInput } from '../../../inputType'
|
||||
|
||||
import { getContext } from 'svelte'
|
||||
import type { AppEditorContext } from '$lib/components/apps/types'
|
||||
import SimpleEditor from '$lib/components/SimpleEditor.svelte'
|
||||
import { buildExtraLib } from '$lib/components/apps/utils'
|
||||
|
||||
export let componentInput: EvalAppInput | undefined
|
||||
export let id: string
|
||||
|
||||
const { onchange, worldStore } = getContext<AppEditorContext>('AppEditorContext')
|
||||
|
||||
$: componentInput && onchange?.()
|
||||
|
||||
$: extraLib =
|
||||
componentInput?.expr && $worldStore
|
||||
? buildExtraLib($worldStore?.outputsById ?? {}, id)
|
||||
: undefined
|
||||
</script>
|
||||
|
||||
{#if componentInput?.type === 'eval'}
|
||||
<div class="border border-gray-300 ">
|
||||
<SimpleEditor
|
||||
lang="javascript"
|
||||
bind:code={componentInput.expr}
|
||||
shouldBindKey={false}
|
||||
{extraLib}
|
||||
autoHeight
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -35,6 +35,13 @@ export type UserInput<U> = {
|
||||
}
|
||||
|
||||
|
||||
|
||||
export type EvalInput = {
|
||||
type: 'eval'
|
||||
expr: string
|
||||
}
|
||||
|
||||
|
||||
export type RowInput = {
|
||||
type: 'row'
|
||||
column: string
|
||||
@@ -79,6 +86,7 @@ type AppInputSpec<T extends InputType, U, V extends InputType = never> = (
|
||||
| ConnectedInput
|
||||
| UserInput<U>
|
||||
| RowInput
|
||||
| EvalInput
|
||||
| ResultInput
|
||||
| TemplateInput
|
||||
) &
|
||||
@@ -125,5 +133,6 @@ export type StaticAppInput = Extract<AppInput, { type: 'static' }>
|
||||
export type ConnectedAppInput = Extract<AppInput, { type: 'connected' }>
|
||||
export type UserAppInput = Extract<AppInput, { type: 'user' }>
|
||||
export type ResultAppInput = Extract<AppInput, { type: 'runnable' }>
|
||||
export type EvalAppInput = Extract<AppInput, { type: 'eval' }>
|
||||
|
||||
export type AppInputs = Record<string, AppInput>
|
||||
|
||||
@@ -6,6 +6,7 @@ import type {
|
||||
AppInput,
|
||||
ConnectedAppInput,
|
||||
ConnectedInput,
|
||||
EvalAppInput,
|
||||
RowAppInput,
|
||||
StaticAppInput,
|
||||
UserAppInput
|
||||
@@ -58,8 +59,9 @@ export type Aligned = {
|
||||
export interface BaseAppComponent extends Partial<Aligned> {
|
||||
id: ComponentID
|
||||
componentInput: AppInput | undefined
|
||||
configuration: Record<string, (StaticAppInput | ConnectedAppInput | UserAppInput | RowAppInput) & {
|
||||
configuration: Record<string, (StaticAppInput | ConnectedAppInput | UserAppInput | RowAppInput | EvalAppInput) & {
|
||||
onlyStatic?: boolean,
|
||||
evaluatedValue?: boolean,
|
||||
tooltip?: string
|
||||
}>
|
||||
card: boolean | undefined
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
SlidersHorizontal
|
||||
} from 'lucide-svelte'
|
||||
import type { AppInput, InputType, ResultAppInput, StaticAppInput } from './inputType'
|
||||
import type { Output } from './rx'
|
||||
import type { App, AppComponent } from './types'
|
||||
|
||||
export async function loadSchema(
|
||||
@@ -244,4 +245,18 @@ export function toStatic(app: App, staticExporter: Record<string, () => any>, su
|
||||
}
|
||||
})
|
||||
return { app: newApp, summary }
|
||||
}
|
||||
|
||||
export function buildExtraLib(components: Record<string, Record<string, Output<any>>>, idToExclude: string): string {
|
||||
return Object.entries(components)
|
||||
.filter(([k, v]) => k != idToExclude)
|
||||
.map(([k, v]) => [k, Object.fromEntries(Object.entries(v).map(([k, v]) => [k, v.peak()]))])
|
||||
.map(
|
||||
([k, v]) => `
|
||||
|
||||
declare const ${k} = ${JSON.stringify(v)};
|
||||
|
||||
`
|
||||
)
|
||||
.join('\n')
|
||||
}
|
||||
Reference in New Issue
Block a user