diff --git a/frontend/src/lib/components/FlowBuilder.svelte b/frontend/src/lib/components/FlowBuilder.svelte
index b3f1105a19..a184eb2184 100644
--- a/frontend/src/lib/components/FlowBuilder.svelte
+++ b/frontend/src/lib/components/FlowBuilder.svelte
@@ -12,7 +12,7 @@
} from '$lib/utils'
import { faGlobe } from '@fortawesome/free-solid-svg-icons'
import { Breadcrumb, BreadcrumbItem } from 'flowbite-svelte'
- import { onDestroy, onMount, setContext } from 'svelte'
+ import { onMount, setContext } from 'svelte'
import Icon from 'svelte-awesome'
import { writable } from 'svelte/store'
import CenteredPage from './CenteredPage.svelte'
@@ -163,13 +163,6 @@
onMount(() => {
loadHubScripts()
})
-
- onDestroy(() => {
- //@ts-ignore
- $flowStore = undefined
- //@ts-ignore
- $flowStateStore = undefined
- })
diff --git a/frontend/src/lib/components/FlowPreviewContent.svelte b/frontend/src/lib/components/FlowPreviewContent.svelte
index 07b2965811..11a51c7046 100644
--- a/frontend/src/lib/components/FlowPreviewContent.svelte
+++ b/frontend/src/lib/components/FlowPreviewContent.svelte
@@ -127,7 +127,7 @@
const [parentIndex] = $selectedId.split('-')
const upToIndex =
previewMode === 'upTo' ? Number(parentIndex) + 1 : $flowStateStore.modules.length
- mapJobResultsToFlowState(e.detail, 'upto', upToIndex, undefined)
+ mapJobResultsToFlowState(e.detail, upToIndex)
}}
/>
{/if}
diff --git a/frontend/src/lib/components/ModulePreview.svelte b/frontend/src/lib/components/ModulePreview.svelte
index 7ab472c826..109f0293cf 100644
--- a/frontend/src/lib/components/ModulePreview.svelte
+++ b/frontend/src/lib/components/ModulePreview.svelte
@@ -12,6 +12,7 @@
import { mapJobResultsToFlowState } from './flows/flowStateUtils'
import Button from './common/button/Button.svelte'
import { faRotateRight } from '@fortawesome/free-solid-svg-icons'
+ import { flowStateStore } from './flows/flowState'
let testJobLoader: TestJobLoader
@@ -21,9 +22,14 @@
export let mod: FlowModule
export let schema: Schema
+ export let indices: [number, number | undefined]
let stepArgs: Record = {}
+ export function runTestWithStepArgs() {
+ runTest(stepArgs)
+ }
+
export async function runTest(args: any) {
const val = mod.value
if (val.type == 'rawscript') {
@@ -38,8 +44,20 @@
}
function jobDone() {
- if (testJob && !testJob.canceled && testJob.type == 'CompletedJob') {
- //mapJobResultsToFlowState(testJob.result, 'justthis', 0, 0)
+ if (testJob && !testJob.canceled && testJob.type == 'CompletedJob' && `result` in testJob) {
+ const result = testJob.result
+ const pMod = $flowStateStore.modules[indices[0]]
+ if (pMod) {
+ if (indices[1] != undefined && pMod.childFlowModules) {
+ const cMod = pMod.childFlowModules[indices[1]]
+ if (cMod) {
+ cMod.previewResult = result
+ }
+ } else {
+ pMod.previewResult = result
+ }
+ $flowStateStore.modules[indices[0]] = pMod
+ }
}
}
@@ -57,9 +75,9 @@
runnable={{ summary: mod.summary ?? '', schema, description: '' }}
runAction={(_, args) => runTest(args)}
schedulable={false}
- buttonText="Test just this step"
+ buttonText="Test just this step (Ctrl+Enter)"
detailed={false}
- args={stepArgs}
+ bind:args={stepArgs}
/>
{#if testIsLoading}
{/if}
-
-
+ {/if}
diff --git a/frontend/src/lib/components/TestJobLoader.svelte b/frontend/src/lib/components/TestJobLoader.svelte
index e2981c84f7..f3838a3a2e 100644
--- a/frontend/src/lib/components/TestJobLoader.svelte
+++ b/frontend/src/lib/components/TestJobLoader.svelte
@@ -91,7 +91,7 @@
} else {
job = await JobService.getJob({ workspace: $workspaceStore!, id })
}
- if (job?.type === 'CompletedJob') {
+ if (job?.type === 'CompletedJob' && isLoading) {
//only CompletedJob has success property
dispatch('done', job)
clearInterval(intervalId)
@@ -103,21 +103,15 @@
}
function syncer(id: string): void {
- if (syncIteration > ITERATIONS_BEFORE_SLOW_REFRESH) {
- loadTestJob(id)
- if (intervalId) {
- clearInterval(intervalId)
- intervalId = setInterval(() => loadTestJob(id), 2000)
- }
- } else {
- syncIteration++
- loadTestJob(id)
+ if (syncIteration == ITERATIONS_BEFORE_SLOW_REFRESH) {
+ intervalId && clearInterval(intervalId)
+ intervalId = setInterval(() => syncer(id), 2000)
}
+ syncIteration++
+ loadTestJob(id)
}
onDestroy(() => {
- if (intervalId) {
- clearInterval(intervalId)
- }
+ intervalId && clearInterval(intervalId)
})
diff --git a/frontend/src/lib/components/common/tabs/TabContent.svelte b/frontend/src/lib/components/common/tabs/TabContent.svelte
index 2c4e8b3bd4..938bfb91ca 100644
--- a/frontend/src/lib/components/common/tabs/TabContent.svelte
+++ b/frontend/src/lib/components/common/tabs/TabContent.svelte
@@ -3,13 +3,15 @@
import type { TabsContext } from './Tabs.svelte'
export let value: string
+ export let alwaysMounted: boolean = false
+
let clazz: string = ''
export { clazz as class }
const { selected } = getContext('Tabs')
-{#if value === $selected}
-
+{#if value === $selected || alwaysMounted}
+
{/if}
diff --git a/frontend/src/lib/components/flows/content/FlowFailureModule.svelte b/frontend/src/lib/components/flows/content/FlowFailureModule.svelte
index f31c99178d..a36bdae218 100644
--- a/frontend/src/lib/components/flows/content/FlowFailureModule.svelte
+++ b/frontend/src/lib/components/flows/content/FlowFailureModule.svelte
@@ -12,7 +12,7 @@
{#if $flowStore.value.failure_module}
{
diff --git a/frontend/src/lib/components/flows/content/FlowModule.svelte b/frontend/src/lib/components/flows/content/FlowModule.svelte
index 85c68081d1..b070b2a358 100644
--- a/frontend/src/lib/components/flows/content/FlowModule.svelte
+++ b/frontend/src/lib/components/flows/content/FlowModule.svelte
@@ -15,7 +15,6 @@
fork,
getStepPropPicker,
isEmptyFlowModule,
- loadFlowModuleSchema,
pickScript
} from '$lib/components/flows/flowStateUtils'
import { flowStore } from '$lib/components/flows/flowStore'
@@ -30,39 +29,54 @@
import { getContext } from 'svelte'
import type { FlowEditorContext } from '../types'
import FlowModuleAdvancedSettings from './FlowModuleAdvancedSettings.svelte'
+ import { loadSchemaFromModule } from '../utils'
const { selectedId, select } = getContext('FlowEditorContext')
export let flowModule: FlowModule
- export let args: Record = {}
+ export let previewArgs: Record = {}
export let flowModuleState: FlowModuleState
$: [parentIndex, childIndex] = $selectedId.split('-').map(Number)
let editor: Editor
+ let modulePreview: ModulePreview
let websocketAlive = { pyright: false, black: false, deno: false }
+ let selected = 'inputs'
$: shouldPick = isEmptyFlowModule(flowModule)
$: stepPropPicker = getStepPropPicker(
$selectedId.split('-').map(Number),
$flowStore.schema,
$flowStateStore,
- args
+ previewArgs
)
+ function onKeyDown(event: KeyboardEvent) {
+ if ((event.ctrlKey || event.metaKey) && event.key == 'Enter') {
+ event.preventDefault()
+ selected = 'test'
+ modulePreview?.runTestWithStepArgs()
+ }
+ }
+
async function apply(fn: (arg: T) => Promise<[FlowModule, FlowModuleState]>, arg: T) {
const [module, moduleState] = await fn(arg)
- flowModule = module
- flowModuleState = moduleState
- }
-
- async function applyState(fn: (arg: T) => Promise, arg: T) {
- flowModuleState = await fn(arg)
+ if (
+ JSON.stringify(flowModule) != JSON.stringify(module) ||
+ JSON.stringify(flowModuleState) != JSON.stringify(moduleState)
+ ) {
+ flowModule = module
+ flowModuleState = moduleState
+ }
}
async function reload(flowModule: FlowModule) {
- applyState(loadFlowModuleSchema, flowModule)
+ const { input_transforms, schema } = await loadSchemaFromModule(flowModule)
+
+ flowModuleState.schema = schema
+ flowModule.input_transforms = input_transforms
}
async function applyCreateLoop() {
@@ -70,6 +84,8 @@
}
+
+
@@ -131,6 +147,10 @@
deno={flowModule.value.language === RawScript.language.DENO}
lang={scriptLangToEditorLang(flowModule.value.language)}
automaticLayout={true}
+ cmdEnterAction={() => {
+ selected = 'test'
+ modulePreview?.runTestWithStepArgs()
+ }}
formatAction={() => reload(flowModule)}
/>
@@ -138,7 +158,7 @@
-
+
Inputs
Test
{#if !$selectedId.includes('failure')}
@@ -159,8 +179,13 @@
/>
-
-
+
+
diff --git a/frontend/src/lib/components/flows/content/FlowModuleWrapper.svelte b/frontend/src/lib/components/flows/content/FlowModuleWrapper.svelte
index d9fe5f8989..9469660fd1 100644
--- a/frontend/src/lib/components/flows/content/FlowModuleWrapper.svelte
+++ b/frontend/src/lib/components/flows/content/FlowModuleWrapper.svelte
@@ -19,7 +19,7 @@
{#each [$flowStateStore.modules[parentIndex].childFlowModules] as state}
{#if mod.type == 'forloopflow' && state != undefined}
{
@@ -37,9 +37,9 @@
{/if}
{/each}
{/each}
-{:else}
+{:else if $flowStore.value.modules[parentIndex]}
{
diff --git a/frontend/src/lib/components/flows/flowState.ts b/frontend/src/lib/components/flows/flowState.ts
index 3cc953c8d7..506d9786a5 100644
--- a/frontend/src/lib/components/flows/flowState.ts
+++ b/frontend/src/lib/components/flows/flowState.ts
@@ -6,6 +6,7 @@ import { emptyFlowModuleState, isEmptyFlowModule, loadFlowModuleSchema } from '.
export type FlowModuleState = {
schema: Schema
childFlowModules?: FlowModuleState[]
+ previewArgs?: any
previewResult?: any
}
diff --git a/frontend/src/lib/components/flows/flowStateUtils.ts b/frontend/src/lib/components/flows/flowStateUtils.ts
index 8ad4f05d7b..b22a74c48d 100644
--- a/frontend/src/lib/components/flows/flowStateUtils.ts
+++ b/frontend/src/lib/components/flows/flowStateUtils.ts
@@ -200,21 +200,22 @@ export function getStepPropPicker(
flowState: FlowState,
args: Record
): StepPropPicker {
- const isInsideLoop: boolean = indexes.length > 1
const [parentIndex, childIndex] = indexes
+ const isInsideLoop: boolean = childIndex !== undefined
const flowInput = schemaToObject(flowInputSchema, args)
const results = getPreviousResults(flowState.modules, parentIndex)
+
const lastResult =
parentIndex == 0
? flowInput
: results.length > 0
- ? results[results.length - 1]
- : NEVER_TESTED_THIS_FAR
+ ? results[results.length - 1]
+ : NEVER_TESTED_THIS_FAR
if (isInsideLoop) {
- const forLoopFlowInput = {
+ let forLoopFlowInput = {
...flowInput,
iter: {
value: "Iteration's value",
@@ -222,13 +223,8 @@ export function getStepPropPicker(
}
}
- if (Array.isArray(lastResult) && lastResult.length > 0) {
- const last = lastResult[lastResult.length - 1]
-
- forLoopFlowInput.iter = {
- value: last,
- index: `Iteration's index (0 to ${lastResult.length - 1})`
- }
+ if (flowState.modules[parentIndex]?.previewArgs) {
+ forLoopFlowInput = flowState.modules[parentIndex]?.previewArgs
}
const innerResults = getPreviousResults(
@@ -240,8 +236,8 @@ export function getStepPropPicker(
childIndex == 0
? forLoopFlowInput
: innerResults.length > 0
- ? innerResults[innerResults.length - 1]
- : NEVER_TESTED_THIS_FAR
+ ? innerResults[innerResults.length - 1]
+ : NEVER_TESTED_THIS_FAR
const extraLib = buildExtraLib(
objectToTsType(forLoopFlowInput),
@@ -292,64 +288,48 @@ export type JobResult = {
loopJobs?: JobResult[]
}
-export function mapJobResultsToFlowState(
- jobs: JobResult,
- config: 'upto' | 'justthis',
- parentIndex: number,
- j: number | undefined
-): void {
- if (config === 'justthis') {
- const job = jobs.job as CompletedJob
-
- flowStateStore.update((flowState: FlowState) => {
- if (flowState.modules) {
- const childFlowModules = flowState.modules[parentIndex].childFlowModules
- if (j && childFlowModules) {
- childFlowModules[j].previewResult = job.result
- flowState.modules[parentIndex].childFlowModules = childFlowModules
- } else {
- flowState.modules[parentIndex].previewResult = job.result
- }
- }
-
- return flowState
- })
- } else {
- if (jobs.innerJobs.length === 0) {
- return
- }
-
- const results = jobs.innerJobs.map(({ job, loopJobs }) => {
- if (Array.isArray(loopJobs) && loopJobs.length > 0) {
- return loopJobs.map(({ job }) => {
- if (job && 'result' in job) {
- return job.result
- }
- })
- } else {
- if (job && 'result' in job) {
- return job.result
- }
- }
- })
-
- flowStateStore.update((flowState: FlowState) => {
- if (!Array.isArray(flowState.modules)) {
- return flowState
- }
-
- const modules = flowState.modules.map((flowModuleState: FlowModuleState, index: number) => {
- if (index <= parentIndex) {
- flowModuleState.previewResult = results[index]
- }
-
- return flowModuleState
- })
-
- return {
- modules,
- failureModule: flowState.failureModule
- }
- })
+function getResult(job: Job | undefined): Result | undefined {
+ if (job && 'result' in job) {
+ return job.result
}
}
+
+export function mapJobResultsToFlowState(
+ jobs: JobResult,
+ upto: number
+): void {
+
+ const results = jobs.innerJobs.map(({ job, loopJobs }) => {
+ if (loopJobs && loopJobs.length > 0) {
+ return [job?.args, loopJobs.map(({ job }) => {
+ return getResult(job)
+ })]
+ } else {
+ return [job?.args, getResult(job)]
+ }
+ })
+
+
+
+ const old = get(flowStateStore)
+ const modules = old.modules.map((flowModuleState: FlowModuleState, index: number) => {
+ if (results[index] && index <= upto) {
+ if (results[index][1] != NEVER_TESTED_THIS_FAR || flowModuleState.previewResult == undefined) {
+ flowModuleState.previewArgs = results[index][0]
+ flowModuleState.previewResult = results[index][1]
+ flowModuleState.childFlowModules?.map((innerMod, j) => {
+ const lastLoopJob = jobs.innerJobs[index].loopJobs?.length ?? 0
+ innerMod.previewResult = getResult(jobs.innerJobs[index].loopJobs?.[lastLoopJob - 1]?.innerJobs?.[j]?.job)
+ })
+ }
+ }
+
+ return flowModuleState
+ })
+
+ flowStateStore.set({
+ modules,
+ failureModule: old.failureModule
+ })
+}
+