Ensure allowed component list is actually accurate and prevent any way around illegal component nesting
This commit is contained in:
parent
fb84674e24
commit
1f1a48b666
|
@ -236,12 +236,12 @@ export const getFrontendStore = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the entire tree and throw and error if an illegal child is
|
// Validate the entire tree and throw an error if an illegal child is
|
||||||
// found anywhere
|
// found anywhere
|
||||||
const illegalChild = findIllegalChild(screen.props)
|
const illegalChild = findIllegalChild(screen.props)
|
||||||
if (illegalChild) {
|
if (illegalChild) {
|
||||||
const def = store.actions.components.getDefinition(illegalChild)
|
const def = store.actions.components.getDefinition(illegalChild)
|
||||||
throw `A ${def.name} can't be inserted here`
|
throw `You can't place a ${def.name} here`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
save: async screen => {
|
save: async screen => {
|
||||||
|
|
|
@ -11,9 +11,10 @@
|
||||||
notifications,
|
notifications,
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import structure from "./componentStructure.json"
|
import structure from "./componentStructure.json"
|
||||||
import { store, selectedComponent } from "builderStore"
|
import { store, selectedComponent, selectedScreen } from "builderStore"
|
||||||
import { onMount } from "svelte"
|
import { onMount } from "svelte"
|
||||||
import { fly } from "svelte/transition"
|
import { fly } from "svelte/transition"
|
||||||
|
import { findComponentPath } from "builderStore/componentUtils"
|
||||||
|
|
||||||
let section = "components"
|
let section = "components"
|
||||||
let searchString
|
let searchString
|
||||||
|
@ -21,8 +22,10 @@
|
||||||
let selectedIndex
|
let selectedIndex
|
||||||
let componentList = []
|
let componentList = []
|
||||||
|
|
||||||
$: currentDefinition = store.actions.components.getDefinition(
|
$: allowedComponents = getAllowedComponents(
|
||||||
$selectedComponent?._component
|
$store.components,
|
||||||
|
$selectedScreen,
|
||||||
|
$selectedComponent
|
||||||
)
|
)
|
||||||
$: enrichedStructure = enrichStructure(
|
$: enrichedStructure = enrichStructure(
|
||||||
structure,
|
structure,
|
||||||
|
@ -31,13 +34,50 @@
|
||||||
)
|
)
|
||||||
$: filteredStructure = filterStructure(
|
$: filteredStructure = filterStructure(
|
||||||
enrichedStructure,
|
enrichedStructure,
|
||||||
section,
|
allowedComponents,
|
||||||
currentDefinition,
|
|
||||||
searchString
|
searchString
|
||||||
)
|
)
|
||||||
$: blocks = enrichedStructure.find(x => x.name === "Blocks").children
|
$: blocks = enrichedStructure.find(x => x.name === "Blocks").children
|
||||||
$: orderMap = createComponentOrderMap(componentList)
|
$: orderMap = createComponentOrderMap(componentList)
|
||||||
|
|
||||||
|
const getAllowedComponents = (allComponents, screen, component) => {
|
||||||
|
const path = findComponentPath(screen?.props, component?._id)
|
||||||
|
if (!path?.length) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get initial set of allowed components
|
||||||
|
let allowedComponents = []
|
||||||
|
const definition = store.actions.components.getDefinition(
|
||||||
|
component?._component
|
||||||
|
)
|
||||||
|
if (definition.legalDirectChildren?.length) {
|
||||||
|
allowedComponents = definition.legalDirectChildren.map(x => {
|
||||||
|
return `@budibase/standard-components/${x}`
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
allowedComponents = Object.keys(allComponents)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build up list of illegal children from ancestors
|
||||||
|
let illegalChildren = definition.illegalChildren || []
|
||||||
|
path.forEach(ancestor => {
|
||||||
|
const def = store.actions.components.getDefinition(ancestor._component)
|
||||||
|
const blacklist = def?.illegalChildren?.map(x => {
|
||||||
|
return `@budibase/standard-components/${x}`
|
||||||
|
})
|
||||||
|
illegalChildren = [...illegalChildren, ...(blacklist || [])]
|
||||||
|
})
|
||||||
|
illegalChildren = [...new Set(illegalChildren)]
|
||||||
|
|
||||||
|
// Filter out illegal children from allowed components
|
||||||
|
allowedComponents = allowedComponents.filter(x => {
|
||||||
|
return !illegalChildren.includes(x)
|
||||||
|
})
|
||||||
|
|
||||||
|
return allowedComponents
|
||||||
|
}
|
||||||
|
|
||||||
// Creates a simple lookup map from an array, so we can find the selected
|
// Creates a simple lookup map from an array, so we can find the selected
|
||||||
// component much faster
|
// component much faster
|
||||||
const createComponentOrderMap = list => {
|
const createComponentOrderMap = list => {
|
||||||
|
@ -90,7 +130,7 @@
|
||||||
return enrichedStructure
|
return enrichedStructure
|
||||||
}
|
}
|
||||||
|
|
||||||
const filterStructure = (structure, section, currentDefinition, search) => {
|
const filterStructure = (structure, allowedComponents, search) => {
|
||||||
selectedIndex = search ? 0 : null
|
selectedIndex = search ? 0 : null
|
||||||
componentList = []
|
componentList = []
|
||||||
if (!structure?.length) {
|
if (!structure?.length) {
|
||||||
|
@ -114,7 +154,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the component is allowed as a child
|
// Check if the component is allowed as a child
|
||||||
return !currentDefinition?.illegalChildren?.includes(name)
|
return allowedComponents.includes(child.component)
|
||||||
})
|
})
|
||||||
if (matchedChildren.length) {
|
if (matchedChildren.length) {
|
||||||
filteredStructure.push({
|
filteredStructure.push({
|
||||||
|
|
Loading…
Reference in New Issue