mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-07 16:02:27 +00:00
progress
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
import { mapJobResultsToFlowState } from './flows/flowStateUtils'
|
||||
import { flowStore } from './flows/flowStore'
|
||||
import type { FlowEditorContext } from './flows/types'
|
||||
import { runFlowPreview } from './flows/utils'
|
||||
import { runFlowPreview, selectedIdToIndexes } from './flows/utils'
|
||||
import SchemaForm from './SchemaForm.svelte'
|
||||
import FlowStatusViewer from '../components/FlowStatusViewer.svelte'
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
if (previewMode === 'whole') {
|
||||
return $flowStore
|
||||
} else {
|
||||
const [parentIndex, childIndex] = $selectedId.split('-')
|
||||
const [parentIndex, childIndex] = selectedIdToIndexes($selectedId)
|
||||
|
||||
const modules = $flowStore.value.modules.slice(0, Number(parentIndex) + 1)
|
||||
const flow = JSON.parse(JSON.stringify($flowStore))
|
||||
@@ -132,7 +132,7 @@
|
||||
{jobId}
|
||||
on:jobsLoaded={(e) => {
|
||||
intervalState = 'done'
|
||||
const [parentIndex] = $selectedId.split('-')
|
||||
const parentIndex = selectedIdToIndexes($selectedId)[0]
|
||||
const upToIndex =
|
||||
previewMode === 'upTo' ? Number(parentIndex) + 1 : $flowStateStore.modules.length
|
||||
mapJobResultsToFlowState(e.detail, upToIndex)
|
||||
|
||||
@@ -9,12 +9,16 @@
|
||||
import { getStepPropPicker } from '../flowStateUtils'
|
||||
import { flowStateStore } from '../flowState'
|
||||
import PropPickerWrapper from '../propPicker/PropPickerWrapper.svelte'
|
||||
import { selectedIdToIndexes, selectedIdToModule } from '../utils'
|
||||
import { Button } from '$lib/components/common'
|
||||
|
||||
const { selectedId, previewArgs } = getContext<FlowEditorContext>('FlowEditorContext')
|
||||
|
||||
$: mod = selectedIdToModule($selectedId, $flowStore)
|
||||
|
||||
let editor: SimpleEditor | undefined = undefined
|
||||
|
||||
$: index = $selectedId.split('-')[1]
|
||||
$: index = selectedIdToIndexes($selectedId)[1]
|
||||
|
||||
$: pickableProperties = getStepPropPicker(
|
||||
[Number(index)],
|
||||
@@ -26,11 +30,11 @@
|
||||
|
||||
<FlowCard title="For loop">
|
||||
<div slot="header" class="grow">
|
||||
<input bind:value={$flowStore.value.modules[index].summary} placeholder={'Summary'} />
|
||||
<input bind:value={mod.summary} placeholder={'Summary'} />
|
||||
</div>
|
||||
<div>
|
||||
<div class="p-6 flex flex-col">
|
||||
{#if $flowStore.value.modules[index].value.type === 'forloopflow'}
|
||||
{#if mod.value.type === 'forloopflow'}
|
||||
<span class="mb-2 text-sm font-bold"
|
||||
>Iterator expression
|
||||
<Tooltip>
|
||||
@@ -39,26 +43,35 @@
|
||||
</Tooltip>
|
||||
</span>
|
||||
|
||||
<div class="border w-full">
|
||||
<PropPickerWrapper
|
||||
{pickableProperties}
|
||||
on:select={({ detail }) => {
|
||||
editor?.insertAtCursor(detail)
|
||||
{#if mod.value.iterator.type == 'javascript'}
|
||||
<div class="border w-full">
|
||||
<PropPickerWrapper
|
||||
{pickableProperties}
|
||||
on:select={({ detail }) => {
|
||||
editor?.insertAtCursor(detail)
|
||||
}}
|
||||
>
|
||||
<SimpleEditor
|
||||
bind:this={editor}
|
||||
lang="javascript"
|
||||
bind:code={mod.value.iterator.expr}
|
||||
class="small-editor"
|
||||
shouldBindKey={false}
|
||||
/>
|
||||
</PropPickerWrapper>
|
||||
</div>
|
||||
{:else}
|
||||
<Button
|
||||
on:click={() => {
|
||||
if (mod.value.type === 'forloopflow') mod.value.iterator.type = 'javascript'
|
||||
}}
|
||||
>
|
||||
<SimpleEditor
|
||||
bind:this={editor}
|
||||
lang="javascript"
|
||||
bind:code={$flowStore.value.modules[index].value.iterator.expr}
|
||||
class="small-editor"
|
||||
shouldBindKey={false}
|
||||
/>
|
||||
</PropPickerWrapper>
|
||||
</div>
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<span class="my-2 text-sm font-bold">Skip failures</span>
|
||||
|
||||
<Toggle
|
||||
bind:checked={$flowStore.value.modules[index].value.skip_failures}
|
||||
bind:checked={mod.value.skip_failures}
|
||||
options={{
|
||||
right: 'Skip failures'
|
||||
}}
|
||||
|
||||
@@ -35,11 +35,12 @@
|
||||
import PropPickerWrapper from '../propPicker/PropPickerWrapper.svelte'
|
||||
import { getContext, setContext } from 'svelte'
|
||||
import type { FlowEditorContext } from '../types'
|
||||
import { loadSchemaFromModule } from '../utils'
|
||||
import { loadSchemaFromModule, selectedIdToIndexes } from '../utils'
|
||||
import { writable, type Writable } from 'svelte/store'
|
||||
import FlowModuleScript from './FlowModuleScript.svelte'
|
||||
import FlowModuleEarlyStop from './FlowModuleEarlyStop.svelte'
|
||||
import FlowModuleSuspend from './FlowModuleSuspend.svelte'
|
||||
import FlowRetries from './FlowRetries.svelte'
|
||||
|
||||
const { selectedId, select, previewArgs } = getContext<FlowEditorContext>('FlowEditorContext')
|
||||
|
||||
@@ -47,7 +48,7 @@
|
||||
export let flowModuleState: FlowModuleState
|
||||
export let failureModule: boolean
|
||||
|
||||
$: [parentIndex, childIndex] = $selectedId.split('-').map(Number)
|
||||
$: [parentIndex, childIndex] = selectedIdToIndexes($selectedId)
|
||||
|
||||
let editor: Editor
|
||||
let modulePreview: ModulePreview
|
||||
@@ -57,12 +58,7 @@
|
||||
$: shouldPick = isEmptyFlowModule(flowModule)
|
||||
$: stepPropPicker = failureModule
|
||||
? { pickableProperties: { previous_result: { error: 'the error message' } }, extraLib: '' }
|
||||
: getStepPropPicker(
|
||||
$selectedId.split('-').map(Number),
|
||||
$flowStore.schema,
|
||||
$flowStateStore,
|
||||
$previewArgs
|
||||
)
|
||||
: getStepPropPicker([parentIndex, childIndex], $flowStore.schema, $flowStateStore, $previewArgs)
|
||||
|
||||
function onKeyDown(event: KeyboardEvent) {
|
||||
if ((event.ctrlKey || event.metaKey) && event.key == 'Enter') {
|
||||
@@ -112,6 +108,7 @@
|
||||
<FlowModuleHeader
|
||||
bind:module={flowModule}
|
||||
on:delete
|
||||
on:toggleRetry={() => (selected = 'retries')}
|
||||
on:toggleStopAfterIf={() => (selected = 'early-stop')}
|
||||
on:fork={() => apply(fork, flowModule)}
|
||||
on:createScriptFromInlineScript={() => {
|
||||
@@ -188,6 +185,7 @@
|
||||
<Tabs bind:selected>
|
||||
<Tab value="inputs">Inputs</Tab>
|
||||
<Tab value="test">Test</Tab>
|
||||
<Tab value="retries">Retries</Tab>
|
||||
{#if !$selectedId.includes('failure')}
|
||||
<Tab value="early-stop">Early Stop</Tab>
|
||||
<Tab value="suspend">Suspend</Tab>
|
||||
@@ -216,6 +214,12 @@
|
||||
/>
|
||||
</TabContent>
|
||||
|
||||
<TabContent value="retries" class="flex flex-col flex-1 h-full">
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<FlowRetries bind:flowModule />
|
||||
</div>
|
||||
</TabContent>
|
||||
|
||||
<TabContent value="early-stop" class="flex flex-col flex-1 h-full">
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<FlowModuleEarlyStop bind:flowModule />
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
import { flowStateStore } from '../flowState'
|
||||
import type { FlowEditorContext } from '../types'
|
||||
import { getContext } from 'svelte'
|
||||
import { selectedIdToIndexes } from '../utils'
|
||||
|
||||
const { selectedId, previewArgs } = getContext<FlowEditorContext>('FlowEditorContext')
|
||||
|
||||
@@ -21,7 +22,7 @@
|
||||
let pickableProperties: Object = {}
|
||||
|
||||
$: {
|
||||
let indices = $selectedId.split('-').map(Number)
|
||||
let indices = selectedIdToIndexes($selectedId)
|
||||
if (indices[1]) {
|
||||
indices[1] += 1
|
||||
} else {
|
||||
|
||||
@@ -35,7 +35,19 @@
|
||||
on:click={() => dispatch('toggleStopAfterIf')}
|
||||
>
|
||||
<Icon data={faStop} class="mr-2" scale={0.8} />
|
||||
{module.stop_after_if ? `Early stop` : 'Early stop'}
|
||||
{module.stop_after_if ? `Early stop o` : 'Early stop x'}
|
||||
</span>
|
||||
<span
|
||||
class={classNames(
|
||||
'whitespace-nowrap text-sm font-medium mr-2 px-2.5 py-0.5 rounded cursor-pointer flex items-center',
|
||||
module.stop_after_if
|
||||
? 'bg-sky-100 text-sky-800 hover:bg-sky-200'
|
||||
: 'bg-gray-100 text-gray-800 hover:bg-gray-200'
|
||||
)}
|
||||
on:click={() => dispatch('toggleRetry')}
|
||||
>
|
||||
<Icon data={faStop} class="mr-2" scale={0.8} />
|
||||
{module.retry ? `Retry o` : 'Retry x'}
|
||||
</span>
|
||||
{#if module.value.type === 'script' && !shouldPick}
|
||||
<Button
|
||||
|
||||
@@ -3,13 +3,10 @@
|
||||
import { flowStateStore } from '../flowState'
|
||||
import { flowStore } from '../flowStore'
|
||||
import type { FlowEditorContext } from '../types'
|
||||
import { selectedIdToIndexes } from '../utils'
|
||||
import FlowModule from './FlowModule.svelte'
|
||||
|
||||
const { selectedId, previewArgs, select } = getContext<FlowEditorContext>('FlowEditorContext')
|
||||
|
||||
function selectedIdToIndexes(selectedId: string): number[] {
|
||||
return selectedId.split('-').map(Number)
|
||||
}
|
||||
const { selectedId } = getContext<FlowEditorContext>('FlowEditorContext')
|
||||
|
||||
$: [parentIndex, childIndex] = selectedIdToIndexes($selectedId)
|
||||
</script>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
<script lang="ts">
|
||||
import Toggle from '$lib/components/Toggle.svelte'
|
||||
import { flowStore } from '../flowStore'
|
||||
import type { FlowModule } from '$lib/gen'
|
||||
|
||||
export let flowModule: FlowModule
|
||||
|
||||
function setConstantRetries() {
|
||||
$flowStore.value.retry = {
|
||||
...$flowStore.value.retry,
|
||||
flowModule.retry = {
|
||||
...flowModule.retry,
|
||||
constant: {
|
||||
attempts: 0,
|
||||
seconds: 0
|
||||
@@ -13,8 +15,8 @@
|
||||
}
|
||||
|
||||
function setExpoentialRetries() {
|
||||
$flowStore.value.retry = {
|
||||
...$flowStore.value.retry,
|
||||
flowModule.retry = {
|
||||
...flowModule.retry,
|
||||
exponential: {
|
||||
attempts: 0,
|
||||
multiplier: 1,
|
||||
@@ -23,16 +25,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
$: isConstantRetryEnabled = Boolean($flowStore.value.retry?.constant)
|
||||
$: isExponentialRetryEnabled = Boolean($flowStore.value.retry?.exponential)
|
||||
$: isConstantRetryEnabled = Boolean(flowModule.retry?.constant)
|
||||
$: isExponentialRetryEnabled = Boolean(flowModule.retry?.exponential)
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col items-start space-y-1">
|
||||
<Toggle
|
||||
checked={isConstantRetryEnabled}
|
||||
on:change={() => {
|
||||
if (isConstantRetryEnabled && $flowStore.value.retry?.constant) {
|
||||
$flowStore.value.retry.constant = undefined
|
||||
if (isConstantRetryEnabled && flowModule.retry?.constant) {
|
||||
flowModule.retry.constant = undefined
|
||||
} else {
|
||||
setConstantRetries()
|
||||
}
|
||||
@@ -41,11 +43,11 @@
|
||||
right: 'Constant retry enabled'
|
||||
}}
|
||||
/>
|
||||
{#if $flowStore.value.retry?.constant}
|
||||
{#if flowModule.retry?.constant}
|
||||
<span class="text-xs font-bold">Attempts</span>
|
||||
<input bind:value={$flowStore.value.retry.constant.attempts} type="number" />
|
||||
<input bind:value={flowModule.retry.constant.attempts} type="number" />
|
||||
<span class="text-xs font-bold">Delay (seconds)</span>
|
||||
<input bind:value={$flowStore.value.retry.constant.seconds} type="number" />
|
||||
<input bind:value={flowModule.retry.constant.seconds} type="number" />
|
||||
{:else}
|
||||
<span class="text-xs font-bold">Attempts</span>
|
||||
<input type="number" disabled />
|
||||
@@ -56,8 +58,8 @@
|
||||
<Toggle
|
||||
checked={isExponentialRetryEnabled}
|
||||
on:change={() => {
|
||||
if (isExponentialRetryEnabled && $flowStore.value.retry?.exponential) {
|
||||
$flowStore.value.retry.exponential = undefined
|
||||
if (isExponentialRetryEnabled && flowModule.retry?.exponential) {
|
||||
flowModule.retry.exponential = undefined
|
||||
} else {
|
||||
setExpoentialRetries()
|
||||
}
|
||||
@@ -66,13 +68,13 @@
|
||||
right: 'Exponential retry enabled'
|
||||
}}
|
||||
/>
|
||||
{#if $flowStore.value.retry?.exponential}
|
||||
{#if flowModule.retry?.exponential}
|
||||
<span class="text-xs font-bold">Attempts</span>
|
||||
<input bind:value={$flowStore.value.retry.exponential.attempts} type="number" />
|
||||
<input bind:value={flowModule.retry.exponential.attempts} type="number" />
|
||||
<span class="text-xs font-bold">Mulitplier</span>
|
||||
<input bind:value={$flowStore.value.retry.exponential.multiplier} type="number" />
|
||||
<input bind:value={flowModule.retry.exponential.multiplier} type="number" />
|
||||
<span class="text-xs font-bold">Initial delay (seconds)</span>
|
||||
<input bind:value={$flowStore.value.retry.exponential.seconds} type="number" />
|
||||
<input bind:value={flowModule.retry.exponential.seconds} type="number" />
|
||||
{:else}
|
||||
<span class="text-xs font-bold">Attempts</span>
|
||||
<input type="number" disabled />
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
import Required from '$lib/components/Required.svelte'
|
||||
import FlowCard from '../common/FlowCard.svelte'
|
||||
import FlowSchedules from './FlowSchedules.svelte'
|
||||
import FlowRetries from './FlowRetries.svelte'
|
||||
import SvelteMarkdown from 'svelte-markdown'
|
||||
|
||||
export let initialPath: string
|
||||
@@ -20,7 +19,6 @@
|
||||
<Tabs selected={defaultTab}>
|
||||
<Tab value="metadata">Metadata</Tab>
|
||||
<Tab value="schedule">Schedule</Tab>
|
||||
<Tab value="retries">Retries</Tab>
|
||||
|
||||
<svelte:fragment slot="content">
|
||||
<TabContent value="metadata" class="p-4">
|
||||
@@ -79,9 +77,6 @@
|
||||
<TabContent value="schedule" class="p-4">
|
||||
<FlowSchedules />
|
||||
</TabContent>
|
||||
<TabContent value="retries" class="px-4">
|
||||
<FlowRetries />
|
||||
</TabContent>
|
||||
</svelte:fragment>
|
||||
</Tabs>
|
||||
</FlowCard>
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
import type { FlowEditorContext } from '../types'
|
||||
|
||||
const { schedule, select } = getContext<FlowEditorContext>('FlowEditorContext')
|
||||
|
||||
$: retriesEnabled = $flowStore.value.retry?.constant || $flowStore.value.retry?.exponential
|
||||
</script>
|
||||
|
||||
<div class="flex space-x-1">
|
||||
@@ -31,16 +29,4 @@
|
||||
|
||||
{$schedule?.enabled ? `Schedule: ${$schedule?.cron}` : 'Schedule disabled'}
|
||||
</span>
|
||||
<span
|
||||
class={classNames(
|
||||
' text-sm font-medium mr-2 px-2.5 py-0.5 rounded cursor-pointer flex items-center',
|
||||
retriesEnabled
|
||||
? 'bg-sky-100 text-sky-800 hover:bg-sky-200'
|
||||
: 'bg-gray-100 text-gray-800 hover:bg-gray-200'
|
||||
)}
|
||||
on:click={() => select('settings-retries')}
|
||||
>
|
||||
<Icon data={faArrowRotateForward} class="mr-2" scale={0.8} />
|
||||
{retriesEnabled ? `Retries enabled` : 'Retries disabled'}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -45,6 +45,20 @@ export function getTypeAsString(arg: any): string {
|
||||
}
|
||||
|
||||
|
||||
export function selectedIdToIndexes(selectedId: string): number[] {
|
||||
return selectedId.split('-').map(Number)
|
||||
}
|
||||
export function selectedIdToModule(selectedId: string, flow: Flow): FlowModule {
|
||||
const [p, c] = selectedIdToIndexes(selectedId)
|
||||
const pm = flow.value.modules[p]
|
||||
if (c && pm.value.type == 'forloopflow') {
|
||||
return pm.value.modules[c]
|
||||
} else {
|
||||
return pm
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export async function loadSchemaFromModule(module: FlowModule): Promise<{
|
||||
input_transforms: Record<string, InputTransform>
|
||||
schema: Schema
|
||||
|
||||
Reference in New Issue
Block a user