This commit is contained in:
Ruben Fiszel
2022-10-04 08:40:01 +02:00
parent 71f6bed5d8
commit 6274836bfe
10 changed files with 98 additions and 74 deletions
@@ -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