From 5f2b4f3ef9bbb8fad0f8aa3996f3565d98d383e3 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Tue, 17 Oct 2023 11:51:23 +0100 Subject: [PATCH 01/34] initial styling and input updates for naming --- .../FlowChart/FlowItem.svelte | 14 +- .../FlowChart/FlowItemHeader.svelte | 130 ++++++++++++++++-- 2 files changed, 133 insertions(+), 11 deletions(-) diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte index 6c964c84a9..0517fe1034 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte @@ -104,13 +104,19 @@ } -
{}}> +
{}} + on:click={() => {}} +> {#if loopBlock}
{ showLooping = !showLooping }} + on:keydown={() => {}} class="splitHeader" >
@@ -129,7 +135,11 @@
-
{}}> +
{}} + on:click={() => {}} + >
diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte index c09474a370..0bbd2d2318 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte @@ -1,6 +1,6 @@ -
-
dispatch("toggle")} class="splitHeader"> +
+
{#if externalActions[block.stepId]} {#if isTrigger} Trigger - When this happens: {:else} Step {idx} - Do this: {/if} - {block?.name?.toUpperCase() || ""} + { + automationNameError = getAutomationNameError(e.target.value) + automationName = e.target.value + if (!automationNameError) { + automationNameError = false // Reset the error when input is valid + } + }} + value={automationName} + on:click={startTyping} + on:blur={() => { + typing = false + if (automationNameError) { + automationName = block?.name + automationNameError = null + } + }} + />
@@ -89,18 +130,46 @@
{/if}
{ onSelect(block) }} > - + {#if !showTestStatus} + + + + + + + {/if} + dispatch("toggle")} + hoverable + name={open ? "ChevronUp" : "ChevronDown"} + />
+ {#if automationNameError} +
+ +
+ +
+
+
+ {/if}
From a209280daa33c248f78844685ddca66692499c70 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Tue, 24 Oct 2023 15:17:22 +0100 Subject: [PATCH 02/34] naming automations --- .../builderStore/store/automation/index.js | 24 ++++++++ .../FlowChart/FlowItemHeader.svelte | 56 +++++++++++++------ 2 files changed, 63 insertions(+), 17 deletions(-) diff --git a/packages/builder/src/builderStore/store/automation/index.js b/packages/builder/src/builderStore/store/automation/index.js index c22240370b..dd28d14461 100644 --- a/packages/builder/src/builderStore/store/automation/index.js +++ b/packages/builder/src/builderStore/store/automation/index.js @@ -221,6 +221,30 @@ const automationActions = store => ({ newAutomation.definition.steps.splice(blockIdx, 0, block) await store.actions.save(newAutomation) }, + saveAutomationName: async (stepId, name) => { + const automation = get(selectedAutomation) + let newAutomation = cloneDeep(automation) + if (!automation) { + return + } + newAutomation.definition.stepNames = { + ...newAutomation.definition.stepNames, + [stepId]: name, + } + + await store.actions.save(newAutomation) + }, + deleteAutomationName: async stepId => { + const automation = get(selectedAutomation) + let newAutomation = cloneDeep(automation) + if (!automation) { + return + } + delete newAutomation.definition.stepNames[stepId] + + await store.actions.save(newAutomation) + }, + deleteAutomationBlock: async block => { const automation = get(selectedAutomation) let newAutomation = cloneDeep(automation) diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte index 0bbd2d2318..7cc124f44c 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte @@ -3,6 +3,7 @@ import { Icon, Body, StatusLight, AbsTooltip } from "@budibase/bbui" import { externalActions } from "./ExternalActions" import { createEventDispatcher } from "svelte" + import { Features } from "constants/backend/automations" export let block export let open @@ -10,16 +11,19 @@ export let testResult export let isTrigger export let idx + export let addLooping + export let deleteStep - $: console.log($selectedAutomation) let validRegex = /^[A-Za-z0-9_\s]+$/ let typing = false - let automationName = block?.name || "" - - $: automationNameError = getAutomationNameError(automationName) const dispatch = createEventDispatcher() + $: stepNames = $selectedAutomation.definition.stepNames + $: automationName = stepNames[block.id] || block.name || "" + $: automationNameError = getAutomationNameError(automationName) + $: status = updateStatus(testResult, isTrigger) + $: isTrigger = isTrigger || block.type === "TRIGGER" $: { if (!testResult) { testResult = $automationStore.testResults?.steps?.filter(step => @@ -27,9 +31,9 @@ )?.[0] } } - $: isTrigger = isTrigger || block.type === "TRIGGER" - - $: status = updateStatus(testResult, isTrigger) + $: loopBlock = $selectedAutomation?.definition.steps.find( + x => x.blockToLoop === block.id + ) async function onSelect(block) { await automationStore.update(state => { @@ -53,9 +57,11 @@ } const getAutomationNameError = name => { - let invalidRoleName = !validRegex.test(name) - if (invalidRoleName) { - return "Please enter a role name consisting of only alphanumeric symbols and underscores" + if (name.length > 0) { + let invalidRoleName = !validRegex.test(name) + if (invalidRoleName) { + return "Please enter a role name consisting of only alphanumeric symbols and underscores" + } } return null } @@ -63,6 +69,18 @@ const startTyping = async () => { typing = true } + + const saveName = async () => { + if (automationNameError) { + return + } + + if (automationName.length === 0) { + automationStore.actions.deleteAutomationName(block.id) + } else { + automationStore.actions.saveAutomationName(block.id, automationName) + } + }
{ automationNameError = getAutomationNameError(e.target.value) automationName = e.target.value @@ -106,13 +125,14 @@ automationNameError = false // Reset the error when input is valid } }} - value={automationName} on:click={startTyping} - on:blur={() => { + on:blur={async () => { typing = false if (automationNameError) { - automationName = block?.name + automationName = stepNames[block.id] automationNameError = null + } else { + await saveName() } }} /> @@ -137,11 +157,13 @@ }} > {#if !showTestStatus} - - - + {#if !isTrigger && !loopBlock && (block?.features?.[Features.LOOPING] || !block.features)} + + + + {/if} - + {/if} Date: Tue, 24 Oct 2023 15:17:39 +0100 Subject: [PATCH 03/34] update bindings to use names --- .../SetupPanel/AutomationBlockSetup.svelte | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index ce8c5c344c..fa1f0c76c9 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -183,20 +183,17 @@ } } const outputs = Object.entries(schema) - let bindingIcon = "" - let bindindingRank = 0 - + let bindingRank = 0 if (idx === 0) { bindingIcon = automation.trigger.icon } else if (isLoopBlock) { bindingIcon = "Reuse" - bindindingRank = idx + 1 + bindingRank = idx + 1 } else { bindingIcon = allSteps[idx].icon - bindindingRank = idx - loopBlockCount + bindingRank = idx - loopBlockCount } - bindings = bindings.concat( outputs.map(([name, value]) => { let runtimeName = isLoopBlock @@ -205,12 +202,21 @@ ? `steps[${idx - loopBlockCount}].${name}` : `steps.${idx - loopBlockCount}.${name}` const runtime = idx === 0 ? `trigger.${name}` : runtimeName - const categoryName = - idx === 0 - ? "Trigger outputs" - : isLoopBlock - ? "Loop Outputs" - : `Step ${idx - loopBlockCount} outputs` + + let bindingName = + automation.stepNames[allSteps[bindingRank - loopBlockCount].id] + + let categoryName + if (idx === 0) { + categoryName = "Trigger outputs" + } else if (isLoopBlock) { + categoryName = "Loop Outputs" + } else if (bindingName) { + categoryName = `${bindingName} outputs` + } else { + categoryName = `Step ${idx - loopBlockCount} outputs` + } + return { readableBinding: runtime, runtimeBinding: runtime, @@ -221,7 +227,7 @@ display: { type: value.type, name: name, - rank: bindindingRank, + rank: bindingRank, }, } }) From 791020580720c7098274329b64a7e82895363a11 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Tue, 24 Oct 2023 15:17:57 +0100 Subject: [PATCH 04/34] update styling of flow items --- .../FlowChart/FlowChart.svelte | 139 +++++++++++------- .../FlowChart/FlowItem.svelte | 24 +-- .../[application]/automation/_layout.svelte | 1 - 3 files changed, 92 insertions(+), 72 deletions(-) diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte index 63a3478ef3..784cdf2357 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte @@ -5,13 +5,7 @@ import TestDataModal from "./TestDataModal.svelte" import { flip } from "svelte/animate" import { fly } from "svelte/transition" - import { - Heading, - Icon, - ActionButton, - notifications, - Modal, - } from "@budibase/bbui" + import { Icon, notifications, Modal } from "@budibase/bbui" import { ActionStepID } from "constants/backend/automations" import UndoRedoControl from "components/common/UndoRedoControl.svelte" import { automationHistoryStore } from "builderStore" @@ -20,7 +14,8 @@ let testDataModal let confirmDeleteDialog - + let scrolling = false + let hasScrolled = false $: blocks = getBlocks(automation) const getBlocks = automation => { @@ -32,58 +27,74 @@ return blocks } - async function deleteAutomation() { + const deleteAutomation = async () => { try { await automationStore.actions.delete($selectedAutomation) } catch (error) { notifications.error("Error deleting automation") } } + + const handleScroll = e => { + if (e.target.scrollTop >= 30 && !hasScrolled) { + scrolling = true + hasScrolled = true + } else if (e.target.scrollTop < 30 && hasScrolled) { + // Set scrolling back to false if scrolled back to less than 100px + scrolling = false + hasScrolled = false + } + } -
-
- {automation.name} -
- +
+
+ +
+
+
+ +
{ + testDataModal.show() + }} + > + Run test +
+
+
-
- { - testDataModal.show() - }} - icon="MultipleCheck" - size="M">Run test - { - $automationStore.showTestPanel = true - }} - size="M">Test Details +
{ + $automationStore.showTestPanel = true + }} + > + Test details
-
- {#each blocks as block, idx (block.id)} -
- {#if block.stepId !== ActionStepID.LOOP} - - {/if} -
- {/each} +
+
+ {#each blocks as block, idx (block.id)} +
+ {#if block.stepId !== ActionStepID.LOOP} + + {/if} +
+ {/each} +
.canvas { padding: var(--spacing-l) var(--spacing-xl); + overflow-y: auto; + max-height: 100%; + } + + .header-left :global(div) { + border-right: none; } /* Fix for firefox not respecting bottom padding in scrolling containers */ .canvas > *:last-child { @@ -117,23 +134,45 @@ } .content { - display: inline-block; - text-align: left; + flex-grow: 1; + padding: 23px 23px 80px; + box-sizing: border-box; + } + + .header.scrolling { + background: var(--background); + z-index: -1; + border-bottom: var(--border-light); + background: var(--background); } .header { + z-index: 1; display: flex; justify-content: space-between; align-items: center; + padding-left: var(--spacing-l); + transition: background 130ms ease-out; + flex: 0 0 48px; + padding-right: var(--spacing-xl); + } + .controls { + display: flex; + gap: var(--spacing-xl); } - .controls, .buttons { display: flex; justify-content: flex-end; align-items: center; - gap: var(--spacing-xl); - } - .buttons { gap: var(--spacing-s); } + + .buttons:hover { + cursor: pointer; + } + + .disabled { + pointer-events: none; + color: var(--spectrum-global-color-gray-500) !important; + } diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte index 0517fe1034..7d00ee4ac1 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte @@ -16,11 +16,7 @@ import ActionModal from "./ActionModal.svelte" import FlowItemHeader from "./FlowItemHeader.svelte" import RoleSelect from "components/design/settings/controls/RoleSelect.svelte" - import { - ActionStepID, - TriggerStepID, - Features, - } from "constants/backend/automations" + import { ActionStepID, TriggerStepID } from "constants/backend/automations" import { permissions } from "stores/backend" export let block @@ -172,28 +168,14 @@ {block} {testDataModal} {idx} + {addLooping} + {deleteStep} on:toggle={() => (open = !open)} /> {#if open}
- {#if !isTrigger} -
-
- {#if !loopBlock && (block?.features?.[Features.LOOPING] || !block.features)} - addLooping()} icon="Reuse"> - Add Looping - - {/if} - deleteStep()} - icon="DeleteOutline" - /> -
-
- {/if} - {#if isAppAction} diff --git a/packages/builder/src/pages/builder/app/[application]/automation/_layout.svelte b/packages/builder/src/pages/builder/app/[application]/automation/_layout.svelte index 0afe257e60..dd18dbba82 100644 --- a/packages/builder/src/pages/builder/app/[application]/automation/_layout.svelte +++ b/packages/builder/src/pages/builder/app/[application]/automation/_layout.svelte @@ -91,7 +91,6 @@ flex-direction: column; justify-content: flex-start; align-items: stretch; - gap: var(--spacing-l); overflow: auto; } .centered { From edb511cbce84e9ed22dd8a502d0a66353516c693 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Wed, 25 Oct 2023 11:57:52 +0100 Subject: [PATCH 05/34] update field styling and ux for individual blocks --- packages/builder/.gitignore | 3 +- .../FlowChart/FlowItem.svelte | 14 +- .../SetupPanel/AutomationBlockSetup.svelte | 434 +++++++++--------- .../automation/SetupPanel/RowSelector.svelte | 122 ++--- .../SetupPanel/RowSelectorTypes.svelte | 4 - 5 files changed, 297 insertions(+), 280 deletions(-) diff --git a/packages/builder/.gitignore b/packages/builder/.gitignore index e5c961d509..abc5671984 100644 --- a/packages/builder/.gitignore +++ b/packages/builder/.gitignore @@ -5,4 +5,5 @@ package-lock.json release/ dist/ routify -.routify/ \ No newline at end of file +.routify/ +svelte.config.js \ No newline at end of file diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte index 7d00ee4ac1..2cdb1e1e72 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte @@ -100,19 +100,13 @@ } -
{}} - on:click={() => {}} -> +
{}}> {#if loopBlock}
{ showLooping = !showLooping }} - on:keydown={() => {}} class="splitHeader" >
@@ -131,11 +125,7 @@
-
{}} - on:click={() => {}} - > +
{}}>
diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index fa1f0c76c9..3a96363751 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -295,245 +295,248 @@
{#each schemaProperties as [key, value]} {#if canShowField(key, value)} -
- {#if key !== "fields" && value.type !== "boolean"} +
+ {#if key !== "fields" && value.type !== "boolean" && value.customType !== "row"} {/if} - {#if value.type === "string" && value.enum && canShowField(key, value)} - onChange(e, key)} - /> -
- {:else if value.type === "date"} - onChange(e, key)} - {bindings} - allowJS={true} - updateOnChange={false} - drawerLeft="260px" - > - onChange(e, key)} + placeholder={false} + options={value.enum} + getOptionLabel={(x, idx) => + value.pretty ? value.pretty[idx] : x} /> - - {:else if value.customType === "column"} - onChange(e, key)} - value={inputData[key]} - /> - {:else if value.customType === "email"} - {#if isTestModal} - onChange(e, key)} - {bindings} - fillWidth - updateOnChange={false} - /> - {:else} - + onChange(e, key)} + /> +
+ {:else if value.type === "date"} + onChange(e, key)} {bindings} - allowJS={false} + allowJS={true} updateOnChange={false} drawerLeft="260px" - /> - {/if} - {:else if value.customType === "query"} - onChange(e, key)} - value={inputData[key]} - /> - {:else if value.customType === "cron"} - onChange(e, key)} - value={inputData[key]} - /> - {:else if value.customType === "queryParams"} - onChange(e, key)} - value={inputData[key]} - {bindings} - /> - {:else if value.customType === "table"} - onChange(e, key)} - /> - {:else if value.customType === "row"} - { - if (e.detail?.key) { - onChange(e, e.detail.key) - } else { - onChange(e, key) - } - }} - {bindings} - {isTestModal} - {isUpdateRow} - /> - {:else if value.customType === "webhookUrl"} - onChange(e, key)} - value={inputData[key]} - /> - {:else if value.customType === "fields"} - onChange(e, key)} - {bindings} - {isTestModal} - /> - {:else if value.customType === "triggerSchema"} - onChange(e, key)} - value={inputData[key]} - /> - {:else if value.customType === "code"} - - {#if codeMode == EditorModes.JS} - (codeBindingOpen = !codeBindingOpen)} - quiet - icon={codeBindingOpen ? "ChevronDown" : "ChevronRight"} - > - Bindings - - {#if codeBindingOpen} -
{JSON.stringify(bindings, null, 2)}
- {/if} - {/if} - { - // need to pass without the value inside - onChange({ detail: e.detail }, key) - inputData[key] = e.detail - }} - completions={stepCompletions} - mode={codeMode} - autocompleteEnabled={codeMode != EditorModes.JS} - height={500} - /> -
- {#if codeMode == EditorModes.Handlebars} - -
-
- Add available bindings by typing - }} - -
-
- {/if} -
-
- {:else if value.customType === "loopOption"} - onChange(e, key)} - {bindings} - updateOnChange={false} + value={inputData[key]} + options={Object.keys(table?.schema || {})} /> - {:else} -
+ {:else if value.customType === "filters"} + Define filters + + + (tempFilters = e.detail)} + /> + + {:else if value.customType === "password"} + onChange(e, key)} + value={inputData[key]} + /> + {:else if value.customType === "email"} + {#if isTestModal} + onChange(e, key)} + {bindings} + fillWidth + updateOnChange={false} + /> + {:else} onChange(e, key)} {bindings} + allowJS={false} updateOnChange={false} - placeholder={value.customType === "queryLimit" - ? queryLimit - : ""} drawerLeft="260px" /> -
+ {/if} + {:else if value.customType === "query"} + onChange(e, key)} + value={inputData[key]} + /> + {:else if value.customType === "cron"} + onChange(e, key)} + value={inputData[key]} + /> + {:else if value.customType === "queryParams"} + onChange(e, key)} + value={inputData[key]} + {bindings} + /> + {:else if value.customType === "table"} + onChange(e, key)} + /> + {:else if value.customType === "row"} + { + if (e.detail?.key) { + onChange(e, e.detail.key) + } else { + onChange(e, key) + } + }} + {bindings} + {isTestModal} + {isUpdateRow} + /> + {:else if value.customType === "webhookUrl"} + onChange(e, key)} + value={inputData[key]} + /> + {:else if value.customType === "fields"} + onChange(e, key)} + {bindings} + {isTestModal} + /> + {:else if value.customType === "triggerSchema"} + onChange(e, key)} + value={inputData[key]} + /> + {:else if value.customType === "code"} + + {#if codeMode == EditorModes.JS} + (codeBindingOpen = !codeBindingOpen)} + quiet + icon={codeBindingOpen ? "ChevronDown" : "ChevronRight"} + > + Bindings + + {#if codeBindingOpen} +
{JSON.stringify(bindings, null, 2)}
+ {/if} + {/if} + { + // need to pass without the value inside + onChange({ detail: e.detail }, key) + inputData[key] = e.detail + }} + completions={stepCompletions} + mode={codeMode} + autocompleteEnabled={codeMode != EditorModes.JS} + height={500} + /> +
+ {#if codeMode == EditorModes.Handlebars} + +
+
+ Add available bindings by typing + }} + +
+
+ {/if} +
+
+ {:else if value.customType === "loopOption"} + table.name} - getOptionValue={table => table._id} -/> +
+ +
+ onChange(e, field)} - label={field} value={value[field]} options={schema.constraints.inclusion} /> @@ -46,7 +45,6 @@ {:else if schema.type === "boolean"} { automationNameError = getAutomationNameError(e.target.value) From 3eba7990f9d1759926c2d3eba76ea4694ef07a60 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Thu, 26 Oct 2023 10:23:51 +0100 Subject: [PATCH 07/34] fix bug with smtp name containing parentheses --- .../AutomationBuilder/FlowChart/FlowItemHeader.svelte | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte index 87934d6520..0d35f955ef 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte @@ -57,14 +57,15 @@ } const getAutomationNameError = name => { - if (name.length > 0) { + if (name !== block.name && block.name.includes(name)) { + if (name?.length > 0) { let invalidRoleName = !validRegex.test(name) if (invalidRoleName) { return "Please enter a role name consisting of only alphanumeric symbols and underscores" } } return null - } + }} const startTyping = async () => { typing = true From 8203139c69639c48190c008336e096e9129619a2 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Thu, 26 Oct 2023 11:27:20 +0100 Subject: [PATCH 08/34] fix bug in adding trigger --- .../FlowChart/FlowItemHeader.svelte | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte index 0d35f955ef..8b907ae0f6 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte @@ -20,7 +20,7 @@ const dispatch = createEventDispatcher() $: stepNames = $selectedAutomation.definition.stepNames - $: automationName = stepNames[block.id] || block.name || "" + $: automationName = stepNames?.[block.id] || block?.name || "" $: automationNameError = getAutomationNameError(automationName) $: status = updateStatus(testResult, isTrigger) $: isTrigger = isTrigger || block.type === "TRIGGER" @@ -32,7 +32,7 @@ } } $: loopBlock = $selectedAutomation?.definition.steps.find( - x => x.blockToLoop === block.id + x => x.blockToLoop === block?.id ) async function onSelect(block) { @@ -59,13 +59,14 @@ const getAutomationNameError = name => { if (name !== block.name && block.name.includes(name)) { if (name?.length > 0) { - let invalidRoleName = !validRegex.test(name) - if (invalidRoleName) { - return "Please enter a role name consisting of only alphanumeric symbols and underscores" + let invalidRoleName = !validRegex.test(name) + if (invalidRoleName) { + return "Please enter a role name consisting of only alphanumeric symbols and underscores" + } } + return null } - return null - }} + } const startTyping = async () => { typing = true From 73a7b8eb50de6f4a4660887974cea14fe4599624 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Thu, 26 Oct 2023 11:27:34 +0100 Subject: [PATCH 09/34] fix formatting of selectors --- .../SetupPanel/AutomationBlockSetup.svelte | 14 ++++- .../SetupPanel/CodeEditorModal.svelte | 9 ++- .../SetupPanel/QueryParamSelector.svelte | 63 +++++++++++-------- 3 files changed, 57 insertions(+), 29 deletions(-) diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index 3a96363751..4a0f1094ad 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -283,6 +283,14 @@ return !dependsOn || !!inputData[dependsOn] } + function shouldRenderField(value) { + return ( + value.customType !== "row" && + value.customType !== "code" && + value.customType !== "queryParams" + ) + } + onMount(async () => { try { await environment.loadVariables() @@ -295,15 +303,15 @@
{#each schemaProperties as [key, value]} {#if canShowField(key, value)} -
- {#if key !== "fields" && value.type !== "boolean" && value.customType !== "row"} +
+ {#if key !== "fields" && value.type !== "boolean" && shouldRenderField(value)} {/if} -
+
{#if value.type === "string" && value.enum && canShowField(key, value)} query._id} - getOptionLabel={query => query.name} - /> +
+ +
+ { - automationNameError = getAutomationNameError(e.target.value) - automationName = e.target.value - if (!automationNameError) { - automationNameError = false // Reset the error when input is valid - } + automationName = e.target.value.trim() }} on:click={startTyping} on:blur={async () => { typing = false if (automationNameError) { automationName = stepNames[block.id] - automationNameError = null } else { await saveName() } @@ -225,7 +220,7 @@ font-family: var(--font-sans); color: var(--ink); background-color: transparent; - border: none; + border: 1px solid transparent; font-size: var(--spectrum-alias-font-size-default); width: 260px; box-sizing: border-box; @@ -246,11 +241,13 @@ } .typing { - border: 0.5px solid var(--spectrum-global-color-static-blue-500); + border: 1px solid var(--spectrum-global-color-static-blue-500); + border-radius: 4px 4px 4px 4px; } .typing-error { - border: 0.5px solid var(--spectrum-global-color-static-red-500); + border: 1px solid var(--spectrum-global-color-static-red-500); + border-radius: 4px 4px 4px 4px; } .error-icon :global(.spectrum-Icon) { diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index 4a0f1094ad..de3a66e216 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -204,7 +204,7 @@ const runtime = idx === 0 ? `trigger.${name}` : runtimeName let bindingName = - automation.stepNames[allSteps[bindingRank - loopBlockCount].id] + automation.stepNames?.[allSteps[bindingRank - loopBlockCount].id] let categoryName if (idx === 0) { @@ -287,7 +287,8 @@ return ( value.customType !== "row" && value.customType !== "code" && - value.customType !== "queryParams" + value.customType !== "queryParams" && + value.customType !== "cron" ) } From 89a242f35456135e81c7cd7f3678addbbb4f221f Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Fri, 27 Oct 2023 09:13:27 +0100 Subject: [PATCH 11/34] fix issue with readable bindings not displayinng correctly --- .../builder/src/builderStore/store/automation/index.js | 9 +++++---- .../automation/SetupPanel/AutomationBlockSetup.svelte | 8 ++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/builder/src/builderStore/store/automation/index.js b/packages/builder/src/builderStore/store/automation/index.js index 66715faf3a..f60e10e50b 100644 --- a/packages/builder/src/builderStore/store/automation/index.js +++ b/packages/builder/src/builderStore/store/automation/index.js @@ -221,7 +221,7 @@ const automationActions = store => ({ newAutomation.definition.steps.splice(blockIdx, 0, block) await store.actions.save(newAutomation) }, - saveAutomationName: async (stepId, name) => { + saveAutomationName: async (blockId, name) => { const automation = get(selectedAutomation) let newAutomation = cloneDeep(automation) if (!automation) { @@ -229,18 +229,18 @@ const automationActions = store => ({ } newAutomation.definition.stepNames = { ...newAutomation.definition.stepNames, - [stepId]: name.trim(), + [blockId]: name.trim(), } await store.actions.save(newAutomation) }, - deleteAutomationName: async stepId => { + deleteAutomationName: async blockId => { const automation = get(selectedAutomation) let newAutomation = cloneDeep(automation) if (!automation) { return } - delete newAutomation.definition.stepNames[stepId] + delete newAutomation.definition.stepNames[blockId] await store.actions.save(newAutomation) }, @@ -257,6 +257,7 @@ const automationActions = store => ({ newAutomation.definition.steps = newAutomation.definition.steps.filter( step => step.id !== block.id ) + delete newAutomation.definition.stepNames[block.id] } await store.actions.save(newAutomation) }, diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index de3a66e216..d38cda8de1 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -194,6 +194,9 @@ bindingIcon = allSteps[idx].icon bindingRank = idx - loopBlockCount } + let bindingName = + automation.stepNames?.[allSteps[bindingRank - loopBlockCount].id] + bindings = bindings.concat( outputs.map(([name, value]) => { let runtimeName = isLoopBlock @@ -203,9 +206,6 @@ : `steps.${idx - loopBlockCount}.${name}` const runtime = idx === 0 ? `trigger.${name}` : runtimeName - let bindingName = - automation.stepNames?.[allSteps[bindingRank - loopBlockCount].id] - let categoryName if (idx === 0) { categoryName = "Trigger outputs" @@ -218,7 +218,7 @@ } return { - readableBinding: runtime, + readableBinding: bindingName ? `${bindingName}.${name}` : runtime, runtimeBinding: runtime, type: value.type, description: value.description, From 8a7a2abd614a7eb05d7bfc62e8187005444ee18a Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Fri, 27 Oct 2023 10:45:58 +0100 Subject: [PATCH 12/34] styling / pr comments --- .../FlowChart/FlowItemHeader.svelte | 53 ++++++++++++------- .../SetupPanel/AutomationBlockSetup.svelte | 4 +- .../SetupPanel/QueryParamSelector.svelte | 2 +- 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte index 868e6eb1bd..02a731dd78 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte @@ -23,7 +23,8 @@ $: automationName = stepNames?.[block.id] || block?.name || "" $: automationNameError = getAutomationNameError(automationName) $: status = updateStatus(testResult, isTrigger) - $: isTrigger = isTrigger || block.type === "TRIGGER" + $: isHeaderTrigger = isTrigger || block.type === "TRIGGER" + $: { if (!testResult) { testResult = $automationStore.testResults?.steps?.filter(step => @@ -109,7 +110,7 @@ {/if}
- {#if isTrigger} + {#if isHeaderTrigger} Trigger {:else}
@@ -138,13 +139,21 @@
{#if showTestStatus && testResult} -
- {status?.message} +
+
+ + {status?.message} + +
+ dispatch("toggle")} + hoverable + name={open ? "ChevronUp" : "ChevronDown"} + />
{/if}
{#if !showTestStatus} - {#if !isTrigger && !loopBlock && (block?.features?.[Features.LOOPING] || !block.features)} + {#if !isHeaderTrigger && !loopBlock && (block?.features?.[Features.LOOPING] || !block.features)} @@ -164,11 +173,13 @@ {/if} - dispatch("toggle")} - hoverable - name={open ? "ChevronUp" : "ChevronDown"} - /> + {#if !showTestStatus} + dispatch("toggle")} + hoverable + name={open ? "ChevronUp" : "ChevronDown"} + /> + {/if}
{#if automationNameError}
@@ -184,10 +195,17 @@
diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index 9d931af7bb..9260a197c2 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -58,7 +58,6 @@ let fillWidth = true let inputData let codeBindingOpen = false - $: console.log($selectedAutomation?.definition) $: filters = lookForFilters(schemaProperties) || [] $: tempFilters = filters $: stepId = block.stepId @@ -136,7 +135,6 @@ await automationStore.actions.addTestDataToAutomation(newTestData) } else { const data = { schema, [key]: e.detail } - console.log(data) await automationStore.actions.updateBlockInputs(block, data) } } catch (error) { @@ -156,7 +154,7 @@ } let blockIdx = allSteps.findIndex(step => step.id === block.id) - // Extract all outputs from all previous steps as available bindins + // Extract all outputs from all previous steps as available bindingsx§x let bindings = [] let loopBlockCount = 0 for (let idx = 0; idx < blockIdx; idx++) { @@ -197,7 +195,6 @@ } let bindingName = automation.stepNames?.[allSteps[idx - loopBlockCount].id] - console.log(bindingName) bindings = bindings.concat( outputs.map(([name, value]) => { let runtimeName = isLoopBlock From b65b6019185bbfbd9b05cfb70d20fc4428dee1b2 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Tue, 31 Oct 2023 13:52:28 +0000 Subject: [PATCH 17/34] remove label --- .../src/components/automation/SetupPanel/RowSelector.svelte | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte b/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte index 4f96c21370..971bb5886b 100644 --- a/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte +++ b/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte @@ -132,7 +132,6 @@ title={value.title} panel={AutomationBindingPanel} type={schema.type} - label={field} {schema} value={value[field]} on:change={e => onChange(e, field)} From 7cba4d3fb21b59dda768581e7e2a525fafa2b70c Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Tue, 31 Oct 2023 16:29:43 +0000 Subject: [PATCH 18/34] formatting found in testing --- .../FlowChart/FlowItem.svelte | 6 ++++-- .../SetupPanel/AutomationBlockSetup.svelte | 1 + .../automation/SetupPanel/RowSelector.svelte | 1 + .../SetupPanel/RowSelectorTypes.svelte | 21 +++---------------- .../common/bindings/DrawerBindableSlot.svelte | 4 ++-- 5 files changed, 11 insertions(+), 22 deletions(-) diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte index 9692154e31..c6d38a4d2e 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte @@ -168,8 +168,10 @@
{#if isAppAction} - - +
+ + +
{/if}
diff --git a/packages/builder/src/components/automation/SetupPanel/RowSelectorTypes.svelte b/packages/builder/src/components/automation/SetupPanel/RowSelectorTypes.svelte index c573049c08..373d174541 100644 --- a/packages/builder/src/components/automation/SetupPanel/RowSelectorTypes.svelte +++ b/packages/builder/src/components/automation/SetupPanel/RowSelectorTypes.svelte @@ -1,11 +1,5 @@
@@ -106,7 +106,7 @@ table._id !== TableNames.USERS)} getOptionLabel={table => table.name} getOptionValue={table => table._id} /> From f1802eb41c8896879351caa3d39fa0de0dca5cb7 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Fri, 3 Nov 2023 10:04:51 +0000 Subject: [PATCH 21/34] update modal sizing for automation test data --- .../automation/AutomationBuilder/FlowChart/TestDataModal.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/TestDataModal.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/TestDataModal.svelte index 17d5b35575..5c97d77ae8 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/TestDataModal.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/TestDataModal.svelte @@ -60,6 +60,7 @@ Date: Fri, 3 Nov 2023 11:05:05 +0000 Subject: [PATCH 22/34] unique name enforcement for automations --- .../AutomationBuilder/FlowChart/FlowItemHeader.svelte | 7 +++++++ .../automation/SetupPanel/AutomationBlockSetup.svelte | 1 - 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte index d07093ad7a..4c72c57208 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte @@ -58,11 +58,18 @@ } const getAutomationNameError = name => { + for (const [key, value] of Object.entries(stepNames)) { + if (name === value && key !== block.id) { + return "This name already exists, please enter a unique name" + } + } + if (name !== block.name && name?.length > 0) { let invalidRoleName = !validRegex.test(name) if (invalidRoleName) { return "Please enter a role name consisting of only alphanumeric symbols and underscores" } + return null } } diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index a42cc34b9d..9260a197c2 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -282,7 +282,6 @@ } function shouldRenderField(value) { - console.log(value) return ( value.customType !== "row" && value.customType !== "code" && From e316124d6e7b5fc70130368e7277e9372039ca6b Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Fri, 3 Nov 2023 11:42:39 +0000 Subject: [PATCH 23/34] Add a test for the user column migration bug fix we did last night. --- .../server/src/api/routes/tests/table.spec.ts | 61 +++++++++++++++++++ .../server/src/tests/utilities/api/row.ts | 21 +++++-- 2 files changed, 78 insertions(+), 4 deletions(-) diff --git a/packages/server/src/api/routes/tests/table.spec.ts b/packages/server/src/api/routes/tests/table.spec.ts index c239c596fe..4743bca814 100644 --- a/packages/server/src/api/routes/tests/table.spec.ts +++ b/packages/server/src/api/routes/tests/table.spec.ts @@ -492,6 +492,67 @@ describe("/tables", () => { } }) + it("should succeed when the row is created from the other side of the relationship", async () => { + // We found a bug just after releasing this feature where if the row was created from the + // users table, not the table linking to it, the migration would succeed but lose the data. + // This happened because the order of the documents in the link was reversed. + const table = await config.api.table.create({ + name: "table", + type: "table", + sourceId: INTERNAL_TABLE_SOURCE_ID, + sourceType: TableSourceType.INTERNAL, + schema: { + "user relationship": { + type: FieldType.LINK, + fieldName: "test", + name: "user relationship", + constraints: { + type: "array", + presence: false, + }, + relationshipType: RelationshipType.MANY_TO_ONE, + tableId: InternalTable.USER_METADATA, + }, + }, + }) + + let testRow = await config.api.row.save(table._id!, {}) + + await Promise.all( + users.map(u => + config.api.row.patch(InternalTable.USER_METADATA, { + tableId: InternalTable.USER_METADATA, + _rev: u._rev!, + _id: u._id!, + test: [testRow], + }) + ) + ) + + await config.api.table.migrate(table._id!, { + oldColumn: table.schema["user relationship"], + newColumn: { + name: "user column", + type: FieldType.BB_REFERENCE, + subtype: FieldSubtype.USERS, + }, + }) + + const migratedTable = await config.api.table.get(table._id!) + expect(migratedTable.schema["user column"]).toBeDefined() + expect(migratedTable.schema["user relationship"]).not.toBeDefined() + + const resp = await config.api.row.get(table._id!, testRow._id!) + const migratedRow = resp.body as Row + + expect(migratedRow["user column"]).toBeDefined() + expect(migratedRow["user relationship"]).not.toBeDefined() + expect(migratedRow["user column"]).toHaveLength(3) + expect(migratedRow["user column"].map((u: Row) => u._id)).toEqual( + expect.arrayContaining(users.map(u => u._id)) + ) + }) + it("should successfully migrate a many-to-many user relationship to a users column", async () => { const table = await config.api.table.create({ name: "table", diff --git a/packages/server/src/tests/utilities/api/row.ts b/packages/server/src/tests/utilities/api/row.ts index bb880bb7da..20b1d6f9ee 100644 --- a/packages/server/src/tests/utilities/api/row.ts +++ b/packages/server/src/tests/utilities/api/row.ts @@ -55,7 +55,13 @@ export class RowAPI extends TestAPI { .send(row) .set(this.config.defaultHeaders()) .expect("Content-Type", /json/) - .expect(expectStatus) + if (resp.status !== expectStatus) { + throw new Error( + `Expected status ${expectStatus} but got ${ + resp.status + }, body: ${JSON.stringify(resp.body)}` + ) + } return resp.body as Row } @@ -77,13 +83,20 @@ export class RowAPI extends TestAPI { sourceId: string, row: PatchRowRequest, { expectStatus } = { expectStatus: 200 } - ) => { - return this.request + ): Promise => { + let resp = await this.request .patch(`/api/${sourceId}/rows`) .send(row) .set(this.config.defaultHeaders()) .expect("Content-Type", /json/) - .expect(expectStatus) + if (resp.status !== expectStatus) { + throw new Error( + `Expected status ${expectStatus} but got ${ + resp.status + }, body: ${JSON.stringify(resp.body)}` + ) + } + return resp.body as Row } delete = async ( From 96534e625f71cafc71d01a8e219ef3a9d6a57cfb Mon Sep 17 00:00:00 2001 From: Michael Drury Date: Fri, 3 Nov 2023 12:22:32 +0000 Subject: [PATCH 24/34] Revert "Updating bull parameters - help queue stalling" --- packages/backend-core/src/index.ts | 1 - .../backend-core/src/queue/inMemoryQueue.ts | 2 +- packages/backend-core/src/queue/queue.ts | 20 ++------ packages/backend-core/src/utils/Duration.ts | 49 ------------------- packages/backend-core/src/utils/index.ts | 1 - .../src/utils/tests/Duration.spec.ts | 19 ------- 6 files changed, 4 insertions(+), 88 deletions(-) delete mode 100644 packages/backend-core/src/utils/Duration.ts delete mode 100644 packages/backend-core/src/utils/tests/Duration.spec.ts diff --git a/packages/backend-core/src/index.ts b/packages/backend-core/src/index.ts index c7cf9f56cc..ffffd8240a 100644 --- a/packages/backend-core/src/index.ts +++ b/packages/backend-core/src/index.ts @@ -30,7 +30,6 @@ export * as timers from "./timers" export { default as env } from "./environment" export * as blacklist from "./blacklist" export * as docUpdates from "./docUpdates" -export * from "./utils/Duration" export { SearchParams } from "./db" // Add context to tenancy for backwards compatibility // only do this for external usages to prevent internal diff --git a/packages/backend-core/src/queue/inMemoryQueue.ts b/packages/backend-core/src/queue/inMemoryQueue.ts index a8add7ecb6..af2ec6dbaa 100644 --- a/packages/backend-core/src/queue/inMemoryQueue.ts +++ b/packages/backend-core/src/queue/inMemoryQueue.ts @@ -36,7 +36,7 @@ class InMemoryQueue { * @param opts This is not used by the in memory queue as there is no real use * case when in memory, but is the same API as Bull */ - constructor(name: string, opts?: any) { + constructor(name: string, opts = null) { this._name = name this._opts = opts this._messages = [] diff --git a/packages/backend-core/src/queue/queue.ts b/packages/backend-core/src/queue/queue.ts index c0d1861de3..0658147709 100644 --- a/packages/backend-core/src/queue/queue.ts +++ b/packages/backend-core/src/queue/queue.ts @@ -2,18 +2,11 @@ import env from "../environment" import { getRedisOptions } from "../redis/utils" import { JobQueue } from "./constants" import InMemoryQueue from "./inMemoryQueue" -import BullQueue, { QueueOptions } from "bull" +import BullQueue from "bull" import { addListeners, StalledFn } from "./listeners" -import { Duration } from "../utils" import * as timers from "../timers" -import * as Redis from "ioredis" -// the queue lock is held for 5 minutes -const QUEUE_LOCK_MS = Duration.fromMinutes(5).toMs() -// queue lock is refreshed every 30 seconds -const QUEUE_LOCK_RENEW_INTERNAL_MS = Duration.fromSeconds(30).toMs() -// cleanup the queue every 60 seconds -const CLEANUP_PERIOD_MS = Duration.fromSeconds(60).toMs() +const CLEANUP_PERIOD_MS = 60 * 1000 let QUEUES: BullQueue.Queue[] | InMemoryQueue[] = [] let cleanupInterval: NodeJS.Timeout @@ -28,14 +21,7 @@ export function createQueue( opts: { removeStalledCb?: StalledFn } = {} ): BullQueue.Queue { const { opts: redisOpts, redisProtocolUrl } = getRedisOptions() - const queueConfig: QueueOptions = { - redis: redisProtocolUrl! || (redisOpts as Redis.RedisOptions), - settings: { - maxStalledCount: 0, - lockDuration: QUEUE_LOCK_MS, - lockRenewTime: QUEUE_LOCK_RENEW_INTERNAL_MS, - }, - } + const queueConfig: any = redisProtocolUrl || { redis: redisOpts } let queue: any if (!env.isTest()) { queue = new BullQueue(jobQueue, queueConfig) diff --git a/packages/backend-core/src/utils/Duration.ts b/packages/backend-core/src/utils/Duration.ts deleted file mode 100644 index f376c2f7c7..0000000000 --- a/packages/backend-core/src/utils/Duration.ts +++ /dev/null @@ -1,49 +0,0 @@ -export enum DurationType { - MILLISECONDS = "milliseconds", - SECONDS = "seconds", - MINUTES = "minutes", - HOURS = "hours", - DAYS = "days", -} - -const conversion: Record = { - milliseconds: 1, - seconds: 1000, - minutes: 60 * 1000, - hours: 60 * 60 * 1000, - days: 24 * 60 * 60 * 1000, -} - -export class Duration { - static convert(from: DurationType, to: DurationType, duration: number) { - const milliseconds = duration * conversion[from] - return milliseconds / conversion[to] - } - - static from(from: DurationType, duration: number) { - return { - to: (to: DurationType) => { - return Duration.convert(from, to, duration) - }, - toMs: () => { - return Duration.convert(from, DurationType.MILLISECONDS, duration) - }, - } - } - - static fromSeconds(duration: number) { - return Duration.from(DurationType.SECONDS, duration) - } - - static fromMinutes(duration: number) { - return Duration.from(DurationType.MINUTES, duration) - } - - static fromHours(duration: number) { - return Duration.from(DurationType.HOURS, duration) - } - - static fromDays(duration: number) { - return Duration.from(DurationType.DAYS, duration) - } -} diff --git a/packages/backend-core/src/utils/index.ts b/packages/backend-core/src/utils/index.ts index ac17227459..318a7f13ba 100644 --- a/packages/backend-core/src/utils/index.ts +++ b/packages/backend-core/src/utils/index.ts @@ -1,4 +1,3 @@ export * from "./hashing" export * from "./utils" export * from "./stringUtils" -export * from "./Duration" diff --git a/packages/backend-core/src/utils/tests/Duration.spec.ts b/packages/backend-core/src/utils/tests/Duration.spec.ts deleted file mode 100644 index 46b996f788..0000000000 --- a/packages/backend-core/src/utils/tests/Duration.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Duration, DurationType } from "../Duration" - -describe("duration", () => { - it("should convert minutes to milliseconds", () => { - expect(Duration.fromMinutes(5).toMs()).toBe(300000) - }) - - it("should convert seconds to milliseconds", () => { - expect(Duration.fromSeconds(30).toMs()).toBe(30000) - }) - - it("should convert days to milliseconds", () => { - expect(Duration.fromDays(1).toMs()).toBe(86400000) - }) - - it("should convert minutes to days", () => { - expect(Duration.fromMinutes(1440).to(DurationType.DAYS)).toBe(1) - }) -}) From 980b9c288299a9f356c0af00067ce57760dbe2e5 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Fri, 3 Nov 2023 12:53:37 +0000 Subject: [PATCH 25/34] Fix tests. --- .../server/src/api/routes/tests/row.spec.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/server/src/api/routes/tests/row.spec.ts b/packages/server/src/api/routes/tests/row.spec.ts index 3ae4a6c1e2..92d581d930 100644 --- a/packages/server/src/api/routes/tests/row.spec.ts +++ b/packages/server/src/api/routes/tests/row.spec.ts @@ -49,7 +49,12 @@ describe.each([ let table: Table let tableId: string - afterAll(setup.afterAll) + afterAll(async () => { + if (dsProvider) { + await dsProvider.stopContainer() + } + setup.afterAll() + }) beforeAll(async () => { await config.init() @@ -521,20 +526,17 @@ describe.each([ const rowUsage = await getRowUsage() const queryUsage = await getQueryUsage() - const res = await config.api.row.patch(table._id!, { + const row = await config.api.row.patch(table._id!, { _id: existing._id!, _rev: existing._rev!, tableId: table._id!, name: "Updated Name", }) - expect((res as any).res.statusMessage).toEqual( - `${table.name} updated successfully.` - ) - expect(res.body.name).toEqual("Updated Name") - expect(res.body.description).toEqual(existing.description) + expect(row.name).toEqual("Updated Name") + expect(row.description).toEqual(existing.description) - const savedRow = await loadRow(res.body._id, table._id!) + const savedRow = await loadRow(row._id!, table._id!) expect(savedRow.body.description).toEqual(existing.description) expect(savedRow.body.name).toEqual("Updated Name") From a27a9dc2afb2246f64ee1b1333f300290e9b3b5a Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Fri, 3 Nov 2023 14:29:54 +0000 Subject: [PATCH 26/34] Eliminate TOCTOU problem in creating bbTmp. --- packages/backend-core/src/objectStore/utils.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/backend-core/src/objectStore/utils.ts b/packages/backend-core/src/objectStore/utils.ts index dba5f3d1c2..4c3a84ba91 100644 --- a/packages/backend-core/src/objectStore/utils.ts +++ b/packages/backend-core/src/objectStore/utils.ts @@ -18,8 +18,12 @@ export const ObjectStoreBuckets = { } const bbTmp = join(tmpdir(), ".budibase") -if (!fs.existsSync(bbTmp)) { +try { fs.mkdirSync(bbTmp) +} catch (e: any) { + if (e.code !== "EEXIST") { + throw e + } } export function budibaseTempDir() { From b2e42c837c8052e011f2797bbf4d721070677272 Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Fri, 3 Nov 2023 15:13:59 +0000 Subject: [PATCH 27/34] Remove spacing --- pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pull_request_template.md b/pull_request_template.md index fa0f7f2143..ca01390557 100644 --- a/pull_request_template.md +++ b/pull_request_template.md @@ -2,7 +2,7 @@ _Describe the problem or feature in addition to a link to the relevant github issues._ -Addresses: +### Addresses: - `` - ...more if required From 927cdae8dfc6d6502d62e0b314666cbb19ed3874 Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Fri, 3 Nov 2023 15:36:33 +0000 Subject: [PATCH 28/34] Remove whitespace --- pull_request_template.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pull_request_template.md b/pull_request_template.md index ca01390557..1dd1a1d45d 100644 --- a/pull_request_template.md +++ b/pull_request_template.md @@ -1,16 +1,12 @@ ## Description - _Describe the problem or feature in addition to a link to the relevant github issues._ ### Addresses: - - `` - ...more if required ## App Export - - If possible, attach an app export file along with your request template to make QA testing easier, with minimal setup. ## Screenshots - _If a UI facing feature, a short video of the happy path, and some screenshots of the new functionality._ From 8fed47766aa514936aec4e41c1a64a9d0d3e4fdc Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Fri, 3 Nov 2023 15:42:25 +0000 Subject: [PATCH 29/34] Bump version to 2.12.10 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 2deb06656d..9257a36444 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.12.9", + "version": "2.12.10", "npmClient": "yarn", "packages": [ "packages/*" From cfc0258f3fdaa0d1d93d87772bd602b22e463d94 Mon Sep 17 00:00:00 2001 From: jvcalderon Date: Sat, 4 Nov 2023 12:46:50 +0100 Subject: [PATCH 30/34] Change Posthog's feature flags Ids --- packages/types/src/sdk/featureFlag.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/types/src/sdk/featureFlag.ts b/packages/types/src/sdk/featureFlag.ts index e3935bc7ee..ca0046696a 100644 --- a/packages/types/src/sdk/featureFlag.ts +++ b/packages/types/src/sdk/featureFlag.ts @@ -1,8 +1,7 @@ export enum FeatureFlag { LICENSING = "LICENSING", - // Feature IDs in Posthog - PER_CREATOR_PER_USER_PRICE = "18873", - PER_CREATOR_PER_USER_PRICE_ALERT = "18530", + PER_CREATOR_PER_USER_PRICE = "PER_CREATOR_PER_USER_PRICE", + PER_CREATOR_PER_USER_PRICE_ALERT = "PER_CREATOR_PER_USER_PRICE_ALERT", } export interface TenantFeatureFlags { From 5e3cb99dbb253e869dce73f18d256e7c71c69a23 Mon Sep 17 00:00:00 2001 From: Michael Drury Date: Sat, 4 Nov 2023 11:53:14 +0000 Subject: [PATCH 31/34] Switching back to old MinIO install method. --- hosting/single/runner.sh | 2 +- scripts/install-minio.sh | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hosting/single/runner.sh b/hosting/single/runner.sh index 770b23eec1..9dc7aa25d8 100644 --- a/hosting/single/runner.sh +++ b/hosting/single/runner.sh @@ -77,7 +77,7 @@ mkdir -p ${DATA_DIR}/minio chown -R couchdb:couchdb ${DATA_DIR}/couch redis-server --requirepass $REDIS_PASSWORD > /dev/stdout 2>&1 & /bbcouch-runner.sh & -minio server --console-address ":9001" ${DATA_DIR}/minio > /dev/stdout 2>&1 & +/minio/minio server --console-address ":9001" ${DATA_DIR}/minio > /dev/stdout 2>&1 & /etc/init.d/nginx restart if [[ ! -z "${CUSTOM_DOMAIN}" ]]; then # Add monthly cron job to renew certbot certificate diff --git a/scripts/install-minio.sh b/scripts/install-minio.sh index b1e0d9ee80..fede984377 100755 --- a/scripts/install-minio.sh +++ b/scripts/install-minio.sh @@ -2,9 +2,9 @@ if [[ $TARGETARCH == arm* ]] ; then echo "INSTALLING ARM64 MINIO" - wget wget https://dl.min.io/server/minio/release/linux-arm64/archive/minio.deb -O minio.deb + wget https://dl.min.io/server/minio/release/linux-arm64/minio else echo "INSTALLING AMD64 MINIO" - wget wget https://dl.min.io/server/minio/release/linux-amd64/archive/minio.deb -O minio.deb + wget https://dl.min.io/server/minio/release/linux-amd64/minio fi -dpkg -i minio.deb +chmod +x minio \ No newline at end of file From c539985088cf8bf98336df7b34f1a3266a85200e Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Sat, 4 Nov 2023 12:07:22 +0000 Subject: [PATCH 32/34] Bump version to 2.12.11 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 9257a36444..d102c3f41f 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.12.10", + "version": "2.12.11", "npmClient": "yarn", "packages": [ "packages/*" From 7b7b2a12eab5cc7f37d79f818c26fa3381bcc260 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 6 Nov 2023 10:06:32 +0000 Subject: [PATCH 33/34] fix issue with stepNames being undefined --- .../AutomationBuilder/FlowChart/FlowItemHeader.svelte | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte index 4c72c57208..0c7ac3d27d 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte @@ -58,9 +58,11 @@ } const getAutomationNameError = name => { - for (const [key, value] of Object.entries(stepNames)) { - if (name === value && key !== block.id) { - return "This name already exists, please enter a unique name" + if (stepNames) { + for (const [key, value] of Object.entries(stepNames)) { + if (name === value && key !== block.id) { + return "This name already exists, please enter a unique name" + } } } From ce6de27714cdc4fe34ccdcff10e99cb4872f0945 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Mon, 6 Nov 2023 10:41:00 +0000 Subject: [PATCH 34/34] Bump version to 2.12.12 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index d102c3f41f..79f80e0d7d 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.12.11", + "version": "2.12.12", "npmClient": "yarn", "packages": [ "packages/*"