mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-21 00:02:23 +00:00
feat(frontend): add input transforms for flow loop
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
|
||||
let jobId: string | undefined = undefined
|
||||
let isValid: boolean = false
|
||||
let intervalState: 'idle' | 'canceled' | 'done' | 'running' = 'idle'
|
||||
let isRunning: boolean = false
|
||||
|
||||
const { selectedId, previewArgs } = getContext<FlowEditorContext>('FlowEditorContext')
|
||||
|
||||
@@ -49,15 +49,27 @@
|
||||
export async function runPreview(args: Record<string, any>) {
|
||||
const newFlow = extractFlow(previewMode)
|
||||
jobId = await runFlowPreview(args, newFlow)
|
||||
|
||||
intervalState = 'running'
|
||||
isRunning = true
|
||||
}
|
||||
|
||||
onDestroy(() => {
|
||||
intervalState = 'done'
|
||||
})
|
||||
function onKeyDown(event: KeyboardEvent) {
|
||||
switch (event.key) {
|
||||
case 'Enter':
|
||||
if (event.ctrlKey) {
|
||||
event.preventDefault()
|
||||
runPreview($previewArgs)
|
||||
}
|
||||
break
|
||||
|
||||
case 'Escape':
|
||||
dispatch('close')
|
||||
break
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window on:keydown={onKeyDown} />
|
||||
|
||||
<div class="flex divide-y flex-col space-y-2 h-screen bg-white p-6 w-full">
|
||||
<div class="flex justify-between">
|
||||
<div class="flex flex-row justify-center items-center ">
|
||||
@@ -77,8 +89,6 @@
|
||||
color="dark"
|
||||
btnClasses="!p-0 !w-8 !h-8"
|
||||
on:click={() => {
|
||||
jobId = undefined
|
||||
intervalState = 'idle'
|
||||
dispatch('close')
|
||||
}}
|
||||
>
|
||||
@@ -93,12 +103,12 @@
|
||||
bind:args={$previewArgs}
|
||||
/>
|
||||
</div>
|
||||
{#if intervalState === 'running'}
|
||||
{#if isRunning}
|
||||
<Button
|
||||
disabled={!isValid}
|
||||
color="red"
|
||||
on:click={async () => {
|
||||
intervalState = 'canceled'
|
||||
isRunning = false
|
||||
try {
|
||||
jobId &&
|
||||
(await JobService.cancelQueuedJob({
|
||||
@@ -116,14 +126,14 @@
|
||||
{:else}
|
||||
<Button
|
||||
variant="contained"
|
||||
endIcon={{ icon: intervalState === 'done' ? faRefresh : faPlay }}
|
||||
endIcon={{ icon: isRunning ? faRefresh : faPlay }}
|
||||
size="lg"
|
||||
color="blue"
|
||||
btnClasses="w-full"
|
||||
disabled={!isValid}
|
||||
on:click={() => runPreview($previewArgs)}
|
||||
>
|
||||
{`Run${intervalState === 'done' ? ' again' : ''}`}
|
||||
Test flow (Ctrl/Cmd + Enter)
|
||||
</Button>
|
||||
{/if}
|
||||
|
||||
@@ -132,7 +142,7 @@
|
||||
<FlowStatusViewer
|
||||
{jobId}
|
||||
on:jobsLoaded={(e) => {
|
||||
intervalState = 'done'
|
||||
isRunning = false
|
||||
const parentIndex = selectedIdToIndexes($selectedId)[0]
|
||||
const upToIndex =
|
||||
previewMode === 'upTo' ? Number(parentIndex) + 1 : $flowStateStore.modules.length
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
let forloop_selected = ''
|
||||
let timeout: NodeJS.Timeout
|
||||
|
||||
$: innerModules = jobResult.job?.flow_status?.modules ?? []
|
||||
$: innerModules = jobResult?.job?.flow_status?.modules ?? []
|
||||
|
||||
async function loadJobInProgress() {
|
||||
const job = await JobService.getJob({
|
||||
@@ -39,10 +39,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
$: jobResult &&
|
||||
jobResult.job?.type === 'CompletedJob' &&
|
||||
jobResult.job.flow_status?.modules.length == jobResult.innerJobs?.length &&
|
||||
dispatch('jobsLoaded', jobResult)
|
||||
$: jobResult && jobResult.job?.type === 'CompletedJob' && dispatch('jobsLoaded', jobResult)
|
||||
|
||||
function updateJobId() {
|
||||
if (jobId !== jobResult.job?.id) {
|
||||
|
||||
@@ -23,8 +23,12 @@
|
||||
export let index: number
|
||||
|
||||
let editor: SimpleEditor | undefined = undefined
|
||||
let monacos: { [id: string]: SimpleEditor } = {}
|
||||
|
||||
let selected: string = 'retries'
|
||||
|
||||
let inputTransformName = ''
|
||||
|
||||
$: mod = $flowStore.value.modules[index]
|
||||
|
||||
$: pickableProperties = getStepPropPicker(
|
||||
@@ -86,6 +90,62 @@
|
||||
right: 'Skip failures'
|
||||
}}
|
||||
/>
|
||||
<span class="my-2 text-sm font-bold"
|
||||
>Pass specific flow context as loop flow input</span
|
||||
>
|
||||
<div class="flex flex-row mt-4 w-80 max-w-full"
|
||||
><input
|
||||
bind:value={inputTransformName}
|
||||
placeholder="Argument name"
|
||||
type="text"
|
||||
class="w-20"
|
||||
/><Button
|
||||
disabled={inputTransformName == ''}
|
||||
btnClasses="ml-2"
|
||||
on:click={() =>
|
||||
(mod.input_transforms[inputTransformName] = { type: 'javascript', expr: '' })}
|
||||
>+</Button
|
||||
></div
|
||||
>
|
||||
|
||||
{#each Object.keys(mod.input_transforms) as key}
|
||||
<div class="flex flex-row my-2">
|
||||
<span class="my-2 text-sm font-bold">{key}</span>
|
||||
|
||||
<Button
|
||||
btnClasses="ml-4"
|
||||
on:click={() => {
|
||||
delete mod.input_transforms[key]
|
||||
mod.input_transforms = mod.input_transforms
|
||||
}}>-</Button
|
||||
>
|
||||
</div>
|
||||
<div class="border w-full">
|
||||
{#if mod.input_transforms[key].type == 'javascript'}
|
||||
<PropPickerWrapper
|
||||
{pickableProperties}
|
||||
on:select={({ detail }) => {
|
||||
monacos[key]?.insertAtCursor(detail)
|
||||
}}
|
||||
>
|
||||
<SimpleEditor
|
||||
bind:this={monacos[key]}
|
||||
lang="javascript"
|
||||
bind:code={mod.input_transforms[key]['expr']}
|
||||
class="small-editor"
|
||||
shouldBindKey={false}
|
||||
/>
|
||||
</PropPickerWrapper>
|
||||
{:else}
|
||||
<Button
|
||||
on:click={() => {
|
||||
mod.input_transforms[key].type = 'javascript'
|
||||
mod.input_transforms[key]['expr'] = ''
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
{/if}
|
||||
</div></top
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user