mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-25 00:01:55 +00:00
flow UI improvements
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
export let pathError = ''
|
||||
export let initialPath: string = ''
|
||||
|
||||
let open = -1
|
||||
let args: Record<string, any> = {}
|
||||
export let mode: FlowMode =
|
||||
$flowStore?.value.modules[1]?.value.type == FlowModuleValue.type.FORLOOPFLOW ? 'pull' : 'push'
|
||||
@@ -94,20 +95,36 @@
|
||||
<CopyFirstStepSchema />
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<SchemaEditor bind:schema={$flowStore.schema} />
|
||||
<SchemaEditor schema={$flowStore.schema} />
|
||||
<div class="my-4" />
|
||||
<FlowPreview {mode} bind:flow={$flowStore} i={numberOfSteps} bind:args />
|
||||
<FlowPreview {mode} flow={$flowStore} i={numberOfSteps} bind:args />
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{#each $flowStore?.value.modules as mod, i}
|
||||
<ModuleStep bind:mod bind:args {i} {mode} />
|
||||
<li class="relative mt-16">
|
||||
<div class="relative flex justify-center">
|
||||
<button
|
||||
class="default-button h-10 w-10 shadow-blue-600/40 border-blue-600 shadow"
|
||||
on:click={() => {
|
||||
addModule(i)
|
||||
open = i
|
||||
}}
|
||||
>
|
||||
<Icon class="text-white mb-1" data={faPlus} />
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<ModuleStep bind:open bind:mod bind:args {i} {mode} />
|
||||
{/each}
|
||||
<li class="relative m-20 ">
|
||||
<div class="relative flex justify-center">
|
||||
<button
|
||||
class="default-button h-10 w-10 shadow-blue-600/40 border-blue-600 shadow"
|
||||
on:click={() => addModule()}
|
||||
on:click={() => {
|
||||
addModule()
|
||||
open = $flowStore?.value.modules.length - 1
|
||||
}}
|
||||
>
|
||||
<Icon class="text-white mb-1" data={faPlus} />
|
||||
Add step
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
type FlowMode
|
||||
} from './flows/flowStore'
|
||||
import SchemaForm from './SchemaForm.svelte'
|
||||
import { slide } from 'svelte/transition'
|
||||
|
||||
export let open: number
|
||||
export let mode: FlowMode
|
||||
export let i: number
|
||||
export let mod: FlowModule
|
||||
@@ -29,61 +31,79 @@
|
||||
)
|
||||
</script>
|
||||
|
||||
<li class="flex flex-row flex-shrink max-w-full mx-auto mt-20">
|
||||
<li class="flex flex-row flex-shrink max-w-full mx-auto mt-16">
|
||||
<div class="bg-white border border-gray xl-rounded shadow-lg w-full max-w-4xl mx-4 md:mx-auto">
|
||||
<div class="flex items-center justify-between flex-wra p-4 sm:px-6">
|
||||
<FlowModuleHeader bind:i bind:shouldPick>
|
||||
<FlowModuleHeader bind:open {mod} {i} {shouldPick}>
|
||||
<h3 class="text-lg font-bold text-gray-900">Step {i + 1}</h3>
|
||||
<p>{mod.value.path ?? ''}</p>
|
||||
<p>
|
||||
{#if mod.value.path}
|
||||
{mod.value.path}
|
||||
{/if}
|
||||
{#if mod.value.language}
|
||||
Inline {mod.value.language}
|
||||
{/if}
|
||||
</p>
|
||||
</FlowModuleHeader>
|
||||
</div>
|
||||
<div class="border-b border-gray-200" />
|
||||
<div class="p-6">
|
||||
{#if shouldPick}
|
||||
<FlowInputs
|
||||
isTrigger={mode == 'pull' && i == 0}
|
||||
on:pick={(e) => pickScript(e.detail.path, i)}
|
||||
on:new={(e) => createInlineScriptModule(e.detail.language, i, mode)}
|
||||
/>
|
||||
{/if}
|
||||
{#if mod.value.type === FlowModuleValue.type.RAWSCRIPT}
|
||||
<div class="h-96">
|
||||
<Editor
|
||||
class="h-full"
|
||||
bind:code={mod.value.content}
|
||||
deno={mod.value.language === FlowModuleValue.language.DENO}
|
||||
/>
|
||||
{#if open == i}
|
||||
<div transition:slide>
|
||||
<div class="p-6">
|
||||
{#if shouldPick}
|
||||
<FlowInputs
|
||||
isTrigger={mode == 'pull' && i == 0}
|
||||
on:pick={(e) => pickScript(e.detail.path, i)}
|
||||
on:new={(e) => createInlineScriptModule(e.detail.language, i, mode)}
|
||||
/>
|
||||
{/if}
|
||||
{#if mod.value.type === FlowModuleValue.type.RAWSCRIPT}
|
||||
<div class="h-96">
|
||||
<Editor
|
||||
class="h-full"
|
||||
bind:code={mod.value.content}
|
||||
deno={mod.value.language === FlowModuleValue.language.DENO}
|
||||
/>
|
||||
</div>
|
||||
<button class="default-button w-full p-1 mt-4" on:click={() => loadSchema(i)}>
|
||||
Infer schema
|
||||
</button>
|
||||
{/if}
|
||||
{#if !shouldPick}
|
||||
<h2 class="mb-4">Step inputs</h2>
|
||||
<SchemaForm
|
||||
inputTransform={true}
|
||||
{schema}
|
||||
{extraLib}
|
||||
{i}
|
||||
{previousSchema}
|
||||
bind:args={mod.input_transform}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
<button class="default-button w-full p-1 mt-4" on:click={() => loadSchema(i)}>
|
||||
Infer schema
|
||||
</button>
|
||||
{/if}
|
||||
{#if !shouldPick}
|
||||
<h2 class="mb-4">Step inputs</h2>
|
||||
<SchemaForm
|
||||
inputTransform={true}
|
||||
{schema}
|
||||
{extraLib}
|
||||
{i}
|
||||
{previousSchema}
|
||||
bind:args={mod.input_transform}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if !shouldPick}
|
||||
<div class="border-b border-gray-200" />
|
||||
<div class="p-3">
|
||||
<FlowPreview
|
||||
bind:args
|
||||
bind:flow={$flowStore}
|
||||
{i}
|
||||
{mode}
|
||||
bind:schemas={$schemasStore}
|
||||
on:change={(e) => {
|
||||
addPreviewResult(e.detail.result, i + 1)
|
||||
}}
|
||||
/>
|
||||
{#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) => {
|
||||
addPreviewResult(e.detail.result, i + 1)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div>
|
||||
<button class="w-full h-full" on:click={() => (open = -1)}>(-)</button>
|
||||
</div>
|
||||
{:else}
|
||||
<div>
|
||||
<button class="w-full h-full" on:click={() => (open = i)}>(+)</button>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
<script lang="ts">
|
||||
import { FlowModuleValue, Script } from '$lib/gen'
|
||||
import { faCode, faCodeBranch, faPlus, faTrashAlt } from '@fortawesome/free-solid-svg-icons'
|
||||
import { FlowModuleValue, Script, type FlowModule } from '$lib/gen'
|
||||
import { faCode, faCodeBranch, faSave, faTrashAlt } from '@fortawesome/free-solid-svg-icons'
|
||||
import Icon from 'svelte-awesome'
|
||||
import { Highlight } from 'svelte-highlight'
|
||||
import { python, typescript } from 'svelte-highlight/languages'
|
||||
import github from 'svelte-highlight/styles/github'
|
||||
import Modal from '../Modal.svelte'
|
||||
import { createScriptFromInlineScript, flowStore, fork, removeModule } from './flowStore'
|
||||
import { createScriptFromInlineScript, fork, removeModule } from './flowStore'
|
||||
import { getScriptByPath } from './utils'
|
||||
|
||||
export let open: number
|
||||
export let i: number
|
||||
export let shouldPick = false
|
||||
export let mod: FlowModule
|
||||
|
||||
$: mod = $flowStore.value.modules[i]
|
||||
let modalViewer: Modal
|
||||
let modalViewerContent = ''
|
||||
let modalViewerLanguage: Script.language = Script.language.DENO
|
||||
@@ -34,7 +35,14 @@
|
||||
</div>
|
||||
<div>
|
||||
{#if mod.value.type === FlowModuleValue.type.SCRIPT && !shouldPick}
|
||||
<button type="button" on:click={() => fork(i)} class="default-secondary-button-v2 text-xs">
|
||||
<button
|
||||
type="button"
|
||||
on:click={() => {
|
||||
open = i
|
||||
fork(i)
|
||||
}}
|
||||
class="default-secondary-button-v2 text-xs"
|
||||
>
|
||||
<Icon data={faCodeBranch} class={`w-4 mr-2 h-4`} />
|
||||
Fork
|
||||
</button>
|
||||
@@ -44,24 +52,29 @@
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
{#if mod.value.type === FlowModuleValue.type.RAWSCRIPT && !shouldPick}
|
||||
<div class="flex flex-row space-x-2">
|
||||
{#if mod.value.type === FlowModuleValue.type.RAWSCRIPT && !shouldPick}
|
||||
<button
|
||||
type="button"
|
||||
on:click={() => createScriptFromInlineScript(i)}
|
||||
class="default-secondary-button-v2 text-sm"
|
||||
>
|
||||
<Icon data={faSave} class="w-4 mr-4" />
|
||||
Save to workspace
|
||||
</button>
|
||||
{/if}
|
||||
<button
|
||||
type="button"
|
||||
on:click={() => createScriptFromInlineScript(i)}
|
||||
class="default-secondary-button-v2 text-sm"
|
||||
on:click={() => {
|
||||
open = -1
|
||||
removeModule(i)
|
||||
}}
|
||||
class="default-secondary-button-v2 text-xs"
|
||||
>
|
||||
<Icon data={faPlus} class="w-4 mr-2" />
|
||||
Create script
|
||||
<Icon data={faTrashAlt} class="w-4 mr-2 h-4" />
|
||||
Remove step
|
||||
</button>
|
||||
{/if}
|
||||
<button
|
||||
type="button"
|
||||
on:click={() => removeModule(i)}
|
||||
class="default-secondary-button-v2 text-xs"
|
||||
>
|
||||
<Icon data={faTrashAlt} class="w-4 mr-2 h-4" />
|
||||
Remove step
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Modal bind:this={modalViewer}>
|
||||
|
||||
@@ -31,14 +31,15 @@ export const isCopyFirstStepSchemaDisabled = derived(flowStore, (flow: Flow | un
|
||||
}
|
||||
})
|
||||
|
||||
export function addModule() {
|
||||
export function addModule(i?: number) {
|
||||
const newModule: FlowModule = {
|
||||
value: { type: FlowModuleValue.type.SCRIPT, path: '' },
|
||||
input_transform: {}
|
||||
}
|
||||
|
||||
flowStore.update((flow: Flow) => {
|
||||
flow.value.modules = flow.value.modules.concat(newModule)
|
||||
flow.value.modules.splice(i ?? flow.value.modules.length, 0, newModule)
|
||||
flow.value.modules = flow.value.modules
|
||||
return flow
|
||||
})
|
||||
}
|
||||
|
||||
@@ -11,6 +11,9 @@ const config = {
|
||||
server: {
|
||||
port: 3000,
|
||||
},
|
||||
preview: {
|
||||
port: 3000,
|
||||
},
|
||||
plugins: [sveltekit()],
|
||||
define: {
|
||||
__pkg__: version
|
||||
|
||||
Reference in New Issue
Block a user