diff --git a/packages/builder/src/builderStore/previewEvents.js b/packages/builder/src/builderStore/previewEvents.js new file mode 100644 index 0000000000..dfee80391f --- /dev/null +++ b/packages/builder/src/builderStore/previewEvents.js @@ -0,0 +1,13 @@ +let subscribers = [] + +export const onPreviewEvent = cb => { + subscribers.push(cb) + + return () => { + subscribers = subscribers.filter(callback => callback !== cb) + } +} + +export const emitPreviewEvent = event => { + subscribers.forEach(cb => cb(event)) +} diff --git a/packages/builder/src/components/design/settings/controls/FieldConfiguration/EditFieldPopover.svelte b/packages/builder/src/components/design/settings/controls/FieldConfiguration/EditFieldPopover.svelte index 7d2eaae478..29c1d21841 100644 --- a/packages/builder/src/components/design/settings/controls/FieldConfiguration/EditFieldPopover.svelte +++ b/packages/builder/src/components/design/settings/controls/FieldConfiguration/EditFieldPopover.svelte @@ -2,9 +2,10 @@ import { Icon, Popover, Layout } from "@budibase/bbui" import { store } from "builderStore" import { cloneDeep } from "lodash/fp" - import { createEventDispatcher } from "svelte" + import { createEventDispatcher, onDestroy, onMount } from "svelte" import ComponentSettingsSection from "../../../../../pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ComponentSettingsSection.svelte" import { getContext } from "svelte" + import { onPreviewEvent } from "builderStore/previewEvents" export let anchor export let field @@ -61,6 +62,21 @@ dispatch("change", update) } + + const handlePreviewEvent = event => { + const { type, data } = event?.data || {} + if (type === "click-form-block-field") { + if (data.field === field.field) { + popover.show() + open = true + } else { + popover.hide() + open = false + } + } + } + + onMount(() => onPreviewEvent(handlePreviewEvent)) - + diff --git a/packages/client/src/components/Component.svelte b/packages/client/src/components/Component.svelte index 03aab21d38..67fb06261f 100644 --- a/packages/client/src/components/Component.svelte +++ b/packages/client/src/components/Component.svelte @@ -35,6 +35,7 @@ export let isLayout = false export let isRoot = false export let isBlock = false + export let onClick = null // Get parent contexts const context = getContext("context") @@ -131,7 +132,10 @@ // Interactive components can be selected, dragged and highlighted inside // the builder preview $: builderInteractive = - $builderStore.inBuilder && insideScreenslot && !isBlock && !instance.static + $builderStore.inBuilder && + insideScreenslot && + (!isBlock || onClick) && + !instance.static $: devToolsInteractive = $devToolsStore.allowSelection && !isBlock $: interactive = !isRoot && (builderInteractive || devToolsInteractive) $: editing = editable && selected && $builderStore.editMode @@ -194,6 +198,8 @@ interactive, draggable, editable, + isBlock, + onClick, }, empty: emptyState, selected, diff --git a/packages/client/src/components/app/blocks/form/InnerFormBlock.svelte b/packages/client/src/components/app/blocks/form/InnerFormBlock.svelte index 8e6984b182..b8abec874a 100644 --- a/packages/client/src/components/app/blocks/form/InnerFormBlock.svelte +++ b/packages/client/src/components/app/blocks/form/InnerFormBlock.svelte @@ -34,6 +34,7 @@ bb_reference: "bbreferencefield", } const context = getContext("context") + const { builderStore } = getContext("sdk") let formId @@ -223,6 +224,11 @@ type={getComponentForField(field)} props={getPropsForField(field)} order={idx} + interactive + name={field?.field} + onClick={() => { + builderStore.actions.clickFormBlockField(field?.field) + }} /> {/if} {/each} diff --git a/packages/client/src/index.js b/packages/client/src/index.js index 1550ba4d7b..0cf6800560 100644 --- a/packages/client/src/index.js +++ b/packages/client/src/index.js @@ -31,6 +31,8 @@ const loadBudibase = async () => { layout: window["##BUDIBASE_PREVIEW_LAYOUT##"], screen: window["##BUDIBASE_PREVIEW_SCREEN##"], selectedComponentId: window["##BUDIBASE_SELECTED_COMPONENT_ID##"], + selectedBlockComponentId: + window["##BUDIBASE_SELECTED_BLOCK_COMPONENT_ID##"], previewId: window["##BUDIBASE_PREVIEW_ID##"], theme: window["##BUDIBASE_PREVIEW_THEME##"], customTheme: window["##BUDIBASE_PREVIEW_CUSTOM_THEME##"], diff --git a/packages/client/src/stores/builder.js b/packages/client/src/stores/builder.js index 036558e8b2..c1865d608f 100644 --- a/packages/client/src/stores/builder.js +++ b/packages/client/src/stores/builder.js @@ -8,6 +8,7 @@ const createBuilderStore = () => { inBuilder: false, screen: null, selectedComponentId: null, + selectedBlockComponentId: null, editMode: false, previewId: null, theme: null, @@ -35,6 +36,9 @@ const createBuilderStore = () => { devToolsStore.actions.setAllowSelection(false) eventStore.actions.dispatchEvent("select-component", { id }) }, + clickFormBlockField: field => { + eventStore.actions.dispatchEvent("click-form-block-field", { field }) + }, updateProp: (prop, value) => { eventStore.actions.dispatchEvent("update-prop", { prop, value }) }, diff --git a/packages/client/src/utils/styleable.js b/packages/client/src/utils/styleable.js index f48eece89b..31c35c4483 100644 --- a/packages/client/src/utils/styleable.js +++ b/packages/client/src/utils/styleable.js @@ -40,6 +40,7 @@ export const styleable = (node, styles = {}) => { const componentId = newStyles.id const customStyles = newStyles.custom || "" + const { isBlock, onClick } = newStyles const normalStyles = { ...baseStyles, ...newStyles.normal } const hoverStyles = { ...normalStyles, @@ -67,7 +68,11 @@ export const styleable = (node, styles = {}) => { // Handler to select a component in the builder when clicking it in the // builder preview selectComponent = event => { - builderStore.actions.selectComponent(componentId) + if (isBlock && onClick) { + onClick() + } else { + builderStore.actions.selectComponent(componentId, isBlock) + } event.preventDefault() event.stopPropagation() return false @@ -76,6 +81,9 @@ export const styleable = (node, styles = {}) => { // Handler to start editing a component (if applicable) when double // clicking in the builder preview editComponent = event => { + if (isBlock) { + return + } if (newStyles.interactive && newStyles.editable) { builderStore.actions.setEditMode(true) } diff --git a/packages/server/src/api/controllers/static/templates/preview.hbs b/packages/server/src/api/controllers/static/templates/preview.hbs index 31bf0762e0..f28469ca22 100644 --- a/packages/server/src/api/controllers/static/templates/preview.hbs +++ b/packages/server/src/api/controllers/static/templates/preview.hbs @@ -63,6 +63,7 @@ // Extract data from message const { selectedComponentId, + selectedBlockComponentId, layout, screen, appId, @@ -81,6 +82,7 @@ window["##BUDIBASE_PREVIEW_LAYOUT##"] = layout window["##BUDIBASE_PREVIEW_SCREEN##"] = screen window["##BUDIBASE_SELECTED_COMPONENT_ID##"] = selectedComponentId + window["##BUDIBASE_SELECTED_BLOCK_COMPONENT_ID##"] = selectedBlockComponentId window["##BUDIBASE_PREVIEW_ID##"] = Math.random() window["##BUDIBASE_PREVIEW_THEME##"] = theme window["##BUDIBASE_PREVIEW_CUSTOM_THEME##"] = customTheme