diff --git a/packages/bbui/src/ActionButton/ActionButton.svelte b/packages/bbui/src/ActionButton/ActionButton.svelte index 83f71d385b..b518ac3d92 100644 --- a/packages/bbui/src/ActionButton/ActionButton.svelte +++ b/packages/bbui/src/ActionButton/ActionButton.svelte @@ -12,6 +12,7 @@ export let dataCy = null export let size = "M" export let active = false + export let fullWidth = false function longPress(element) { if (!longPressable) return @@ -40,6 +41,7 @@ class:spectrum-ActionButton--quiet={quiet} class:spectrum-ActionButton--emphasized={emphasized} class:is-selected={selected} + class:fullWidth class="spectrum-ActionButton spectrum-ActionButton--size{size}" class:active {disabled} @@ -71,6 +73,9 @@ diff --git a/packages/builder/assets/discord.svg b/packages/builder/assets/discord.svg new file mode 100644 index 0000000000..3efe1ec110 --- /dev/null +++ b/packages/builder/assets/discord.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/builder/assets/integromat.png b/packages/builder/assets/integromat.png new file mode 100644 index 0000000000..1fbbe63e74 Binary files /dev/null and b/packages/builder/assets/integromat.png differ diff --git a/packages/builder/assets/n8n.png b/packages/builder/assets/n8n.png new file mode 100644 index 0000000000..b9dad93e5a Binary files /dev/null and b/packages/builder/assets/n8n.png differ diff --git a/packages/builder/assets/slack.svg b/packages/builder/assets/slack.svg new file mode 100644 index 0000000000..adcae7e39d --- /dev/null +++ b/packages/builder/assets/slack.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/builder/assets/zapier.png b/packages/builder/assets/zapier.png new file mode 100644 index 0000000000..3805331440 Binary files /dev/null and b/packages/builder/assets/zapier.png differ diff --git a/packages/builder/cypress/integration/createAutomation.spec.js b/packages/builder/cypress/integration/createAutomation.spec.js index e5040c3c45..0620a15e25 100644 --- a/packages/builder/cypress/integration/createAutomation.spec.js +++ b/packages/builder/cypress/integration/createAutomation.spec.js @@ -7,26 +7,42 @@ context("Create a automation", () => { // https://on.cypress.io/interacting-with-elements it("should create a automation", () => { cy.createTestTableWithData() - + cy.wait(2000) cy.contains("Automate").click() cy.get("[data-cy='new-screen'] > .spectrum-Icon").click() - cy.get(".spectrum-Dialog-grid").within(() => { + cy.get(".modal-inner-wrapper").within(() => { cy.get("input").type("Add Row") + cy.contains("Row Created").click() + cy.wait(500) cy.get(".spectrum-Button--cta").click() }) - // Add trigger - cy.contains("Trigger").click() - cy.contains("Row Created").click() - cy.get(".setup").within(() => { - cy.get(".spectrum-Picker-label").click() - cy.contains("dog").click() - }) + // Setup trigger + cy.contains("Setup").click() + cy.get(".spectrum-Picker-label").click() + cy.wait(500) + cy.contains("dog").click() // Create action - cy.contains("Internal").click() - cy.contains("Create Row").click() - cy.get(".setup").within(() => { + cy.contains("Add Action").click() + cy.get(".modal-inner-wrapper").within(() => { + cy.wait(1000) + cy.contains("Create Row").trigger('mouseover').click().click() + cy.get(".spectrum-Button--cta").click() + }) + cy.contains("Setup").click() + cy.get(".spectrum-Picker-label").click() + cy.contains("dog").click() + cy.get(".spectrum-Textfield-input") + .first() + .type("goodboy") + cy.get(".spectrum-Textfield-input") + .eq(1) + .type("11") + + cy.contains("Run test").click() + cy.get(".modal-inner-wrapper").within(() => { + cy.wait(1000) cy.get(".spectrum-Picker-label").click() cy.contains("dog").click() cy.get(".spectrum-Textfield-input") @@ -35,19 +51,12 @@ context("Create a automation", () => { cy.get(".spectrum-Textfield-input") .eq(1) .type("11") + cy.get(".spectrum-Textfield-input") + .eq(2) + .type("123456") + cy.get(".spectrum-Textfield-input") + .eq(3) + .type("123456") }) - - // Save - cy.contains("Save Automation").click() - - // Activate Automation - cy.get("[data-cy=activate-automation]").click() - }) - - it("should add row when a new row is added", () => { - cy.contains("Data").click() - cy.addRow(["Rover", 15]) - cy.reload() - cy.contains("goodboy").should("have.text", "goodboy") }) }) diff --git a/packages/builder/src/builderStore/store/automation/Automation.js b/packages/builder/src/builderStore/store/automation/Automation.js index a9dce88258..dcbb747e38 100644 --- a/packages/builder/src/builderStore/store/automation/Automation.js +++ b/packages/builder/src/builderStore/store/automation/Automation.js @@ -13,6 +13,10 @@ export default class Automation { return this.automation.definition.trigger } + addTestData(data) { + this.automation.testData = data + } + addBlock(block) { // Make sure to add trigger if doesn't exist if (!this.hasTrigger() && block.type === "TRIGGER") { diff --git a/packages/builder/src/builderStore/store/automation/index.js b/packages/builder/src/builderStore/store/automation/index.js index f8e7db04a0..db06ce1726 100644 --- a/packages/builder/src/builderStore/store/automation/index.js +++ b/packages/builder/src/builderStore/store/automation/index.js @@ -17,7 +17,6 @@ const automationActions = store => ({ state.blockDefinitions = { TRIGGER: jsonResponses[1].trigger, ACTION: jsonResponses[1].action, - LOGIC: jsonResponses[1].logic, } // if previously selected find the new obj and select it if (selected) { @@ -80,9 +79,14 @@ const automationActions = store => ({ const { _id } = automation return await api.post(`/api/automations/${_id}/trigger`) }, - test: async ({ automation }) => { + test: async ({ automation }, testData) => { const { _id } = automation - return await api.post(`/api/automations/${_id}/test`) + const response = await api.post(`/api/automations/${_id}/test`, testData) + const json = await response.json() + store.update(state => { + state.selectedAutomation.testResults = json + return state + }) }, select: automation => { store.update(state => { @@ -91,6 +95,12 @@ const automationActions = store => ({ return state }) }, + addTestDataToAutomation: data => { + store.update(state => { + state.selectedAutomation.addTestData(data) + return state + }) + }, addBlockToAutomation: block => { store.update(state => { const newBlock = state.selectedAutomation.addBlock(cloneDeep(block)) @@ -132,7 +142,6 @@ export const getAutomationStore = () => { blockDefinitions: { TRIGGER: [], ACTION: [], - LOGIC: [], }, selectedAutomation: null, } diff --git a/packages/builder/src/components/automation/AutomationBuilder/AutomationBuilder.svelte b/packages/builder/src/components/automation/AutomationBuilder/AutomationBuilder.svelte index 62faff3caa..7ce77a58e3 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/AutomationBuilder.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/AutomationBuilder.svelte @@ -1,10 +1,8 @@ {#if automation} - {/if} diff --git a/packages/builder/src/components/automation/AutomationBuilder/BlockList.svelte b/packages/builder/src/components/automation/AutomationBuilder/BlockList.svelte deleted file mode 100644 index a04541cfad..0000000000 --- a/packages/builder/src/components/automation/AutomationBuilder/BlockList.svelte +++ /dev/null @@ -1,114 +0,0 @@ - - -
- {#each tabs as tab, idx} -
- onChangeTab(idx)} - > - {tab.label} - -
- {/each} -
- (selectedIndex = null)} - bind:this={popover} - {anchor} - align="left" -> - - {#each blocks as [stepId, blockDefinition]} - addBlockToAutomation(stepId, blockDefinition)} - /> - {/each} - - - - - - - diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ActionModal.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ActionModal.svelte new file mode 100644 index 0000000000..8820259e90 --- /dev/null +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ActionModal.svelte @@ -0,0 +1,136 @@ + + + { + blockComplete = true + addBlockToAutomation() + }} +> + Select an app or event. + + Apps + +
+ {#each Object.entries(external) as [idx, action]} +
selectAction(action)} + > +
+ zapier + + {idx.charAt(0).toUpperCase() + idx.slice(1)} +
+
+ {/each} +
+ + Actions + +
+ {#each Object.entries(internal) as [idx, action]} +
selectAction(action)} + > +
+ + + {action.name} +
+
+ {/each} +
+
+
+ + diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/Arrow.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/Arrow.svelte index 931490b197..5aec39abeb 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/Arrow.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/Arrow.svelte @@ -6,6 +6,7 @@ xmlns="http://www.w3.org/2000/svg" > diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ExternalActions.js b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ExternalActions.js new file mode 100644 index 0000000000..843445a3c2 --- /dev/null +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ExternalActions.js @@ -0,0 +1,11 @@ +import DiscordLogo from "assets/discord.svg" +import ZapierLogo from "assets/zapier.png" +import IntegromatLogo from "assets/integromat.png" +import SlackLogo from "assets/slack.svg" + +export const externalActions = { + zapier: { name: "zapier", icon: ZapierLogo }, + discord: { name: "discord", icon: DiscordLogo }, + slack: { name: "slack", icon: SlackLogo }, + integromat: { name: "integromat", icon: IntegromatLogo }, +} diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte index e960271b87..53a5de3b51 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte @@ -1,12 +1,25 @@ -{#if !blocks.length}Add a trigger to your automation to get started{/if} -
- {#each blocks as block, idx (block.id)} -
- - {#if idx !== blocks.length - 1} - - {/if} +
+
+
+
+ {automation.name} +
+ deleteAutomation()} class="iconPadding"> + + + { + testDataModal.show() + }} + icon="MultipleCheck" + size="S">Run test +
+
- {/each} -
+ {#each blocks as block, idx (block.id)} +
+ + {#if idx !== blocks.length - 1} +
+ +
+ {/if} +
+ {/each} +
+ + + +
diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte index 439db62639..5898537dae 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte @@ -1,86 +1,204 @@
onSelect(block)} + on:click={() => { + onSelect(block) + }} > -
- {#if block.type === "TRIGGER"} - - When this happens... - {:else if block.type === "ACTION"} - - Do this... - {:else if block.type === "LOGIC"} - - Only continue if... - {/if} -
- {#if block.type === "TRIGGER"}Trigger{:else}Step {blockIdx + 1}{/if} +
+
{ + blockComplete = !blockComplete + }} + class="splitHeader" + > +
+ {#if externalActions[block.stepId]} + {externalActions[block.stepId].name} + {:else} + + + + {/if} +
+ {#if isTrigger} + When this happens: + {:else} + Do this: + {/if} + + {block?.name?.toUpperCase() || ""} +
+
+ {#if testResult} + resultsModal.show()}> + View response + + {/if}
- {#if block.type !== "TRIGGER" || allowDeleteTrigger} -
- {/if} -
-
-

- -

+
+ {#if !blockComplete} + +
+ +
+
{ + setupToggled = !setupToggled + }} + class="center-items" + > + {#if setupToggled} + + {:else} + + {/if} + Setup +
+ {#if !isTrigger} +
deleteStep()}> + +
+ {/if} +
+ + {#if setupToggled} + + {#if lastStep} + + {/if} + + {/if} +
+
+ {/if} + + + + + + + + + + + + diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ResultsModal.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ResultsModal.svelte new file mode 100644 index 0000000000..7dfdff20a7 --- /dev/null +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ResultsModal.svelte @@ -0,0 +1,114 @@ + + + +
+
+ {#if isTrigger || testResult[0].outputs.success} +
+ +
+ {:else} +
+ +
+ {/if} +
+
+ +
{ + inputToggled = !inputToggled + }} + class="toggle splitHeader" + > +
+
+ + Input + +
+
+
+ {#if inputToggled} + + {:else} + + {/if} +
+
+ {#if inputToggled} +
+