mirror of https://github.com/Budibase/budibase.git
7 changed files with 130 additions and 54 deletions
@ -1,12 +1,65 @@ |
|||||
<script> |
<script> |
||||
import { getContext, setContext } from "svelte" |
import { getContext, setContext } from "svelte" |
||||
|
import { builderStore } from "../stores/builder.js" |
||||
|
import { Button } from "@budibase/bbui" |
||||
|
|
||||
const component = getContext("component") |
const component = getContext("component") |
||||
|
|
||||
// We need to set a block context to know we're inside a block, but also |
let structureLookupMap = {} |
||||
// to be able to reference the actual component ID of the block from |
const registerBlockComponent = (id, order, parentId, instance) => { |
||||
// any depth |
// Ensure child array exists |
||||
setContext("block", { id: $component.id }) |
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> |
</script> |
||||
|
|
||||
<slot /> |
<slot /> |
||||
|
|
||||
|
{#if $component.selected} |
||||
|
<div> |
||||
|
<Button cta on:click={eject}>Eject block</Button> |
||||
|
</div> |
||||
|
{/if} |
||||
|
|||||
Loading…
Reference in new issue