add dynamic disabled field to button

This commit is contained in:
Ruben Fiszel
2023-01-16 01:52:18 +01:00
parent 7940b04723
commit 7fc2996e7a
10 changed files with 102 additions and 27 deletions
@@ -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>
@@ -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>
+3 -1
View File
@@ -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
+15
View File
@@ -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')
}