From 919323b500091eec73a0f36245a5f31d0d8fefa4 Mon Sep 17 00:00:00 2001 From: melohagan <101575380+melohagan@users.noreply.github.com> Date: Tue, 31 Jan 2023 10:11:56 +0000 Subject: [PATCH] Fix/automation update deletes relationship (#9468) * Add padding to text field input * Apply padding to modal binding input * Support relationships in automation bindings * Trim automation field keys * Trim automation field name * Empty string check * Add checkbox for clearing relationships update row * Added state for automation field metadata * clearRelationships updateRow check * Padding tweak --- .../SetupPanel/AutomationBlockSetup.svelte | 21 +++++- .../automation/SetupPanel/RowSelector.svelte | 65 ++++++++++++++----- .../automation/SetupPanel/SchemaSetup.svelte | 2 +- .../common/bindings/ModalBindableInput.svelte | 4 ++ .../actions/TriggerAutomation.svelte | 8 ++- .../server/src/automations/automationUtils.ts | 10 +++ .../server/src/automations/steps/updateRow.ts | 9 ++- 7 files changed, 99 insertions(+), 20 deletions(-) diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index a73db5648b..98fbefaf8e 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -72,8 +72,19 @@ $: schemaFields = Object.values(schema || {}) $: queryLimit = tableId?.includes("datasource") ? "∞" : "1000" $: isTrigger = block?.type === "TRIGGER" + $: isUpdateRow = stepId === ActionStepID.UPDATE_ROW const onChange = Utils.sequential(async (e, key) => { + if (e.detail?.tableId) { + const tableSchema = getSchemaForTable(e.detail.tableId, { + searchableSchema: true, + }).schema + if (isTestModal) { + testData.schema = tableSchema + } else { + block.inputs.schema = tableSchema + } + } try { if (isTestModal) { // Special case for webhook, as it requires a body, but the schema already brings back the body's contents @@ -293,9 +304,17 @@ onChange(e, key)} + meta={inputData["meta"] || {}} + on:change={e => { + if (e.detail?.key) { + onChange(e, e.detail.key) + } else { + onChange(e, key) + } + }} {bindings} {isTestModal} + {isUpdateRow} /> {:else if value.customType === "webhookUrl"} import { tables } from "stores/backend" - import { Select } from "@budibase/bbui" + import { Select, Checkbox } from "@budibase/bbui" import DrawerBindableInput from "../../common/bindings/DrawerBindableInput.svelte" import AutomationBindingPanel from "../../common/bindings/ServerBindingPanel.svelte" import { createEventDispatcher } from "svelte" @@ -10,9 +10,11 @@ const dispatch = createEventDispatcher() export let value + export let meta export let bindings export let block export let isTestModal + export let isUpdateRow $: parsedBindings = bindings.map(binding => { let clone = Object.assign({}, binding) @@ -97,6 +99,17 @@ dispatch("change", value) } + const onChangeSetting = (e, field) => { + let fields = {} + fields[field] = { + clearRelationships: e.detail, + } + dispatch("change", { + key: "meta", + fields, + }) + } + // Ensure any nullish tableId values get set to empty string so // that the select works $: if (value?.tableId == null) value = { tableId: "" } @@ -124,21 +137,33 @@ {onChange} /> {:else} - onChange(e, field, schema.type)} - label={field} - type="string" - bindings={parsedBindings} - fillWidth={true} - allowJS={true} - updateOnChange={false} - /> +
+ onChange(e, field, schema.type)} + label={field} + type="string" + bindings={parsedBindings} + fillWidth={true} + allowJS={true} + updateOnChange={false} + /> + {#if isUpdateRow && schema.type === "link"} +
+ onChangeSetting(e, field)} + /> +
+ {/if} +
{/if} {/if} {/if} @@ -155,4 +180,12 @@ .schema-fields :global(label) { text-transform: capitalize; } + .checkbox-field { + padding-bottom: var(--spacing-s); + padding-left: 1px; + padding-top: var(--spacing-s); + } + .checkbox-field :global(label) { + text-transform: none; + } diff --git a/packages/builder/src/components/automation/SetupPanel/SchemaSetup.svelte b/packages/builder/src/components/automation/SetupPanel/SchemaSetup.svelte index cb80072694..b5173682d0 100644 --- a/packages/builder/src/components/automation/SetupPanel/SchemaSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/SchemaSetup.svelte @@ -58,7 +58,7 @@ entries = entries.filter(f => f.name !== originalName) } value = entries.reduce((newVals, current) => { - newVals[current.name] = current.type + newVals[current.name.trim()] = current.type return newVals }, {}) dispatch("change", value) diff --git a/packages/builder/src/components/common/bindings/ModalBindableInput.svelte b/packages/builder/src/components/common/bindings/ModalBindableInput.svelte index a3fddac3a5..dc851eb270 100644 --- a/packages/builder/src/components/common/bindings/ModalBindableInput.svelte +++ b/packages/builder/src/components/common/bindings/ModalBindableInput.svelte @@ -106,4 +106,8 @@ border: var(--border-light); border-radius: 4px; } + + .control :global(.spectrum-Textfield-input) { + padding-right: 40px; + } diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/TriggerAutomation.svelte b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/TriggerAutomation.svelte index 21768ac461..a2ffb144c0 100644 --- a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/TriggerAutomation.svelte +++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/TriggerAutomation.svelte @@ -36,7 +36,13 @@ $: selectedSchema = selectedAutomation?.schema const onFieldsChanged = e => { - parameters.fields = e.detail + parameters.fields = Object.entries(e.detail || {}).reduce( + (acc, [key, value]) => { + acc[key.trim()] = value + return acc + }, + {} + ) } const setNew = () => { diff --git a/packages/server/src/automations/automationUtils.ts b/packages/server/src/automations/automationUtils.ts index 8a75de83dd..aa52a7fe5c 100644 --- a/packages/server/src/automations/automationUtils.ts +++ b/packages/server/src/automations/automationUtils.ts @@ -51,6 +51,16 @@ export function cleanInputValues(inputs: Record, schema: any) { } } } + //Check if input field should be a relationship and cast to array + for (let key in inputs.row) { + if ( + inputs.schema?.[key]?.type === "link" && + inputs.row[key] && + typeof inputs.row[key] === "string" + ) { + inputs.row[key] = JSON.parse(inputs.row[key]) + } + } return inputs } diff --git a/packages/server/src/automations/steps/updateRow.ts b/packages/server/src/automations/steps/updateRow.ts index 953313986e..9e905a0706 100644 --- a/packages/server/src/automations/steps/updateRow.ts +++ b/packages/server/src/automations/steps/updateRow.ts @@ -19,6 +19,10 @@ export const definition: AutomationStepSchema = { schema: { inputs: { properties: { + meta: { + type: "object", + title: "Field settings", + }, row: { type: "object", customType: "row", @@ -73,7 +77,10 @@ export async function run({ inputs, appId, emitter }: AutomationStepInput) { // clear any undefined, null or empty string properties so that they aren't updated for (let propKey of Object.keys(inputs.row)) { - if (inputs.row[propKey] == null || inputs.row[propKey] === "") { + if ( + (inputs.row[propKey] == null || inputs.row[propKey] === "") && + !inputs.meta?.fields?.[propKey]?.clearRelationships + ) { delete inputs.row[propKey] } }