{
dependents = getDependentComponents(id, flowStore.val)
const cb = () => {
push(history, flowStore.val)
if (id === 'preprocessor') {
selectionManager.selectId('Input')
flowStore.val.value.preprocessor_module = undefined
} else {
selectNextId(id)
removeAtId(flowStore.val.value.modules, id)
}
refreshStateStore(flowStore)
onDelete?.(id)
delete flowStateStore.val[id]
}
if (Object.keys(dependents).length > 0) {
deleteCallback = cb
} else {
cb()
}
}}
onInsert={async (detail) => {
{
let originalModules
let targetModules
if (
detail.sourceId == 'Input' ||
detail.targetId == 'Result' ||
detail.kind == 'trigger'
) {
targetModules = flowStore.val.value.modules
}
dfs(flowStore.val.value.modules, (mod, modules, branches) => {
// console.log('mod', mod.id, $moving?.id, detail, branches)
if (mod.id == $moving?.id) {
originalModules = modules
}
if (detail.branch) {
if (mod.id == detail.branch.rootId) {
targetModules = branches[detail.branch.branch]
}
} else if (mod.id == detail.sourceId || mod.id == detail.targetId) {
targetModules = modules
} else if (mod.id == detail.agentId && mod.value.type === 'aiagent') {
targetModules = mod.value.tools
}
})
if (flowStore.val.value.modules && Array.isArray(flowStore.val.value.modules)) {
await tick()
if ($moving) {
// console.log('modules', modules, movingModules, movingModule)
push(history, flowStore.val)
let indexToRemove = originalModules.findIndex((m) => $moving?.id == m.id)
let [removedModule] = originalModules.splice(indexToRemove, 1)
targetModules.splice(detail.index, 0, removedModule)
selectionManager.selectId(removedModule.id)
$moving = undefined
} else {
if (detail.isPreprocessor) {
await insertNewPreprocessorModule(
flowStore,
flowStateStore,
detail.inlineScript,
detail.script
)
selectionManager.selectId('preprocessor')
if (detail.inlineScript?.instructions) {
dispatch('generateStep', {
moduleId: 'preprocessor',
lang: detail.inlineScript?.language,
instructions: detail.inlineScript?.instructions
})
}
} else {
const index = (detail.agentId ? targetModules?.length : detail.index) ?? 0
const toolKind = detail.agentId
? detail.kind === 'mcpTool'
? 'mcpTool'
: 'flowmoduleTool'
: undefined
await insertNewModuleAtIndex(
targetModules,
index,
detail.kind,
detail.script,
detail.flow,
detail.inlineScript,
toolKind
)
const id = targetModules[index].id
selectionManager.selectId(id)
if (detail.inlineScript?.instructions) {
dispatch('generateStep', {
moduleId: id,
lang: detail.inlineScript?.language,
instructions: detail.inlineScript?.instructions
})
}
if (detail.kind == 'trigger') {
await insertNewModuleAtIndex(
targetModules,
index + 1,
'forloop',
undefined,
undefined,
undefined
)
setExpr(targetModules[index + 1], `results.${id}`)
setScheduledPollSchedule(triggersState, triggersCount)
}
if (detail.flow?.path) {
loadLastJob(detail.flow.path, id)
} else if (detail.script?.path) {
loadLastJob(detail.script?.path, id)
}
}
}
if (['branchone', 'branchall'].includes(detail.kind)) {
await addBranch(targetModules[detail.index ?? 0].id)
}
refreshStateStore(flowStore)
dispatch('change')
}
}
}}
onNewBranch={async (id) => {
if (id) {
await addBranch(id)
refreshStateStore(flowStore)
}
}}
onSelect={(id) => {
flowPropPickerConfig.set(undefined)
}}
onChangeId={(detail) => {
let { id, newId, deps } = detail
dfs(flowStore.val.value.modules, (mod) => {
if (deps[mod.id]) {
deps[mod.id].forEach((dep) => {
if (
mod.value.type == 'rawscript' ||
mod.value.type == 'script' ||
mod.value.type == 'flow'
) {
mod.value.input_transforms = Object.fromEntries(
Object.entries(mod.value.input_transforms).map(([k, v]) => {
if (v.type == 'javascript') {
return [k, { ...v, expr: replaceId(v.expr, id, newId) }]
} else {
return [k, v]
}
})
)
} else if (mod?.value?.type === 'forloopflow') {
if (mod.value.iterator.type === 'javascript') {
mod.value.iterator.expr = replaceId(mod.value.iterator.expr, id, newId)
}
} else if (mod?.value?.type === 'branchone') {
mod.value.branches.forEach((branch) => {
branch.expr = replaceId(branch.expr, id, newId)
})
}
})
}
if (mod.id == id) {
mod.id = newId
}
})
flowStateStore.val[newId] = flowStateStore.val[id]
delete flowStateStore.val[id]
refreshStateStore(flowStore)
selectionManager.selectId(newId)
}}
onDeleteBranch={async ({ id, index }) => {
if (id) {
await removeBranch(id, index)
refreshStateStore(flowStore)
selectionManager.selectId(id)
}
}}
onMove={(id) => {
if (!$moving || $moving.id !== id) {
$moving = { id }
} else {
$moving = undefined
}
}}
onUpdateMock={(detail) => {
let module = findModuleById(detail.id)
module.mock = $state.snapshot(detail.mock)
refreshStateStore(flowStore)
}}
{onTestFlow}
{isRunning}
{onCancelTestFlow}
{onOpenPreview}
{onHideJobStatus}
exitNoteMode={() => (noteMode = false)}
onNotePositionUpdate={(noteId, position) => {
// Update note position via NoteEditor context in edit mode
if (noteEditorContext?.noteEditor) {
noteEditorContext.noteEditor.updatePosition(noteId, position)
}
}}
multiSelectEnabled
/>
{#if !disableTutorials}