Refactored the selectedAutomation derived store to include tree metadata and moved the core doc to a new data attribute. All refs to selectedAutomation updated. Moved the id migration into the selectedAutomation store. Remove bindings from AutomationSetupBlock, moved to StepNode

This commit is contained in:
Dean 2024-10-13 22:34:17 +01:00
parent 61188fcc70
commit 9cfc3d499d
17 changed files with 145 additions and 133 deletions

View File

@ -3,8 +3,8 @@
import Flowchart from "./FlowChart/FlowChart.svelte" import Flowchart from "./FlowChart/FlowChart.svelte"
</script> </script>
{#if $selectedAutomation} {#if $selectedAutomation?.data}
{#key $selectedAutomation._id} {#key $selectedAutomation.data._id}
<Flowchart automation={$selectedAutomation} /> <Flowchart automation={$selectedAutomation.data} />
{/key} {/key}
{/if} {/if}

View File

@ -27,10 +27,13 @@
ActionStepID.TRIGGER_AUTOMATION_RUN, ActionStepID.TRIGGER_AUTOMATION_RUN,
] ]
$: blockRef = $automationStore.blocks?.[block.id] $: blockRef = $selectedAutomation.blockRefs?.[block.id]
$: lastStep = blockRef?.terminating $: lastStep = blockRef?.terminating
$: pathSteps = block.id $: pathSteps = block.id
? automationStore.actions.getPathSteps(blockRef.pathTo, $selectedAutomation) ? automationStore.actions.getPathSteps(
blockRef.pathTo,
$selectedAutomation?.data
)
: [] : []
$: collectBlockExists = pathSteps?.some( $: collectBlockExists = pathSteps?.some(
@ -81,7 +84,7 @@
// Filter out Collect block if not App Action or Webhook // Filter out Collect block if not App Action or Webhook
if ( if (
!collectBlockAllowedSteps.includes( !collectBlockAllowedSteps.includes(
$selectedAutomation.definition.trigger.stepId $selectedAutomation.data.definition.trigger.stepId
) )
) { ) {
delete acc.COLLECT delete acc.COLLECT

View File

@ -28,6 +28,7 @@
export let step export let step
export let isLast export let isLast
export let bindings export let bindings
export let automation
let drawer let drawer
let condition let condition
@ -85,13 +86,14 @@
<div class="flow-item"> <div class="flow-item">
<div class={`block branch-node hoverable`} class:selected={false}> <div class={`block branch-node hoverable`} class:selected={false}>
<FlowItemHeader <FlowItemHeader
{automation}
{open} {open}
itemName={branch.name} itemName={branch.name}
block={step} block={step}
deleteStep={async () => { deleteStep={async () => {
await automationStore.actions.deleteBranch( await automationStore.actions.deleteBranch(
branchBlockRef.pathTo, branchBlockRef.pathTo,
$selectedAutomation $selectedAutomation.data
) )
}} }}
on:update={async e => { on:update={async e => {
@ -103,7 +105,7 @@
const updatedAuto = automationStore.actions.updateStep( const updatedAuto = automationStore.actions.updateStep(
pathTo, pathTo,
$selectedAutomation, $selectedAutomation.data,
stepUpdate stepUpdate
) )
await automationStore.actions.save(updatedAuto) await automationStore.actions.save(updatedAuto)
@ -115,7 +117,7 @@
on:click={() => { on:click={() => {
automationStore.actions.branchLeft( automationStore.actions.branchLeft(
branchBlockRef.pathTo, branchBlockRef.pathTo,
$selectedAutomation, $selectedAutomation.data,
step step
) )
}} }}
@ -130,7 +132,7 @@
on:click={() => { on:click={() => {
automationStore.actions.branchRight( automationStore.actions.branchRight(
branchBlockRef.pathTo, branchBlockRef.pathTo,
$selectedAutomation, $selectedAutomation.data,
step step
) )
}} }}

View File

@ -1,8 +1,8 @@
<script> <script>
import { import {
automationStore, automationStore,
selectedAutomation,
automationHistoryStore, automationHistoryStore,
selectedAutomation,
} from "stores/builder" } from "stores/builder"
import ConfirmDialog from "components/common/ConfirmDialog.svelte" import ConfirmDialog from "components/common/ConfirmDialog.svelte"
import TestDataModal from "./TestDataModal.svelte" import TestDataModal from "./TestDataModal.svelte"
@ -12,8 +12,6 @@
import StepNode from "./StepNode.svelte" import StepNode from "./StepNode.svelte"
import { memo } from "@budibase/frontend-core" import { memo } from "@budibase/frontend-core"
import { sdk } from "@budibase/shared-core" import { sdk } from "@budibase/shared-core"
import { migrateReferencesInObject } from "dataBinding"
import { cloneDeep } from "lodash/fp"
import { onMount } from "svelte" import { onMount } from "svelte"
export let automation export let automation
@ -26,7 +24,7 @@
let blockRefs = {} let blockRefs = {}
let treeEle let treeEle
// Memo auto // Memo auto - selectedAutomation
$: memoAutomation.set(automation) $: memoAutomation.set(automation)
// Parse the automation tree state // Parse the automation tree state
@ -37,49 +35,20 @@
) )
$: isRowAction = sdk.automations.isRowAction($memoAutomation) $: isRowAction = sdk.automations.isRowAction($memoAutomation)
const refresh = auto => { const refresh = () => {
automationStore.update(state => {
return {
...state,
blocks: {},
}
})
// Traverse the automation and build metadata
automationStore.actions.traverse(auto)
blockRefs = $automationStore.blocks
// Build global automation bindings. // Build global automation bindings.
const environmentBindings = const environmentBindings =
automationStore.actions.buildEnvironmentBindings() automationStore.actions.buildEnvironmentBindings()
// Push common bindings globally // Get all processed block references
automationStore.update(state => ({ blockRefs = $selectedAutomation.blockRefs
...state,
bindings: [...environmentBindings],
}))
// Parse the steps for references to sequential binding automationStore.update(state => {
const updatedAuto = cloneDeep(auto) return {
...state,
// Parse and migrate all bindings bindings: [...environmentBindings],
Object.values(blockRefs) }
.filter(blockRef => { })
// Pulls out all distinct terminating nodes
return blockRef.terminating
})
.forEach(blockRef => {
automationStore.actions
.getPathSteps(blockRef.pathTo, updatedAuto)
.forEach((step, idx, steps) => {
migrateReferencesInObject({
obj: step,
originalIndex: idx,
steps,
})
})
})
} }
const getBlocks = automation => { const getBlocks = automation => {
@ -93,7 +62,7 @@
const deleteAutomation = async () => { const deleteAutomation = async () => {
try { try {
await automationStore.actions.delete($selectedAutomation) await automationStore.actions.delete(automation)
} catch (error) { } catch (error) {
notifications.error("Error deleting automation") notifications.error("Error deleting automation")
} }
@ -127,7 +96,7 @@
</div> </div>
<div class="controls"> <div class="controls">
<div <div
class:disabled={!$selectedAutomation?.definition?.trigger} class:disabled={!automation?.definition?.trigger}
on:click={() => { on:click={() => {
testDataModal.show() testDataModal.show()
}} }}
@ -155,7 +124,7 @@
automation._id, automation._id,
automation.disabled automation.disabled
)} )}
disabled={!$selectedAutomation?.definition?.trigger} disabled={!automation?.definition?.trigger}
value={!automation.disabled} value={!automation.disabled}
/> />
</div> </div>

View File

@ -1,9 +1,9 @@
<script> <script>
import { import {
automationStore, automationStore,
selectedAutomation,
permissions, permissions,
selectedAutomationDisplayData, selectedAutomationDisplayData,
selectedAutomation,
} from "stores/builder" } from "stores/builder"
import { import {
Icon, Icon,
@ -86,7 +86,7 @@
} }
async function removeLooping() { async function removeLooping() {
let loopBlockRef = $automationStore.blocks[blockRef.looped] let loopBlockRef = $selectedAutomation.blockRefs[blockRef.looped]
await automationStore.actions.deleteAutomationBlock(loopBlockRef.pathTo) await automationStore.actions.deleteAutomationBlock(loopBlockRef.pathTo)
} }
@ -173,6 +173,7 @@
{/if} {/if}
<FlowItemHeader <FlowItemHeader
{automation}
{open} {open}
{block} {block}
{testDataModal} {testDataModal}
@ -224,8 +225,8 @@
{block} {block}
on:branch={() => { on:branch={() => {
automationStore.actions.branchAutomation( automationStore.actions.branchAutomation(
$automationStore.blocks[block.id].pathTo, $selectedAutomation.blockRefs[block.id].pathTo,
$selectedAutomation automation
) )
}} }}
/> />

View File

@ -14,14 +14,15 @@
export let deleteStep export let deleteStep
export let enableNaming = true export let enableNaming = true
export let itemName export let itemName
export let automation
let validRegex = /^[A-Za-z0-9_\s]+$/ let validRegex = /^[A-Za-z0-9_\s]+$/
let typing = false let typing = false
let editing = false let editing = false
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
$: stepNames = $selectedAutomation?.definition.stepNames $: stepNames = automation?.definition.stepNames
$: allSteps = $selectedAutomation?.definition.steps || [] $: allSteps = automation?.definition.steps || []
$: automationName = itemName || stepNames?.[block.id] || block?.name || "" $: automationName = itemName || stepNames?.[block.id] || block?.name || ""
$: automationNameError = getAutomationNameError(automationName) $: automationNameError = getAutomationNameError(automationName)
$: status = updateStatus(testResult) $: status = updateStatus(testResult)
@ -36,7 +37,7 @@
} }
} }
$: blockRef = $automationStore.blocks[block.id] $: blockRef = $selectedAutomation.blockRefs[block.id]
$: isLooped = blockRef?.looped $: isLooped = blockRef?.looped
async function onSelect(block) { async function onSelect(block) {

View File

@ -4,7 +4,9 @@
import { AutomationActionStepId } from "@budibase/types" import { AutomationActionStepId } from "@budibase/types"
import { ActionButton } from "@budibase/bbui" import { ActionButton } from "@budibase/bbui"
import { automationStore } from "stores/builder" import { automationStore } from "stores/builder"
import { environment } from "stores/portal"
import { cloneDeep } from "lodash" import { cloneDeep } from "lodash"
import { memo } from "@budibase/frontend-core"
export let step = {} export let step = {}
export let stepIdx export let stepIdx
@ -12,6 +14,9 @@
export let blocks export let blocks
export let isLast = false export let isLast = false
const memoEnvVariables = memo($environment.variables)
$: memoEnvVariables.set($environment.variables)
$: blockRef = blocks?.[step.id] $: blockRef = blocks?.[step.id]
$: pathToCurrentNode = blockRef?.pathTo $: pathToCurrentNode = blockRef?.pathTo
$: isBranch = step.stepId === AutomationActionStepId.BRANCH $: isBranch = step.stepId === AutomationActionStepId.BRANCH
@ -23,8 +28,12 @@
automation automation
) )
// Fetch the env bindings
$: environmentBindings =
automationStore.actions.buildEnvironmentBindings($memoEnvVariables)
// Combine all bindings for the step // Combine all bindings for the step
$: bindings = [...availableBindings, ...($automationStore.bindings || [])] $: bindings = [...availableBindings, ...environmentBindings]
</script> </script>
{#if isBranch} {#if isBranch}
@ -51,6 +60,7 @@
> >
<div class="branch-node"> <div class="branch-node">
<BranchNode <BranchNode
{automation}
{step} {step}
{bindings} {bindings}
pathTo={pathToCurrentNode} pathTo={pathToCurrentNode}

View File

@ -28,7 +28,7 @@
* @todo Parse *all* data for each trigger type and relay adequate feedback * @todo Parse *all* data for each trigger type and relay adequate feedback
*/ */
const parseTestData = testData => { const parseTestData = testData => {
const autoTrigger = $selectedAutomation?.definition?.trigger const autoTrigger = $selectedAutomation.data?.definition?.trigger
const { tableId } = autoTrigger?.inputs || {} const { tableId } = autoTrigger?.inputs || {}
// Ensure the tableId matches the trigger table for row trigger automations // Ensure the tableId matches the trigger table for row trigger automations
@ -62,12 +62,12 @@
return true return true
} }
const memoTestData = memo(parseTestData($selectedAutomation.testData)) const memoTestData = memo(parseTestData($selectedAutomation.data.testData))
$: memoTestData.set(parseTestData($selectedAutomation.testData)) $: memoTestData.set(parseTestData($selectedAutomation.data.testData))
$: { $: {
// clone the trigger so we're not mutating the reference // clone the trigger so we're not mutating the reference
trigger = cloneDeep($selectedAutomation.definition.trigger) trigger = cloneDeep($selectedAutomation.data.definition.trigger)
// get the outputs so we can define the fields // get the outputs so we can define the fields
let schema = Object.entries(trigger.schema?.outputs?.properties || {}) let schema = Object.entries(trigger.schema?.outputs?.properties || {})
@ -110,7 +110,10 @@
const testAutomation = async () => { const testAutomation = async () => {
try { try {
await automationStore.actions.test($selectedAutomation, $memoTestData) await automationStore.actions.test(
$selectedAutomation.data,
$memoTestData
)
$automationStore.showTestPanel = true $automationStore.showTestPanel = true
} catch (error) { } catch (error) {
notifications.error(error) notifications.error(error)
@ -158,7 +161,7 @@
{#if selectedJSON} {#if selectedJSON}
<div class="text-area-container"> <div class="text-area-container">
<TextArea <TextArea
value={JSON.stringify($selectedAutomation.testData, null, 2)} value={JSON.stringify($selectedAutomation.data.testData, null, 2)}
error={failedParse} error={failedParse}
on:change={e => parseTestJSON(e)} on:change={e => parseTestJSON(e)}
/> />

View File

@ -3,7 +3,7 @@
import FlowItemHeader from "./FlowChart/FlowItemHeader.svelte" import FlowItemHeader from "./FlowChart/FlowItemHeader.svelte"
import { ActionStepID } from "constants/backend/automations" import { ActionStepID } from "constants/backend/automations"
import { JsonView } from "@zerodevx/svelte-json-view" import { JsonView } from "@zerodevx/svelte-json-view"
import { automationStore } from "stores/builder" import { automationStore, selectedAutomation } from "stores/builder"
import { AutomationActionStepId } from "@budibase/types" import { AutomationActionStepId } from "@budibase/types"
export let automation export let automation
@ -45,7 +45,8 @@
: [] : []
} else if (automation) { } else if (automation) {
const terminatingStep = filteredResults.at(-1) const terminatingStep = filteredResults.at(-1)
const terminatingBlockRef = $automationStore.blocks[terminatingStep.id] const terminatingBlockRef =
$selectedAutomation.blockRefs[terminatingStep.id]
const pathSteps = automationStore.actions.getPathSteps( const pathSteps = automationStore.actions.getPathSteps(
terminatingBlockRef.pathTo, terminatingBlockRef.pathTo,
automation automation
@ -67,6 +68,7 @@
<div class="block" style={width ? `width: ${width}` : ""}> <div class="block" style={width ? `width: ${width}` : ""}>
{#if block.stepId !== ActionStepID.LOOP} {#if block.stepId !== ActionStepID.LOOP}
<FlowItemHeader <FlowItemHeader
{automation}
enableNaming={false} enableNaming={false}
itemName={block.stepId === AutomationActionStepId.BRANCH itemName={block.stepId === AutomationActionStepId.BRANCH
? getBranchName(block, filteredResults?.[idx].outputs?.branchId) ? getBranchName(block, filteredResults?.[idx].outputs?.branchId)

View File

@ -115,7 +115,7 @@
? "var(--spectrum-global-color-gray-600)" ? "var(--spectrum-global-color-gray-600)"
: "var(--spectrum-global-color-gray-900)"} : "var(--spectrum-global-color-gray-900)"}
text={automation.displayName} text={automation.displayName}
selected={automation._id === $selectedAutomation?._id} selected={automation._id === $selectedAutomation?.data?._id}
hovering={automation._id === $contextMenuStore.id} hovering={automation._id === $contextMenuStore.id}
on:click={() => automationStore.actions.select(automation._id)} on:click={() => automationStore.actions.select(automation._id)}
selectedBy={$userSelectedResourceMap[automation._id]} selectedBy={$userSelectedResourceMap[automation._id]}

View File

@ -65,6 +65,7 @@
export let testData export let testData
export let schemaProperties export let schemaProperties
export let isTestModal = false export let isTestModal = false
export let bindings = []
// Stop unnecessary rendering // Stop unnecessary rendering
const memoBlock = memo(block) const memoBlock = memo(block)
@ -103,14 +104,6 @@
$: tempFilters = cloneDeep(filters) $: tempFilters = cloneDeep(filters)
$: stepId = $memoBlock.stepId $: stepId = $memoBlock.stepId
$: automationBindings = automationStore.actions.getPathBindings(
$memoBlock.id,
automation
)
$: environmentBindings =
automationStore.actions.buildEnvironmentBindings($memoEnvVariables)
$: bindings = [...automationBindings, ...environmentBindings]
$: getInputData(testData, $memoBlock.inputs) $: getInputData(testData, $memoBlock.inputs)
$: tableId = inputData ? inputData.tableId : null $: tableId = inputData ? inputData.tableId : null
$: table = tableId $: table = tableId

View File

@ -29,7 +29,7 @@
$: filteredAutomations = $automationStore.automations.filter( $: filteredAutomations = $automationStore.automations.filter(
automation => automation =>
automation.definition.trigger.stepId === TriggerStepID.APP && automation.definition.trigger.stepId === TriggerStepID.APP &&
automation._id !== $selectedAutomation._id automation._id !== $selectedAutomation.data._id
) )
</script> </script>

View File

@ -11,7 +11,7 @@
let schemaURL let schemaURL
let propCount = 0 let propCount = 0
$: automation = $selectedAutomation $: automation = $selectedAutomation.data
onMount(async () => { onMount(async () => {
if (!automation?.definition?.trigger?.inputs.schemaUrl) { if (!automation?.definition?.trigger?.inputs.schemaUrl) {

View File

@ -13,7 +13,7 @@
selectedAutomation, selectedAutomation,
} from "stores/builder" } from "stores/builder"
$: automationId = $selectedAutomation?._id $: automationId = $selectedAutomation?.data?._id
$: builderStore.selectResource(automationId) $: builderStore.selectResource(automationId)
// Keep URL and state in sync for selected screen ID // Keep URL and state in sync for selected screen ID
@ -68,7 +68,7 @@
{#if $automationStore.showTestPanel} {#if $automationStore.showTestPanel}
<div class="setup"> <div class="setup">
<TestPanel automation={$selectedAutomation} /> <TestPanel automation={$selectedAutomation.data} />
</div> </div>
{/if} {/if}
<Modal bind:this={modal}> <Modal bind:this={modal}>

View File

@ -6,7 +6,7 @@ import { createHistoryStore } from "stores/builder/history"
import { licensing } from "stores/portal" import { licensing } from "stores/portal"
import { tables } from "stores/builder" import { tables } from "stores/builder"
import { notifications } from "@budibase/bbui" import { notifications } from "@budibase/bbui"
import { getEnvironmentBindings } from "dataBinding" import { getEnvironmentBindings, migrateReferencesInObject } from "dataBinding"
import { import {
AutomationTriggerStepId, AutomationTriggerStepId,
AutomationEventType, AutomationEventType,
@ -16,10 +16,7 @@ import { ActionStepID } from "constants/backend/automations"
import { FIELDS } from "constants/backend" import { FIELDS } from "constants/backend"
import { sdk } from "@budibase/shared-core" import { sdk } from "@budibase/shared-core"
import { rowActions } from "./rowActions" import { rowActions } from "./rowActions"
import { import { getNewStepName } from "helpers/automations/nameHelpers"
updateBindingsInSteps,
getNewStepName,
} from "helpers/automations/nameHelpers"
import { QueryUtils } from "@budibase/frontend-core" import { QueryUtils } from "@budibase/frontend-core"
const initialAutomationState = { const initialAutomationState = {
@ -76,29 +73,23 @@ const automationActions = store => ({
* @param {Object} block * @param {Object} block
* @param {Array<Object>} pathTo * @param {Array<Object>} pathTo
*/ */
registerBlock: (block, pathTo, terminating) => { registerBlock: (blocks, block, pathTo, terminating) => {
store.update(state => { // Directly mutate the `blocks` object without reassigning
state.blocks = { blocks[block.id] = {
...state.blocks, ...(blocks[block.id] || {}),
[block.id]: { pathTo,
...state.blocks[block.id], bindings: [],
pathTo, terminating: terminating || false,
bindings: [], ...(block.blockToLoop ? { blockToLoop: block.blockToLoop } : {}),
terminating: terminating || false, }
// Register the looped block
...(block.blockToLoop ? { blockToLoop: block.blockToLoop } : {}),
},
}
// If this is a loop block, add a reference to the block being looped // If this is a loop block, add a reference to the block being looped
if (block.blockToLoop) { if (block.blockToLoop) {
state.blocks[block.blockToLoop] = { blocks[block.blockToLoop] = {
...(state.blocks[block.blockToLoop] || {}), ...(blocks[block.blockToLoop] || {}),
looped: block.id, looped: block.id,
}
} }
return state }
})
}, },
/** /**
* Build a sequential list of all steps on the step path provided * Build a sequential list of all steps on the step path provided
@ -204,7 +195,7 @@ const automationActions = store => ({
const block = get(store).blocks[id] const block = get(store).blocks[id]
const bindings = store.actions.getAvailableBindings( const bindings = store.actions.getAvailableBindings(
block, block,
get(selectedAutomation) get(selectedAutomation).data
) )
return bindings return bindings
@ -217,7 +208,7 @@ const automationActions = store => ({
* *
* @param {Object} automation * @param {Object} automation
*/ */
traverse: automation => { traverse: (blockRefs, automation) => {
let blocks = [] let blocks = []
if (automation.definition.trigger) { if (automation.definition.trigger) {
blocks.push(automation.definition.trigger) blocks.push(automation.definition.trigger)
@ -245,22 +236,19 @@ const automationActions = store => ({
}) })
store.actions.registerBlock( store.actions.registerBlock(
blockRefs,
block, block,
pathToCurrentNode, pathToCurrentNode,
terminating && !branches.length terminating && !branches.length
) )
} }
// Purge refs
store.update(state => {
state.blocks = {}
return state
})
// Traverse the entire tree. // Traverse the entire tree.
blocks.forEach((block, idx, array) => { blocks.forEach((block, idx, array) => {
treeTraverse(block, null, idx, null, array.length - 1 === idx) treeTraverse(block, null, idx, null, array.length - 1 === idx)
}) })
return blockRefs
}, },
/** /**
@ -599,7 +587,7 @@ const automationActions = store => ({
}) })
// Create new modified automation // Create new modified automation
const automation = get(selectedAutomation) const automation = get(selectedAutomation).data
const newAutomation = store.actions.getUpdatedDefinition( const newAutomation = store.actions.getUpdatedDefinition(
automation, automation,
newBlock newBlock
@ -685,7 +673,7 @@ const automationActions = store => ({
}) })
}, },
addTestDataToAutomation: async data => { addTestDataToAutomation: async data => {
let newAutomation = cloneDeep(get(selectedAutomation)) let newAutomation = cloneDeep(get(selectedAutomation).data)
newAutomation.testData = { newAutomation.testData = {
...newAutomation.testData, ...newAutomation.testData,
...data, ...data,
@ -701,7 +689,7 @@ const automationActions = store => ({
type, type,
id: generate(), id: generate(),
} }
newName = getNewStepName(get(selectedAutomation), newStep) newName = getNewStepName(get(selectedAutomation).data, newStep)
newStep.name = newName newStep.name = newName
return newStep return newStep
}, },
@ -729,7 +717,7 @@ const automationActions = store => ({
* @param {Array<Object>} pathWay location of insert point * @param {Array<Object>} pathWay location of insert point
*/ */
addBlockToAutomation: async (block, pathWay) => { addBlockToAutomation: async (block, pathWay) => {
const automation = get(selectedAutomation) const automation = get(selectedAutomation).data
let newAutomation = cloneDeep(automation) let newAutomation = cloneDeep(automation)
const steps = [ const steps = [
@ -754,7 +742,7 @@ const automationActions = store => ({
if (!cache) { if (!cache) {
if (final) { if (final) {
// Offset path to accommodate the // Offset path to accommodate the trigger
insertBlock(newAutomation.definition.steps, stepIdx - 1) insertBlock(newAutomation.definition.steps, stepIdx - 1)
cache = block cache = block
} else { } else {
@ -869,7 +857,7 @@ const automationActions = store => ({
return createBranch(`Branch ${idx + 1}`) return createBranch(`Branch ${idx + 1}`)
}) })
// Init the branch children. Shift all steps following the new branch // Init the branch children. Shift all steps following the new branch step
// into the 0th branch. // into the 0th branch.
newBranch.inputs.children = newBranch.inputs.branches.reduce( newBranch.inputs.children = newBranch.inputs.branches.reduce(
(acc, branch, idx) => { (acc, branch, idx) => {
@ -1030,7 +1018,7 @@ const automationActions = store => ({
}, },
saveAutomationName: async (blockId, name) => { saveAutomationName: async (blockId, name) => {
const automation = get(selectedAutomation) const automation = get(selectedAutomation).data
let newAutomation = cloneDeep(automation) let newAutomation = cloneDeep(automation)
if (!newAutomation) { if (!newAutomation) {
return return
@ -1046,7 +1034,7 @@ const automationActions = store => ({
await store.actions.save(newAutomation) await store.actions.save(newAutomation)
}, },
deleteAutomationName: async blockId => { deleteAutomationName: async blockId => {
const automation = get(selectedAutomation) const automation = get(selectedAutomation).data
let newAutomation = cloneDeep(automation) let newAutomation = cloneDeep(automation)
if (!automation) { if (!automation) {
return return
@ -1065,7 +1053,7 @@ const automationActions = store => ({
* @param {Array<Object>} pathTo * @param {Array<Object>} pathTo
*/ */
deleteAutomationBlock: async pathTo => { deleteAutomationBlock: async pathTo => {
const automation = get(selectedAutomation) const automation = get(selectedAutomation).data
let newAutomation = cloneDeep(automation) let newAutomation = cloneDeep(automation)
const steps = [ const steps = [
@ -1196,15 +1184,45 @@ export const selectedAutomation = derived(automationStore, $automationStore => {
x => x._id === $automationStore.selectedAutomationId x => x._id === $automationStore.selectedAutomationId
) )
return selected // Traverse the entire tree and record all nodes found
// Also store any info relevant to the UX
const blockRefs = {}
automationStore.actions.traverse(blockRefs, selected)
// Parse the steps for references to sequential binding
// Replace all bindings with id based alternatives
const updatedAuto = cloneDeep(selected)
Object.values(blockRefs)
.filter(blockRef => {
// Pulls out all distinct terminating nodes
return blockRef.terminating
})
.forEach(blockRef => {
automationStore.actions
.getPathSteps(blockRef.pathTo, updatedAuto)
.forEach((step, idx, steps) => {
migrateReferencesInObject({
obj: step,
originalIndex: idx,
steps,
})
})
})
return {
data: updatedAuto,
blockRefs,
}
}) })
export const selectedAutomationDisplayData = derived( export const selectedAutomationDisplayData = derived(
[automationStore, selectedAutomation], [automationStore, selectedAutomation],
([$automationStore, $selectedAutomation]) => { ([$automationStore, $selectedAutomation]) => {
if (!$selectedAutomation?._id) { if (!$selectedAutomation?.data?._id) {
return null return null
} }
return $automationStore.automationDisplayData[$selectedAutomation._id] return $automationStore.automationDisplayData[
$selectedAutomation?.data?._id
]
} }
) )

View File

@ -218,7 +218,7 @@
targetGroup.filters.push({ targetGroup.filters.push({
valueType: FilterValueType.VALUE, valueType: FilterValueType.VALUE,
...(builderType === "condition" ...(builderType === "condition"
? { operator: OperatorOptions.Equals.value } ? { operator: OperatorOptions.Equals.value, type: FieldType.STRING }
: {}), : {}),
}) })
} else if (group) { } else if (group) {
@ -240,6 +240,11 @@
filters: [ filters: [
{ {
valueType: FilterValueType.VALUE, valueType: FilterValueType.VALUE,
...(builderType === "condition"
? {
operator: OperatorOptions.Equals.value,
}
: {}),
}, },
], ],
}) })
@ -391,7 +396,12 @@
? "Edit binding" ? "Edit binding"
: null} : null}
{allowBindings} {allowBindings}
{filter} filter={{
...filter,
...(builderType === "condition"
? { type: FieldType.STRING }
: {}),
}}
{schemaFields} {schemaFields}
{bindings} {bindings}
{panel} {panel}

View File

@ -232,7 +232,7 @@
<div class="binding-control"> <div class="binding-control">
<!-- needs field, operator --> <!-- needs field, operator -->
{#if !disabled && allowBindings && filter.field && !filter.noValue} {#if !disabled && allowBindings && !filter.noValue}
<!-- svelte-ignore a11y-click-events-have-key-events --> <!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<div <div