mirror of https://github.com/Budibase/budibase.git
7 changed files with 130 additions and 54 deletions
@ -1,12 +1,65 @@ |
|||
<script> |
|||
import { getContext, setContext } from "svelte" |
|||
import { builderStore } from "../stores/builder.js" |
|||
import { Button } from "@budibase/bbui" |
|||
|
|||
const component = getContext("component") |
|||
|
|||
// 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 |
|||
setContext("block", { id: $component.id }) |
|||
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, |
|||
}) |
|||
</script> |
|||
|
|||
<slot /> |
|||
|
|||
{#if $component.selected} |
|||
<div> |
|||
<Button cta on:click={eject}>Eject block</Button> |
|||
</div> |
|||
{/if} |
|||
|
|||
Loading…
Reference in new issue