mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-09 08:03:50 +00:00
* migrate FlowPreviewContent to svelte 5 * run background preview from input panel * share local run test * Show approval in graph is testing in graph * use component and props instead of portal for approval in graph * Add a toggle to show module status in graph * open module result after each run * Fix module reactivity issue * Add test flow button * Extract preview run logic from flowPreviewContent * Revert "Extract preview run logic from flowPreviewContent" This reverts commita39c70a920. * nit * lazy load preview content * create component for flow preview button * open preview v0 * open preview v1 * connect open preview button * improve graph run display * enable cancel preview * Run test flow from input panel * nit * wip * Use global context instead of module context for moduleTestState * nit * fix flow preview rendering * Add testJob to modulesTest context * update module status based on individual test data * fix: clear job status on run preview * detatch run buttons from input node * move preview job in FlowEditorContext * move outputPickerOpenFns to FlowEditorContext * add result panel * Add result output picker * add status to loops and branch * add open detail button to result panel * fix test up to * clean unnecessary binding * clean * Make iteration annotation smaller in editmode * detatch test button to and aproval from node * prevent flow edition during execution * Prevent step test run during flow run * Show approval in graph edges * prevent opening output popover if node is outside the graph * fix pointerdownOutside action * fix test up to dropdown not closing * fix test up to * nit * change job status badge display * fix running status * Enable test flow in Dev * fix darkmode * fix node panel display in Dev * fix test flow button positionning * fix suspend in subflows * improve lazy load of preview * prevent preview data unmount on close drawer * clean code * move flowjob into flow context * Revert "move flowjob into flow context" This reverts commit939e9dbaaf. * clean context * nit * fix dark mode status view * fix test button alignment * clean job status on deleted step * fix retry bad status display * Detect flow change * Update frontend/src/lib/components/flows/header/FlowPreviewButtons.svelte Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> --------- Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
177 lines
4.2 KiB
Svelte
177 lines
4.2 KiB
Svelte
<script lang="ts">
|
|
import Button from '$lib/components/common/button/Button.svelte'
|
|
|
|
import Drawer from '$lib/components/common/drawer/Drawer.svelte'
|
|
import FlowPreviewContent from '$lib/components/FlowPreviewContent.svelte'
|
|
import { createEventDispatcher, tick } from 'svelte'
|
|
|
|
import { getContext } from 'svelte'
|
|
import type { FlowEditorContext } from '../types'
|
|
import { Play } from 'lucide-svelte'
|
|
import { aiChatManager } from '$lib/components/copilot/chat/AIChatManager.svelte'
|
|
|
|
interface Props {
|
|
loading?: boolean
|
|
onRunPreview?: () => void
|
|
onJobDone?: () => void
|
|
}
|
|
|
|
let { loading = false, onRunPreview, onJobDone }: Props = $props()
|
|
|
|
const { selectedId } = getContext<FlowEditorContext>('FlowEditorContext')
|
|
|
|
let flowPreviewContent: FlowPreviewContent | undefined = $state(undefined)
|
|
let preventEscape = $state(false)
|
|
let selectedJobStep: string | undefined = $state(undefined)
|
|
let selectedJobStepIsTopLevel: boolean | undefined = $state(undefined)
|
|
let selectedJobStepType: 'single' | 'forloop' | 'branchall' = $state('single')
|
|
let branchOrIterationN: number = $state(0)
|
|
let scrollTop: number = $state(0)
|
|
let previewMode: 'upTo' | 'whole' = $state('whole')
|
|
let upToId: string | undefined = $state(undefined)
|
|
let previewOpen = $state(false)
|
|
let deferContent = $state(false)
|
|
|
|
export async function openPreview(test: boolean = false) {
|
|
if (!previewOpen) {
|
|
previewOpen = true
|
|
await tick()
|
|
flowPreviewContent?.refresh()
|
|
if (!test) return
|
|
}
|
|
previewMode = 'whole'
|
|
flowPreviewContent?.test()
|
|
}
|
|
|
|
export async function runPreview() {
|
|
if (!previewOpen) {
|
|
deferContent = true
|
|
await tick()
|
|
}
|
|
previewMode = 'whole'
|
|
flowPreviewContent?.refresh()
|
|
flowPreviewContent?.test()
|
|
}
|
|
|
|
export function cancelTest() {
|
|
flowPreviewContent?.cancelTest()
|
|
}
|
|
|
|
const dispatch = createEventDispatcher()
|
|
|
|
let rightColumnSelect: 'timeline' | 'node_status' | 'node_definition' | 'user_states' =
|
|
$state('timeline')
|
|
|
|
let upToDisabled = $derived.by(() => {
|
|
const upToSelected = upToId ?? $selectedId
|
|
return (
|
|
upToSelected == undefined ||
|
|
[
|
|
'settings',
|
|
'settings-metadata',
|
|
'settings-schedule',
|
|
'settings-retries',
|
|
'settings-same-worker',
|
|
'settings-graph',
|
|
'settings-worker-group',
|
|
'settings-cache',
|
|
'settings-concurrency',
|
|
'settings-early-stop',
|
|
'settings-early-return',
|
|
'inputs',
|
|
'schedules',
|
|
'failure',
|
|
'preprocessor',
|
|
'constants',
|
|
'Result',
|
|
'Input',
|
|
'triggers'
|
|
].includes(upToSelected) ||
|
|
upToSelected?.includes('branch') ||
|
|
aiChatManager.flowAiChatHelpers?.getModuleAction(upToSelected) === 'removed'
|
|
)
|
|
})
|
|
|
|
export async function testUpTo(id: string | undefined, openPreview: boolean = false) {
|
|
upToId = id
|
|
if (upToDisabled) return
|
|
if (openPreview) {
|
|
previewOpen = true
|
|
} else if (!previewOpen) {
|
|
deferContent = true
|
|
await tick()
|
|
}
|
|
previewMode = 'upTo'
|
|
flowPreviewContent?.refresh()
|
|
if (!openPreview) {
|
|
flowPreviewContent?.test()
|
|
}
|
|
}
|
|
|
|
export function getPreviewMode() {
|
|
return previewMode
|
|
}
|
|
|
|
export function getPreviewOpen() {
|
|
return previewOpen
|
|
}
|
|
|
|
export function getFlowPreviewContent() {
|
|
return flowPreviewContent
|
|
}
|
|
</script>
|
|
|
|
<Button
|
|
color="dark"
|
|
size="xs"
|
|
on:click={() => {
|
|
previewMode = 'whole'
|
|
previewOpen = !previewOpen
|
|
if (previewOpen) {
|
|
flowPreviewContent?.refresh()
|
|
}
|
|
}}
|
|
startIcon={{ icon: Play }}
|
|
id="flow-editor-test-flow"
|
|
dropdownItems={!upToDisabled
|
|
? [
|
|
{
|
|
label: 'Test up to ' + $selectedId,
|
|
onClick: () => testUpTo($selectedId, true)
|
|
}
|
|
]
|
|
: undefined}
|
|
>
|
|
Test flow
|
|
</Button>
|
|
|
|
{#if !loading}
|
|
<Drawer bind:open={previewOpen} size="75%" {preventEscape} alwaysOpen={deferContent}>
|
|
<FlowPreviewContent
|
|
bind:this={flowPreviewContent}
|
|
open={previewOpen}
|
|
bind:scrollTop
|
|
bind:previewMode
|
|
bind:selectedJobStep
|
|
bind:selectedJobStepIsTopLevel
|
|
bind:selectedJobStepType
|
|
bind:branchOrIterationN
|
|
bind:rightColumnSelect
|
|
on:close={() => {
|
|
// keep the data in the preview content
|
|
deferContent = true
|
|
previewOpen = false
|
|
}}
|
|
on:openTriggers={(e) => {
|
|
previewOpen = false
|
|
dispatch('openTriggers', e.detail)
|
|
}}
|
|
bind:preventEscape
|
|
{onRunPreview}
|
|
render={previewOpen}
|
|
{onJobDone}
|
|
{upToId}
|
|
/>
|
|
</Drawer>
|
|
{/if}
|