mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-19 16:02:14 +00:00
apps UX nits
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
export let noVariablePicker = false
|
||||
export let filter: string[] | undefined = undefined
|
||||
export let noDynamicToggle = false
|
||||
export let flexWrap = false
|
||||
|
||||
let clazz: string = ''
|
||||
export { clazz as class }
|
||||
@@ -55,7 +56,7 @@
|
||||
let variableEditor: VariableEditor | undefined = undefined
|
||||
</script>
|
||||
|
||||
<div class="w-full {clazz}">
|
||||
<div class="w-full {clazz} {flexWrap ? 'flex flex-row flex-wrap gap-x-4' : ''}">
|
||||
{#if Object.keys(schema?.properties ?? {}).length > 0}
|
||||
{#each Object.keys(schema?.properties ?? {}) as argName, i (argName)}
|
||||
{#if !filter || filter.includes(argName)}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
} from '$lib/editorUtils'
|
||||
import { languages, editor as meditor, Uri as mUri, Range } from 'monaco-editor'
|
||||
import libStdContent from '$lib/es5.d.ts.txt?raw'
|
||||
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
|
||||
|
||||
languages.typescript.javascriptDefaults.setCompilerOptions({
|
||||
target: languages.typescript.ScriptTarget.Latest,
|
||||
@@ -386,7 +387,11 @@
|
||||
// @ts-ignore
|
||||
self.MonacoEnvironment = {
|
||||
getWorker: function (_moduleId: any, label: string) {
|
||||
return new tsWorker()
|
||||
if (label == 'typescript') {
|
||||
return new tsWorker()
|
||||
} else {
|
||||
return new editorWorker()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
export let id: string
|
||||
export let componentInput: AppInput | undefined
|
||||
export let horizontalAlignment: 'left' | 'center' | 'right' | undefined = undefined
|
||||
export let horizontalAlignment: 'left' | 'center' | 'right' | undefined = 'left'
|
||||
export let verticalAlignment: 'top' | 'center' | 'bottom' | undefined = undefined
|
||||
export let configuration: Record<string, AppInput>
|
||||
|
||||
|
||||
@@ -63,28 +63,38 @@
|
||||
forceSchemaDisplay={true}
|
||||
>
|
||||
<AlignWrapper {horizontalAlignment}>
|
||||
<Button
|
||||
on:pointerdown={(e) => {
|
||||
e?.stopPropagation()
|
||||
window.dispatchEvent(new Event('pointerup'))
|
||||
}}
|
||||
on:click={() => {
|
||||
runnableComponent?.runComponent()
|
||||
<div class="flex flex-col gap-2 px-4 w-full">
|
||||
<div>
|
||||
{#if componentInput?.type != 'runnable' || Object.values(componentInput?.fields ?? {}).filter((x) => x.type == 'user').length == 0}
|
||||
<span class="text-gray-600 italic text-sm py-2"
|
||||
>Run forms are meant to be associated with a runnable with some user inputs. Pick a
|
||||
runnable and set some 'Runnable Inputs' to 'User Input'</span
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
<Button
|
||||
{loading}
|
||||
btnClasses="mt-1"
|
||||
on:pointerdown={(e) => {
|
||||
e?.stopPropagation()
|
||||
window.dispatchEvent(new Event('pointerup'))
|
||||
}}
|
||||
on:click={() => {
|
||||
runnableComponent?.runComponent()
|
||||
|
||||
if (recomputeIds) {
|
||||
recomputeIds.forEach((id) => {
|
||||
$runnableComponents[id]?.()
|
||||
})
|
||||
}
|
||||
}}
|
||||
{size}
|
||||
{color}
|
||||
endIcon={{
|
||||
icon: loading ? faRefresh : faArrowRight,
|
||||
classes: loading ? 'animate-spin w-4' : 'w-4'
|
||||
}}
|
||||
>
|
||||
{labelValue}
|
||||
</Button>
|
||||
if (recomputeIds) {
|
||||
recomputeIds.forEach((id) => {
|
||||
$runnableComponents[id]?.()
|
||||
})
|
||||
}
|
||||
}}
|
||||
{size}
|
||||
{color}
|
||||
>
|
||||
{labelValue}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</AlignWrapper>
|
||||
</RunnableWrapper>
|
||||
|
||||
@@ -253,10 +253,17 @@
|
||||
bind:this={testJobLoader}
|
||||
/>
|
||||
|
||||
<div class="h-full flex flex-col">
|
||||
{#if schemaStripped !== undefined && (autoRefresh || forceSchemaDisplay)}
|
||||
<div class="px-2">
|
||||
<div class="h-full flex relative flex-row flex-wrap">
|
||||
{#if autoRefresh === true}
|
||||
<div class="flex absolute top-1 right-1">
|
||||
<RefreshButton componentId={id} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if schemaStripped && Object.keys(schemaStripped?.properties ?? {}).length > 0 && (autoRefresh || forceSchemaDisplay)}
|
||||
<div class="px-2 h-fit min-h-0">
|
||||
<SchemaForm
|
||||
compact
|
||||
flexWrap
|
||||
schema={schemaStripped}
|
||||
bind:args
|
||||
{disabledArgs}
|
||||
@@ -276,13 +283,9 @@
|
||||
<pre title={result.error} class="text-2xs whitespace-pre-wrap">{result.error}</pre>
|
||||
</Alert>
|
||||
</div>
|
||||
{:else if autoRefresh === true}
|
||||
<div class="flex absolute top-1 right-1">
|
||||
<RefreshButton componentId={id} />
|
||||
</div>
|
||||
|
||||
<slot />
|
||||
{:else}
|
||||
<slot />
|
||||
<div class="grow min-w-1/2 min-h-[66%]">
|
||||
<slot />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
}
|
||||
|
||||
const options = writable<TableOptions<T>>({
|
||||
...tableOptions,
|
||||
data: [],
|
||||
columns: [],
|
||||
...tableOptions
|
||||
columns: []
|
||||
})
|
||||
|
||||
let table = createSvelteTable(options)
|
||||
@@ -67,14 +67,14 @@
|
||||
const headers = Array.from(new Set(result.flatMap((row) => Object.keys(row))))
|
||||
|
||||
$options = {
|
||||
...tableOptions,
|
||||
data: filteredResult,
|
||||
columns: headers.map((header) => {
|
||||
return {
|
||||
accessorKey: header,
|
||||
cell: (info) => info.getValue()
|
||||
}
|
||||
}),
|
||||
...tableOptions
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
{@const component = renderCell(cell.column.columnDef.cell, context)}
|
||||
<td
|
||||
on:click={() => toggleRow(row, rowIndex)}
|
||||
class="p-4 whitespace-nowrap text-xs text-gray-900"
|
||||
class="p-4 whitespace-pre-wrap truncate text-xs text-gray-900"
|
||||
>
|
||||
{#if typeof cell.column.columnDef.cell != 'string' && cellIsObject(cell.column.columnDef.cell, context)}
|
||||
{JSON.stringify(cell.column.columnDef.cell(context), null, 4)}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import { getCoreRowModel, getPaginationRowModel } from '@tanstack/svelte-table'
|
||||
import { getCoreRowModel, getPaginationRowModel, type TableOptions } from '@tanstack/svelte-table'
|
||||
|
||||
const tableOptions = {
|
||||
const tableOptions: TableOptions<Record<string, any>> = {
|
||||
data: [],
|
||||
columns: [],
|
||||
enableColumnResizing: false,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
getPaginationRowModel: getPaginationRowModel(),
|
||||
initialState: {
|
||||
pagination: {
|
||||
pageSize: 10
|
||||
pageSize: 25
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export { tableOptions }
|
||||
|
||||
@@ -14,9 +14,12 @@
|
||||
</script>
|
||||
|
||||
<span
|
||||
title={`Id: ${component.id}`}
|
||||
class={classNames(
|
||||
'px-2 text-2xs font-bold rounded-t-sm w-fit absolute z-50',
|
||||
selected ? 'bg-indigo-500/90 text-white' : 'bg-gray-200/60 text-gray-500'
|
||||
'px-2 text-2xs font-bold rounded-t-sm w-fit absolute shadow -top-1 -left-2 border z-50',
|
||||
selected
|
||||
? 'bg-indigo-500/90 border-blue-500 text-white'
|
||||
: 'bg-gray-200/90 border-gray-300 text-gray-500'
|
||||
)}
|
||||
style="padding-top: 1px; padding-bottom: 1px;"
|
||||
>
|
||||
@@ -25,29 +28,31 @@
|
||||
|
||||
{#if pointerdown || selected || hover}
|
||||
<button
|
||||
title="Position locking"
|
||||
class={classNames(
|
||||
'text-gray-800 px-1 text-2xs py-0.5 font-bold rounded-t-sm w-fit absolute right-10 z-50 cursor-pointer',
|
||||
'text-gray-800 px-1 text-2xs py-0.5 font-bold rounded-t-sm w-fit shadow border border-gray-300 absolute -top-1 right-[2.5rem] z-50 cursor-pointer',
|
||||
' hover:bg-gray-300',
|
||||
selected ? 'bg-gray-200/80' : 'bg-gray-200/60'
|
||||
selected ? 'bg-gray-200/80' : 'bg-gray-200/80'
|
||||
)}
|
||||
on:click={() => {
|
||||
dispatch('lock')
|
||||
}}
|
||||
>
|
||||
{#if locked}
|
||||
<Anchor size={14} class="text-orange-500" />
|
||||
<Anchor aria-label="Unlock position" size={14} class="text-orange-500" />
|
||||
{:else}
|
||||
<Anchor size={14} />
|
||||
<Anchor aria-label="Lock position" size={14} />
|
||||
{/if}
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
{#if selected || hover}
|
||||
<span
|
||||
title="Move"
|
||||
on:mousedown|stopPropagation|capture
|
||||
class={classNames(
|
||||
'text-gray-600 px-1 text-2xs py-0.5 font-bold rounded-t-sm w-fit absolute right-16 z-50 cursor-move',
|
||||
'bg-gray-200/60'
|
||||
'text-gray-600 px-1 text-2xs py-0.5 font-bold rounded-t-sm w-fit absolute border border-gray-300 -top-1 shadow right-[4.5rem] z-50 cursor-move',
|
||||
'bg-gray-200/80'
|
||||
)}><Move size={14} /></span
|
||||
>
|
||||
{/if}
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="px-4 pt-4 {$connectingInput?.opened ? '' : 'bg-gray-50/70'}"
|
||||
class="px-4 pt-4 {$connectingInput?.opened ? '' : ''}"
|
||||
on:pointerdown={onpointerdown}
|
||||
on:pointerleave={onpointerup}
|
||||
on:pointerup={onpointerup}
|
||||
@@ -124,7 +124,7 @@
|
||||
<Grid
|
||||
bind:items={$app.grid}
|
||||
let:dataItem
|
||||
rowHeight={23}
|
||||
rowHeight={30}
|
||||
cols={columnConfiguration}
|
||||
fastStart={true}
|
||||
on:pointerup={({ detail }) => selectComponent(detail.id)}
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
function getMinDimensionsByComponent(componentType: AppComponent['type'], column: number): Size {
|
||||
// Dimensions key formula: <mobile width>:<mobile height>-<desktop width>:<desktop height>
|
||||
const dimensions: Record<`${number}:${number}-${number}:${number}`, AppComponent['type'][]> = {
|
||||
'4:1-4:1': ['textcomponent'],
|
||||
'2:1-2:1': ['buttoncomponent'],
|
||||
'4:2-4:2': [
|
||||
'buttoncomponent',
|
||||
'textcomponent',
|
||||
'checkboxcomponent',
|
||||
'textinputcomponent',
|
||||
'numberinputcomponent',
|
||||
@@ -29,7 +29,8 @@
|
||||
'passwordinputcomponent',
|
||||
'dateinputcomponent'
|
||||
],
|
||||
'4:12-4:12': ['barchartcomponent', 'piechartcomponent', 'formcomponent', 'displaycomponent'],
|
||||
'3:5-6:5': ['formcomponent'],
|
||||
'4:12-4:12': ['barchartcomponent', 'piechartcomponent', 'displaycomponent'],
|
||||
'3:10-6:12': ['tablecomponent']
|
||||
}
|
||||
// Finds the key that is associated with the component type and extracts the dimensions from it
|
||||
|
||||
@@ -14,6 +14,7 @@ const inputs: ComponentSet = {
|
||||
type: 'static',
|
||||
value: 'Type...',
|
||||
fieldType: 'text',
|
||||
onlyStatic: true,
|
||||
},
|
||||
},
|
||||
card: false
|
||||
@@ -100,6 +101,7 @@ const buttons: ComponentSet = {
|
||||
components: [
|
||||
{
|
||||
...defaultAlignement,
|
||||
softWrap: true,
|
||||
id: 'buttoncomponent',
|
||||
type: 'buttoncomponent',
|
||||
componentInput: {
|
||||
@@ -120,14 +122,14 @@ const buttons: ComponentSet = {
|
||||
color: {
|
||||
fieldType: 'select',
|
||||
type: 'static',
|
||||
|
||||
onlyStatic: true,
|
||||
optionValuesKey: 'buttonColorOptions',
|
||||
value: 'blue'
|
||||
},
|
||||
size: {
|
||||
fieldType: 'select',
|
||||
type: 'static',
|
||||
|
||||
onlyStatic: true,
|
||||
optionValuesKey: 'buttonSizeOptions',
|
||||
value: 'xs'
|
||||
}
|
||||
@@ -156,6 +158,7 @@ const buttons: ComponentSet = {
|
||||
color: {
|
||||
fieldType: 'select',
|
||||
type: 'static',
|
||||
onlyStatic: true,
|
||||
value: 'dark',
|
||||
optionValuesKey: 'buttonColorOptions',
|
||||
},
|
||||
@@ -163,6 +166,7 @@ const buttons: ComponentSet = {
|
||||
fieldType: 'select',
|
||||
type: 'static',
|
||||
value: 'xs',
|
||||
onlyStatic: true,
|
||||
optionValuesKey: 'buttonSizeOptions',
|
||||
}
|
||||
},
|
||||
@@ -176,20 +180,21 @@ const display: ComponentSet = {
|
||||
title: 'Display',
|
||||
components: [
|
||||
{
|
||||
...defaultAlignement,
|
||||
softWrap: true,
|
||||
horizontalAlignment: 'left',
|
||||
verticalAlignment: 'top',
|
||||
id: 'textcomponent',
|
||||
type: 'textcomponent',
|
||||
componentInput: {
|
||||
type: 'static',
|
||||
fieldType: 'textarea',
|
||||
value: 'Lorem ipsum',
|
||||
|
||||
value: 'Hello ${ctx.username}',
|
||||
},
|
||||
configuration: {
|
||||
style: {
|
||||
fieldType: 'select',
|
||||
type: 'static',
|
||||
|
||||
onlyStatic: true,
|
||||
optionValuesKey: 'textStyleOptions',
|
||||
value: 'Body'
|
||||
},
|
||||
@@ -205,21 +210,22 @@ const display: ComponentSet = {
|
||||
card: false
|
||||
},
|
||||
{
|
||||
|
||||
id: 'tablecomponent',
|
||||
type: 'tablecomponent',
|
||||
configuration: {
|
||||
search: {
|
||||
fieldType: 'select',
|
||||
type: 'static',
|
||||
|
||||
onlyStatic: true,
|
||||
optionValuesKey: 'tableSearchOptions',
|
||||
value: 'Disabled'
|
||||
},
|
||||
pagination: {
|
||||
type: 'static',
|
||||
|
||||
onlyStatic: true,
|
||||
fieldType: 'boolean',
|
||||
value: false
|
||||
value: true
|
||||
}
|
||||
},
|
||||
componentInput: {
|
||||
@@ -249,7 +255,7 @@ const display: ComponentSet = {
|
||||
configuration: {
|
||||
theme: {
|
||||
type: 'static',
|
||||
|
||||
onlyStatic: true,
|
||||
fieldType: 'select',
|
||||
optionValuesKey: 'chartThemeOptions',
|
||||
value: 'theme1'
|
||||
@@ -276,7 +282,7 @@ const display: ComponentSet = {
|
||||
configuration: {
|
||||
theme: {
|
||||
type: 'static',
|
||||
|
||||
onlyStatic: true,
|
||||
fieldType: 'select',
|
||||
optionValuesKey: 'chartThemeOptions',
|
||||
value: 'theme1'
|
||||
|
||||
@@ -30,13 +30,13 @@
|
||||
|
||||
if (component?.data.type) {
|
||||
return displayData[component?.data.type].name
|
||||
} else if (componentId == 'context') {
|
||||
} else if (componentId == 'ctx') {
|
||||
return 'Context'
|
||||
} else {
|
||||
return 'Table action'
|
||||
}
|
||||
}
|
||||
$: panels = [['context', ['email', 'username']] as [string, string[]]].concat(
|
||||
$: panels = [['ctx', ['email', 'username']] as [string, string[]]].concat(
|
||||
Object.entries($staticOutputs)
|
||||
)
|
||||
</script>
|
||||
@@ -58,7 +58,7 @@
|
||||
? undefined
|
||||
: () => ($selectedComponent = componentId)}
|
||||
class={classNames(
|
||||
'px-2 text-2xs py-0.5 font-bold rounded-t-sm w-fit',
|
||||
'px-2 text-2xs py-0.5 border border-gray-300 font-bold rounded-t-sm w-fit',
|
||||
$selectedComponent === componentId
|
||||
? ' bg-indigo-500 text-white'
|
||||
: 'bg-gray-200 text-gray-500'
|
||||
@@ -80,7 +80,7 @@
|
||||
<div
|
||||
class={classNames(
|
||||
$connectingInput?.opened ? 'bg-white z-50' : '',
|
||||
`w-full py-2 grow border relative overflow-x-auto`,
|
||||
`w-full py-2 grow border relative `,
|
||||
$selectedComponent === componentId ? 'border border-blue-500 ' : '',
|
||||
$connectingInput.hoveredComponent === componentId ? 'outline outline-blue-500' : ''
|
||||
)}
|
||||
|
||||
+2
-2
@@ -57,8 +57,8 @@
|
||||
|
||||
<InlineScriptEditorDrawer {editor} bind:this={inlineScriptEditorDrawer} bind:inlineScript />
|
||||
|
||||
<div class="h-full p-2 flex flex-col gap-2" transition:fly={{ duration: 50 }}>
|
||||
<div class="flex justify-between w-full gap-1 flex-row items-center">
|
||||
<div class="h-full flex flex-col gap-1" transition:fly={{ duration: 50 }}>
|
||||
<div class="flex justify-between w-full gap-1 px-2 pt-1 flex-row items-center">
|
||||
{#if name !== undefined}
|
||||
<input bind:value={name} placeholder="Inline script name" />
|
||||
{/if}
|
||||
|
||||
+4
-3
@@ -13,6 +13,7 @@
|
||||
$: if (componentInput.fieldType == 'textarea' && componentInput.type == 'static') {
|
||||
//@ts-ignore
|
||||
componentInput.type = 'template'
|
||||
componentInput['eval'] = componentInput.value
|
||||
}
|
||||
|
||||
const brackets = '${}'
|
||||
@@ -37,7 +38,7 @@
|
||||
disable={disableStatic}
|
||||
>
|
||||
{#if clientWidth > 250}
|
||||
<span class="hidden lg:block"> Static </span>
|
||||
<span class="hidden lg:block">Static</span>
|
||||
{/if}
|
||||
</ToggleButton>
|
||||
{/if}
|
||||
@@ -50,7 +51,7 @@
|
||||
size="xs"
|
||||
>
|
||||
{#if clientWidth > 250}
|
||||
<span class="hidden lg:block"> Connect </span>
|
||||
<span class="hidden lg:block">Connect</span>
|
||||
{/if}
|
||||
</ToggleButton>
|
||||
<ToggleButton
|
||||
@@ -61,7 +62,7 @@
|
||||
size="xs"
|
||||
>
|
||||
{#if clientWidth > 250}
|
||||
<span class="hidden lg:block"> Compute </span>
|
||||
<span class="hidden lg:block">Compute</span>
|
||||
{/if}
|
||||
</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
export let inputSpecs: Record<
|
||||
string,
|
||||
StaticAppInput | ConnectedAppInput | UserAppInput | RowAppInput
|
||||
(StaticAppInput | ConnectedAppInput | UserAppInput | RowAppInput) & { onlyStatic?: boolean }
|
||||
>
|
||||
export let userInputEnabled: boolean = true
|
||||
export let staticOnly: boolean = false
|
||||
@@ -31,54 +31,56 @@
|
||||
{shouldCapitalize ? capitalize(inputSpecKey) : inputSpecKey}
|
||||
</span>
|
||||
|
||||
<div class="flex gap-2 items-center">
|
||||
<div class="flex gap-2 flex-wrap items-center">
|
||||
<Badge color="blue">
|
||||
{input.fieldType === 'array' && input.subFieldType
|
||||
? `${capitalize(fieldTypeToTsType(input.subFieldType))}[]`
|
||||
: capitalize(fieldTypeToTsType(input.fieldType))}
|
||||
</Badge>
|
||||
|
||||
<ToggleButtonGroup bind:selected={inputSpecs[inputSpecKey].type}>
|
||||
<ToggleButton
|
||||
title="Static"
|
||||
position="left"
|
||||
value="static"
|
||||
startIcon={{ icon: faPen }}
|
||||
size="xs"
|
||||
iconOnly
|
||||
/>
|
||||
{#if rowColumns}
|
||||
{#if !inputSpecs[inputSpecKey].onlyStatic}
|
||||
<ToggleButtonGroup bind:selected={inputSpecs[inputSpecKey].type}>
|
||||
<ToggleButton
|
||||
title="From Row"
|
||||
position="center"
|
||||
value="row"
|
||||
startIcon={{ icon: faTableCells }}
|
||||
title="Static"
|
||||
position="left"
|
||||
value="static"
|
||||
startIcon={{ icon: faPen }}
|
||||
size="xs"
|
||||
iconOnly
|
||||
/>
|
||||
{#if rowColumns}
|
||||
<ToggleButton
|
||||
title="From Row"
|
||||
position="center"
|
||||
value="row"
|
||||
startIcon={{ icon: faTableCells }}
|
||||
size="xs"
|
||||
iconOnly
|
||||
disabled={staticOnly}
|
||||
/>
|
||||
{/if}
|
||||
{#if userInputEnabled && (!input.format?.startsWith('resource-') || true)}
|
||||
<ToggleButton
|
||||
title="User Input"
|
||||
position="center"
|
||||
value="user"
|
||||
startIcon={{ icon: faUser }}
|
||||
size="xs"
|
||||
iconOnly
|
||||
disabled={staticOnly}
|
||||
/>
|
||||
{/if}
|
||||
<ToggleButton
|
||||
title="Connected"
|
||||
position="right"
|
||||
value="connected"
|
||||
startIcon={{ icon: faArrowRight }}
|
||||
size="xs"
|
||||
iconOnly
|
||||
disabled={staticOnly}
|
||||
/>
|
||||
{/if}
|
||||
{#if userInputEnabled && (!input.format?.startsWith('resource-') || true)}
|
||||
<ToggleButton
|
||||
title="User Input"
|
||||
position="center"
|
||||
value="user"
|
||||
startIcon={{ icon: faUser }}
|
||||
size="xs"
|
||||
iconOnly
|
||||
disabled={staticOnly}
|
||||
/>
|
||||
{/if}
|
||||
<ToggleButton
|
||||
title="Connected"
|
||||
position="right"
|
||||
value="connected"
|
||||
startIcon={{ icon: faArrowRight }}
|
||||
size="xs"
|
||||
iconOnly
|
||||
disabled={staticOnly}
|
||||
/>
|
||||
</ToggleButtonGroup>
|
||||
</ToggleButtonGroup>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
{#each Object.keys($runnableComponents ?? {}).filter((id) => id !== ownId) as id}
|
||||
<tr>
|
||||
<td class="whitespace-nowrap px-4 py-2 text-xs">
|
||||
<Badge color="blue">{id}</Badge>
|
||||
<Badge color="dark-indigo">{id}</Badge>
|
||||
</td>
|
||||
<td class="relative whitespace-nowrap px-4 py-2 ">
|
||||
<input
|
||||
|
||||
@@ -68,7 +68,7 @@ export type Runnable = RunnableByPath | RunnableByName | undefined
|
||||
// Runnable input, set by the developer in the component panel
|
||||
export type ResultInput = {
|
||||
runnable: Runnable
|
||||
fields: Record<string, StaticAppInput | ConnectedAppInput | RowAppInput>
|
||||
fields: Record<string, StaticAppInput | ConnectedAppInput | RowAppInput | UserAppInput>
|
||||
type: 'runnable'
|
||||
}
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@ export function buildWorld(
|
||||
const state = writable(0)
|
||||
|
||||
const outputsById: Record<string, Record<string, Output<any>>> = {
|
||||
context: Object.fromEntries(Object.entries(context).map(([k, v]) => {
|
||||
return [k, newWorld.newOutput('context', k, state, v)]
|
||||
ctx: Object.fromEntries(Object.entries(context).map(([k, v]) => {
|
||||
return [k, newWorld.newOutput('ctx', k, state, v)]
|
||||
}))
|
||||
}
|
||||
for (const [k, outputs] of Object.entries(components)) {
|
||||
|
||||
@@ -53,7 +53,7 @@ export type Aligned = {
|
||||
export interface BaseAppComponent extends Partial<Aligned> {
|
||||
id: ComponentID
|
||||
componentInput: AppInput | undefined
|
||||
configuration: Record<string, StaticAppInput | ConnectedAppInput | UserAppInput>
|
||||
configuration: Record<string, (StaticAppInput | ConnectedAppInput | UserAppInput) & { onlyStatic?: boolean }>
|
||||
card: boolean | undefined
|
||||
/**
|
||||
* If `true` then the wrapper will allow items to flow outside of it's borders.
|
||||
|
||||
Reference in New Issue
Block a user