From 5d1374bfa2ecc642d0f3fff5fc20b574a70efd10 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 18 Aug 2021 11:32:39 +0100 Subject: [PATCH 01/36] Add stepper component to bbui for numeric values --- packages/bbui/package.json | 1 + packages/bbui/src/Form/Core/Stepper.svelte | 172 ++++++++++++++++++ packages/bbui/src/Form/Core/index.js | 1 + packages/bbui/src/Form/Stepper.svelte | 45 +++++ packages/bbui/src/index.js | 1 + packages/bbui/yarn.lock | 5 + .../PropertyControls/componentSettings.js | 4 +- packages/standard-components/manifest.json | 6 + 8 files changed, 233 insertions(+), 2 deletions(-) create mode 100644 packages/bbui/src/Form/Core/Stepper.svelte create mode 100644 packages/bbui/src/Form/Stepper.svelte diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 368c80d85f..ee7a56ecde 100644 --- a/packages/bbui/package.json +++ b/packages/bbui/package.json @@ -65,6 +65,7 @@ "@spectrum-css/search": "^3.0.2", "@spectrum-css/sidenav": "^3.0.2", "@spectrum-css/statuslight": "^3.0.2", + "@spectrum-css/stepper": "^3.0.3", "@spectrum-css/switch": "^1.0.2", "@spectrum-css/table": "^3.0.1", "@spectrum-css/tabs": "^3.0.1", diff --git a/packages/bbui/src/Form/Core/Stepper.svelte b/packages/bbui/src/Form/Core/Stepper.svelte new file mode 100644 index 0000000000..895dc2d3de --- /dev/null +++ b/packages/bbui/src/Form/Core/Stepper.svelte @@ -0,0 +1,172 @@ + + +
+ {#if error} + + {/if} + +
+ +
+ + + + +
+ + diff --git a/packages/bbui/src/Form/Core/index.js b/packages/bbui/src/Form/Core/index.js index a31c5941ec..440c4a1b15 100644 --- a/packages/bbui/src/Form/Core/index.js +++ b/packages/bbui/src/Form/Core/index.js @@ -9,3 +9,4 @@ export { default as CoreSwitch } from "./Switch.svelte" export { default as CoreSearch } from "./Search.svelte" export { default as CoreDatePicker } from "./DatePicker.svelte" export { default as CoreDropzone } from "./Dropzone.svelte" +export { default as CoreStepper } from "./Stepper.svelte" diff --git a/packages/bbui/src/Form/Stepper.svelte b/packages/bbui/src/Form/Stepper.svelte new file mode 100644 index 0000000000..9eff2e368e --- /dev/null +++ b/packages/bbui/src/Form/Stepper.svelte @@ -0,0 +1,45 @@ + + + + + diff --git a/packages/bbui/src/index.js b/packages/bbui/src/index.js index 3a491bfb54..08ece6b93c 100644 --- a/packages/bbui/src/index.js +++ b/packages/bbui/src/index.js @@ -5,6 +5,7 @@ import "@spectrum-css/icon/dist/index-vars.css" // Components export { default as Input } from "./Form/Input.svelte" +export { default as Stepper } from "./Form/Stepper.svelte" export { default as TextArea } from "./Form/TextArea.svelte" export { default as Select } from "./Form/Select.svelte" export { default as Combobox } from "./Form/Combobox.svelte" diff --git a/packages/bbui/yarn.lock b/packages/bbui/yarn.lock index 6deff28fad..a3b20aa862 100644 --- a/packages/bbui/yarn.lock +++ b/packages/bbui/yarn.lock @@ -206,6 +206,11 @@ resolved "https://registry.yarnpkg.com/@spectrum-css/statuslight/-/statuslight-3.0.2.tgz#dc54b6cd113413dcdb909c486b5d7bae60db65c5" integrity sha512-xodB8g8vGJH20XmUj9ZsPlM1jHrGeRbvmVXkz0q7YvQrYAhim8pP3W+XKKZAletPFAuu8cmUOc6SWn6i4X4z6w== +"@spectrum-css/stepper@^3.0.3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@spectrum-css/stepper/-/stepper-3.0.3.tgz#ae89846886431e3edeee060207b8f81540f73a34" + integrity sha512-prAD61ImlOTs9b6PfB3cB08x4lAfxtvnW+RZiTYky0E8GgZdrc/MfCkL5/oqQaIQUtyQv/3Lb7ELAf/0K8QTXw== + "@spectrum-css/switch@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@spectrum-css/switch/-/switch-1.0.2.tgz#f0b4c69271964573e02b08e90998096e49e1de44" diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/componentSettings.js b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/componentSettings.js index 64668d05c8..213ffbbc92 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/componentSettings.js +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/componentSettings.js @@ -1,4 +1,4 @@ -import { Checkbox, Input, Select } from "@budibase/bbui" +import { Checkbox, Input, Select, Stepper } from "@budibase/bbui" import DataSourceSelect from "./DataSourceSelect.svelte" import DataProviderSelect from "./DataProviderSelect.svelte" import EventsEditor from "./EventsEditor" @@ -22,7 +22,7 @@ const componentMap = { dataSource: DataSourceSelect, dataProvider: DataProviderSelect, boolean: Checkbox, - number: Input, + number: Stepper, event: EventsEditor, table: TableSelect, color: ColorPicker, diff --git a/packages/standard-components/manifest.json b/packages/standard-components/manifest.json index 95f41a85ef..b8c7bdc41d 100644 --- a/packages/standard-components/manifest.json +++ b/packages/standard-components/manifest.json @@ -1725,6 +1725,12 @@ "label": "Custom" } }, + { + "type": "number", + "label": "Number of steps", + "key": "steps", + "defaultValue": 1 + }, { "type": "boolean", "label": "Disabled", From c1597f848179c181d7fd799a13f272447541736c Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 18 Aug 2021 14:58:35 +0100 Subject: [PATCH 02/36] Add initial form step component --- packages/standard-components/src/forms/FormStep.svelte | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/standard-components/src/forms/FormStep.svelte diff --git a/packages/standard-components/src/forms/FormStep.svelte b/packages/standard-components/src/forms/FormStep.svelte new file mode 100644 index 0000000000..e69de29bb2 From c44d0a684be1050ff2d2f0acbf80b75c8359ef9e Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 18 Aug 2021 14:58:58 +0100 Subject: [PATCH 03/36] Support multiple component context exports and export additional context from forms --- .../builder/src/builderStore/dataBinding.js | 122 ++++++++++-------- .../design/AppPreview/componentStructure.json | 1 + .../ComponentSettingsSection.svelte | 2 + packages/client/src/constants.js | 2 + packages/standard-components/manifest.json | 51 +++++++- .../src/forms/FormStep.svelte | 18 +++ .../src/forms/InnerForm.svelte | 28 +++- .../standard-components/src/forms/index.js | 1 + 8 files changed, 163 insertions(+), 62 deletions(-) diff --git a/packages/builder/src/builderStore/dataBinding.js b/packages/builder/src/builderStore/dataBinding.js index dc995d611c..00eaaf0249 100644 --- a/packages/builder/src/builderStore/dataBinding.js +++ b/packages/builder/src/builderStore/dataBinding.js @@ -120,71 +120,79 @@ const getContextBindings = (asset, componentId) => { // Create bindings for each data provider dataProviders.forEach(component => { const def = store.actions.components.getDefinition(component._component) - const contextDefinition = def.context - let schema - let readablePrefix + const contexts = Array.isArray(def.context) ? def.context : [def.context] - if (contextDefinition.type === "form") { - // Forms do not need table schemas - // Their schemas are built from their component field names - schema = buildFormSchema(component) - readablePrefix = "Fields" - } else if (contextDefinition.type === "static") { - // Static contexts are fully defined by the components - schema = {} - const values = contextDefinition.values || [] - values.forEach(value => { - schema[value.key] = { name: value.label, type: "string" } - }) - } else if (contextDefinition.type === "schema") { - // Schema contexts are generated dynamically depending on their data - const datasource = getDatasourceForProvider(asset, component) - if (!datasource) { + // Create bindings for each context block provided by this data provider + contexts.forEach(context => { + if (!context?.type) { return } - const info = getSchemaForDatasource(asset, datasource) - schema = info.schema - readablePrefix = info.table?.name - } - if (!schema) { - return - } - const keys = Object.keys(schema).sort() + let schema + let readablePrefix - // Create bindable properties for each schema field - const safeComponentId = makePropSafe(component._id) - keys.forEach(key => { - const fieldSchema = schema[key] - - // Make safe runtime binding and replace certain bindings with a - // new property to help display components - let runtimeBoundKey = key - if (fieldSchema.type === "link") { - runtimeBoundKey = `${key}_text` - } else if (fieldSchema.type === "attachment") { - runtimeBoundKey = `${key}_first` + if (context.type === "form") { + // Forms do not need table schemas + // Their schemas are built from their component field names + schema = buildFormSchema(component) + readablePrefix = "Fields" + } else if (context.type === "static") { + // Static contexts are fully defined by the components + schema = {} + const values = context.values || [] + values.forEach(value => { + schema[value.key] = { name: value.label, type: "string" } + }) + } else if (context.type === "schema") { + // Schema contexts are generated dynamically depending on their data + const datasource = getDatasourceForProvider(asset, component) + if (!datasource) { + return + } + const info = getSchemaForDatasource(asset, datasource) + schema = info.schema + readablePrefix = info.table?.name } - const runtimeBinding = `${safeComponentId}.${makePropSafe( - runtimeBoundKey - )}` - - // Optionally use a prefix with readable bindings - let readableBinding = component._instanceName - if (readablePrefix) { - readableBinding += `.${readablePrefix}` + if (!schema) { + return } - readableBinding += `.${fieldSchema.name || key}` - // Create the binding object - bindings.push({ - type: "context", - runtimeBinding, - readableBinding, - // Field schema and provider are required to construct relationship - // datasource options, based on bindable properties - fieldSchema, - providerId: component._id, + const keys = Object.keys(schema).sort() + + // Create bindable properties for each schema field + const safeComponentId = makePropSafe(component._id) + keys.forEach(key => { + const fieldSchema = schema[key] + + // Make safe runtime binding and replace certain bindings with a + // new property to help display components + let runtimeBoundKey = key + if (fieldSchema.type === "link") { + runtimeBoundKey = `${key}_text` + } else if (fieldSchema.type === "attachment") { + runtimeBoundKey = `${key}_first` + } + const runtimeBinding = `${safeComponentId}.${makePropSafe( + runtimeBoundKey + )}` + + // Optionally use a prefix with readable bindings + let readableBinding = component._instanceName + if (readablePrefix) { + readableBinding += `.${readablePrefix}` + } + readableBinding += `.${fieldSchema.name || key}` + + // Create the binding object + bindings.push({ + type: "context", + runtimeBinding, + readableBinding, + // Field schema and provider are required to construct relationship + // datasource options, based on bindable properties + fieldSchema, + providerId: component._id, + }) }) }) }) diff --git a/packages/builder/src/components/design/AppPreview/componentStructure.json b/packages/builder/src/components/design/AppPreview/componentStructure.json index c83686158f..cea20a7dcf 100644 --- a/packages/builder/src/components/design/AppPreview/componentStructure.json +++ b/packages/builder/src/components/design/AppPreview/componentStructure.json @@ -10,6 +10,7 @@ "icon": "Form", "children": [ "form", + "formstep", "fieldgroup", "stringfield", "numberfield", diff --git a/packages/builder/src/components/design/PropertiesPanel/ComponentSettingsSection.svelte b/packages/builder/src/components/design/PropertiesPanel/ComponentSettingsSection.svelte index 9ec1108985..f047e9316b 100644 --- a/packages/builder/src/components/design/PropertiesPanel/ComponentSettingsSection.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/ComponentSettingsSection.svelte @@ -85,6 +85,8 @@ props={{ options: setting.options || [], placeholder: setting.placeholder || null, + min: setting.min || null, + max: setting.max || null, }} {bindings} {componentDefinition} diff --git a/packages/client/src/constants.js b/packages/client/src/constants.js index 7204b8c951..99e95e8398 100644 --- a/packages/client/src/constants.js +++ b/packages/client/src/constants.js @@ -7,6 +7,8 @@ export const ActionTypes = { RefreshDatasource: "RefreshDatasource", SetDataProviderQuery: "SetDataProviderQuery", ClearForm: "ClearForm", + NextFormStep: "NextFormStep", + PrevFormStep: "PrevFormStep", } export const ApiVersion = "1" diff --git a/packages/standard-components/manifest.json b/packages/standard-components/manifest.json index b8c7bdc41d..d5d22aba3a 100644 --- a/packages/standard-components/manifest.json +++ b/packages/standard-components/manifest.json @@ -1705,7 +1705,9 @@ "illegalChildren": ["section"], "actions": [ "ValidateForm", - "ClearForm" + "ClearForm", + "NextFormStep", + "PrevFormStep" ], "styles": ["size"], "settings": [ @@ -1727,7 +1729,7 @@ }, { "type": "number", - "label": "Number of steps", + "label": "Steps", "key": "steps", "defaultValue": 1 }, @@ -1738,8 +1740,51 @@ "defaultValue": false } ], + "context": [ + { + "type": "static", + "values": [ + { + "label": "Valid", + "key": "valid" + }, + { + "label": "Step", + "key": "step" + } + ] + }, + { + "type": "form" + } + ] + }, + "formstep": { + "name": "Form Step", + "icon": "Form", + "hasChildren": true, + "illegalChildren": ["section"], + "actions": [ + "ValidateFormStep" + ], + "styles": ["size"], + "settings": [ + { + "type": "number", + "label": "Step", + "key": "step", + "defaultValue": 1, + "min": 1 + } + ], "context": { - "type": "form" + "type": "static", + "values": [ + { + "label": "Valid", + "key": "valid" + } + ] } }, "fieldgroup": { diff --git a/packages/standard-components/src/forms/FormStep.svelte b/packages/standard-components/src/forms/FormStep.svelte index e69de29bb2..449978ec08 100644 --- a/packages/standard-components/src/forms/FormStep.svelte +++ b/packages/standard-components/src/forms/FormStep.svelte @@ -0,0 +1,18 @@ + + +{#if !formContext} + +{:else} +
+ +
+{/if} diff --git a/packages/standard-components/src/forms/InnerForm.svelte b/packages/standard-components/src/forms/InnerForm.svelte index eea2e6ebf0..9355c67660 100644 --- a/packages/standard-components/src/forms/InnerForm.svelte +++ b/packages/standard-components/src/forms/InnerForm.svelte @@ -17,7 +17,12 @@ let fieldMap = {} // Form state contains observable data about the form - const formState = writable({ values: initialValues, errors: {}, valid: true }) + const formState = writable({ + values: initialValues, + errors: {}, + valid: true, + step: 1, + }) // Form API contains functions to control the form const formApi = { @@ -82,6 +87,18 @@ fieldApi.clearValue() }) }, + nextStep: () => { + formState.update(state => ({ + ...state, + step: state.step + 1, + })) + }, + prevStep: () => { + formState.update(state => ({ + ...state, + step: Math.max(1, state.step - 1), + })) + }, } // Provide both form API and state to children @@ -91,6 +108,8 @@ const actions = [ { type: ActionTypes.ValidateForm, callback: formApi.validate }, { type: ActionTypes.ClearForm, callback: formApi.clear }, + { type: ActionTypes.NextFormStep, callback: formApi.nextStep }, + { type: ActionTypes.PrevFormStep, callback: formApi.prevStep }, ] // Creates an API for a specific field @@ -229,7 +248,12 @@
{#if loaded} diff --git a/packages/standard-components/src/forms/index.js b/packages/standard-components/src/forms/index.js index fed371278b..4f3eaa5adb 100644 --- a/packages/standard-components/src/forms/index.js +++ b/packages/standard-components/src/forms/index.js @@ -9,3 +9,4 @@ export { default as datetimefield } from "./DateTimeField.svelte" export { default as attachmentfield } from "./AttachmentField.svelte" export { default as relationshipfield } from "./RelationshipField.svelte" export { default as passwordfield } from "./PasswordField.svelte" +export { default as formstep } from "./FormStep.svelte" From 01b28f358a9888ca1fd5683bc0223c85941532cc Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 18 Aug 2021 15:21:18 +0100 Subject: [PATCH 04/36] Add button actions for navigating form steps --- .../EventsEditor/actions/NextFormStep.svelte | 35 +++++++++++++++++++ .../EventsEditor/actions/PrevFormStep.svelte | 35 +++++++++++++++++++ .../EventsEditor/actions/index.js | 10 ++++++ packages/client/src/utils/buttonActions.js | 18 ++++++++++ .../src/forms/FormStep.svelte | 9 ++++- 5 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/NextFormStep.svelte create mode 100644 packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/PrevFormStep.svelte diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/NextFormStep.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/NextFormStep.svelte new file mode 100644 index 0000000000..a635e158cb --- /dev/null +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/NextFormStep.svelte @@ -0,0 +1,35 @@ + + +
+ + x._instanceName} + getOptionValue={x => x._id} + /> +
+ + diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/index.js b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/index.js index c769a2300f..75feb533a7 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/index.js +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/index.js @@ -7,6 +7,8 @@ import ValidateForm from "./ValidateForm.svelte" import LogOut from "./LogOut.svelte" import ClearForm from "./ClearForm.svelte" import CloseScreenModal from "./CloseScreenModal.svelte" +import NextFormStep from "./NextFormStep.svelte" +import PrevFormStep from "./PrevFormStep.svelte" // Defines which actions are available to configure in the front end. // Unfortunately the "name" property is used as the identifier so please don't @@ -52,4 +54,12 @@ export default [ name: "Close Screen Modal", component: CloseScreenModal, }, + { + name: "Next Form Step", + component: NextFormStep, + }, + { + name: "Previous Form Step", + component: PrevFormStep, + }, ] diff --git a/packages/client/src/utils/buttonActions.js b/packages/client/src/utils/buttonActions.js index 408b35a705..dc190bad2f 100644 --- a/packages/client/src/utils/buttonActions.js +++ b/packages/client/src/utils/buttonActions.js @@ -99,6 +99,22 @@ const clearFormHandler = async (action, context) => { ) } +const nextFormStepHandler = async (action, context) => { + return await executeActionHandler( + context, + action.parameters.componentId, + ActionTypes.NextFormStep + ) +} + +const prevFormStepHandler = async (action, context) => { + return await executeActionHandler( + context, + action.parameters.componentId, + ActionTypes.PrevFormStep + ) +} + const closeScreenModalHandler = () => { // Emit this as a window event, so parent screens which are iframing us in // can close the modal @@ -116,6 +132,8 @@ const handlerMap = { ["Log Out"]: logoutHandler, ["Clear Form"]: clearFormHandler, ["Close Screen Modal"]: closeScreenModalHandler, + ["Next Form Step"]: nextFormStepHandler, + ["Previous Form Step"]: prevFormStepHandler, } const confirmTextMap = { diff --git a/packages/standard-components/src/forms/FormStep.svelte b/packages/standard-components/src/forms/FormStep.svelte index 449978ec08..45db9d1f52 100644 --- a/packages/standard-components/src/forms/FormStep.svelte +++ b/packages/standard-components/src/forms/FormStep.svelte @@ -7,12 +7,19 @@ const { styleable } = getContext("sdk") const component = getContext("component") const formContext = getContext("form") + + $: formState = formContext?.formState {#if !formContext} -{:else} +{:else if step === $formState.step}
+
+ Step {step} is visible! +
+{:else} +
hiding step {step}!
{/if} From 9e24a76810dfb2ea0683d414b01eed14e6bd8fd0 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 19 Aug 2021 12:52:13 +0100 Subject: [PATCH 05/36] Ensure client preview indicator doesn't crash when encountering incorrect node types --- packages/client/src/components/preview/IndicatorSet.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/components/preview/IndicatorSet.svelte b/packages/client/src/components/preview/IndicatorSet.svelte index 74c9f06f0d..3151a8bd75 100644 --- a/packages/client/src/components/preview/IndicatorSet.svelte +++ b/packages/client/src/components/preview/IndicatorSet.svelte @@ -61,7 +61,7 @@ // Sanity limit of 100 active indicators const children = Array.from(parents) .map(parent => parent?.childNodes?.[0]) - .filter(child => child != null) + .filter(node => node?.nodeType === 1) .slice(0, 100) // If there aren't any nodes then reset From 3fa5b3b57174cccdd6ad9d07b4ed896eb3bb605d Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 19 Aug 2021 12:52:50 +0100 Subject: [PATCH 06/36] Update validate form action to be able to only validate the current form step --- .../EventsEditor/actions/ValidateForm.svelte | 7 ++++++- packages/client/src/utils/buttonActions.js | 12 +++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/ValidateForm.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/ValidateForm.svelte index 462597f265..d61c9567d8 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/ValidateForm.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/ValidateForm.svelte @@ -1,5 +1,5 @@
diff --git a/packages/standard-components/src/forms/FieldGroupFallback.svelte b/packages/standard-components/src/forms/FieldGroupFallback.svelte index 782552a54e..fd0346a9ef 100644 --- a/packages/standard-components/src/forms/FieldGroupFallback.svelte +++ b/packages/standard-components/src/forms/FieldGroupFallback.svelte @@ -1,7 +1,7 @@ {#if fieldGroupContext} diff --git a/packages/standard-components/src/forms/Form.svelte b/packages/standard-components/src/forms/Form.svelte index 2514232ebc..a065432030 100644 --- a/packages/standard-components/src/forms/Form.svelte +++ b/packages/standard-components/src/forms/Form.svelte @@ -1,5 +1,5 @@ -{#key resetKey} - - - -{/key} +{#if loaded} + {#key resetKey} + + + + {/key} +{/if} diff --git a/packages/standard-components/src/forms/FormStep.svelte b/packages/standard-components/src/forms/FormStep.svelte index 45db9d1f52..e048a600f5 100644 --- a/packages/standard-components/src/forms/FormStep.svelte +++ b/packages/standard-components/src/forms/FormStep.svelte @@ -1,5 +1,5 @@ {#if !formContext} -{:else if step === $formState.step} +{:else if step === currentStep}
-
- Step {step} is visible! -
-{:else} -
hiding step {step}!
{/if} diff --git a/packages/standard-components/src/forms/InnerForm.svelte b/packages/standard-components/src/forms/InnerForm.svelte index 9355c67660..32cae9f8bc 100644 --- a/packages/standard-components/src/forms/InnerForm.svelte +++ b/packages/standard-components/src/forms/InnerForm.svelte @@ -1,41 +1,84 @@
- {#if loaded} - - {/if} +
diff --git a/packages/standard-components/src/forms/LongFormField.svelte b/packages/standard-components/src/forms/LongFormField.svelte index f710904254..81ad42bbcb 100644 --- a/packages/standard-components/src/forms/LongFormField.svelte +++ b/packages/standard-components/src/forms/LongFormField.svelte @@ -25,11 +25,11 @@ > {#if fieldState} fieldApi.setValue(e.detail)} - disabled={$fieldState.disabled} - error={$fieldState.error} - id={$fieldState.fieldId} + disabled={fieldState.disabled} + error={fieldState.error} + id={fieldState.fieldId} {placeholder} /> {/if} diff --git a/packages/standard-components/src/forms/OptionsField.svelte b/packages/standard-components/src/forms/OptionsField.svelte index b43ddb9f36..9f3e4a4557 100644 --- a/packages/standard-components/src/forms/OptionsField.svelte +++ b/packages/standard-components/src/forms/OptionsField.svelte @@ -77,10 +77,10 @@ {#if fieldState} {#if !optionsType || optionsType === "select"} fieldApi.setValue(e.detail)} @@ -90,10 +90,10 @@ /> {:else if optionsType === "radio"} fieldApi.setValue(e.detail)} getOptionLabel={flatOptions ? x => x : x => x.label} diff --git a/packages/standard-components/src/forms/RelationshipField.svelte b/packages/standard-components/src/forms/RelationshipField.svelte index b8600513ad..43f4e64aef 100644 --- a/packages/standard-components/src/forms/RelationshipField.svelte +++ b/packages/standard-components/src/forms/RelationshipField.svelte @@ -23,8 +23,8 @@ $: linkedTableId = fieldSchema?.tableId $: fetchRows(linkedTableId) $: fetchTable(linkedTableId) - $: singleValue = flatten($fieldState?.value)?.[0] - $: multiValue = flatten($fieldState?.value) ?? [] + $: singleValue = flatten(fieldState?.value)?.[0] + $: multiValue = flatten(fieldState?.value) ?? [] $: component = multiselect ? CoreMultiselect : CoreSelect const fetchTable = async id => { @@ -81,9 +81,9 @@ {autocomplete} value={multiselect ? multiValue : singleValue} on:change={multiselect ? multiHandler : singleHandler} - id={$fieldState.fieldId} - disabled={$fieldState.disabled} - error={$fieldState.error} + id={fieldState.fieldId} + disabled={fieldState.disabled} + error={fieldState.error} getOptionLabel={getDisplayName} getOptionValue={option => option._id} {placeholder} diff --git a/packages/standard-components/src/forms/StringField.svelte b/packages/standard-components/src/forms/StringField.svelte index f04177ec05..7bc4104cc5 100644 --- a/packages/standard-components/src/forms/StringField.svelte +++ b/packages/standard-components/src/forms/StringField.svelte @@ -26,12 +26,12 @@ > {#if fieldState} fieldApi.setValue(e.detail)} - disabled={$fieldState.disabled} - error={$fieldState.error} - id={$fieldState.fieldId} + disabled={fieldState.disabled} + error={fieldState.error} + id={fieldState.fieldId} {placeholder} {type} /> From 4f114e42db890970b4b8c6c9726ecd8bdfdbf5cc Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 19 Aug 2021 13:41:18 +0100 Subject: [PATCH 08/36] Clear form field error when re-registering the same field --- packages/standard-components/src/forms/InnerForm.svelte | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/standard-components/src/forms/InnerForm.svelte b/packages/standard-components/src/forms/InnerForm.svelte index 32cae9f8bc..ec5c066699 100644 --- a/packages/standard-components/src/forms/InnerForm.svelte +++ b/packages/standard-components/src/forms/InnerForm.svelte @@ -73,9 +73,14 @@ return } - // Skip if we've already registered this field + // If we've already registered this field then wipe any errors and + // return the existing field const existingField = getField(field) if (existingField) { + existingField.update(state => { + state.fieldState.error = null + return state + }) return existingField } From 4859bea3a8049db3bd7273b75d3a86e35dd6438f Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 19 Aug 2021 14:02:03 +0100 Subject: [PATCH 09/36] Fix form validation exiting early --- .../src/forms/InnerForm.svelte | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/packages/standard-components/src/forms/InnerForm.svelte b/packages/standard-components/src/forms/InnerForm.svelte index ec5c066699..c8b76a7200 100644 --- a/packages/standard-components/src/forms/InnerForm.svelte +++ b/packages/standard-components/src/forms/InnerForm.svelte @@ -118,24 +118,21 @@ return fieldInfo }, validate: (onlyCurrentStep = false) => { - // Validate only the current step if required + let valid = true + let validationFields = fields + + // Reduce fields to only the current step if required if (onlyCurrentStep) { - const stepFields = fields.filter(f => get(f).step === get(currentStep)) - for (let field of stepFields) { - if (!get(field).fieldApi.validate()) { - return false - } - } - return true + validationFields = fields.filter(f => get(f).step === get(currentStep)) } - // Otherwise validate all fields - for (let field of fields) { + // Validate fields and check if any are invalid + validationFields.forEach(field => { if (!get(field).fieldApi.validate()) { - return false + valid = false } - } - return true + }) + return valid }, clear: () => { // Clear the form by clearing each individual field From a4d23aa578ba2811ec349e852d86391399848461 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 19 Aug 2021 14:02:33 +0100 Subject: [PATCH 10/36] Disable updating form values on change due to performance issues of enrichment --- packages/standard-components/src/forms/StringField.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/standard-components/src/forms/StringField.svelte b/packages/standard-components/src/forms/StringField.svelte index 7bc4104cc5..4764cba4d3 100644 --- a/packages/standard-components/src/forms/StringField.svelte +++ b/packages/standard-components/src/forms/StringField.svelte @@ -26,7 +26,7 @@ > {#if fieldState} fieldApi.setValue(e.detail)} disabled={fieldState.disabled} From a5778f9dbc66596d89f83b3eae3e734fafe743a7 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 19 Aug 2021 14:53:13 +0100 Subject: [PATCH 11/36] Ensure that the correct form step is always visible in builder preview --- packages/client/src/store/builder.js | 34 +++++++++++++++++++ .../src/forms/FormStep.svelte | 15 +++++++- .../src/forms/InnerForm.svelte | 5 +++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/packages/client/src/store/builder.js b/packages/client/src/store/builder.js index 401ccfcc79..65e4f70e65 100644 --- a/packages/client/src/store/builder.js +++ b/packages/client/src/store/builder.js @@ -28,6 +28,26 @@ const findComponentById = (component, componentId) => { return null } +const findComponentIdPath = (component, componentId, path = []) => { + if (!component || !componentId) { + return null + } + path = [...path, component._id] + if (component._id === componentId) { + return path + } + if (!component._children?.length) { + return null + } + for (let child of component._children) { + const result = findComponentIdPath(child, componentId, path) + if (result) { + return result + } + } + return null +} + const createBuilderStore = () => { const initialState = { inBuilder: false, @@ -37,6 +57,7 @@ const createBuilderStore = () => { selectedComponentId: null, previewId: null, previewType: null, + selectedPath: [], } const writableStore = writable(initialState) const derivedStore = derived(writableStore, $state => { @@ -47,10 +68,15 @@ const createBuilderStore = () => { const prefix = "@budibase/standard-components/" const type = component?._component?.replace(prefix, "") const definition = type ? Manifest[type] : null + + // Derive the selected component path + const path = findComponentIdPath(asset.props, selectedComponentId) || [] + return { ...$state, selectedComponent: component, selectedComponentDefinition: definition, + selectedComponentPath: path, } }) @@ -67,6 +93,14 @@ const createBuilderStore = () => { notifyLoaded: () => { dispatchEvent("preview-loaded") }, + setSelectedPath: path => { + console.log("set to ") + console.log(path) + writableStore.update(state => { + state.selectedPath = path + return state + }) + }, } return { ...writableStore, diff --git a/packages/standard-components/src/forms/FormStep.svelte b/packages/standard-components/src/forms/FormStep.svelte index e048a600f5..4806cfc86c 100644 --- a/packages/standard-components/src/forms/FormStep.svelte +++ b/packages/standard-components/src/forms/FormStep.svelte @@ -4,7 +4,7 @@ export let step - const { styleable } = getContext("sdk") + const { styleable, builderStore } = getContext("sdk") const component = getContext("component") const formContext = getContext("form") @@ -13,6 +13,19 @@ $: formState = formContext?.formState $: currentStep = $formState?.currentStep + + // If in the builder preview, show this step if it is selected + $: { + if (step && formContext && $builderStore.inBuilder) { + console.log($builderStore.selectedPath) + console.log($component.id) + + if ($builderStore.selectedComponentPath?.includes($component.id)) { + console.log("selecting " + step) + formContext.formApi.setStep(step) + } + } + } {#if !formContext} diff --git a/packages/standard-components/src/forms/InnerForm.svelte b/packages/standard-components/src/forms/InnerForm.svelte index c8b76a7200..774419bbdc 100644 --- a/packages/standard-components/src/forms/InnerForm.svelte +++ b/packages/standard-components/src/forms/InnerForm.svelte @@ -146,6 +146,11 @@ prevStep: () => { currentStep.update(step => Math.max(1, step - 1)) }, + setStep: step => { + if (step) { + currentStep.set(step) + } + }, } // Creates an API for a specific field From 3020b59d86c0f04d37dcb9d54a02da06bb981b12 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 19 Aug 2021 14:56:56 +0100 Subject: [PATCH 12/36] Only show the selected step if not already selected --- .../src/forms/FormStep.svelte | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/standard-components/src/forms/FormStep.svelte b/packages/standard-components/src/forms/FormStep.svelte index 4806cfc86c..34894aa6eb 100644 --- a/packages/standard-components/src/forms/FormStep.svelte +++ b/packages/standard-components/src/forms/FormStep.svelte @@ -2,7 +2,7 @@ import { getContext, setContext } from "svelte" import Placeholder from "../Placeholder.svelte" - export let step + export let step = 1 const { styleable, builderStore } = getContext("sdk") const component = getContext("component") @@ -14,16 +14,15 @@ $: formState = formContext?.formState $: currentStep = $formState?.currentStep - // If in the builder preview, show this step if it is selected + // If in the builder preview, show this step if a child is selected $: { - if (step && formContext && $builderStore.inBuilder) { - console.log($builderStore.selectedPath) - console.log($component.id) - - if ($builderStore.selectedComponentPath?.includes($component.id)) { - console.log("selecting " + step) - formContext.formApi.setStep(step) - } + if ( + formContext && + $builderStore.inBuilder && + $builderStore.selectedComponentPath?.includes($component.id) && + $formState?.currentStep !== step + ) { + formContext.formApi.setStep(step) } } From 643952e119e86dd10a17af08bbc17da370e321f2 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 19 Aug 2021 16:04:15 +0100 Subject: [PATCH 13/36] Fix crash when evaluating builder preview specific code in prod apps --- packages/client/src/store/builder.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/client/src/store/builder.js b/packages/client/src/store/builder.js index 65e4f70e65..0fa109fc1c 100644 --- a/packages/client/src/store/builder.js +++ b/packages/client/src/store/builder.js @@ -61,6 +61,11 @@ const createBuilderStore = () => { } const writableStore = writable(initialState) const derivedStore = derived(writableStore, $state => { + // Avoid any of this logic if we aren't in the builder preview + if (!writableStore.inBuilder) { + return $state + } + // Derive the selected component instance and definition const { layout, screen, previewType, selectedComponentId } = $state const asset = previewType === "layout" ? layout : screen From a895771179c997ef3ab4e1ada9235dfd5847cfac Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 19 Aug 2021 16:06:33 +0100 Subject: [PATCH 14/36] Fix bug determining whether an app is inside the preview or not --- packages/client/src/store/builder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/store/builder.js b/packages/client/src/store/builder.js index 0fa109fc1c..530f49843a 100644 --- a/packages/client/src/store/builder.js +++ b/packages/client/src/store/builder.js @@ -62,7 +62,7 @@ const createBuilderStore = () => { const writableStore = writable(initialState) const derivedStore = derived(writableStore, $state => { // Avoid any of this logic if we aren't in the builder preview - if (!writableStore.inBuilder) { + if (!$state.inBuilder) { return $state } From 10066bf3e045bd1236b4457f0c87f6a05b0de943 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 20 Aug 2021 09:27:38 +0100 Subject: [PATCH 15/36] Fix dependency loop in client stores --- .../client/src/components/Component.svelte | 1 - packages/client/src/store/builder.js | 44 +------------ packages/client/src/store/screens.js | 38 +++++++++++- packages/client/src/utils/components.js | 62 +++++++++++++++++++ .../src/forms/InnerForm.svelte | 2 +- 5 files changed, 103 insertions(+), 44 deletions(-) create mode 100644 packages/client/src/utils/components.js diff --git a/packages/client/src/components/Component.svelte b/packages/client/src/components/Component.svelte index 8c7437e523..ed53a7eb32 100644 --- a/packages/client/src/components/Component.svelte +++ b/packages/client/src/components/Component.svelte @@ -74,7 +74,6 @@ styles: { ...instance._styles, id, empty, interactive }, empty, selected, - props: componentSettings, name, }) diff --git a/packages/client/src/store/builder.js b/packages/client/src/store/builder.js index 530f49843a..cf6e8afb95 100644 --- a/packages/client/src/store/builder.js +++ b/packages/client/src/store/builder.js @@ -1,5 +1,6 @@ import { writable, derived } from "svelte/store" import Manifest from "@budibase/standard-components/manifest.json" +import { findComponentById, findComponentPathById } from "../utils/components" const dispatchEvent = (type, data = {}) => { window.dispatchEvent( @@ -9,45 +10,6 @@ const dispatchEvent = (type, data = {}) => { ) } -const findComponentById = (component, componentId) => { - if (!component || !componentId) { - return null - } - if (component._id === componentId) { - return component - } - if (!component._children?.length) { - return null - } - for (let child of component._children) { - const result = findComponentById(child, componentId) - if (result) { - return result - } - } - return null -} - -const findComponentIdPath = (component, componentId, path = []) => { - if (!component || !componentId) { - return null - } - path = [...path, component._id] - if (component._id === componentId) { - return path - } - if (!component._children?.length) { - return null - } - for (let child of component._children) { - const result = findComponentIdPath(child, componentId, path) - if (result) { - return result - } - } - return null -} - const createBuilderStore = () => { const initialState = { inBuilder: false, @@ -75,13 +37,13 @@ const createBuilderStore = () => { const definition = type ? Manifest[type] : null // Derive the selected component path - const path = findComponentIdPath(asset.props, selectedComponentId) || [] + const path = findComponentPathById(asset.props, selectedComponentId) || [] return { ...$state, selectedComponent: component, selectedComponentDefinition: definition, - selectedComponentPath: path, + selectedComponentPath: path?.map(component => component._id), } }) diff --git a/packages/client/src/store/screens.js b/packages/client/src/store/screens.js index 367d9ecfea..702f662f8a 100644 --- a/packages/client/src/store/screens.js +++ b/packages/client/src/store/screens.js @@ -1,7 +1,12 @@ -import { derived } from "svelte/store" +import { derived, get } from "svelte/store" import { routeStore } from "./routes" import { builderStore } from "./builder" import { appStore } from "./app" +import { + findComponentPathById, + findChildrenByType, + findComponentById, +} from "../utils/components" const createScreenStore = () => { const store = derived( @@ -36,8 +41,39 @@ const createScreenStore = () => { } ) + // Utils to parse component definitions + const actions = { + findComponentById: componentId => { + const { activeScreen, activeLayout } = get(store) + let result = findComponentById(activeScreen?.props, componentId) + if (result) { + return result + } + return findComponentById(activeLayout?.props) + }, + findComponentPathById: componentId => { + const { activeScreen, activeLayout } = get(store) + let result = findComponentPathById(activeScreen?.props, componentId) + if (result) { + return result + } + return findComponentPathById(activeLayout?.props) + }, + findChildrenByType: (componentId, type) => { + const component = actions.findComponentById(componentId) + if (!component || !component._children) { + return null + } + let children = [] + findChildrenByType(component, type, children) + console.log(children) + return children + }, + } + return { subscribe: store.subscribe, + actions, } } diff --git a/packages/client/src/utils/components.js b/packages/client/src/utils/components.js new file mode 100644 index 0000000000..4b1b8a7ada --- /dev/null +++ b/packages/client/src/utils/components.js @@ -0,0 +1,62 @@ +/** + * Finds a component instance by ID + */ +export const findComponentById = (component, componentId) => { + if (!component || !componentId) { + return null + } + if (component._id === componentId) { + return component + } + if (!component._children?.length) { + return null + } + for (let child of component._children) { + const result = findComponentById(child, componentId) + if (result) { + return result + } + } + return null +} + +/** + * Finds the component path to a component + */ +export const findComponentPathById = (component, componentId, path = []) => { + if (!component || !componentId) { + return null + } + path = [...path, component] + if (component._id === componentId) { + return path + } + if (!component._children?.length) { + return null + } + for (let child of component._children) { + const result = findComponentPathById(child, componentId, path) + if (result) { + return result + } + } + return null +} + +/** + * Finds all children instances of a certain component type of a given component + */ +export const findChildrenByType = (component, type, children = []) => { + if (!component) { + return + } + if (component._component.endsWith(`/${type}`)) { + children.push(component) + } + if (!component._children?.length) { + return + } + component._children.forEach(child => { + findChildrenByType(child, type, children) + }) +} diff --git a/packages/standard-components/src/forms/InnerForm.svelte b/packages/standard-components/src/forms/InnerForm.svelte index 774419bbdc..3719de4750 100644 --- a/packages/standard-components/src/forms/InnerForm.svelte +++ b/packages/standard-components/src/forms/InnerForm.svelte @@ -27,7 +27,7 @@ $: errors = deriveFieldProperty(fields, f => f.fieldState.error) $: valid = !Object.values($errors).some(error => error != null) - // Derive which fields belong in which steps + // Derive whether the current form step is valid $: currentStepValid = derived( [currentStep, ...fields], ([currentStepValue, ...fieldsValue]) => { From 7f0739027782a44ff7444231d32d061ac9632eb9 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 20 Aug 2021 09:54:54 +0100 Subject: [PATCH 16/36] Add single button action for changing form step --- .../EventsEditor/EventEditor.svelte | 4 +- .../actions/ChangeFormStep.svelte | 68 +++++++++++++++++++ .../EventsEditor/actions/ClearForm.svelte | 2 +- .../actions/CloseScreenModal.svelte | 1 - .../EventsEditor/actions/LogOut.svelte | 1 - .../EventsEditor/actions/NavigateTo.svelte | 2 +- .../EventsEditor/actions/NextFormStep.svelte | 35 ---------- .../EventsEditor/actions/PrevFormStep.svelte | 35 ---------- .../EventsEditor/actions/ValidateForm.svelte | 2 +- .../EventsEditor/actions/index.js | 11 +-- packages/client/src/constants.js | 3 +- packages/client/src/utils/buttonActions.js | 16 ++--- packages/standard-components/manifest.json | 6 +- .../src/forms/InnerForm.svelte | 18 +++-- 14 files changed, 93 insertions(+), 111 deletions(-) create mode 100644 packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/ChangeFormStep.svelte delete mode 100644 packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/NextFormStep.svelte delete mode 100644 packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/PrevFormStep.svelte diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/EventEditor.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/EventEditor.svelte index 2e2a318610..4ff746a034 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/EventEditor.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/EventEditor.svelte @@ -33,7 +33,7 @@ $: selectedActionComponent = selectedAction && - actionTypes.find(t => t.name === selectedAction[EVENT_TYPE_KEY]).component + actionTypes.find(t => t.name === selectedAction[EVENT_TYPE_KEY])?.component // Select the first action if we delete an action $: { @@ -116,7 +116,7 @@ - {#if selectedAction} + {#if selectedActionComponent}
+ import { Select, Label, Stepper } from "@budibase/bbui" + import { currentAsset, store } from "builderStore" + import { getActionProviderComponents } from "builderStore/dataBinding" + import { onMount } from "svelte" + + export let parameters + + $: actionProviders = getActionProviderComponents( + $currentAsset, + $store.selectedComponentId, + "ChangeFormStep" + ) + + const typeOptions = [ + { + label: "Next step", + value: "next", + }, + { + label: "Previous step", + value: "prev", + }, + { + label: "First step", + value: "first", + }, + { + label: "Specific step", + value: "specific", + }, + ] + + onMount(() => { + if (!parameters.type) { + parameters.type = "next" + } + }) + + +
+ + + {#if parameters.type === "specific"} + + + {/if} +
+ + diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/ClearForm.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/ClearForm.svelte index 74eae6283c..b3bf7ebf7c 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/ClearForm.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/ClearForm.svelte @@ -29,7 +29,7 @@ row-gap: var(--spacing-s); grid-template-columns: 60px 1fr; align-items: center; - max-width: 800px; + max-width: 400px; margin: 0 auto; } diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/CloseScreenModal.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/CloseScreenModal.svelte index 0afb8dd46e..873c9ccf65 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/CloseScreenModal.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/CloseScreenModal.svelte @@ -11,7 +11,6 @@ diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/LogOut.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/LogOut.svelte index 8782127243..3434d63480 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/LogOut.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/LogOut.svelte @@ -8,7 +8,6 @@ diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/NavigateTo.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/NavigateTo.svelte index 5a0e163655..d90b645315 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/NavigateTo.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/NavigateTo.svelte @@ -25,7 +25,7 @@ align-items: center; gap: var(--spacing-m); grid-template-columns: auto 1fr; - max-width: 800px; + max-width: 400px; margin: 0 auto; } diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/NextFormStep.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/NextFormStep.svelte deleted file mode 100644 index a635e158cb..0000000000 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/NextFormStep.svelte +++ /dev/null @@ -1,35 +0,0 @@ - - -
- - x._instanceName} - getOptionValue={x => x._id} - /> -
- - diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/ValidateForm.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/ValidateForm.svelte index d61c9567d8..e572dc6c1c 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/ValidateForm.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/ValidateForm.svelte @@ -34,7 +34,7 @@ row-gap: var(--spacing-s); grid-template-columns: 60px 1fr; align-items: center; - max-width: 800px; + max-width: 400px; margin: 0 auto; } diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/index.js b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/index.js index 75feb533a7..9cf2461b77 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/index.js +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/index.js @@ -7,8 +7,7 @@ import ValidateForm from "./ValidateForm.svelte" import LogOut from "./LogOut.svelte" import ClearForm from "./ClearForm.svelte" import CloseScreenModal from "./CloseScreenModal.svelte" -import NextFormStep from "./NextFormStep.svelte" -import PrevFormStep from "./PrevFormStep.svelte" +import ChangeFormStep from "./ChangeFormStep.svelte" // Defines which actions are available to configure in the front end. // Unfortunately the "name" property is used as the identifier so please don't @@ -55,11 +54,7 @@ export default [ component: CloseScreenModal, }, { - name: "Next Form Step", - component: NextFormStep, - }, - { - name: "Previous Form Step", - component: PrevFormStep, + name: "Change Form Step", + component: ChangeFormStep, }, ] diff --git a/packages/client/src/constants.js b/packages/client/src/constants.js index 99e95e8398..d2237ba3b9 100644 --- a/packages/client/src/constants.js +++ b/packages/client/src/constants.js @@ -7,8 +7,7 @@ export const ActionTypes = { RefreshDatasource: "RefreshDatasource", SetDataProviderQuery: "SetDataProviderQuery", ClearForm: "ClearForm", - NextFormStep: "NextFormStep", - PrevFormStep: "PrevFormStep", + ChangeFormStep: "ChangeFormStep", } export const ApiVersion = "1" diff --git a/packages/client/src/utils/buttonActions.js b/packages/client/src/utils/buttonActions.js index 6affe66491..a18cd74891 100644 --- a/packages/client/src/utils/buttonActions.js +++ b/packages/client/src/utils/buttonActions.js @@ -105,19 +105,12 @@ const clearFormHandler = async (action, context) => { ) } -const nextFormStepHandler = async (action, context) => { +const changeFormStepHandler = async (action, context) => { return await executeActionHandler( context, action.parameters.componentId, - ActionTypes.NextFormStep - ) -} - -const prevFormStepHandler = async (action, context) => { - return await executeActionHandler( - context, - action.parameters.componentId, - ActionTypes.PrevFormStep + ActionTypes.ChangeFormStep, + action.parameters ) } @@ -138,8 +131,7 @@ const handlerMap = { ["Log Out"]: logoutHandler, ["Clear Form"]: clearFormHandler, ["Close Screen Modal"]: closeScreenModalHandler, - ["Next Form Step"]: nextFormStepHandler, - ["Previous Form Step"]: prevFormStepHandler, + ["Change Form Step"]: changeFormStepHandler, } const confirmTextMap = { diff --git a/packages/standard-components/manifest.json b/packages/standard-components/manifest.json index 785b549c31..b54812e8b3 100644 --- a/packages/standard-components/manifest.json +++ b/packages/standard-components/manifest.json @@ -1706,8 +1706,7 @@ "actions": [ "ValidateForm", "ClearForm", - "NextFormStep", - "PrevFormStep" + "ChangeFormStep" ], "styles": ["size"], "settings": [ @@ -1768,9 +1767,6 @@ "icon": "Form", "hasChildren": true, "illegalChildren": ["section"], - "actions": [ - "ValidateFormStep" - ], "styles": ["size"], "settings": [ { diff --git a/packages/standard-components/src/forms/InnerForm.svelte b/packages/standard-components/src/forms/InnerForm.svelte index 3719de4750..5422d50d1b 100644 --- a/packages/standard-components/src/forms/InnerForm.svelte +++ b/packages/standard-components/src/forms/InnerForm.svelte @@ -140,11 +140,16 @@ get(field).fieldApi.clearValue() }) }, - nextStep: () => { - currentStep.update(step => step + 1) - }, - prevStep: () => { - currentStep.update(step => Math.max(1, step - 1)) + changeStep: ({ type, number }) => { + if (type === "next") { + currentStep.update(step => step + 1) + } else if (type === "prev") { + currentStep.update(step => Math.max(1, step - 1)) + } else if (type === "first") { + currentStep.set(1) + } else if (type === "specific" && number && !isNaN(number)) { + currentStep.set(number) + } }, setStep: step => { if (step) { @@ -249,8 +254,7 @@ const actions = [ { type: ActionTypes.ValidateForm, callback: formApi.validate }, { type: ActionTypes.ClearForm, callback: formApi.clear }, - { type: ActionTypes.NextFormStep, callback: formApi.nextStep }, - { type: ActionTypes.PrevFormStep, callback: formApi.prevStep }, + { type: ActionTypes.ChangeFormStep, callback: formApi.changeStep }, ] From a656b419b919cb6f3712d68e23da911f653ce4da Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 20 Aug 2021 10:03:21 +0100 Subject: [PATCH 17/36] Making picker sorting optional and default to off. Sort by default for client apps --- packages/bbui/src/Form/Core/Multiselect.svelte | 2 ++ packages/bbui/src/Form/Core/Picker.svelte | 8 ++++++-- packages/bbui/src/Form/Core/Select.svelte | 2 ++ packages/bbui/src/Form/Multiselect.svelte | 2 ++ packages/bbui/src/Form/Select.svelte | 2 ++ .../components/backend/DataTable/RowFieldControl.svelte | 1 + .../backend/TableNavigator/TableDataImport.svelte | 1 + .../src/components/common/LinkedRowSelector.svelte | 2 ++ .../standard-components/src/forms/OptionsField.svelte | 1 + .../src/forms/RelationshipField.svelte | 1 + 10 files changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/bbui/src/Form/Core/Multiselect.svelte b/packages/bbui/src/Form/Core/Multiselect.svelte index 94d4f2b768..3eb1add267 100644 --- a/packages/bbui/src/Form/Core/Multiselect.svelte +++ b/packages/bbui/src/Form/Core/Multiselect.svelte @@ -12,6 +12,7 @@ export let getOptionValue = option => option export let readonly = false export let autocomplete = false + export let sort = false const dispatch = createEventDispatcher() $: selectedLookupMap = getSelectedLookupMap(value) @@ -83,4 +84,5 @@ {getOptionLabel} {getOptionValue} onSelectOption={toggleOption} + {sort} /> diff --git a/packages/bbui/src/Form/Core/Picker.svelte b/packages/bbui/src/Form/Core/Picker.svelte index de7bfb02b8..8acbc4e1a6 100644 --- a/packages/bbui/src/Form/Core/Picker.svelte +++ b/packages/bbui/src/Form/Core/Picker.svelte @@ -25,11 +25,12 @@ export let quiet = false export let autoWidth = false export let autocomplete = false + export let sort = false const dispatch = createEventDispatcher() let searchTerm = null - $: sortedOptions = getSortedOptions(options, getOptionLabel) + $: sortedOptions = getSortedOptions(options, getOptionLabel, sort) $: filteredOptions = getFilteredOptions( sortedOptions, searchTerm, @@ -45,10 +46,13 @@ open = true } - const getSortedOptions = (options, getLabel) => { + const getSortedOptions = (options, getLabel, sort) => { if (!options?.length || !Array.isArray(options)) { return [] } + if (!sort) { + return options + } return options.sort((a, b) => { const labelA = getLabel(a) const labelB = getLabel(b) diff --git a/packages/bbui/src/Form/Core/Select.svelte b/packages/bbui/src/Form/Core/Select.svelte index 3a2daf25cf..413b11dd34 100644 --- a/packages/bbui/src/Form/Core/Select.svelte +++ b/packages/bbui/src/Form/Core/Select.svelte @@ -15,6 +15,7 @@ export let quiet = false export let autoWidth = false export let autocomplete = false + export let sort = false const dispatch = createEventDispatcher() let open = false @@ -72,6 +73,7 @@ {getOptionIcon} {fieldIcon} {autocomplete} + {sort} isPlaceholder={value == null || value === ""} placeholderOption={placeholder} isOptionSelected={option => option === value} diff --git a/packages/bbui/src/Form/Multiselect.svelte b/packages/bbui/src/Form/Multiselect.svelte index 1bb0039914..957dcccddf 100644 --- a/packages/bbui/src/Form/Multiselect.svelte +++ b/packages/bbui/src/Form/Multiselect.svelte @@ -13,6 +13,7 @@ export let options = [] export let getOptionLabel = option => option export let getOptionValue = option => option + export let sort = false const dispatch = createEventDispatcher() const onChange = e => { @@ -29,6 +30,7 @@ {value} {options} {placeholder} + {sort} {getOptionLabel} {getOptionValue} on:change={onChange} diff --git a/packages/bbui/src/Form/Select.svelte b/packages/bbui/src/Form/Select.svelte index eecc719a9a..b6547c0a98 100644 --- a/packages/bbui/src/Form/Select.svelte +++ b/packages/bbui/src/Form/Select.svelte @@ -16,6 +16,7 @@ export let getOptionIcon = option => option?.icon export let quiet = false export let autoWidth = false + export let sort = false const dispatch = createEventDispatcher() const onChange = e => { @@ -41,6 +42,7 @@ {options} {placeholder} {autoWidth} + {sort} {getOptionLabel} {getOptionValue} {getOptionIcon} diff --git a/packages/builder/src/components/backend/DataTable/RowFieldControl.svelte b/packages/builder/src/components/backend/DataTable/RowFieldControl.svelte index 078dbf25b2..0724016679 100644 --- a/packages/builder/src/components/backend/DataTable/RowFieldControl.svelte +++ b/packages/builder/src/components/backend/DataTable/RowFieldControl.svelte @@ -19,6 +19,7 @@ data-cy="{meta.name}-select" bind:value options={meta.constraints.inclusion} + sort /> {:else if type === "datetime"} diff --git a/packages/builder/src/components/backend/TableNavigator/TableDataImport.svelte b/packages/builder/src/components/backend/TableNavigator/TableDataImport.svelte index 8ce2ebe7f9..2bbbb471c2 100644 --- a/packages/builder/src/components/backend/TableNavigator/TableDataImport.svelte +++ b/packages/builder/src/components/backend/TableNavigator/TableDataImport.svelte @@ -153,6 +153,7 @@ label="Display Column" bind:value={primaryDisplay} options={fields} + sort />
{/if} diff --git a/packages/builder/src/components/common/LinkedRowSelector.svelte b/packages/builder/src/components/common/LinkedRowSelector.svelte index 080f09809d..1f3dea137f 100644 --- a/packages/builder/src/components/common/LinkedRowSelector.svelte +++ b/packages/builder/src/components/common/LinkedRowSelector.svelte @@ -47,6 +47,7 @@ getOptionValue={row => row._id} on:change={e => (linkedIds = e.detail ? [e.detail] : [])} {label} + sort /> {:else} row._id} + sort /> {/if} diff --git a/packages/standard-components/src/forms/OptionsField.svelte b/packages/standard-components/src/forms/OptionsField.svelte index 9f3e4a4557..c5efa6f58d 100644 --- a/packages/standard-components/src/forms/OptionsField.svelte +++ b/packages/standard-components/src/forms/OptionsField.svelte @@ -87,6 +87,7 @@ getOptionLabel={flatOptions ? x => x : x => x.label} getOptionValue={flatOptions ? x => x : x => x.value} {autocomplete} + sort={true} /> {:else if optionsType === "radio"} option._id} {placeholder} + sort={true} /> {/if} From f04b860146e4881595436de8850a3ba768f5ddb1 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 20 Aug 2021 14:12:52 +0100 Subject: [PATCH 18/36] Automatically name and number form step components upon creation --- .../src/builderStore/store/frontend.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/builder/src/builderStore/store/frontend.js b/packages/builder/src/builderStore/store/frontend.js index 1924ae07a2..192ade9e5d 100644 --- a/packages/builder/src/builderStore/store/frontend.js +++ b/packages/builder/src/builderStore/store/frontend.js @@ -20,7 +20,12 @@ import { fetchComponentLibDefinitions } from "../loadComponentLibraries" import api from "../api" import { FrontendTypes } from "constants" import analytics from "analytics" -import { findComponentType, findComponentParent } from "../storeUtils" +import { + findComponentType, + findComponentParent, + findClosestMatchingComponent, + findAllMatchingComponents, +} from "../storeUtils" import { uuid } from "../uuid" import { removeBindings } from "../dataBinding" @@ -334,6 +339,18 @@ export const getFrontendStore = () => { if (definition.hasChildren) { extras._children = [] } + if (componentName.endsWith("/formstep")) { + const parentForm = findClosestMatchingComponent( + get(currentAsset).props, + get(selectedComponent)._id, + component => component._component.endsWith("/form") + ) + const formSteps = findAllMatchingComponents(parentForm, component => + component._component.endsWith("/formstep") + ) + extras.step = formSteps.length + 1 + extras._instanceName = `Step ${formSteps.length + 1}` + } return { _id: uuid(), From 9cb1ce6862be8ce7133f70eee2a4fe5bd65c7fb1 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 20 Aug 2021 15:16:20 +0100 Subject: [PATCH 19/36] Prevent adding form steps inside other form steps and fix illegalChildren usage --- .../design/AppPreview/ComponentSelectionList.svelte | 3 ++- packages/standard-components/manifest.json | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/builder/src/components/design/AppPreview/ComponentSelectionList.svelte b/packages/builder/src/components/design/AppPreview/ComponentSelectionList.svelte index d8881a8d96..9893b07404 100644 --- a/packages/builder/src/components/design/AppPreview/ComponentSelectionList.svelte +++ b/packages/builder/src/components/design/AppPreview/ComponentSelectionList.svelte @@ -46,7 +46,7 @@ onItemChosen(item)} + disabled={isChildAllowed(item, $selectedComponent)} > {item.name} diff --git a/packages/standard-components/manifest.json b/packages/standard-components/manifest.json index b54812e8b3..04519f4f0f 100644 --- a/packages/standard-components/manifest.json +++ b/packages/standard-components/manifest.json @@ -1702,7 +1702,7 @@ "name": "Form", "icon": "Form", "hasChildren": true, - "illegalChildren": ["section"], + "illegalChildren": ["section", "form"], "actions": [ "ValidateForm", "ClearForm", @@ -1764,9 +1764,9 @@ }, "formstep": { "name": "Form Step", - "icon": "Form", + "icon": "AssetsAdded", "hasChildren": true, - "illegalChildren": ["section"], + "illegalChildren": ["section", "form", "form step"], "styles": ["size"], "settings": [ { From 97fdcc0209f1e8e398416db90c5c1a5057b4aa3c Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 20 Aug 2021 15:20:19 +0100 Subject: [PATCH 20/36] Fix endless loop when nesting 2 form steps inside each other --- packages/standard-components/src/forms/FormStep.svelte | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/standard-components/src/forms/FormStep.svelte b/packages/standard-components/src/forms/FormStep.svelte index 34894aa6eb..665205f7d4 100644 --- a/packages/standard-components/src/forms/FormStep.svelte +++ b/packages/standard-components/src/forms/FormStep.svelte @@ -19,8 +19,7 @@ if ( formContext && $builderStore.inBuilder && - $builderStore.selectedComponentPath?.includes($component.id) && - $formState?.currentStep !== step + $builderStore.selectedComponentPath?.includes($component.id) ) { formContext.formApi.setStep(step) } From 801ea8f902a868fe08911a68ac408c178efc2751 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 20 Aug 2021 15:20:57 +0100 Subject: [PATCH 21/36] Remove steps setting on form --- packages/standard-components/manifest.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/standard-components/manifest.json b/packages/standard-components/manifest.json index 04519f4f0f..559a34c4d2 100644 --- a/packages/standard-components/manifest.json +++ b/packages/standard-components/manifest.json @@ -1726,12 +1726,6 @@ "label": "Custom" } }, - { - "type": "number", - "label": "Steps", - "key": "steps", - "defaultValue": 1 - }, { "type": "boolean", "label": "Disabled", From 27be64a6fd78913061c7d8ce5f8ff3f386014c20 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 23 Aug 2021 11:09:33 +0100 Subject: [PATCH 22/36] Give detail autoscreen repeater a placeholder for when no rows exist --- .../src/builderStore/store/screenTemplates/rowDetailScreen.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/builder/src/builderStore/store/screenTemplates/rowDetailScreen.js b/packages/builder/src/builderStore/store/screenTemplates/rowDetailScreen.js index a1a1e17fd5..f19f4e3652 100644 --- a/packages/builder/src/builderStore/store/screenTemplates/rowDetailScreen.js +++ b/packages/builder/src/builderStore/store/screenTemplates/rowDetailScreen.js @@ -94,6 +94,7 @@ const createScreen = table => { .instanceName("Repeater") .customProps({ dataProvider: `{{ literal ${makePropSafe(provider._json._id)} }}`, + noRowsMessage: "We couldn't find a row to display", }) const form = makeMainForm() From 88354073aaa485db280934b1ea8b7c183d8f546f Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 23 Aug 2021 11:10:07 +0100 Subject: [PATCH 23/36] Add missing initial form values to form context and prefix static values to avoid clashes with column names --- packages/standard-components/manifest.json | 6 +++--- .../src/forms/InnerForm.svelte | 21 +++++++++++-------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/packages/standard-components/manifest.json b/packages/standard-components/manifest.json index 559a34c4d2..da3736a076 100644 --- a/packages/standard-components/manifest.json +++ b/packages/standard-components/manifest.json @@ -1739,15 +1739,15 @@ "values": [ { "label": "Valid", - "key": "valid" + "key": "__valid" }, { "label": "Current Step", - "key": "currentStep" + "key": "__currentStep" }, { "label": "Current Step Valid", - "key": "currentStepValid" + "key": "__currentStepValid" } ] }, diff --git a/packages/standard-components/src/forms/InnerForm.svelte b/packages/standard-components/src/forms/InnerForm.svelte index 5422d50d1b..660b784fd0 100644 --- a/packages/standard-components/src/forms/InnerForm.svelte +++ b/packages/standard-components/src/forms/InnerForm.svelte @@ -256,17 +256,20 @@ { type: ActionTypes.ClearForm, callback: formApi.clear }, { type: ActionTypes.ChangeFormStep, callback: formApi.changeStep }, ] + + // Create data context to provide + $: dataContext = { + ...initialValues, + ...$values, + + // These static values are prefixed to avoid clashes with actual columns + __valid: valid, + __currentStep: $currentStep, + __currentStepValid: $currentStepValid, + } - +
From 6d902616cc1ac3844a5e67ca648903b12f5da98c Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 23 Aug 2021 11:46:50 +0100 Subject: [PATCH 24/36] Always limit data providers to 1 row on details screens, even for external tables --- .../src/builderStore/store/screenTemplates/rowDetailScreen.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/builder/src/builderStore/store/screenTemplates/rowDetailScreen.js b/packages/builder/src/builderStore/store/screenTemplates/rowDetailScreen.js index f19f4e3652..ec737fe36b 100644 --- a/packages/builder/src/builderStore/store/screenTemplates/rowDetailScreen.js +++ b/packages/builder/src/builderStore/store/screenTemplates/rowDetailScreen.js @@ -86,7 +86,7 @@ const createScreen = table => { valueType: "Binding", }, ], - limit: table.type === "external" ? undefined : 1, + limit: 1, paginate: false, }) From e411f771d2a0c766336ffeaed5947d6dd58a4ac8 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 23 Aug 2021 14:00:45 +0100 Subject: [PATCH 25/36] Fix button casing --- .../PropertyControls/ValidationEditor/ValidationEditor.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ValidationEditor/ValidationEditor.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ValidationEditor/ValidationEditor.svelte index 0b7fd12de2..6c62c9f5af 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ValidationEditor/ValidationEditor.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ValidationEditor/ValidationEditor.svelte @@ -17,7 +17,7 @@ } -Configure Validation +Configure validation Configure validation rules for this field. From 8c114fae34930296a4a17181b0815a023ed9b540 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 23 Aug 2021 14:01:57 +0100 Subject: [PATCH 26/36] Show component hidden by conditional UI if they would otherwise hide the selected component --- packages/client/src/components/Component.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/client/src/components/Component.svelte b/packages/client/src/components/Component.svelte index ed53a7eb32..a10c88f410 100644 --- a/packages/client/src/components/Component.svelte +++ b/packages/client/src/components/Component.svelte @@ -63,6 +63,7 @@ $: selected = $builderStore.inBuilder && $builderStore.selectedComponentId === instance._id + $: inSelectedPath = $builderStore.selectedComponentPath?.includes(id) $: interactive = $builderStore.previewType === "layout" || insideScreenslot $: evaluateConditions(enrichedSettings?._conditions) $: componentSettings = { ...enrichedSettings, ...conditionalSettings } @@ -174,13 +175,12 @@ {#key propsHash} - {#if constructor && componentSettings && visible} + {#if constructor && componentSettings && (visible || inSelectedPath)}
{#if children.length} From 918f269e6ea37267c46a49335afb13ac1429a6b3 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 23 Aug 2021 15:13:41 +0100 Subject: [PATCH 27/36] Fix issue with svelte reactive statements not being sufficiently 'reactive' in core form field in client lib by replacing with manual store subscription --- packages/standard-components/src/forms/Field.svelte | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/standard-components/src/forms/Field.svelte b/packages/standard-components/src/forms/Field.svelte index b202bc506c..9f08f204c2 100644 --- a/packages/standard-components/src/forms/Field.svelte +++ b/packages/standard-components/src/forms/Field.svelte @@ -1,7 +1,7 @@