diff --git a/packages/builder/src/builderStore/store/frontend.js b/packages/builder/src/builderStore/store/frontend.js index ec810e5c31..333e74bd60 100644 --- a/packages/builder/src/builderStore/store/frontend.js +++ b/packages/builder/src/builderStore/store/frontend.js @@ -575,6 +575,14 @@ export const getFrontendStore = () => { }) await store.actions.preview.saveSelected() }, + ejectBlock: async (id, definition) => { + const asset = get(currentAsset) + let parent = findComponentParent(asset.props, id) + const childIndex = parent._children.findIndex(x => x._id === id) + parent._children[childIndex] = definition + await store.actions.preview.saveSelected() + await store.actions.components.select(definition) + }, }, links: { save: async (url, title) => { diff --git a/packages/builder/src/components/design/AppPreview/CurrentItemPreview.svelte b/packages/builder/src/components/design/AppPreview/CurrentItemPreview.svelte index 706550cca7..1b5bbb1dbc 100644 --- a/packages/builder/src/components/design/AppPreview/CurrentItemPreview.svelte +++ b/packages/builder/src/components/design/AppPreview/CurrentItemPreview.svelte @@ -202,6 +202,9 @@ block: "center", }) } + } else if (type === "eject-block") { + const { id, definition } = data + await store.actions.components.ejectBlock(id, definition) } else { console.warn(`Client sent unknown event type: ${type}`) } diff --git a/packages/builder/src/components/design/NavigationPanel/ComponentNavigationTree/ComponentDropdownMenu.svelte b/packages/builder/src/components/design/NavigationPanel/ComponentNavigationTree/ComponentDropdownMenu.svelte index ae031e14bd..43306d309d 100644 --- a/packages/builder/src/components/design/NavigationPanel/ComponentNavigationTree/ComponentDropdownMenu.svelte +++ b/packages/builder/src/components/design/NavigationPanel/ComponentNavigationTree/ComponentDropdownMenu.svelte @@ -12,6 +12,7 @@ $: definition = store.actions.components.getDefinition(component?._component) $: noChildrenAllowed = !component || !definition?.hasChildren $: noPaste = !$store.componentToPaste + $: isBlock = definition?.block === true // "editable" has been repurposed for inline text editing. // It remains here for legacy compatibility. @@ -83,6 +84,8 @@ notifications.error("Error saving component") } } + + const ejectBlock = () => {} {#if showMenu} @@ -93,6 +96,9 @@ Delete + {#if isBlock} + Eject block + {/if} Move up diff --git a/packages/client/src/components/Block.svelte b/packages/client/src/components/Block.svelte index b5e610c1bb..5605ebb711 100644 --- a/packages/client/src/components/Block.svelte +++ b/packages/client/src/components/Block.svelte @@ -1,12 +1,65 @@ + +{#if $component.selected} +
+ +
+{/if} diff --git a/packages/client/src/components/BlockComponent.svelte b/packages/client/src/components/BlockComponent.svelte index c23f18f55c..75ad7b57fe 100644 --- a/packages/client/src/components/BlockComponent.svelte +++ b/packages/client/src/components/BlockComponent.svelte @@ -7,11 +7,13 @@ export let props export let styles export let context + export let order = 0 // ID is only exposed as a prop so that it can be bound to from parent // block components export let id + const component = getContext("component") const block = getContext("block") const rand = generate() @@ -21,6 +23,7 @@ $: instance = { _component: `@budibase/standard-components/${type}`, _id: id, + _instanceName: type, _styles: { normal: { ...styles, @@ -28,6 +31,7 @@ }, ...props, } + $: block.registerComponent(id, order, $component?.id, instance) diff --git a/packages/client/src/components/app/blocks/TableBlock.svelte b/packages/client/src/components/app/blocks/TableBlock.svelte index 4f5e0e1114..151d2bcadb 100644 --- a/packages/client/src/components/app/blocks/TableBlock.svelte +++ b/packages/client/src/components/app/blocks/TableBlock.svelte @@ -112,28 +112,52 @@ props={{ dataSource, disableValidation: true }} > {#if title || enrichedSearchColumns?.length || showTitleButton} -
-
- {title || ""} -
-
+ + + {#if enrichedSearchColumns?.length} - + {#each enrichedSearchColumns as column, idx} + + {/each} {/if} {#if showTitleButton} {/if} -
-
+ + {/if} - .header { - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - gap: 20px; - margin-bottom: 20px; - } - - .title { - overflow: hidden; - } - .title :global(.spectrum-Heading) { - flex: 1 1 auto; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - - .controls { - flex: 0 1 auto; - display: flex; - flex-direction: row; - justify-content: flex-end; - align-items: center; - gap: 20px; - } .controls :global(.spectrum-InputGroup .spectrum-InputGroup-input) { width: 100%; } diff --git a/packages/client/src/stores/builder.js b/packages/client/src/stores/builder.js index f641bb56e6..4311c8e272 100644 --- a/packages/client/src/stores/builder.js +++ b/packages/client/src/stores/builder.js @@ -71,6 +71,9 @@ const createBuilderStore = () => { highlightSetting: setting => { dispatchEvent("highlight-setting", { setting }) }, + ejectBlock: (id, definition) => { + dispatchEvent("eject-block", { id, definition }) + }, } return { ...store,