From 494d38029fb5a47d6256884d1aea147483d305f1 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 11 Sep 2020 14:23:31 +0100 Subject: [PATCH] Rewrite workflow editing state for better UI sync --- .../builderStore/store/workflow/Workflow.js | 59 +++--------------- .../src/builderStore/store/workflow/index.js | 53 +++++----------- .../SetupPanel/DeleteWorkflowModal.svelte | 2 +- .../ParamInputs/ModelSelector.svelte | 6 +- .../workflow/SetupPanel/SetupPanel.svelte | 61 +++---------------- .../SetupPanel/WorkflowBlockSetup.svelte | 32 ++++------ .../WorkflowBuilder/WorkflowBuilder.svelte | 28 ++++----- .../flowchart/FlowChart.svelte | 20 ++++-- .../WorkflowBuilder/flowchart/FlowItem.svelte | 13 ++-- .../WorkflowPanel/BlockList/BlockList.svelte | 2 +- .../WorkflowList/WorkflowList.svelte | 8 +-- .../WorkflowPanel/WorkflowPanel.svelte | 2 +- 12 files changed, 92 insertions(+), 194 deletions(-) diff --git a/packages/builder/src/builderStore/store/workflow/Workflow.js b/packages/builder/src/builderStore/store/workflow/Workflow.js index 3e02fa62da..a69db28aad 100644 --- a/packages/builder/src/builderStore/store/workflow/Workflow.js +++ b/packages/builder/src/builderStore/store/workflow/Workflow.js @@ -1,4 +1,3 @@ -import mustache from "mustache" import { generate } from "shortid" /** @@ -6,9 +5,8 @@ import { generate } from "shortid" * Workflow definitions are stored in linked lists. */ export default class Workflow { - constructor(workflow, blockDefinitions) { + constructor(workflow) { this.workflow = workflow - this.blockDefinitions = blockDefinitions } hasTrigger() { @@ -22,23 +20,26 @@ export default class Workflow { return } - this.workflow.definition.steps.push({ - id: generate(), - ...block, - }) + const newBlock = { id: generate(), ...block } + this.workflow.definition.steps = [ + ...this.workflow.definition.steps, + newBlock, + ] + return newBlock } updateBlock(updatedBlock, id) { const { steps, trigger } = this.workflow.definition if (trigger && trigger.id === id) { - this.workflow.definition.trigger = null + this.workflow.definition.trigger = updatedBlock return } const stepIdx = steps.findIndex(step => step.id === id) if (stepIdx < 0) throw new Error("Block not found.") steps.splice(stepIdx, 1, updatedBlock) + this.workflow.definition.steps = steps } deleteBlock(id) { @@ -52,46 +53,6 @@ export default class Workflow { const stepIdx = steps.findIndex(step => step.id === id) if (stepIdx < 0) throw new Error("Block not found.") steps.splice(stepIdx, 1) - } - - createUiTree() { - if (!this.workflow.definition) return [] - return Workflow.buildUiTree(this.workflow.definition, this.blockDefinitions) - } - - static buildUiTree(definition, blockDefinitions) { - const steps = [] - if (definition.trigger) { - steps.push(definition.trigger) - } - - return [...steps, ...definition.steps].map(step => { - // The client side display definition for the block - const definition = blockDefinitions[step.type][step.stepId] - if (!definition) { - throw new Error( - `No block definition exists for the chosen block. Check there's an entry in the block definitions for ${step.stepId}` - ) - } - - if (!definition.params) { - throw new Error( - `Blocks should always have parameters. Ensure that the block definition is correct for ${step.stepId}` - ) - } - - const tagline = definition.tagline || "" - const args = step.args || {} - - return { - id: step.id, - type: step.type, - params: step.params, - args, - heading: step.stepId, - body: mustache.render(tagline, args), - name: definition.name, - } - }) + this.workflow.definition.steps = steps } } diff --git a/packages/builder/src/builderStore/store/workflow/index.js b/packages/builder/src/builderStore/store/workflow/index.js index 66b27aa6bd..74a2b86359 100644 --- a/packages/builder/src/builderStore/store/workflow/index.js +++ b/packages/builder/src/builderStore/store/workflow/index.js @@ -1,6 +1,7 @@ import { writable } from "svelte/store" import api from "../../api" import Workflow from "./Workflow" +import { cloneDeep } from "lodash/fp" const workflowActions = store => ({ fetch: async () => { @@ -32,11 +33,8 @@ const workflowActions = store => ({ const response = await api.post(CREATE_WORKFLOW_URL, workflow) const json = await response.json() store.update(state => { - state.workflows = state.workflows.concat(json.workflow) - state.currentWorkflow = new Workflow( - json.workflow, - state.blockDefinitions - ) + state.workflows = [...state.workflows, json.workflow] + store.actions.select(json.workflow) return state }) }, @@ -50,23 +48,7 @@ const workflowActions = store => ({ ) state.workflows.splice(existingIdx, 1, json.workflow) state.workflows = state.workflows - state.currentWorkflow = new Workflow( - json.workflow, - state.blockDefinitions - ) - return state - }) - }, - update: async ({ workflow }) => { - const UPDATE_WORKFLOW_URL = `/api/workflows` - const response = await api.put(UPDATE_WORKFLOW_URL, workflow) - const json = await response.json() - store.update(state => { - const existingIdx = state.workflows.findIndex( - existing => existing._id === workflow._id - ) - state.workflows.splice(existingIdx, 1, json.workflow) - state.workflows = state.workflows + store.actions.select(json.workflow) return state }) }, @@ -81,37 +63,34 @@ const workflowActions = store => ({ ) state.workflows.splice(existingIdx, 1) state.workflows = state.workflows - state.currentWorkflow = null + state.selectedWorkflow = null + state.selectedBlock = null return state }) }, select: workflow => { store.update(state => { - state.currentWorkflow = new Workflow(workflow, state.blockDefinitions) - state.selectedWorkflowBlock = null + state.selectedWorkflow = new Workflow(cloneDeep(workflow)) + state.selectedBlock = null return state }) }, addBlockToWorkflow: block => { store.update(state => { - state.currentWorkflow.addBlock(block) - const steps = state.currentWorkflow.workflow.definition.steps - state.selectedWorkflowBlock = steps.length - ? steps[steps.length - 1] - : state.currentWorkflow.workflow.definition.trigger + const newBlock = state.selectedWorkflow.addBlock(block) + state.selectedBlock = newBlock return state }) }, deleteWorkflowBlock: block => { store.update(state => { - console.log(state.currentWorkflow.workflow) - const idx = state.currentWorkflow.workflow.definition.steps.findIndex( + const idx = state.selectedWorkflow.workflow.definition.steps.findIndex( x => x.id === block.id ) - state.currentWorkflow.deleteBlock(block.id) + state.selectedWorkflow.deleteBlock(block.id) // Select next closest step - const steps = state.currentWorkflow.workflow.definition.steps + const steps = state.selectedWorkflow.workflow.definition.steps let nextSelectedBlock if (steps[idx] != null) { nextSelectedBlock = steps[idx] @@ -119,9 +98,9 @@ const workflowActions = store => ({ nextSelectedBlock = steps[idx - 1] } else { nextSelectedBlock = - state.currentWorkflow.workflow.definition.trigger || null + state.selectedWorkflow.workflow.definition.trigger || null } - state.selectedWorkflowBlock = nextSelectedBlock + state.selectedBlock = nextSelectedBlock return state }) }, @@ -135,8 +114,8 @@ export const getWorkflowStore = () => { ACTION: [], LOGIC: [], }, + selectedWorkflow: null, } - const store = writable(INITIAL_WORKFLOW_STATE) store.actions = workflowActions(store) return store diff --git a/packages/builder/src/components/workflow/SetupPanel/DeleteWorkflowModal.svelte b/packages/builder/src/components/workflow/SetupPanel/DeleteWorkflowModal.svelte index e2e8b9976b..b96e9f92b3 100644 --- a/packages/builder/src/components/workflow/SetupPanel/DeleteWorkflowModal.svelte +++ b/packages/builder/src/components/workflow/SetupPanel/DeleteWorkflowModal.svelte @@ -13,7 +13,7 @@ async function deleteWorkflow() { await workflowStore.actions.delete({ instanceId, - workflow: $workflowStore.currentWorkflow.workflow, + workflow: $workflowStore.selectedWorkflow.workflow, }) onClosed() notifier.danger("Workflow deleted.") diff --git a/packages/builder/src/components/workflow/SetupPanel/ParamInputs/ModelSelector.svelte b/packages/builder/src/components/workflow/SetupPanel/ParamInputs/ModelSelector.svelte index 6041701d52..968d142797 100644 --- a/packages/builder/src/components/workflow/SetupPanel/ParamInputs/ModelSelector.svelte +++ b/packages/builder/src/components/workflow/SetupPanel/ParamInputs/ModelSelector.svelte @@ -2,13 +2,15 @@ import { backendUiStore } from "builderStore" export let value + let modelId = value ? value._id : "" + $: value = $backendUiStore.models.find(x => x._id === modelId)
- + {/each}
diff --git a/packages/builder/src/components/workflow/SetupPanel/SetupPanel.svelte b/packages/builder/src/components/workflow/SetupPanel/SetupPanel.svelte index cda9dd5ff1..0d0f2b7f89 100644 --- a/packages/builder/src/components/workflow/SetupPanel/SetupPanel.svelte +++ b/packages/builder/src/components/workflow/SetupPanel/SetupPanel.svelte @@ -1,6 +1,6 @@
- {#each workflowParams as [parameter, type]} + {#each params as [parameter, type]}
{#if Array.isArray(type)} - {#each type as option} {/each} {:else if type === 'component'} - + {:else if type === 'accessLevel'} - {:else if type === 'password'} - + {:else if type === 'number'} - + {:else if type === 'longText'} -