diff --git a/packages/builder/src/components/design/settings/componentSettings.js b/packages/builder/src/components/design/settings/componentSettings.js index 65a21f368d..39a82c20dd 100644 --- a/packages/builder/src/components/design/settings/componentSettings.js +++ b/packages/builder/src/components/design/settings/componentSettings.js @@ -21,6 +21,7 @@ import DrawerBindableCombobox from "components/common/bindings/DrawerBindableCom import ColumnEditor from "./controls/ColumnEditor/ColumnEditor.svelte" import BasicColumnEditor from "./controls/ColumnEditor/BasicColumnEditor.svelte" import BarButtonList from "./controls/BarButtonList.svelte" +import FieldConfiguration from "./controls/FieldConfiguration/FieldConfiguration.svelte" const componentMap = { text: DrawerBindableCombobox, @@ -43,6 +44,7 @@ const componentMap = { section: SectionSelect, filter: FilterEditor, url: URLSelect, + fieldConfiguration: FieldConfiguration, columns: ColumnEditor, "columns/basic": BasicColumnEditor, "field/sortable": SortableFieldSelect, diff --git a/packages/builder/src/components/design/settings/controls/FieldConfiguration.svelte b/packages/builder/src/components/design/settings/controls/FieldConfiguration.svelte new file mode 100644 index 0000000000..59340d4898 --- /dev/null +++ b/packages/builder/src/components/design/settings/controls/FieldConfiguration.svelte @@ -0,0 +1,91 @@ + + +Configure columns + + + Configure the columns in your {subject.toLowerCase()}. + + + + diff --git a/packages/builder/src/components/design/settings/controls/FieldConfiguration/CellEditor.svelte b/packages/builder/src/components/design/settings/controls/FieldConfiguration/CellEditor.svelte new file mode 100644 index 0000000000..e70decc035 --- /dev/null +++ b/packages/builder/src/components/design/settings/controls/FieldConfiguration/CellEditor.svelte @@ -0,0 +1,26 @@ + + + + + + "{column.name}" field validation + + + +
+ +
+
+
diff --git a/packages/builder/src/components/design/settings/controls/FieldConfiguration/ColumnDrawer.svelte b/packages/builder/src/components/design/settings/controls/FieldConfiguration/ColumnDrawer.svelte new file mode 100644 index 0000000000..316bf56da3 --- /dev/null +++ b/packages/builder/src/components/design/settings/controls/FieldConfiguration/ColumnDrawer.svelte @@ -0,0 +1,202 @@ + + + +
+ + {#if columns?.length} + +
+
+ + +
+
+
+
+ {#each columns as column (column.id)} +
+
(dragDisabled = false)} + > + +
+ + + removeColumn(column.id)} + disabled={columns.length === 1} + /> +
+ {/each} +
+ + {:else} +
+
+ Add columns to be included in your form below. +
+
+ {/if} +
+
+ + + {#if columns?.length} + + {/if} +
+
+ +
+ + + diff --git a/packages/builder/src/components/design/settings/controls/FieldConfiguration/FieldConfiguration.svelte b/packages/builder/src/components/design/settings/controls/FieldConfiguration/FieldConfiguration.svelte new file mode 100644 index 0000000000..f9127460e2 --- /dev/null +++ b/packages/builder/src/components/design/settings/controls/FieldConfiguration/FieldConfiguration.svelte @@ -0,0 +1,89 @@ + + +Configure fields + + + Configure the fields in your form. + + + + diff --git a/packages/builder/src/components/design/settings/controls/ValidationEditor/ValidationDrawer.svelte b/packages/builder/src/components/design/settings/controls/ValidationEditor/ValidationDrawer.svelte index 8d9ca7e0cd..0bff2ccce6 100644 --- a/packages/builder/src/components/design/settings/controls/ValidationEditor/ValidationDrawer.svelte +++ b/packages/builder/src/components/design/settings/controls/ValidationEditor/ValidationDrawer.svelte @@ -16,6 +16,7 @@ import DrawerBindableInput from "components/common/bindings/DrawerBindableInput.svelte" import { generate } from "shortid" + export let fieldName = null export let rules = [] export let bindings = [] export let type @@ -124,7 +125,7 @@ } $: dataSourceSchema = getDataSourceSchema($currentAsset, $selectedComponent) - $: field = $selectedComponent?.field + $: field = fieldName || $selectedComponent?.field $: schemaRules = parseRulesFromSchema(field, dataSourceSchema || {}) $: fieldType = type?.split("/")[1] || "string" $: constraintOptions = getConstraintsForType(fieldType) @@ -140,8 +141,12 @@ const formParent = findClosestMatchingComponent( asset.props, component._id, - component => component._component.endsWith("/form") + component => + component._component.endsWith("/form") || + component._component.endsWith("/formblock") || + component._component.endsWith("/tableblock") ) + return getSchemaForDatasource(asset, formParent?.dataSource) } diff --git a/packages/client/manifest.json b/packages/client/manifest.json index f27d090617..84ffca314c 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -4435,6 +4435,48 @@ "key": "row" } ] + }, + { + "label": "Fields", + "type": "fieldConfiguration", + "key": "sidePanelFields", + "nested": true, + "dependsOn": { + "setting": "clickBehaviour", + "value": "details" + } + }, + { + "label": "Show delete", + "type": "boolean", + "key": "sidePanelShowDelete", + "nested": true, + "dependsOn": { + "setting": "clickBehaviour", + "value": "details" + } + }, + { + "label": "Save label", + "type": "text", + "key": "sidePanelSaveLabel", + "defaultValue": "Save", + "nested": true, + "dependsOn": { + "setting": "clickBehaviour", + "value": "details" + } + }, + { + "label": "Delete label", + "type": "text", + "key": "sidePanelDeleteLabel", + "defaultValue": "Delete", + "nested": true, + "dependsOn": { + "setting": "clickBehaviour", + "value": "details" + } } ] }, @@ -4979,7 +5021,7 @@ "name": "Fields", "settings": [ { - "type": "multifield", + "type": "fieldConfiguration", "label": "Fields", "key": "fields", "selectAllFields": true @@ -5028,6 +5070,17 @@ "invert": true } }, + { + "type": "text", + "key": "saveButtonLabel", + "label": "Save button label", + "nested": true, + "defaultValue": "Save", + "dependsOn": { + "setting": "showSaveButton", + "value": true + } + }, { "type": "boolean", "label": "Allow delete", @@ -5038,6 +5091,17 @@ "value": "Update" } }, + { + "type": "text", + "key": "deleteButtonLabel", + "label": "Delete button label", + "nested": true, + "defaultValue": "Delete", + "dependsOn": { + "setting": "showDeleteButton", + "value": true + } + }, { "type": "url", "label": "Navigate after button press", diff --git a/packages/client/src/components/app/blocks/TableBlock.svelte b/packages/client/src/components/app/blocks/TableBlock.svelte index 26e44922dd..e45b53880d 100644 --- a/packages/client/src/components/app/blocks/TableBlock.svelte +++ b/packages/client/src/components/app/blocks/TableBlock.svelte @@ -26,6 +26,10 @@ export let titleButtonClickBehaviour export let onClickTitleButton export let noRowsMessage + export let sidePanelFields + export let sidePanelShowDelete + export let sidePanelSaveLabel + export let sidePanelDeleteLabel const { fetchDatasourceSchema, API } = getContext("sdk") const stateKey = `ID_${generate()}` @@ -241,10 +245,12 @@ props={{ dataSource, showSaveButton: true, - showDeleteButton: true, + showDeleteButton: sidePanelShowDelete, + saveButtonLabel: sidePanelSaveLabel, + deleteButtonLabel: sidePanelDeleteLabel, actionType: "Update", rowId: `{{ ${safe("state")}.${safe(stateKey)} }}`, - fields: normalFields, + fields: sidePanelFields || normalFields, title: editTitle, labelPosition: "left", }} @@ -266,8 +272,9 @@ dataSource, showSaveButton: true, showDeleteButton: false, + saveButtonLabel: sidePanelSaveLabel, actionType: "Create", - fields: normalFields, + fields: sidePanelFields || normalFields, title: "Create Row", labelPosition: "left", }} diff --git a/packages/client/src/components/app/blocks/form/FormBlock.svelte b/packages/client/src/components/app/blocks/form/FormBlock.svelte index a05a7e141c..6874c23cf4 100644 --- a/packages/client/src/components/app/blocks/form/FormBlock.svelte +++ b/packages/client/src/components/app/blocks/form/FormBlock.svelte @@ -12,6 +12,8 @@ export let fields export let labelPosition export let title + export let saveButtonLabel + export let deleteButtonLabel export let showSaveButton export let showDeleteButton export let rowId @@ -20,10 +22,40 @@ const { fetchDatasourceSchema } = getContext("sdk") + const convertOldFieldFormat = fields => { + if (typeof fields?.[0] === "string") { + return fields.map(field => ({ name: field, displayName: field })) + } + + return fields + } + + const getDefaultFields = (fields, schema) => { + 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, + }) + }) + + return defaultFields + } + + return fields + } + let schema let providerId let repeaterId + $: formattedFields = convertOldFieldFormat(fields) + $: fieldsOrDefault = getDefaultFields(formattedFields, schema) + $: fetchSchema(dataSource) $: dataProvider = `{{ literal ${safe(providerId)} }}` $: filter = [ @@ -46,9 +78,11 @@ actionType, size, disabled, - fields, + fields: fieldsOrDefault, labelPosition, title, + saveButtonLabel, + deleteButtonLabel, showSaveButton, showDeleteButton, schema, diff --git a/packages/client/src/components/app/blocks/form/InnerFormBlock.svelte b/packages/client/src/components/app/blocks/form/InnerFormBlock.svelte index da5345e6ad..b89ec4bcab 100644 --- a/packages/client/src/components/app/blocks/form/InnerFormBlock.svelte +++ b/packages/client/src/components/app/blocks/form/InnerFormBlock.svelte @@ -11,6 +11,8 @@ export let fields export let labelPosition export let title + export let saveButtonLabel + export let deleteButtonLabel export let showSaveButton export let showDeleteButton export let schema @@ -33,6 +35,12 @@ let formId $: onSave = [ + { + "##eventHandlerType": "Validate Form", + parameters: { + componentId: formId, + }, + }, { "##eventHandlerType": "Save Row", parameters: { @@ -163,7 +171,7 @@ {#each fields as field, idx} - {#if getComponentForField(field)} + {#if getComponentForField(field.name)}