From 1ec2faf74d3561d52727b2477952238de9096b9e Mon Sep 17 00:00:00 2001 From: Dean Date: Thu, 24 Aug 2023 14:39:53 +0100 Subject: [PATCH] List refinement, Form Block UX updates for action type. Bug fixes for FormBlock bindings. TableBlock UX updates and Component Setting updates --- packages/bbui/src/Popover/Popover.svelte | 14 ++ .../builder/src/builderStore/dataBinding.js | 86 ++++++- .../src/builderStore/store/frontend.js | 89 +++----- .../bindings/DrawerBindableInput.svelte | 2 + .../ButtonActionEditor.svelte | 2 +- ...ttingsList.svelte => DraggableList.svelte} | 106 +++++---- .../EditFieldPopover.svelte | 207 +++++++---------- .../FieldConfiguration.svelte | 209 ++++++++---------- .../FieldConfiguration/FieldSetting.svelte | 56 +++++ .../controls/FieldConfiguration/utils.js | 46 ++++ .../OptionsEditor/OptionsEditor.svelte | 15 +- .../settings/controls/PropertyControl.svelte | 2 + .../ValidationEditor/ValidationEditor.svelte | 7 +- .../settings/ComponentInfoSection.svelte | 38 +--- .../settings/ComponentSettingsPanel.svelte | 5 +- .../settings/ComponentSettingsSection.svelte | 62 +++--- .../_components/settings/InfoDisplay.svelte | 61 +++++ packages/client/manifest.json | 20 +- .../components/app/blocks/TableBlock.svelte | 9 +- .../app/blocks/form/FormBlock.svelte | 75 +++---- .../app/blocks/form/InnerFormBlock.svelte | 40 ++-- 21 files changed, 666 insertions(+), 485 deletions(-) rename packages/builder/src/components/design/settings/controls/{SettingsList.svelte => DraggableList.svelte} (55%) create mode 100644 packages/builder/src/components/design/settings/controls/FieldConfiguration/FieldSetting.svelte create mode 100644 packages/builder/src/components/design/settings/controls/FieldConfiguration/utils.js create mode 100644 packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/settings/InfoDisplay.svelte diff --git a/packages/bbui/src/Popover/Popover.svelte b/packages/bbui/src/Popover/Popover.svelte index 6706bf7a8b..198f96c672 100644 --- a/packages/bbui/src/Popover/Popover.svelte +++ b/packages/bbui/src/Popover/Popover.svelte @@ -23,6 +23,9 @@ export let animate = true export let customZindex + export let showPopover = true + export let clickOutsideOverride = false + $: target = portalTarget || getContext(Context.PopoverRoot) || ".spectrum" export const show = () => { @@ -36,6 +39,9 @@ } const handleOutsideClick = e => { + if (clickOutsideOverride) { + return + } if (open) { // Stop propagation if the source is the anchor let node = e.target @@ -54,6 +60,9 @@ } function handleEscape(e) { + if (!clickOutsideOverride) { + return + } if (open && e.key === "Escape") { hide() } @@ -79,6 +88,7 @@ on:keydown={handleEscape} class="spectrum-Popover is-open" class:customZindex + class:hide-popover={open && !showPopover} role="presentation" style="height: {customHeight}; --customZindex: {customZindex};" transition:fly|local={{ y: -20, duration: animate ? 200 : 0 }} @@ -89,6 +99,10 @@ {/if} diff --git a/packages/builder/src/components/design/settings/controls/FieldConfiguration/EditFieldPopover.svelte b/packages/builder/src/components/design/settings/controls/FieldConfiguration/EditFieldPopover.svelte index 859f019a26..94fd98c707 100644 --- a/packages/builder/src/components/design/settings/controls/FieldConfiguration/EditFieldPopover.svelte +++ b/packages/builder/src/components/design/settings/controls/FieldConfiguration/EditFieldPopover.svelte @@ -1,86 +1,58 @@ - @@ -93,69 +65,60 @@ }} /> - - - - - - + on:drawerShow={e => { + drawers = [...drawers, e.detail] + }} + on:drawerHide={e => { + drawers = drawers.slice(0, -1) + }} + /> + + + + diff --git a/packages/builder/src/components/design/settings/controls/FieldConfiguration/FieldConfiguration.svelte b/packages/builder/src/components/design/settings/controls/FieldConfiguration/FieldConfiguration.svelte index 922b994c5a..596bb95639 100644 --- a/packages/builder/src/components/design/settings/controls/FieldConfiguration/FieldConfiguration.svelte +++ b/packages/builder/src/components/design/settings/controls/FieldConfiguration/FieldConfiguration.svelte @@ -1,127 +1,76 @@
- + {#if fieldList?.length} + + {/if}
diff --git a/packages/builder/src/components/design/settings/controls/FieldConfiguration/utils.js b/packages/builder/src/components/design/settings/controls/FieldConfiguration/utils.js new file mode 100644 index 0000000000..d4a8963dba --- /dev/null +++ b/packages/builder/src/components/design/settings/controls/FieldConfiguration/utils.js @@ -0,0 +1,46 @@ +export const convertOldFieldFormat = fields => { + if (!fields) { + return [] + } + const converted = fields.map(field => { + if (typeof field === "string") { + // existed but was a string + return { + field, + active: true, + } + } else if (typeof field?.active != "boolean") { + // existed but had no state + return { + field: field.name, + active: true, + } + } else { + return field + } + }) + return converted +} + +export const getComponentForField = (field, schema) => { + if (!field || !schema?.[field]) { + return null + } + const type = schema[field].type + return FieldTypeToComponentMap[type] +} + +export const FieldTypeToComponentMap = { + string: "stringfield", + number: "numberfield", + bigint: "bigintfield", + options: "optionsfield", + array: "multifieldselect", + boolean: "booleanfield", + longform: "longformfield", + datetime: "datetimefield", + attachment: "attachmentfield", + link: "relationshipfield", + json: "jsonfield", + barcodeqr: "codescanner", +} diff --git a/packages/builder/src/components/design/settings/controls/OptionsEditor/OptionsEditor.svelte b/packages/builder/src/components/design/settings/controls/OptionsEditor/OptionsEditor.svelte index 1201edd31e..c626081042 100644 --- a/packages/builder/src/components/design/settings/controls/OptionsEditor/OptionsEditor.svelte +++ b/packages/builder/src/components/design/settings/controls/OptionsEditor/OptionsEditor.svelte @@ -24,11 +24,22 @@ } -Define Options - +
+
+
Define Options
+
+ Define the options for this picker. + + diff --git a/packages/builder/src/components/design/settings/controls/PropertyControl.svelte b/packages/builder/src/components/design/settings/controls/PropertyControl.svelte index 5125c3bade..c8135b4f61 100644 --- a/packages/builder/src/components/design/settings/controls/PropertyControl.svelte +++ b/packages/builder/src/components/design/settings/controls/PropertyControl.svelte @@ -100,6 +100,8 @@ {key} {type} {...props} + on:drawerHide + on:drawerShow />
{#if info} diff --git a/packages/builder/src/components/design/settings/controls/ValidationEditor/ValidationEditor.svelte b/packages/builder/src/components/design/settings/controls/ValidationEditor/ValidationEditor.svelte index 6db24e8d69..96953b56b8 100644 --- a/packages/builder/src/components/design/settings/controls/ValidationEditor/ValidationEditor.svelte +++ b/packages/builder/src/components/design/settings/controls/ValidationEditor/ValidationEditor.svelte @@ -5,9 +5,8 @@ export let value = [] export let bindings = [] - export let componentDefinition + export let componentInstance export let type - const dispatch = createEventDispatcher() let drawer @@ -31,7 +30,7 @@ {text} - + Configure validation rules for this field. @@ -41,7 +40,7 @@ bind:rules={value} {type} {bindings} - {componentDefinition} + fieldName={componentInstance?.field} /> diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/settings/ComponentInfoSection.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/settings/ComponentInfoSection.svelte index f0288f0059..e73e6d7841 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/settings/ComponentInfoSection.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/settings/ComponentInfoSection.svelte @@ -1,36 +1,12 @@ - -
-
- - {componentDefinition.name} -
- {componentDefinition.info} -
+ + - - diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/settings/ComponentSettingsPanel.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/settings/ComponentSettingsPanel.svelte index 2ff605cc77..581e69cfaf 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/settings/ComponentSettingsPanel.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/settings/ComponentSettingsPanel.svelte @@ -5,7 +5,7 @@ import DesignSection from "./DesignSection.svelte" import CustomStylesSection from "./CustomStylesSection.svelte" import ConditionalUISection from "./ConditionalUISection.svelte" - import ComponentInfoSection from "./ComponentInfoSection.svelte" + import { getBindableProperties, getComponentBindableProperties, @@ -55,9 +55,6 @@ {#if section == "settings"} - {#if componentDefinition?.info} - - {/if} { const settings = definition?.settings ?? [] - console.log( - "ComponentSettingsSection::definition?.settings", - definition?.settings - ) const generalSettings = settings.filter(setting => !setting.section) const customSections = settings.filter(setting => setting.section) let sections = [ @@ -51,23 +50,22 @@ } const updateSetting = async (setting, value) => { - if (typeof onUpdateSetting === "function") { - onUpdateSetting(setting, value) - } else { - try { + try { + if (typeof onUpdateSetting === "function") { + await onUpdateSetting(setting, value) + } else { await store.actions.components.updateSetting(setting.key, value) - - // Send event if required - if (setting.sendEvents) { - analytics.captureEvent(Events.COMPONENT_UPDATED, { - name: componentInstance._component, - setting: setting.key, - value, - }) - } - } catch (error) { - notifications.error("Error updating component prop") } + // Send event if required + if (setting.sendEvents) { + analytics.captureEvent(Events.COMPONENT_UPDATED, { + name: componentInstance._component, + setting: setting.key, + value, + }) + } + } catch (error) { + notifications.error("Error updating component prop") } } @@ -106,7 +104,7 @@ } } - return true + return typeof setting.visible == "boolean" ? setting.visible : true } const canRenderControl = (instance, setting, isScreen) => { @@ -125,9 +123,22 @@ {#each sections as section, idx (section.name)} {#if section.visible} - + + {#if section.info} + + {:else if idx === 0 && section.name === "General" && componentDefinition.info} + + {/if}
- {#if idx === 0 && !componentInstance._component.endsWith("/layout") && !isScreen} + {#if idx === 0 && !componentInstance._component.endsWith("/layout") && !isScreen && showInstanceName} {/if} {/each} diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/settings/InfoDisplay.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/settings/InfoDisplay.svelte new file mode 100644 index 0000000000..a48f5d92b8 --- /dev/null +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/settings/InfoDisplay.svelte @@ -0,0 +1,61 @@ + + +
+ {#if title} +
+ + {title || ""} +
+ {@html body} + {:else} + + + + {@html body} + {/if} +
+ + diff --git a/packages/client/manifest.json b/packages/client/manifest.json index a03b6be8af..d1f718aaf3 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -5282,6 +5282,11 @@ }, { "section": true, + "dependsOn": { + "setting": "actionType", + "value": "Create", + "invert": true + }, "name": "Row details", "info": "How to pass a row ID using bindings", "settings": [ @@ -5289,23 +5294,13 @@ "type": "text", "label": "Row ID", "key": "rowId", - "nested": true, - "dependsOn": { - "setting": "actionType", - "value": "Create", - "invert": true - } + "nested": true }, { "type": "text", "label": "Empty text", "key": "noRowsMessage", - "defaultValue": "We couldn't find a row to display", - "dependsOn": { - "setting": "actionType", - "value": "Create", - "invert": true - } + "defaultValue": "We couldn't find a row to display" } ] }, @@ -5399,6 +5394,7 @@ { "type": "fieldConfiguration", "key": "fields", + "nested": true, "selectAllFields": true }, { diff --git a/packages/client/src/components/app/blocks/TableBlock.svelte b/packages/client/src/components/app/blocks/TableBlock.svelte index efc83fd5ac..e07c26544c 100644 --- a/packages/client/src/components/app/blocks/TableBlock.svelte +++ b/packages/client/src/components/app/blocks/TableBlock.svelte @@ -45,6 +45,9 @@ let enrichedSearchColumns let schemaLoaded = false + // Accommodate old config to ensure delete button does not reappear + $: deleteLabel = sidePanelShowDelete === false ? "" : sidePanelDeleteLabel + $: fetchSchema(dataSource) $: enrichSearchColumns(searchColumns, schema).then( val => (enrichedSearchColumns = val) @@ -245,10 +248,8 @@ bind:id={detailsFormBlockId} props={{ dataSource, - showSaveButton: true, - showDeleteButton: sidePanelShowDelete, - saveButtonLabel: sidePanelSaveLabel, - deleteButtonLabel: sidePanelDeleteLabel, + saveButtonLabel: sidePanelSaveLabel || "Save", //always show + deleteButtonLabel: deleteLabel, //respect config actionType: "Update", rowId: `{{ ${safe("state")}.${safe(stateKey)} }}`, fields: sidePanelFields || normalFields, diff --git a/packages/client/src/components/app/blocks/form/FormBlock.svelte b/packages/client/src/components/app/blocks/form/FormBlock.svelte index c6a149e57c..5d57d10ab6 100644 --- a/packages/client/src/components/app/blocks/form/FormBlock.svelte +++ b/packages/client/src/components/app/blocks/form/FormBlock.svelte @@ -12,55 +12,59 @@ export let fields export let labelPosition export let title + export let showDeleteButton + export let showSaveButton export let saveButtonLabel export let deleteButtonLabel - export let showSaveButton - export let showDeleteButton 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() + const { fetchDatasourceSchema } = getContext("sdk") const convertOldFieldFormat = fields => { - return typeof fields?.[0] === "string" - ? fields.map(field => ({ + if (!fields) { + return [] + } + return fields.map(field => { + if (typeof field === "string") { + // existed but was a string + return { name: field, - displayName: field, active: true, - })) - : fields - } - - //All settings need to derive from the block config now - - // Parse the fields here too. Not present means false. - const getDefaultFields = (fields, schema) => { - let formFields - if (schema && (!fields || fields.length === 0)) { - const defaultFields = [] - - Object.values(schema).forEach(field => { - if (field.autocolumn) return - - defaultFields.push({ - name: field.name, - displayName: field.name, - active: true, - }) - }) - formFields = [...defaultFields] - } else { - formFields = (fields || []).map(field => { + } + } else { + // existed but had no state return { ...field, active: typeof field?.active != "boolean" ? true : field?.active, } - }) - } + } + }) + } - return formFields.filter(field => field.active) + const getDefaultFields = (fields, schema) => { + if (!schema) { + return [] + } + let defaultFields = [] + + if (!fields || fields.length === 0) { + Object.values(schema) + .filter(field => !field.autocolumn) + .forEach(field => { + defaultFields.push({ + name: field.name, + active: true, + }) + }) + } + return [...fields, ...defaultFields].filter(field => field.active) } let schema @@ -94,15 +98,12 @@ fields: fieldsOrDefault, labelPosition, title, - saveButtonLabel, - deleteButtonLabel, - showSaveButton, - showDeleteButton, + saveButtonLabel: saveLabel, + deleteButtonLabel: deleteLabel, schema, repeaterId, notificationOverride, } - 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 5415768dc9..1f69645280 100644 --- a/packages/client/src/components/app/blocks/form/InnerFormBlock.svelte +++ b/packages/client/src/components/app/blocks/form/InnerFormBlock.svelte @@ -13,8 +13,6 @@ export let title export let saveButtonLabel export let deleteButtonLabel - export let showSaveButton - export let showDeleteButton export let schema export let repeaterId export let notificationOverride @@ -100,18 +98,33 @@ }, ] - $: renderDeleteButton = showDeleteButton && actionType === "Update" - $: renderSaveButton = showSaveButton && actionType !== "View" + $: renderDeleteButton = deleteButtonLabel && actionType === "Update" + $: renderSaveButton = saveButtonLabel && actionType !== "View" $: renderButtons = renderDeleteButton || renderSaveButton $: renderHeader = renderButtons || title const getComponentForField = field => { - if (!field || !schema?.[field]) { + const fieldSchemaName = field.field || field.name + if (!fieldSchemaName || !schema?.[fieldSchemaName]) { return null } - const type = schema[field].type + const type = schema[fieldSchemaName].type return FieldTypeToComponentMap[type] } + + const getPropsForField = field => { + let fieldProps = field._component + ? { + ...field, + } + : { + field: field.name, + label: field.name, + placeholder: field.name, + _instanceName: field.name, + } + return fieldProps + } {#if fields?.length} @@ -175,7 +188,7 @@ {#each fields as field, idx} - {#if getComponentForField(field.name)} + {#if getComponentForField(field) && field.active} {/if}