Files
windmill/frontend/src/lib/components/flows/content/FlowEditorPanel.svelte
T
ebfde197fc fix(ui): capture v2 UX (#4954)
* feat: captures

* flow UI and improvements

* fix: build

* fix sqlx

* Move Capture WIP

* Add capture to webhook and websocket

* Move connection status viewer in the head

* change trigger section label

* Add popover capture picker using melt ui

* Add shortcut to triggers capture from input form

* remove capture tab in input

* Allways show capture

* remove useless logs

* Add email capture

* Add kafka capture into triggers

* Add edit option in capture table

* use light header for arg input

* Add prefilled group id

* Change button label

* fix logic

* Open resource drawer if prototype has fields

* fix default completion

* Change name Prototype

* Dissociate Editor Mode for triggers

* Fix bug for script

* Fix apply args

* fix apply schema

* Add capture table to script

* fix apply args

* Add capture button for script

* Delete capture tab

* Set capture on when opening triggers capture

* fix connection indicator

* fix minor issues

* Add preprocessor logic

* Use slot in log Panel for captures

* handle capture refresh in script

* Delete capture tab from script editor

* reset kafka resource on toggle static

* fix minor issue

* Allow resource in kafka capture

* use simple capture button in flow

* Remove capture panel

* Polish route trigger editor

* Fix resource saving

* Remove excessive padding

* merge nits

* Add history tab

# Conflicts:
#	frontend/src/lib/components/EditableSchemaForm.svelte

* add workflow_dispatch to build

* add workflow_dispatch to build

* Move input copy from in a panel

* better capture UI

* Add smoothing animation on open input editor

* fix bad wrapping in input editor menu

* clean code

* restore captureTable

* clean

* fix sqlx

* fix build

* fix build

* build

* make initial_messages optional in line with db

* fix npm check

* better handle args for capture webhook and http

* add capture pagination

* Add capture table

* Add table for history inputs

* nit

* simplify capture table

* stop capturing on closing capture section

* show only 10 items per page for captures

* set focus to logs on script test

* Fix collapsable section

* nit

* open captures when applying args from triggers

* update edit input drawer

* fix all EditableSchemaForm

* fix panel init animation

* Add capture popover

* change open tab button

* clean code

* fix bad table display

* Fix JSON input bad sync

* make capture icon bigger

* nit

* nit

* revert unwanted change

* Change capture name and nits

* infinite scroll and cleaning

* Add toast when failing to retreive first step input

* add icons to dropdown edit input list

* remove unused log

* Add click outside to all schema pickers

* fix click oustide

* Fix migrations

* solve run button not refreshing properly

* Add a capture drawer

* change apply args and schema logic

* change apply args and schema logic

* fix toggle display

* fix schema display

* improve preview mode

* Add first step panel

* nit

* clean

* Add hint for captures

* clean

* nit

* nit

* fix script node page height

* improve animation on redirecting to capture

* improve saved input picker

* nit

* add Json placeholder

* nit

* add list animations

* delete useless logs

* add animated list to captures history and saved inputs

* Delete unused component

* clean

* nit

* clean code

* improve tab scroll experience

* nit

* nits

* nits

* fix script args update

* nit

* nit: include preview in history inputs in edit mode

---------

Co-authored-by: HugoCasa <hugo@casademont.ch>
Co-authored-by: Ruben Fiszel <ruben@rubenfiszel.com>
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
2025-01-13 14:45:38 +01:00

146 lines
4.0 KiB
Svelte

<script lang="ts">
import { getContext, onMount } from 'svelte'
import type { FlowEditorContext } from '../types'
import FlowModuleWrapper from './FlowModuleWrapper.svelte'
import FlowSettings from './FlowSettings.svelte'
import FlowInput from './FlowInput.svelte'
import FlowFailureModule from './FlowFailureModule.svelte'
import FlowConstants from './FlowConstants.svelte'
import TriggersEditor from '../../triggers/TriggersEditor.svelte'
import type { FlowModule } from '$lib/gen'
import { initFlowStepWarnings } from '../utils'
import { dfs } from '../dfs'
import FlowPreprocessorModule from './FlowPreprocessorModule.svelte'
import type { TriggerContext } from '$lib/components/triggers'
import { insertNewPreprocessorModule } from '../flowStateUtils'
export let noEditor = false
export let enableAi = false
export let newFlow = false
export let disabledFlowInputs = false
const {
selectedId,
flowStore,
flowStateStore,
flowInputsStore,
pathStore,
initialPath,
previewArgs,
flowInputEditorState
} = getContext<FlowEditorContext>('FlowEditorContext')
const { selectedTrigger, defaultValues, captureOn, showCaptureHint } =
getContext<TriggerContext>('TriggerContext')
function checkDup(modules: FlowModule[]): string | undefined {
let seenModules: string[] = []
for (const m of modules) {
if (seenModules.includes(m.id)) {
console.error(`Duplicate module id: ${m.id}`)
return m.id
}
seenModules.push(m.id)
}
}
async function initWarnings() {
for (const module of $flowStore?.value?.modules) {
if (!module) {
continue
}
if (!$flowInputsStore) {
$flowInputsStore = {}
}
$flowInputsStore[module?.id] = {
flowStepWarnings: await initFlowStepWarnings(
module.value,
$flowStateStore?.[module?.id]?.schema,
dfs($flowStore.value.modules, (fm) => fm.id)
)
}
}
}
onMount(() => {
initWarnings()
})
</script>
{#if $selectedId?.startsWith('settings')}
<FlowSettings {noEditor} />
{:else if $selectedId === 'Input'}
<FlowInput
{noEditor}
disabled={disabledFlowInputs}
on:openTriggers={(ev) => {
$selectedId = 'triggers'
selectedTrigger.set(ev.detail.kind)
defaultValues.set(ev.detail.config)
captureOn.set(true)
showCaptureHint.set(true)
}}
on:applyArgs
/>
{:else if $selectedId === 'Result'}
<p class="p-4 text-secondary">The result of the flow will be the result of the last node.</p>
{:else if $selectedId === 'constants'}
<FlowConstants {noEditor} />
{:else if $selectedId === 'failure'}
<FlowFailureModule {noEditor} />
{:else if $selectedId === 'preprocessor'}
<FlowPreprocessorModule {noEditor} />
{:else if $selectedId === 'triggers'}
<TriggersEditor
on:applyArgs
on:addPreprocessor={async () => {
await insertNewPreprocessorModule(flowStore, flowStateStore, {
language: 'bun',
subkind: 'preprocessor'
})
$selectedId = 'preprocessor'
}}
on:updateSchema={(e) => {
const { payloadData, redirect } = e.detail
if (payloadData) {
$previewArgs = JSON.parse(JSON.stringify(payloadData))
}
if (redirect) {
$selectedId = 'Input'
$flowInputEditorState.selectedTab = 'captures'
$flowInputEditorState.payloadData = payloadData
}
}}
on:testWithArgs
currentPath={$pathStore}
{initialPath}
schema={$flowStore.schema}
{noEditor}
newItem={newFlow}
isFlow={true}
hasPreprocessor={!!$flowStore.value.preprocessor_module}
canHavePreprocessor={true}
/>
{:else if $selectedId.startsWith('subflow:')}
<div class="p-4"
>Selected step is witin an expanded subflow and is not directly editable in the flow editor</div
>
{:else}
{@const dup = checkDup($flowStore.value.modules)}
{#if dup}
<div class="text-red-600 text-xl p-2">There are duplicate modules in the flow at id: {dup}</div>
{:else}
{#key $selectedId}
{#each $flowStore.value.modules as flowModule, index (flowModule.id ?? index)}
<FlowModuleWrapper
{noEditor}
bind:flowModule
previousModule={$flowStore.value.modules[index - 1]}
{enableAi}
/>
{/each}
{/key}
{/if}
{/if}