Files
windmill/frontend/src/lib/components/ModuleStep.svelte
T
Ruben Fiszel 9d991f968c feat: implement go support (#571)
* progress

* progress

* all in one

* frontend

* small nits

* go job test

* go.sum is optional

* add golang-go to backend test image

Co-authored-by: sqwishy <somebody@froghat.ca>
2022-09-13 21:14:21 +02:00

155 lines
4.4 KiB
Svelte

<script lang="ts">
import type { FlowModule } from '$lib/gen'
import { faChevronDown, faChevronUp } 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 { flowStore } from './flows/flowStore'
import {
createInlineScriptModule,
createLoop,
fork,
loadFlowModuleSchema,
pickScript,
createScriptFromInlineScript,
isEmptyFlowModule,
getStepPropPicker
} from './flows/flowStateUtils'
import SchemaForm from './SchemaForm.svelte'
import type { Schema } from '$lib/common'
import { flowStateStore, type FlowModuleSchema } from './flows/flowState'
import { stepOpened } from './flows/stepOpenedStore'
import { scriptLangToEditorLang } from '$lib/utils'
export let indexes: number[]
export let mod: FlowModule
export let args: Record<string, any> = {}
export let schema: Schema
export let childFlowModules: FlowModuleSchema[] | undefined = undefined
let editor: Editor
let websocketAlive = { pyright: false, black: false, deno: false }
let bigEditor = false
const i = indexes[0]
$: shouldPick = isEmptyFlowModule(mod)
$: stepPropPicker = getStepPropPicker(indexes, $flowStore.schema, $flowStateStore, args)
async function apply<T>(fn: (arg: T) => Promise<FlowModuleSchema>, arg: T) {
const flowModuleSchema = await fn(arg)
mod = flowModuleSchema.flowModule
schema = flowModuleSchema.schema
if (flowModuleSchema.childFlowModules) {
childFlowModules = flowModuleSchema.childFlowModules
}
}
async function reload(flowModule: FlowModule) {
apply(loadFlowModuleSchema, flowModule)
}
async function applyCreateLoop() {
await apply(createLoop, null)
stepOpened.update(() => `${indexes[0]}-0`)
}
$: opened = $stepOpened === String(indexes.join('-'))
</script>
<FlowBox
headerClickable={true}
on:clickheader={() => ($stepOpened = !opened ? String(indexes.join('-')) : undefined)}
>
<svelte:fragment slot="header">
<FlowModuleHeader
bind:mod
bind:indexes
on:delete
on:fork={() => apply(fork, mod)}
on:createScriptFromInlineScript={() => {
apply(createScriptFromInlineScript, {
flowModule: mod,
suffix: indexes.join('-'),
schema
})
}}
/>
</svelte:fragment>
<div slot="content">
{#if opened}
<div class="p-6 border-t border-gray-300">
{#if shouldPick}
<FlowInputs
shouldDisableTriggerScripts={i != 0}
shouldDisableLoopCreation={indexes.length > 1 || i == 0}
on:pick={(e) => apply(pickScript, e.detail.path)}
on:new={(e) =>
apply(createInlineScriptModule, {
language: e.detail.language,
kind: e.detail.kind,
subkind: e.detail.subkind
})}
on:loop={() => applyCreateLoop()}
/>
{/if}
{#if mod.value.type === 'rawscript'}
<div class="mb-2 overflow-hidden">
<EditorBar {editor} {websocketAlive} lang={mod.value.language ?? 'deno'} />
</div>
<div on:mouseleave={() => reload(mod)}>
<Editor
bind:websocketAlive
bind:this={editor}
class="{bigEditor ? 'h-2/3' : 'h-80'} border p-2 rounded"
bind:code={mod.value.content}
lang={scriptLangToEditorLang(mod.value.language)}
automaticLayout={true}
formatAction={() => reload(mod)}
/>
<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
{schema}
inputTransform={true}
importPath={String(indexes.join('-'))}
bind:pickableProperties={stepPropPicker.pickableProperties}
bind:args={mod.input_transforms}
bind:extraLib={stepPropPicker.extraLib}
/>
{/if}
{#if !shouldPick}
<div class="border-b border-gray-200" />
<div class="pt-2">
<FlowPreview bind:args flow={$flowStore} {i} {schema} />
</div>
{/if}
</div>
{/if}
</div>
</FlowBox>