mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-20 16:02:19 +00:00
feat(apps): state can be used as input in apps
This commit is contained in:
@@ -84,7 +84,8 @@
|
||||
true,
|
||||
$state,
|
||||
$mode == 'dnd',
|
||||
$componentControl
|
||||
$componentControl,
|
||||
$worldStore
|
||||
)
|
||||
error = ''
|
||||
return r
|
||||
@@ -103,7 +104,8 @@
|
||||
true,
|
||||
$state,
|
||||
$mode == 'dnd',
|
||||
$componentControl
|
||||
$componentControl,
|
||||
$worldStore
|
||||
)
|
||||
error = ''
|
||||
return r
|
||||
|
||||
@@ -163,7 +163,8 @@
|
||||
false,
|
||||
$state,
|
||||
$mode == 'dnd',
|
||||
$componentControl
|
||||
$componentControl,
|
||||
$worldStore
|
||||
)
|
||||
setResult(r)
|
||||
$state = $state
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { goto } from '$app/navigation'
|
||||
import { sendUserToast } from '$lib/utils'
|
||||
import type { World } from '../../rx'
|
||||
|
||||
@@ -10,7 +9,7 @@ export function computeGlobalContext(
|
||||
return {
|
||||
...Object.fromEntries(
|
||||
Object.entries(world?.outputsById ?? {})
|
||||
.filter(([k, _]) => k != id)
|
||||
.filter(([k, _]) => k != id && k != 'state')
|
||||
.map(([key, value]) => {
|
||||
return [
|
||||
key,
|
||||
@@ -47,17 +46,29 @@ function make_context_evaluator(
|
||||
}
|
||||
|
||||
export async function eval_like(
|
||||
text,
|
||||
text: string,
|
||||
context = {},
|
||||
noReturn: boolean,
|
||||
state: any,
|
||||
state: Record<string, any>,
|
||||
editor: boolean,
|
||||
controlComponents: Record<string, { setTab?: (index: number) => void }>
|
||||
controlComponents: Record<string, { setTab?: (index: number) => void }>,
|
||||
worldStore: World | undefined
|
||||
) {
|
||||
const proxiedState = new Proxy(state, {
|
||||
set(target, key, value) {
|
||||
if (typeof key !== 'string') {
|
||||
throw new Error('Invalid key')
|
||||
}
|
||||
let o = worldStore?.newOutput('state', key, value)
|
||||
o?.set(value)
|
||||
target[key] = value
|
||||
return true
|
||||
}
|
||||
})
|
||||
let evaluator = make_context_evaluator(text, context, noReturn)
|
||||
return await evaluator(
|
||||
context,
|
||||
state,
|
||||
proxiedState,
|
||||
async (x, newTab) => {
|
||||
if (newTab || editor) {
|
||||
if (!newTab) {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
import { push } from '$lib/history'
|
||||
import { expandGriditem, findGridItem } from './appUtils'
|
||||
import Grid from '../svelte-grid/Grid.svelte'
|
||||
import { settableOutput } from '../rx'
|
||||
|
||||
export let policy: Policy
|
||||
|
||||
|
||||
@@ -75,14 +75,14 @@
|
||||
/>
|
||||
</OutputHeader>
|
||||
|
||||
<OutputHeader id={'State'} name={'State'} color="blue" {expanded}>
|
||||
{#key $state}
|
||||
{#if Object.keys(filteredState).length > 0}
|
||||
<ObjectViewer json={filteredState} />
|
||||
{:else}
|
||||
<div class="text-xs pl-2">No results</div>
|
||||
{/if}
|
||||
{/key}
|
||||
<OutputHeader id={'state'} name={'State'} color="blue" {expanded}>
|
||||
<ComponentOutputViewer
|
||||
componentId={'state'}
|
||||
outputs={Object.keys($state)}
|
||||
on:select={({ detail }) => {
|
||||
$connectingInput = connectInput($connectingInput, 'state', detail)
|
||||
}}
|
||||
/>
|
||||
</OutputHeader>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
class={classNames(
|
||||
'flex items-center justify-between p-1 cursor-pointer border-b',
|
||||
'flex items-center justify-between p-1 cursor-pointer border-b gap-1 truncate',
|
||||
hoverColor[color],
|
||||
open && !manuallyOpen ? openBackground[color] : 'bg-white',
|
||||
first ? 'border-t' : '',
|
||||
@@ -66,7 +66,7 @@
|
||||
>
|
||||
{id}
|
||||
</div>
|
||||
<div class="text-2xs font-bold flex flex-row gap-2 items-center">
|
||||
<div class="text-2xs font-bold flex flex-row gap-2 items-center truncate">
|
||||
{name}
|
||||
{#if !open && !manuallyOpen}
|
||||
<ChevronDown size={14} />
|
||||
|
||||
@@ -23,6 +23,7 @@ export type World = {
|
||||
outputsById: Record<string, Record<string, Output<any>>>
|
||||
connect: <T>(inputSpec: AppInput, next: (x: T) => void, id?: string) => Input<T>
|
||||
stateId: Writable<number>
|
||||
newOutput: <T>(id: string, name: string, previousValue: T) => Output<T>
|
||||
}
|
||||
|
||||
export function buildWorld(
|
||||
@@ -38,7 +39,8 @@ export function buildWorld(
|
||||
Object.entries(context).map(([k, v]) => {
|
||||
return [k, newWorld.newOutput('ctx', k, stateId, v)]
|
||||
})
|
||||
)
|
||||
),
|
||||
state: previousWorld?.outputsById?.state ?? {}
|
||||
}
|
||||
for (const [k, outputs] of Object.entries(components)) {
|
||||
outputsById[k] = {}
|
||||
@@ -52,9 +54,20 @@ export function buildWorld(
|
||||
)
|
||||
}
|
||||
}
|
||||
function newOutput<T>(id: string, name: string, previousValue: T) {
|
||||
if (outputsById[id]?.[name]) {
|
||||
return outputsById[id][name]
|
||||
}
|
||||
let o = newWorld.newOutput(id, name, stateId, previousValue)
|
||||
if (!outputsById[id]) {
|
||||
outputsById[id] = {}
|
||||
}
|
||||
outputsById[id][name] = o
|
||||
return o
|
||||
}
|
||||
stateId.update((x) => x + 1)
|
||||
|
||||
return { outputsById, connect: newWorld.connect, stateId }
|
||||
return { outputsById, connect: newWorld.connect, stateId, newOutput }
|
||||
}
|
||||
|
||||
export function buildObservableWorld() {
|
||||
@@ -166,7 +179,6 @@ export function settableOutput<T>(state: Writable<number>, previousValue: T): Ou
|
||||
state.update((x) => x + 1)
|
||||
|
||||
value = x
|
||||
|
||||
subscribers.forEach((x) => x.next(value!))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user