mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-21 16:02:28 +00:00
feat: remove connect in favor of eval
This commit is contained in:
@@ -282,7 +282,7 @@
|
||||
editor.insertAtCursor(`v, _ := wmill.GetVariable("${path}")`)
|
||||
} else if (lang == 'bash') {
|
||||
editor.insertAtCursor(`curl -s -H "Authorization: Bearer $WM_TOKEN" \\
|
||||
"$BASE_INTERNAL_URL/api/w/$WM_WORKSPACE/variables/get_value/${path} | jq -r"`)
|
||||
"$BASE_INTERNAL_URL/api/w/$WM_WORKSPACE/variables/get_value/${path} | jq -r ."`)
|
||||
}
|
||||
sendUserToast(`${name} inserted at cursor`)
|
||||
}}
|
||||
|
||||
+9
-4
@@ -132,11 +132,11 @@
|
||||
|
||||
async function inferSuggestions(code: string) {
|
||||
const outputs = await parseOutputs(code, true)
|
||||
if (outputs) {
|
||||
for (const [key, id] of outputs) {
|
||||
if (outputs && inlineScript) {
|
||||
inlineScript.suggestedRefreshOn = []
|
||||
for (const [id, key] of outputs) {
|
||||
if (
|
||||
id in ($worldStore?.outputsById[key] ?? {}) &&
|
||||
inlineScript &&
|
||||
key in ($worldStore?.outputsById[id] ?? {}) &&
|
||||
!itemsExists(inlineScript.refreshOn, { key, id }) &&
|
||||
!itemsExists(inlineScript.suggestedRefreshOn, { key, id })
|
||||
) {
|
||||
@@ -146,6 +146,7 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
$stateId++
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -169,6 +170,10 @@
|
||||
bind:value={name}
|
||||
placeholder="Inline script name"
|
||||
class="!text-xs !rounded-xs"
|
||||
on:keydown={() => {
|
||||
$app = $app
|
||||
$stateId++
|
||||
}}
|
||||
/>
|
||||
{:else}
|
||||
<span class="text-xs font-semibold truncate w-full">{name} of {id}</span>
|
||||
|
||||
+51
-8
@@ -1,16 +1,19 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from 'svelte'
|
||||
import type { AppInput } from '../../inputType'
|
||||
import type { AppInput, InputConnection } from '../../inputType'
|
||||
import type { AppViewerContext } from '../../types'
|
||||
import { CurlyBraces, FunctionSquare, Pen, Plug2 } from 'lucide-svelte'
|
||||
import { Code, CurlyBraces, FunctionSquare, Pen, Plug, Plug2 } from 'lucide-svelte'
|
||||
|
||||
import ToggleButtonGroup from '$lib/components/common/toggleButton-v2/ToggleButtonGroup.svelte'
|
||||
import ToggleButton from '$lib/components/common/toggleButton-v2/ToggleButton.svelte'
|
||||
import { Button } from '$lib/components/common'
|
||||
import type EvalV2InputEditor from './inputEditor/EvalV2InputEditor.svelte'
|
||||
|
||||
export let componentInput: AppInput
|
||||
export let disableStatic: boolean = false
|
||||
export let evalV2editor: EvalV2InputEditor | undefined
|
||||
|
||||
const { onchange } = getContext<AppViewerContext>('AppViewerContext')
|
||||
const { onchange, connectingInput, app } = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
$: if (componentInput.fieldType == 'template' && componentInput.type == 'static') {
|
||||
//@ts-ignore
|
||||
@@ -19,16 +22,30 @@
|
||||
componentInput['connections'] = [{ componentId: 'ctx', id: 'email' }]
|
||||
}
|
||||
|
||||
function applyConnection(connection: InputConnection) {
|
||||
const expr = `${connection.componentId}.${connection.path}`
|
||||
//@ts-ignore
|
||||
componentInput = {
|
||||
...componentInput,
|
||||
type: 'evalv2',
|
||||
expr: expr,
|
||||
connections: [{ componentId: connection.componentId, id: connection.path.split('.')[0] }]
|
||||
}
|
||||
evalV2editor?.setCode(expr)
|
||||
$app = $app
|
||||
}
|
||||
|
||||
let clientWidth: number
|
||||
</script>
|
||||
|
||||
{#if componentInput.fieldType !== 'any'}
|
||||
<div class="w-full">
|
||||
<div class="mx-auto" bind:clientWidth>
|
||||
<div class="mx-auto flex gap-2" bind:clientWidth>
|
||||
<ToggleButtonGroup
|
||||
on:selected={() => {
|
||||
onchange?.()
|
||||
}}
|
||||
noWFull
|
||||
bind:selected={componentInput.type}
|
||||
>
|
||||
{#if componentInput.fieldType === 'template'}
|
||||
@@ -58,15 +75,41 @@
|
||||
icon={Pen}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<ToggleButton value="connected" icon={Plug2} iconOnly={clientWidth < 250} label="Connect" />
|
||||
{#if componentInput.type == 'connected'}
|
||||
<ToggleButton
|
||||
value="connected"
|
||||
icon={Plug2}
|
||||
iconOnly={clientWidth < 250}
|
||||
label="Connect"
|
||||
/>
|
||||
{/if}
|
||||
<ToggleButton
|
||||
value="runnable"
|
||||
value="evalv2"
|
||||
icon={FunctionSquare}
|
||||
iconOnly={clientWidth < 250}
|
||||
label="Compute"
|
||||
label="Eval"
|
||||
/>
|
||||
|
||||
<ToggleButton value="runnable" icon={Code} iconOnly={clientWidth < 250} label="Compute" />
|
||||
</ToggleButtonGroup>
|
||||
<div class="flex">
|
||||
<Button
|
||||
size="xs"
|
||||
variant="border"
|
||||
color="light"
|
||||
title="Connect"
|
||||
on:click={() => {
|
||||
$connectingInput = {
|
||||
opened: true,
|
||||
input: undefined,
|
||||
hoveredComponent: undefined,
|
||||
onConnect: applyConnection
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Plug size={12} />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
import GridCondition from './GridCondition.svelte'
|
||||
import { isTriggerable } from './script/utils'
|
||||
import { inferDeps } from '../appUtilsInfer'
|
||||
import EvalV2InputEditor from './inputEditor/EvalV2InputEditor.svelte'
|
||||
import type { ResultAppInput } from '../../inputType'
|
||||
|
||||
export let componentSettings: { item: GridItem; parent: string | undefined } | undefined =
|
||||
undefined
|
||||
@@ -127,6 +129,35 @@
|
||||
const hasInteraction = componentSettings?.item.data.type
|
||||
? isTriggerable(componentSettings?.item.data.type)
|
||||
: false
|
||||
|
||||
let evalV2editor: EvalV2InputEditor | undefined = undefined
|
||||
|
||||
function transformToFrontend() {
|
||||
if (componentSettings?.item.data.componentInput) {
|
||||
const id = componentSettings?.item?.data?.id
|
||||
let appInput: ResultAppInput = {
|
||||
...componentSettings.item.data.componentInput,
|
||||
type: 'runnable',
|
||||
runnable: {
|
||||
type: 'runnableByName',
|
||||
name: `Eval of ${id}`,
|
||||
inlineScript: {
|
||||
path: `${id}_eval`,
|
||||
content: `return ${componentSettings?.item.data.componentInput?.['expr']}`,
|
||||
language: 'frontend',
|
||||
refreshOn: componentSettings?.item.data.componentInput?.['connections']?.map((c) => {
|
||||
return {
|
||||
id: c.componentId,
|
||||
key: c.id
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
fields: {}
|
||||
}
|
||||
componentSettings.item.data.componentInput = appInput
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window on:keydown={keydown} />
|
||||
@@ -171,6 +202,7 @@
|
||||
|
||||
{#if componentSettings.item.data.componentInput}
|
||||
<ComponentInputTypeEditor
|
||||
{evalV2editor}
|
||||
bind:componentInput={componentSettings.item.data.componentInput}
|
||||
/>
|
||||
|
||||
@@ -219,6 +251,15 @@
|
||||
<ConnectedInputEditor
|
||||
bind:componentInput={componentSettings.item.data.componentInput}
|
||||
/>
|
||||
{:else if componentSettings.item.data.componentInput.type === 'evalv2' && component.componentInput !== undefined}
|
||||
<EvalV2InputEditor
|
||||
bind:this={evalV2editor}
|
||||
id={component.id}
|
||||
bind:componentInput={componentSettings.item.data.componentInput}
|
||||
/>
|
||||
<a class="text-2xs" on:click={transformToFrontend} href="#"
|
||||
>transform to a frontend script</a
|
||||
>
|
||||
{:else if componentSettings.item.data.componentInput?.type === 'runnable' && component.componentInput !== undefined}
|
||||
<RunnableInputEditor
|
||||
appComponent={component}
|
||||
@@ -257,7 +298,7 @@
|
||||
</PanelSection>
|
||||
{/if}
|
||||
{#if Object.values(initialConfiguration).length > 0}
|
||||
<PanelSection title={`Configuration (${Object.values(initialConfiguration).length})`}>
|
||||
<PanelSection title="Configuration">
|
||||
<InputsSpecsEditor
|
||||
id={component.id}
|
||||
inputSpecsConfiguration={initialConfiguration}
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
expr: expr,
|
||||
connections: [{ componentId: connection.componentId, id: connection.path.split('.')[0] }]
|
||||
}
|
||||
evalV2editor.setCode(expr)
|
||||
evalV2editor?.setCode(expr)
|
||||
$app = $app
|
||||
}
|
||||
|
||||
@@ -113,22 +113,24 @@
|
||||
{/if}
|
||||
<ToggleButton value="evalv2" icon={FunctionSquare} iconOnly tooltip="Eval" />
|
||||
</ToggleButtonGroup>
|
||||
<Button
|
||||
size="xs"
|
||||
variant="border"
|
||||
color="light"
|
||||
title="Connect"
|
||||
on:click={() => {
|
||||
$connectingInput = {
|
||||
opened: true,
|
||||
input: undefined,
|
||||
hoveredComponent: undefined,
|
||||
onConnect: applyConnection
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Plug size={12} />
|
||||
</Button>
|
||||
<div>
|
||||
<Button
|
||||
size="xs"
|
||||
variant="border"
|
||||
color="light"
|
||||
title="Connect"
|
||||
on:click={() => {
|
||||
$connectingInput = {
|
||||
opened: true,
|
||||
input: undefined,
|
||||
hoveredComponent: undefined,
|
||||
onConnect: applyConnection
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Plug size={14} />
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+11
-9
@@ -28,7 +28,7 @@
|
||||
|
||||
let runnable = appInput.runnable
|
||||
|
||||
const { runnableComponents } = getContext<AppViewerContext>('AppViewerContext')
|
||||
const { runnableComponents, stateId } = getContext<AppViewerContext>('AppViewerContext')
|
||||
export let actions: ActionType[] = []
|
||||
|
||||
function updateAutoRefresh() {
|
||||
@@ -50,14 +50,16 @@
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<ScriptSettingHeader
|
||||
name={runnable?.type === 'runnableByName'
|
||||
? runnable.name
|
||||
: runnable?.type === 'runnableByPath'
|
||||
? runnable.path
|
||||
: ''}
|
||||
{actions}
|
||||
/>
|
||||
{#key $stateId}
|
||||
<ScriptSettingHeader
|
||||
name={runnable?.type === 'runnableByName'
|
||||
? runnable.name
|
||||
: runnable?.type === 'runnableByPath'
|
||||
? runnable.path
|
||||
: ''}
|
||||
{actions}
|
||||
/>
|
||||
{/key}
|
||||
{#if !isTriggerable(appComponent.type)}
|
||||
<div class="flex items-center justify-between w-full">
|
||||
<div class="flex flex-row items-center gap-2 text-xs"> Hide Refresh Button </div>
|
||||
|
||||
+26
-24
@@ -17,7 +17,7 @@
|
||||
|
||||
$: changeEvents = isFrontend
|
||||
? inlineScript?.refreshOn
|
||||
? inlineScript.refreshOn.map((x) => `${x.id} - ${x.key}`)
|
||||
? inlineScript.refreshOn.map((x) => `${x.id}.${x.key}`)
|
||||
: []
|
||||
: dependencies
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
indigo: 'text-indigo-800 border-indigo-600 bg-indigo-100',
|
||||
blue: 'text-blue-800 border-blue-600 bg-blue-100'
|
||||
}
|
||||
const { connectingInput, app } = getContext<AppViewerContext>('AppViewerContext')
|
||||
const { connectingInput, app, stateId } = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
function applyConnection(connection: InputConnection) {
|
||||
const refresh = {
|
||||
@@ -70,7 +70,7 @@
|
||||
</div>
|
||||
{/if}
|
||||
{#if changeEvents.length > 0 && shoudlDisplayChangeEvents}
|
||||
<div class="text-xs font-semibold text-secondary mb-1 mt-2">Change on value</div>
|
||||
<div class="text-xs font-semibold text-secondary mb-1 mt-2">Values watched</div>
|
||||
<div class="flex flex-row gap-2 flex-wrap">
|
||||
{#each changeEvents as changeEvent}
|
||||
<span class={classNames(badgeClass, colors['blue'])}>
|
||||
@@ -88,9 +88,9 @@
|
||||
on:click={() => {
|
||||
if (inlineScript?.refreshOn) {
|
||||
inlineScript.refreshOn = inlineScript.refreshOn.filter(
|
||||
(x) => `${x.id} - ${x.key}` !== changeEvent
|
||||
(x) => `${x.id}.${x.key}` !== changeEvent
|
||||
)
|
||||
const ch = changeEvent.split(' - ')
|
||||
const ch = changeEvent.split('.')
|
||||
const suggestion = {
|
||||
id: ch[0],
|
||||
key: ch[1]
|
||||
@@ -135,26 +135,28 @@
|
||||
{#if (inlineScript?.suggestedRefreshOn ?? []).length > 0}
|
||||
<div class="gap-1 flex flex-wrap mb-2"
|
||||
><span class="text-secondary text-sm">Quick add:</span>
|
||||
{#each inlineScript?.suggestedRefreshOn ?? [] as suggestion}
|
||||
<button
|
||||
class={classNames(
|
||||
'p-0.5 rounded-md hover:bg-blue-400 cursor-pointer !text-2xs text-secondary',
|
||||
badgeClass
|
||||
)}
|
||||
on:click={() => {
|
||||
if (inlineScript) {
|
||||
if (!itemsExists(inlineScript.refreshOn, suggestion)) {
|
||||
inlineScript.refreshOn = [...(inlineScript.refreshOn ?? []), suggestion]
|
||||
inlineScript.suggestedRefreshOn = inlineScript.suggestedRefreshOn?.filter(
|
||||
(x) => !deepEqual(x, suggestion)
|
||||
)
|
||||
{#key $stateId}
|
||||
{#each inlineScript?.suggestedRefreshOn ?? [] as suggestion}
|
||||
<button
|
||||
class={classNames(
|
||||
'p-0.5 rounded-md hover:bg-blue-400 cursor-pointer !text-2xs text-secondary',
|
||||
badgeClass
|
||||
)}
|
||||
on:click={() => {
|
||||
if (inlineScript) {
|
||||
if (!itemsExists(inlineScript.refreshOn, suggestion)) {
|
||||
inlineScript.refreshOn = [...(inlineScript.refreshOn ?? []), suggestion]
|
||||
inlineScript.suggestedRefreshOn = inlineScript.suggestedRefreshOn?.filter(
|
||||
(x) => !deepEqual(x, suggestion)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
+{suggestion.key}-{suggestion.id}
|
||||
</button>
|
||||
{/each}
|
||||
}}
|
||||
>
|
||||
+{suggestion.id}.{suggestion.key}
|
||||
</button>
|
||||
{/each}
|
||||
{/key}
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
@@ -46,8 +46,7 @@
|
||||
{label}
|
||||
{/if}
|
||||
</Tab>
|
||||
|
||||
<svelte:fragment slot="text">
|
||||
{tooltip ?? label}
|
||||
{tooltip}
|
||||
</svelte:fragment>
|
||||
</Popover>
|
||||
|
||||
Reference in New Issue
Block a user