From 253642ad1fec11faf385bb1050799c46a87e597d Mon Sep 17 00:00:00 2001 From: Dean Date: Mon, 23 May 2022 16:12:56 +0100 Subject: [PATCH] Refactored the approach to builder focus. Extending the behaviour beyond form fields --- packages/bbui/src/Form/Core/Combobox.svelte | 15 +- .../bbui/src/Form/Core/Multiselect.svelte | 2 + packages/bbui/src/Form/Core/Picker.svelte | 14 + packages/bbui/src/Form/Core/Select.svelte | 2 + packages/bbui/src/Form/Multiselect.svelte | 2 + packages/bbui/src/Form/Select.svelte | 2 + .../src/builderStore/store/frontend.js | 38 +- .../bindings/DrawerBindableCombobox.svelte | 2 + .../AppPreview/CurrentItemPreview.svelte | 26 +- .../ComponentSettingsSection.svelte | 22 +- .../DataProviderSelect.svelte | 2 + .../PropertyControls/FieldSelect.svelte | 9 +- .../PropertyControls/FormFieldSelect.svelte | 13 +- .../PropertyControls/MultiFieldSelect.svelte | 9 +- .../design/[assetType]/_layout.svelte | 24 +- packages/client/manifest.json | 582 +++++++++++++----- .../src/components/app/BackgroundImage.svelte | 18 +- .../client/src/components/app/Image.svelte | 18 +- .../client/src/components/app/Link.svelte | 31 +- .../src/components/app/MarkdownViewer.svelte | 19 +- .../src/components/app/Placeholder.svelte | 15 +- .../components/app/charts/ApexChart.svelte | 19 +- .../src/components/app/charts/BarChart.svelte | 1 - .../src/components/app/forms/Field.svelte | 57 +- packages/client/src/stores/builder.js | 3 + 25 files changed, 672 insertions(+), 273 deletions(-) diff --git a/packages/bbui/src/Form/Core/Combobox.svelte b/packages/bbui/src/Form/Core/Combobox.svelte index 1c590ea395..183e7486ff 100644 --- a/packages/bbui/src/Form/Core/Combobox.svelte +++ b/packages/bbui/src/Form/Core/Combobox.svelte @@ -3,7 +3,7 @@ import "@spectrum-css/popover/dist/index-vars.css" import "@spectrum-css/menu/dist/index-vars.css" import { fly } from "svelte/transition" - import { createEventDispatcher, getContext } from "svelte" + import { createEventDispatcher } from "svelte" export let value = null export let id = null @@ -21,11 +21,7 @@ let focus = false let comboInput - let builderFocus = getContext("field_focus") - - $: if (autofocus && comboInput) { - comboInput.focus() - } + $: focus = autofocus && comboInput const selectOption = value => { dispatch("change", value) @@ -61,12 +57,7 @@ {id} type="text" on:focus={() => (focus = true)} - on:blur={() => { - if (builderFocus) { - builderFocus.clear() - } - focus = false - }} + on:blur={() => (focus = false)} on:change={onType} value={value || ""} placeholder={placeholder || ""} diff --git a/packages/bbui/src/Form/Core/Multiselect.svelte b/packages/bbui/src/Form/Core/Multiselect.svelte index 3eb1add267..1263b1431a 100644 --- a/packages/bbui/src/Form/Core/Multiselect.svelte +++ b/packages/bbui/src/Form/Core/Multiselect.svelte @@ -13,6 +13,7 @@ export let readonly = false export let autocomplete = false export let sort = false + export let autofocus = false const dispatch = createEventDispatcher() $: selectedLookupMap = getSelectedLookupMap(value) @@ -85,4 +86,5 @@ {getOptionValue} onSelectOption={toggleOption} {sort} + {autofocus} /> diff --git a/packages/bbui/src/Form/Core/Picker.svelte b/packages/bbui/src/Form/Core/Picker.svelte index 2585f11939..e25abb918a 100644 --- a/packages/bbui/src/Form/Core/Picker.svelte +++ b/packages/bbui/src/Form/Core/Picker.svelte @@ -26,9 +26,14 @@ export let autoWidth = false export let autocomplete = false export let sort = false + export let autofocus = false const dispatch = createEventDispatcher() let searchTerm = null + let focus = false + let pickerButton + + $: focus = autofocus && pickerButton $: sortedOptions = getSortedOptions(options, getOptionLabel, sort) $: filteredOptions = getFilteredOptions( @@ -80,7 +85,15 @@ class:is-invalid={!!error} class:is-open={open} aria-haspopup="listbox" + class:is-focused={focus} + bind:this={pickerButton} on:mousedown={onClick} + on:focus={() => { + focus = true + }} + on:blur={() => { + focus = false + }} > {#if fieldIcon} @@ -199,6 +212,7 @@ } .spectrum-Picker { width: 100%; + box-shadow: none; } .spectrum-Picker-label:not(.auto-width) { overflow: hidden; diff --git a/packages/bbui/src/Form/Core/Select.svelte b/packages/bbui/src/Form/Core/Select.svelte index 413b11dd34..e1e726981a 100644 --- a/packages/bbui/src/Form/Core/Select.svelte +++ b/packages/bbui/src/Form/Core/Select.svelte @@ -16,6 +16,7 @@ export let autoWidth = false export let autocomplete = false export let sort = false + export let autofocus = false const dispatch = createEventDispatcher() let open = false @@ -74,6 +75,7 @@ {fieldIcon} {autocomplete} {sort} + {autofocus} 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 957dcccddf..021bb8913e 100644 --- a/packages/bbui/src/Form/Multiselect.svelte +++ b/packages/bbui/src/Form/Multiselect.svelte @@ -14,6 +14,7 @@ export let getOptionLabel = option => option export let getOptionValue = option => option export let sort = false + export let autofocus = false const dispatch = createEventDispatcher() const onChange = e => { @@ -35,5 +36,6 @@ {getOptionValue} on:change={onChange} on:click + {autofocus} /> diff --git a/packages/bbui/src/Form/Select.svelte b/packages/bbui/src/Form/Select.svelte index 0df27e2ff0..ac7da1bb67 100644 --- a/packages/bbui/src/Form/Select.svelte +++ b/packages/bbui/src/Form/Select.svelte @@ -18,6 +18,7 @@ export let autoWidth = false export let sort = false export let tooltip = "" + export let autofocus = false const dispatch = createEventDispatcher() const onChange = e => { @@ -44,6 +45,7 @@ {placeholder} {autoWidth} {sort} + {autofocus} {getOptionLabel} {getOptionValue} {getOptionIcon} diff --git a/packages/builder/src/builderStore/store/frontend.js b/packages/builder/src/builderStore/store/frontend.js index 48e5982eae..3b94a2713e 100644 --- a/packages/builder/src/builderStore/store/frontend.js +++ b/packages/builder/src/builderStore/store/frontend.js @@ -380,21 +380,6 @@ export const getFrontendStore = () => { const selected = get(selectedComponent) const asset = get(currentAsset) - const formComponents = [ - "stringfield", - "optionsfield", - "numberfield", - "datetimefield", - "booleanfield", - "passwordfield", - "longformfield", - "attachmentfield", - "jsonfield", - "relationshipfield", - "multifieldselect", - "s3upload", - ] - // Create new component const componentInstance = store.actions.components.createInstance( componentName, @@ -432,16 +417,7 @@ export const getFrontendStore = () => { } parentComponent._children.push(componentInstance) - let isFormComponent = false - let componentPrefix = "@budibase/standard-components/" - if (parentComponent._component === componentPrefix + "form") { - const mappedComponentTypes = formComponents.map(cmp => { - return componentPrefix + cmp - }) - if (mappedComponentTypes.indexOf(componentInstance._component) > -1) { - isFormComponent = true - } - } + const definition = store.actions.components.getDefinition(componentName) // Save components and update UI await store.actions.preview.saveSelected() @@ -449,13 +425,17 @@ export const getFrontendStore = () => { state.currentView = "component" state.selectedComponentId = componentInstance._id - if (isFormComponent) { - //A field component added to a form. - state.builderFocus = { - key: "field", + const focusSetting = definition.settings.filter((setting) => { return setting.required }) + const mappedSettings = focusSetting.map((setting) => { + return { + key: setting.key, target: state.selectedComponentId, location: "component_settings", } + }) + + if(focusSetting.length){ + state.builderFocus = mappedSettings } return state }) diff --git a/packages/builder/src/components/common/bindings/DrawerBindableCombobox.svelte b/packages/builder/src/components/common/bindings/DrawerBindableCombobox.svelte index 44f88e841a..d95986d583 100644 --- a/packages/builder/src/components/common/bindings/DrawerBindableCombobox.svelte +++ b/packages/builder/src/components/common/bindings/DrawerBindableCombobox.svelte @@ -18,6 +18,7 @@ export let options export let allowJS = true export let appendBindingsAsOptions = true + export let autofocus = false const dispatch = createEventDispatcher() let bindingDrawer @@ -61,6 +62,7 @@ on:pick={e => onChange(e.detail, true)} {placeholder} options={allOptions} + {autofocus} /> {#if !disabled}
{ + if($store.builderFocus){ + const comp = $store.builderFocus.reduce((acc, item)=>{ + acc = item.target + return acc + }, "") + if(data.id !== comp){ + store.update(state => { + delete state.builderFocus + return state + }) + } + } + } + const handleBudibaseEvent = async event => { const { type, data } = event.data || event.detail if (!type) { @@ -157,14 +172,7 @@ try { if (type === "select-component" && data.id) { store.actions.components.select({ _id: data.id }) - //Clear focus - if(data.id !== $store.builderFocus?.target){ - store.update(state => { - delete state.builderFocus - return state - }) - } - //check if the builder-focus matches? + resolveFocus(data) } else if (type === "update-prop") { await store.actions.components.updateProp(data.prop, data.value) } else if (type === "delete-component" && data.id) { @@ -202,7 +210,7 @@ store.update(state => ({ ...state, builderFocus : - { ...data } + [{...data}] })) } else { console.warn(`Client sent unknown event type: ${type}`) diff --git a/packages/builder/src/components/design/PropertiesPanel/ComponentSettingsSection.svelte b/packages/builder/src/components/design/PropertiesPanel/ComponentSettingsSection.svelte index a36ce52379..bc8a0d362f 100644 --- a/packages/builder/src/components/design/PropertiesPanel/ComponentSettingsSection.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/ComponentSettingsSection.svelte @@ -3,29 +3,16 @@ import { Input, DetailSummary, notifications } from "@budibase/bbui" import { store } from "builderStore" import PropertyControl from "./PropertyControls/PropertyControl.svelte" - import LayoutSelect from "./PropertyControls/LayoutSelect.svelte" - import RoleSelect from "./PropertyControls/RoleSelect.svelte" import ResetFieldsButton from "./PropertyControls/ResetFieldsButton.svelte" import { getComponentForSettingType } from "./PropertyControls/componentSettings" import { Utils } from "@budibase/frontend-core" export let componentDefinition export let componentInstance - export let assetInstance export let bindings export let componentBindings - const layoutDefinition = [] - const screenDefinition = [ - { key: "description", label: "Description", control: Input }, - { key: "routing.route", label: "Route", control: Input }, - { key: "routing.roleId", label: "Access", control: RoleSelect }, - { key: "layoutId", label: "Layout", control: LayoutSelect }, - ] - $: sections = getSections(componentDefinition) - $: isLayout = assetInstance && assetInstance.favicon - $: assetDefinition = isLayout ? layoutDefinition : screenDefinition const getSections = definition => { const settings = definition?.settings ?? [] @@ -88,11 +75,10 @@ } const isFocused = setting => { - return ( - componentInstance._id === $store.builderFocus?.target && - setting.key === $store.builderFocus?.key && - "component_settings" === $store.builderFocus?.location - ) + if (!$store.builderFocus) { + return false + } + return setting.required === true } diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/DataProviderSelect.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/DataProviderSelect.svelte index a5b7a08255..b16530bfe6 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/DataProviderSelect.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/DataProviderSelect.svelte @@ -6,6 +6,7 @@ import { createEventDispatcher, onMount } from "svelte" export let value + export let autofocus = false const dispatch = createEventDispatcher() const getValue = component => `{{ literal ${makePropSafe(component._id)} }}` @@ -24,6 +25,7 @@ +