2021-11-02 09:45:27 +01:00
|
|
|
<script>
|
|
|
|
import { getContext, setContext } from "svelte"
|
2022-06-30 20:31:25 +02:00
|
|
|
import { builderStore } from "../stores/builder.js"
|
|
|
|
import { Button } from "@budibase/bbui"
|
2021-11-02 09:45:27 +01:00
|
|
|
|
|
|
|
const component = getContext("component")
|
|
|
|
|
2022-06-30 20:31:25 +02:00
|
|
|
let structureLookupMap = {}
|
|
|
|
const registerBlockComponent = (id, order, parentId, instance) => {
|
|
|
|
// Ensure child array exists
|
|
|
|
if (!structureLookupMap[parentId]) {
|
|
|
|
structureLookupMap[parentId] = []
|
|
|
|
}
|
|
|
|
// Remove existing instance of this component in case props changed
|
|
|
|
structureLookupMap[parentId] = structureLookupMap[parentId].filter(
|
|
|
|
x => x.instance._id !== id
|
|
|
|
)
|
|
|
|
// Add new instance of this component
|
|
|
|
structureLookupMap[parentId].push({ order, instance })
|
|
|
|
}
|
|
|
|
|
|
|
|
const eject = () => {
|
|
|
|
// Start the new structure with the first top level component
|
|
|
|
let definition = structureLookupMap[$component.id][0].instance
|
|
|
|
attachChildren(definition, structureLookupMap)
|
|
|
|
builderStore.actions.ejectBlock($component.id, definition)
|
|
|
|
}
|
|
|
|
|
|
|
|
const attachChildren = (rootComponent, map) => {
|
|
|
|
let id = rootComponent._id
|
|
|
|
if (!map[id]?.length) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sort children by order
|
|
|
|
map[id].sort((a, b) => (a.order < b.order ? -1 : 1))
|
|
|
|
|
|
|
|
// Attach all children of this component
|
|
|
|
rootComponent._children = map[id].map(x => x.instance)
|
|
|
|
|
|
|
|
// Recurse for each child
|
|
|
|
rootComponent._children.forEach(child => {
|
|
|
|
attachChildren(child, map)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
setContext("block", {
|
|
|
|
// We need to set a block context to know we're inside a block, but also
|
|
|
|
// to be able to reference the actual component ID of the block from
|
|
|
|
// any depth
|
|
|
|
id: $component.id,
|
|
|
|
|
|
|
|
// We register block components with their raw props so that we can eject
|
|
|
|
// blocks later on
|
|
|
|
registerComponent: registerBlockComponent,
|
|
|
|
})
|
2021-11-02 09:45:27 +01:00
|
|
|
</script>
|
|
|
|
|
2021-11-03 12:58:06 +01:00
|
|
|
<slot />
|
2022-06-30 20:31:25 +02:00
|
|
|
|
|
|
|
{#if $component.selected}
|
|
|
|
<div>
|
|
|
|
<Button cta on:click={eject}>Eject block</Button>
|
|
|
|
</div>
|
|
|
|
{/if}
|