{ const id = nextId($flowStateStore, $flowStore) const index = options?.indexToInsertAt ?? $flowStore.value.modules.length const isFirst = id === 'a' let tempId = '' return [ { popover: { title: 'For loops tutorial', description: 'Learn how to build our first for loop to iterate on. You can use arrow keys to navigate.' } }, { element: `#flow-editor-add-step-${index}`, popover: { title: 'Add a step', description: 'Click here to add a step to your flow', onNextClick: () => { triggerAddFlowStep(index) setTimeout(() => { driver.moveNext() }) } } }, { popover: { title: 'Steps kind', description: "Choose the kind of step you want to add. Let's start with a simple action" }, element: '#flow-editor-insert-module' }, { popover: { title: 'Insert loop', description: "Let's pick forloop", onNextClick: () => { selectFlowStepKind(isFirst ? 4 : 3) setTimeout(() => { driver.moveNext() }) } }, element: `#flow-editor-insert-module > div > button:nth-child(${isFirst ? 4 : 3})` }, { element: '#flow-editor-iterator-expression', popover: { title: 'Iterator expression', description: 'The iterator expression is a javascript expression that respresents the array to iterate on. Here we will iterate on the firstname input letter by letter', onNextClick: () => { updateFlowModuleById($flowStore, id, (module) => { if (module.value.type === 'forloopflow') { if (module.value.iterator.type === 'javascript') { module.value.iterator.expr = '[1,2,3]' } } }) dispatch('reload') setTimeout(() => { driver.moveNext() }) } } }, { element: '#flow-editor-iterator-expression', popover: { title: 'Iterator expression', description: 'We can refer to the result of previous steps using the results object: results.a or use static values like [1,2,3] in this case.', onNextClick: () => { updateFlowModuleById($flowStore, id, (module) => { const newId = nextId($flowStateStore, $flowStore) tempId = newId if (module.value.type === 'forloopflow') { module.value.modules = [ { id: newId, value: { type: 'rawscript', content: 'def main(x):\n return x', // @ts-ignore language: 'python3', input_transforms: { x: { type: 'javascript', // @ts-ignore value: '', expr: '' } } } } ] } $flowStateStore[newId] = emptyFlowModuleState() $flowStateStore[newId].schema.properties = { x: { type: 'string', description: '', default: null } } }) dispatch('reload') setTimeout(() => { driver.moveNext() }) } } }, { popover: { title: 'Step of the loop', description: 'We added an action to the loop. Let’s configure it', onNextClick: () => { $selectedId = tempId $flowStore = $flowStore dispatch('reload') setTimeout(() => { driver.moveNext() }) } } }, { element: '#flow-editor-editor', popover: { title: 'Python step', description: 'We can write python code in the editor. In this example we will capitalize the letter' } }, { element: '#flow-editor-step-input', popover: { title: 'Flow inputs', description: 'UI is autogenerated from your code.' } }, { element: '#flow-editor-plug', popover: { title: 'Input configuration', description: 'Let’s connect the input to the letter input', onNextClick: () => { clickButtonBySelector('#flow-editor-plug') setTimeout(() => { driver.moveNext() }) } } }, { element: '.key', popover: { title: 'Connect', description: 'As we did before, we can connect to the iterator of the loop', onNextClick: () => { updateFlowModuleById($flowStore, id, (module) => { if ( module.value.type === 'forloopflow' && module.value.modules[0].value.type === 'rawscript' ) { module.value.modules[0].value.input_transforms = { x: { type: 'javascript', expr: 'flow_input.iter.value' } } } }) dispatch('reload') setTimeout(() => { driver.moveNext() }) } } }, { element: '#flow-editor-step-input', popover: { title: 'Iterator', description: 'Loops expose an iterator object that contains the current value of the loop and the index', onNextClick: () => { setTimeout(() => { driver.moveNext() updateProgress(1) }) } } }, { element: '#flow-editor-test-flow', popover: { title: 'Test your flow', description: 'We can now test our flow', onNextClick: () => { clickButtonBySelector('#flow-editor-test-flow') setTimeout(() => { driver.moveNext() }) } } }, { element: '#flow-editor-test-flow-drawer', popover: { title: 'Test your flow', description: 'Finally we can test our flow, and view the results!', onNextClick: () => { clickButtonBySelector('#flow-editor-test-flow-drawer') setTimeout(() => { driver.moveNext() updateProgress(0) }) } } } ] }} />