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 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}