diff --git a/packages/builder/src/components/design/PropertiesPanel/ComponentSettingsSection.svelte b/packages/builder/src/components/design/PropertiesPanel/ComponentSettingsSection.svelte index 35a4a9db19..c8e23cc535 100644 --- a/packages/builder/src/components/design/PropertiesPanel/ComponentSettingsSection.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/ComponentSettingsSection.svelte @@ -32,9 +32,29 @@ if (!control) { return false } - if (setting.dependsOn && isEmpty(componentInstance[setting.dependsOn])) { - return false + + // Parse dependant settings + if (setting.dependsOn) { + let dependantSetting = setting.dependsOn + let dependantValue = null + if (typeof setting.dependsOn === "object") { + dependantSetting = setting.dependsOn.setting + dependantValue = setting.dependsOn.value + } + if (!dependantSetting) { + return false + } + + // If no specific value is depended upon, check if a value exists at all + // for the dependent setting + if (dependantValue == null) { + return !isEmpty(componentInstance[dependantSetting]) + } + + // Otherwise check the value matches + return componentInstance[dependantSetting] === dependantValue } + return true } diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/OptionsEditor/OptionsDrawer.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/OptionsEditor/OptionsDrawer.svelte new file mode 100644 index 0000000000..340c1eb107 --- /dev/null +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/OptionsEditor/OptionsDrawer.svelte @@ -0,0 +1,82 @@ + + + +
+ + {#if !options.length} + Add an option to get started. + {/if} + {#if options?.length} +
+ {#each options as option (option.id)} + + + removeOption(option.id)} + /> + {/each} +
+ {/if} +
+ +
+
+
+
+ + diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/OptionsEditor/OptionsEditor.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/OptionsEditor/OptionsEditor.svelte new file mode 100644 index 0000000000..4d74ea9940 --- /dev/null +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/OptionsEditor/OptionsEditor.svelte @@ -0,0 +1,28 @@ + + +Define Options + + + Define the options for this picker. + + + + diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/componentSettings.js b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/componentSettings.js index 6cf2d7e056..64668d05c8 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/componentSettings.js +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/componentSettings.js @@ -12,6 +12,7 @@ import SectionSelect from "./SectionSelect.svelte" import NavigationEditor from "./NavigationEditor/NavigationEditor.svelte" import FilterEditor from "./FilterEditor/FilterEditor.svelte" import URLSelect from "./URLSelect.svelte" +import OptionsEditor from "./OptionsEditor/OptionsEditor.svelte" import FormFieldSelect from "./FormFieldSelect.svelte" import ValidationEditor from "./ValidationEditor/ValidationEditor.svelte" @@ -28,6 +29,7 @@ const componentMap = { icon: IconSelect, field: FieldSelect, multifield: MultiFieldSelect, + options: OptionsEditor, schema: SchemaSelect, section: SectionSelect, navigation: NavigationEditor, diff --git a/packages/standard-components/manifest.json b/packages/standard-components/manifest.json index 1b7a09cdef..17d95321c9 100644 --- a/packages/standard-components/manifest.json +++ b/packages/standard-components/manifest.json @@ -1908,6 +1908,7 @@ "type": "select", "label": "Type", "key": "optionsType", + "defaultValue": "select", "placeholder": "Pick an options type", "options": [ { @@ -1931,6 +1932,62 @@ "key": "disabled", "defaultValue": false }, + { + "type": "select", + "label": "Options source", + "key": "optionsSource", + "defaultValue": "schema", + "placeholder": "Pick an options source", + "options": [ + { + "label": "Schema", + "value": "schema" + }, + { + "label": "Data provider", + "value": "provider" + }, + { + "label": "Custom", + "value": "custom" + } + ] + }, + { + "type": "dataProvider", + "label": "Options Provider", + "key": "dataProvider", + "dependsOn": { + "setting": "optionsSource", + "value": "provider" + } + }, + { + "type": "field", + "label": "Label Column", + "key": "labelColumn", + "dependsOn": { + "setting": "optionsSource", + "value": "provider" + } + }, + { + "type": "field", + "label": "Value Column", + "key": "valueColumn", + "dependsOn": { + "setting": "optionsSource", + "value": "provider" + } + }, + { + "type": "options", + "key": "customOptions", + "dependsOn": { + "setting": "optionsSource", + "value": "custom" + } + }, { "type": "validation/string", "label": "Validation", diff --git a/packages/standard-components/src/forms/OptionsField.svelte b/packages/standard-components/src/forms/OptionsField.svelte index 04bb582190..29ec7c2328 100644 --- a/packages/standard-components/src/forms/OptionsField.svelte +++ b/packages/standard-components/src/forms/OptionsField.svelte @@ -9,10 +9,57 @@ export let optionsType = "select" export let validation export let defaultValue + export let optionsSource = "schema" + export let dataProvider + export let labelColumn + export let valueColumn + export let customOptions let fieldState let fieldApi let fieldSchema + + $: flatOptions = optionsSource == null || optionsSource === "schema" + $: options = getOptions( + optionsSource, + fieldSchema, + dataProvider, + labelColumn, + valueColumn + ) + + const getOptions = ( + optionsSource, + fieldSchema, + dataProvider, + labelColumn, + valueColumn + ) => { + // Take options from schema + if (optionsSource == null || optionsSource === "schema") { + return fieldSchema?.constraints?.inclusion ?? [] + } + + // Extract options from data provider + if (optionsSource === "provider" && valueColumn) { + let optionsSet = {} + dataProvider?.rows?.forEach(row => { + const value = row?.[valueColumn] + if (value) { + const label = row[labelColumn] || value + optionsSet[value] = { value, label } + } + }) + return Object.values(optionsSet) + } + + // Extract custom options + if (optionsSource === "custom" && customOptions) { + return customOptions + } + + return [] + } fieldApi.setValue(e.detail)} + getOptionLabel={flatOptions ? x => x : x => x.label} + getOptionValue={flatOptions ? x => x : x => x.value} /> {:else if optionsType === "radio"}