From ce73963ac18d75b477a3ab280402eb2c8a7b216e Mon Sep 17 00:00:00 2001 From: Dean Date: Thu, 23 Nov 2023 09:12:11 +0000 Subject: [PATCH 1/6] 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 2/6] 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 @@