From 7ed273e15897762d29af772fbbe11e0030a3e623 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Tue, 21 Nov 2023 10:04:49 +0000 Subject: [PATCH 01/19] expand block when header is clicked --- .../FlowChart/FlowItemHeader.svelte | 16 +++++++++++++++- 1 file changed, 15 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 3c9e1a13b1..a935d5e3dd 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte @@ -97,6 +97,7 @@ class:typing={typing && !automationNameError} class:typing-error={automationNameError} class="blockSection" + on:click={() => dispatch("toggle")} >
@@ -138,7 +139,20 @@ on:input={e => { automationName = e.target.value.trim() }} - on:click={startTyping} + on:click={e => { + e.stopPropagation() + startTyping() + }} + on:keydown={async e => { + if (e.key === "Enter") { + typing = false + if (automationNameError) { + automationName = stepNames[block.id] || block?.name + } else { + await saveName() + } + } + }} on:blur={async () => { typing = false if (automationNameError) { From 19f527d620283631a47ebb229db39f2e848f8c84 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Tue, 21 Nov 2023 13:46:34 +0000 Subject: [PATCH 02/19] fix disabled state interfering with column name input --- .../DataTable/modals/CreateEditColumn.svelte | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte index 4eb1f962f0..309584e4c3 100644 --- a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte +++ b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte @@ -149,7 +149,7 @@ } const initialiseField = (field, savingColumn) => { isCreating = !field - + console.log("triggered") if (field && !savingColumn) { editableColumn = cloneDeep(field) originalName = editableColumn.name ? editableColumn.name + "" : null @@ -171,7 +171,8 @@ relationshipPart2 = part2 } } - } else if (!savingColumn) { + } + if (!field && !savingColumn) { let highestNumber = 0 Object.keys(table.schema).forEach(columnName => { const columnNumber = extractColumnNumber(columnName) @@ -182,9 +183,9 @@ }) if (highestNumber >= 1) { - editableColumn.name = `Column 0${highestNumber + 1}` + //editableColumn.name = `Column 0${highestNumber + 1}` } else { - editableColumn.name = "Column 01" + //editableColumn.name = "Column 01" } } @@ -535,13 +536,22 @@ onMount(() => { mounted = true }) + $: console.log(editableColumn) {#if mounted} { + if ( + !uneditable && + !(linkEditDisabled && editableColumn.type === LINK_TYPE) + ) { + editableColumn.name = e.target.value + } + }} disabled={uneditable || (linkEditDisabled && editableColumn.type === LINK_TYPE)} error={errors?.name} From ce73963ac18d75b477a3ab280402eb2c8a7b216e Mon Sep 17 00:00:00 2001 From: Dean Date: Thu, 23 Nov 2023 09:12:11 +0000 Subject: [PATCH 03/19] Manifest updates to remove button config items from Formblocks --- packages/client/manifest.json | 62 +++++++++++------------------------ 1 file changed, 20 insertions(+), 42 deletions(-) diff --git a/packages/client/manifest.json b/packages/client/manifest.json index d409061e91..4289ee4403 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -6036,54 +6036,32 @@ } ] }, + { + "tag": "style", + "type": "select", + "label": "Button position", + "key": "buttonPosition", + "options": [ + { + "label": "Bottom", + "value": "bottom" + }, + { + "label": "Top", + "value": "top" + } + ], + "defaultValue": "bottom" + }, { "section": true, "name": "Buttons", - "dependsOn": { - "setting": "actionType", - "value": "View", - "invert": true - }, "settings": [ { - "type": "text", - "key": "saveButtonLabel", - "label": "Save button", + "type": "buttonConfiguration", + "key": "buttons", "nested": true, - "defaultValue": "Save" - }, - { - "type": "text", - "key": "deleteButtonLabel", - "label": "Delete button", - "nested": true, - "defaultValue": "Delete", - "dependsOn": { - "setting": "actionType", - "value": "Update" - } - }, - { - "type": "url", - "label": "Navigate after button press", - "key": "actionUrl", - "placeholder": "Choose a screen", - "dependsOn": { - "setting": "actionType", - "value": "View", - "invert": true - } - }, - { - "type": "boolean", - "label": "Hide notifications", - "key": "notificationOverride", - "defaultValue": false, - "dependsOn": { - "setting": "actionType", - "value": "View", - "invert": true - } + "resetOn": ["actionType", "dataSource"] } ] }, From c0012409f773e28d394886caf83914c6f9c07ae8 Mon Sep 17 00:00:00 2001 From: Dean Date: Thu, 23 Nov 2023 10:45:13 +0000 Subject: [PATCH 04/19] Added button group support to Formblock and Tableblock components --- .../src/builderStore/store/frontend.js | 40 +++++- .../Component/ComponentSettingsSection.svelte | 2 + .../components/app/blocks/TableBlock.svelte | 32 ++++- .../app/blocks/form/FormBlock.svelte | 33 +++-- .../app/blocks/form/InnerFormBlock.svelte | 129 +++-------------- packages/frontend-core/src/utils/utils.js | 135 ++++++++++++++++++ 6 files changed, 243 insertions(+), 128 deletions(-) diff --git a/packages/builder/src/builderStore/store/frontend.js b/packages/builder/src/builderStore/store/frontend.js index a4729b4a8a..caf2b6dfa6 100644 --- a/packages/builder/src/builderStore/store/frontend.js +++ b/packages/builder/src/builderStore/store/frontend.js @@ -601,6 +601,27 @@ export const getFrontendStore = () => { // Finally try an external table return validTables.find(table => table.sourceType === DB_TYPE_EXTERNAL) }, + processNestedSettings: enrichedComponent => { + const componentPrefix = "@budibase/standard-components" + + if (enrichedComponent?._component == `${componentPrefix}/formblock`) { + // Use default config if the 'buttons' prop has never been initialised + if (!("buttons" in enrichedComponent)) { + enrichedComponent["buttons"] = + Utils.buildDynamicButtonConfig(enrichedComponent) + //Ensure existing Formblocks position their buttons at the top. + enrichedComponent["buttonPosition"] = "top" + } else if (enrichedComponent["buttons"] == null) { + // Ignore legacy config if 'buttons' has been reset by 'resetOn' + const { _id, actionType, dataSource } = enrichedComponent + enrichedComponent["buttons"] = Utils.buildDynamicButtonConfig({ + _id, + actionType, + dataSource, + }) + } + } + }, enrichEmptySettings: (component, opts) => { if (!component?._component) { return @@ -672,7 +693,6 @@ export const getFrontendStore = () => { component[setting.key] = setting.defaultValue } } - // Validate non-empty settings else { if (setting.type === "dataProvider") { @@ -722,6 +742,9 @@ export const getFrontendStore = () => { useDefaultValues: true, }) + // Process nested component settings + store.actions.components.processNestedSettings(instance) + // Add any extra properties the component needs let extras = {} if (definition.hasChildren) { @@ -1247,9 +1270,13 @@ export const getFrontendStore = () => { const settings = getComponentSettings(component._component) const updatedSetting = settings.find(setting => setting.key === name) - const resetFields = settings.filter( - setting => name === setting.resetOn - ) + // Can be a single string or array of strings + const resetFields = settings.filter(setting => { + return ( + name === setting.resetOn || + (Array.isArray(setting.resetOn) && setting.resetOn.includes(name)) + ) + }) resetFields?.forEach(setting => { component[setting.key] = null }) @@ -1271,6 +1298,9 @@ export const getFrontendStore = () => { }) } component[name] = value + + // Process nested component settings + store.actions.components.processNestedSettings(component) } }, requestEjectBlock: componentId => { @@ -1278,7 +1308,7 @@ export const getFrontendStore = () => { }, handleEjectBlock: async (componentId, ejectedDefinition) => { let nextSelectedComponentId - + console.log("EJECTING") await store.actions.screens.patch(screen => { const block = findComponent(screen.props, componentId) const parent = findComponentParent(screen.props, componentId) diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ComponentSettingsSection.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ComponentSettingsSection.svelte index 6093d2a45e..c9094f89db 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ComponentSettingsSection.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ComponentSettingsSection.svelte @@ -19,6 +19,8 @@ export let includeHidden = false export let tag + $: store.actions.components.processNestedSettings(componentInstance) + $: sections = getSections( componentInstance, componentDefinition, diff --git a/packages/client/src/components/app/blocks/TableBlock.svelte b/packages/client/src/components/app/blocks/TableBlock.svelte index 1cb77cb3e5..c8b6a07e3d 100644 --- a/packages/client/src/components/app/blocks/TableBlock.svelte +++ b/packages/client/src/components/app/blocks/TableBlock.svelte @@ -5,6 +5,7 @@ import BlockComponent from "components/BlockComponent.svelte" import { makePropSafe as safe } from "@budibase/string-templates" import { enrichSearchColumns, enrichFilter } from "utils/blocks.js" + import { Utils } from "@budibase/frontend-core" export let title export let dataSource @@ -33,6 +34,7 @@ export let notificationOverride const { fetchDatasourceSchema, API } = getContext("sdk") + const component = getContext("component") const stateKey = `ID_${generate()}` let formId @@ -259,16 +261,25 @@ name="Details form block" type="formblock" bind:id={detailsFormBlockId} + context="form-edit" props={{ dataSource, - saveButtonLabel: sidePanelSaveLabel || "Save", //always show - deleteButtonLabel: deleteLabel, + buttonPosition: "top", + buttons: Utils.buildDynamicButtonConfig({ + _id: $component.id + "-form-edit", + showDeleteButton: deleteLabel !== "", + showSaveButton: true, + saveButtonLabel: sidePanelSaveLabel || "Save", + deleteButtonLabel: deleteLabel, + notificationOverride, + actionType: "Update", + dataSource, + }), actionType: "Update", rowId: `{{ ${safe("state")}.${safe(stateKey)} }}`, fields: sidePanelFields || normalFields, title: editTitle, labelPosition: "left", - notificationOverride, }} /> @@ -284,16 +295,23 @@ diff --git a/packages/client/src/components/app/blocks/form/FormBlock.svelte b/packages/client/src/components/app/blocks/form/FormBlock.svelte index e4d3b55eff..5446514534 100644 --- a/packages/client/src/components/app/blocks/form/FormBlock.svelte +++ b/packages/client/src/components/app/blocks/form/FormBlock.svelte @@ -4,28 +4,31 @@ import Block from "components/Block.svelte" import { makePropSafe as safe } from "@budibase/string-templates" import InnerFormBlock from "./InnerFormBlock.svelte" + import { Utils } from "@budibase/frontend-core" export let actionType export let dataSource export let size export let disabled export let fields + export let buttons + export let buttonPosition + export let title export let description - export let showDeleteButton - export let showSaveButton - export let saveButtonLabel - export let deleteButtonLabel export let rowId export let actionUrl export let noRowsMessage export let notificationOverride - // Accommodate old config to ensure delete button does not reappear - $: deleteLabel = showDeleteButton === false ? "" : deleteButtonLabel?.trim() - $: saveLabel = showSaveButton === false ? "" : saveButtonLabel?.trim() + // Legacy + export let showDeleteButton + export let showSaveButton + export let saveButtonLabel + export let deleteButtonLabel const { fetchDatasourceSchema } = getContext("sdk") + const component = getContext("component") const convertOldFieldFormat = fields => { if (!fields) { @@ -98,11 +101,23 @@ fields: fieldsOrDefault, title, description, - saveButtonLabel: saveLabel, - deleteButtonLabel: deleteLabel, schema, repeaterId, notificationOverride, + buttons: + buttons || + Utils.buildDynamicButtonConfig({ + _id: $component.id, + showDeleteButton, + showSaveButton, + saveButtonLabel, + deleteButtonLabel, + notificationOverride, + actionType, + actionUrl, + dataSource, + }), + buttonPosition, } const fetchSchema = async () => { schema = (await fetchDatasourceSchema(dataSource)) || {} diff --git a/packages/client/src/components/app/blocks/form/InnerFormBlock.svelte b/packages/client/src/components/app/blocks/form/InnerFormBlock.svelte index 52ef3ac80c..e74fd7d0f7 100644 --- a/packages/client/src/components/app/blocks/form/InnerFormBlock.svelte +++ b/packages/client/src/components/app/blocks/form/InnerFormBlock.svelte @@ -1,22 +1,18 @@ - - -
- -
- -
- -
-