mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-07 08:02:40 +00:00
* Improve flow ui * Finish reworking * Fix formating * Fix naviation * Fix navigaion + adjust icon sizes * Remove duplicate code Co-authored-by: Ruben Fiszel <ruben@rubenfiszel.com>
181 lines
5.1 KiB
Svelte
181 lines
5.1 KiB
Svelte
<script lang="ts">
|
|
import { RawScript, type FlowModule } from '$lib/gen'
|
|
import { previewResults } from '$lib/stores'
|
|
import { buildExtraLib, objectToTsType, schemaToTsType } from '$lib/utils'
|
|
import { faChevronDown, faChevronUp, faPlus } from '@fortawesome/free-solid-svg-icons'
|
|
import Icon from 'svelte-awesome'
|
|
import Editor from './Editor.svelte'
|
|
import EditorBar from './EditorBar.svelte'
|
|
import FlowPreview from './FlowPreview.svelte'
|
|
import FlowBox from './flows/FlowBox.svelte'
|
|
import FlowInputs from './flows/FlowInputs.svelte'
|
|
import FlowModuleHeader from './flows/FlowModuleHeader.svelte'
|
|
import {
|
|
addModule,
|
|
createInlineScriptModule,
|
|
flowStore,
|
|
loadSchema,
|
|
pickScript,
|
|
schemasStore,
|
|
type FlowMode
|
|
} from './flows/flowStore'
|
|
import { getPickableProperties } from './flows/utils'
|
|
import SchemaForm from './SchemaForm.svelte'
|
|
import Tooltip from './Tooltip.svelte'
|
|
|
|
export let open: number
|
|
export let mode: FlowMode
|
|
export let i: number
|
|
export let mod: FlowModule
|
|
export let args: Record<string, any> = {}
|
|
|
|
let editor: Editor
|
|
let websocketAlive = { pyright: false, black: false, deno: false }
|
|
let pickableProperties: Object | undefined = undefined
|
|
|
|
let bigEditor = false
|
|
|
|
$: schema = $schemasStore[i]
|
|
$: shouldPick = 'path' in mod.value && mod.value.path === '' && !('language' in mod.value)
|
|
$: pickableProperties = getPickableProperties($flowStore?.schema, args, $previewResults, mode, i)
|
|
$: extraLib = buildExtraLib(
|
|
schemaToTsType($flowStore?.schema),
|
|
i === 0 ? schemaToTsType($flowStore?.schema) : objectToTsType($previewResults[i])
|
|
)
|
|
|
|
function toResults(jobs: any) {
|
|
return jobs.map((job) => {
|
|
if (job.result) {
|
|
return job.result
|
|
} else if (Array.isArray(job)) {
|
|
return toResults(job)
|
|
}
|
|
})
|
|
}
|
|
|
|
const isTrigger = mode === 'pull' && i === 0
|
|
</script>
|
|
|
|
<button
|
|
class="rounded-full h-10 w-10 bg-white border-2 border-gray-400"
|
|
on:click={() => {
|
|
addModule(i)
|
|
open = i
|
|
}}
|
|
>
|
|
<Icon class="text-gray-400 mb-1" data={faPlus} />
|
|
</button>
|
|
<FlowBox>
|
|
<div id="module-{i}">
|
|
<FlowModuleHeader bind:open {mod} {i} {shouldPick}>
|
|
<div>
|
|
<h3 class="text-lg font-bold text-gray-900">Step {i + 1}</h3>
|
|
{#if isTrigger}
|
|
<h3 class="font-bold">
|
|
Trigger Script
|
|
<Tooltip>
|
|
When a flow is 'Pull', the first step is a trigger script. Trigger scripts are scripts
|
|
that must return a list which are the new items to be treated one by one by the rest
|
|
of the flow, usually the list of new items since last time the flow was run. One can
|
|
retrieve the item in the next step using `previous_result._value`. To easily compute
|
|
the diff, windmill provides some helpers under the form of `getInternalState` and
|
|
`setInternalState`.
|
|
</Tooltip>
|
|
</h3>
|
|
{/if}
|
|
<p>
|
|
{#if 'path' in mod.value && mod.value.path}
|
|
{mod.value.path}
|
|
{/if}
|
|
{#if 'language' in mod.value && mod.value.language}
|
|
Inline {mod.value.language}
|
|
{/if}
|
|
{#if !('path' in mod.value) && !('language' in mod.value)}
|
|
Select a script
|
|
{/if}
|
|
</p>
|
|
</div>
|
|
</FlowModuleHeader>
|
|
{#if open == i}
|
|
<div class="p-6">
|
|
{#if shouldPick}
|
|
<FlowInputs
|
|
{isTrigger}
|
|
on:pick={(e) => pickScript(e.detail.path, i)}
|
|
on:new={(e) => createInlineScriptModule(e.detail.language, i, mode)}
|
|
/>
|
|
{/if}
|
|
{#if mod.value.type === 'rawscript'}
|
|
<div class="mb-2 overflow-hidden">
|
|
<EditorBar {editor} {websocketAlive} lang={mod.value.language ?? 'deno'} />
|
|
</div>
|
|
<div>
|
|
<Editor
|
|
bind:websocketAlive
|
|
bind:this={editor}
|
|
class="{bigEditor ? 'h-2/3' : 'h-80'} border p-2 rounded"
|
|
bind:code={mod.value.content}
|
|
deno={mod.value.language === RawScript.language.DENO}
|
|
automaticLayout={true}
|
|
on:blur={() => loadSchema(i)}
|
|
formatAction={() => loadSchema(i)}
|
|
/>
|
|
<button
|
|
class="w-full text-center"
|
|
on:click={() => {
|
|
bigEditor = !bigEditor
|
|
}}><Icon data={bigEditor ? faChevronUp : faChevronDown} scale={1.0} /></button
|
|
>
|
|
</div>
|
|
<div class="mt-2 mb-8">
|
|
<p class="text-gray-500 italic">
|
|
Move the focus outside of the text editor to recompute the input schema or press
|
|
Ctrl/Cmd+S
|
|
</p>
|
|
</div>
|
|
{/if}
|
|
{#if !shouldPick}
|
|
<p class="text-lg font-bold text-gray-900 mb-2">Step inputs</p>
|
|
<SchemaForm
|
|
inputTransform={true}
|
|
{schema}
|
|
{extraLib}
|
|
{i}
|
|
bind:pickableProperties
|
|
bind:args={mod.input_transform}
|
|
/>
|
|
{/if}
|
|
</div>
|
|
|
|
{#if !shouldPick}
|
|
<div class="border-b border-gray-200" />
|
|
<div class="p-3">
|
|
<FlowPreview
|
|
bind:args
|
|
flow={$flowStore}
|
|
{i}
|
|
{mode}
|
|
schemas={$schemasStore}
|
|
on:change={(e) => {
|
|
previewResults.set(toResults(e.detail))
|
|
}}
|
|
/>
|
|
</div>
|
|
{/if}
|
|
{/if}
|
|
{#if open == i}
|
|
<div>
|
|
<button class="w-full h-full" on:click={() => (open = -1)}>
|
|
<Icon data={faChevronUp} scale={1.0} />
|
|
</button>
|
|
</div>
|
|
{:else}
|
|
<div>
|
|
<button class="w-full h-full" on:click={() => (open = i)}>
|
|
<Icon data={faChevronDown} scale={1.0} />
|
|
</button>
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
</FlowBox>
|