wip
This commit is contained in:
parent
33f03f91f3
commit
2f90d7f431
|
@ -10,6 +10,7 @@
|
||||||
navigationStore,
|
navigationStore,
|
||||||
selectedScreen,
|
selectedScreen,
|
||||||
hoverStore,
|
hoverStore,
|
||||||
|
componentTreeNodesStore,
|
||||||
} from "stores/builder"
|
} from "stores/builder"
|
||||||
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
||||||
import {
|
import {
|
||||||
|
@ -130,6 +131,13 @@
|
||||||
error = event.error || "An unknown error occurred"
|
error = event.error || "An unknown error occurred"
|
||||||
} else if (type === "select-component" && data.id) {
|
} else if (type === "select-component" && data.id) {
|
||||||
componentStore.select(data.id)
|
componentStore.select(data.id)
|
||||||
|
|
||||||
|
const componentPath = findComponentPath(
|
||||||
|
$selectedScreen?.props,
|
||||||
|
data.id
|
||||||
|
).map(component => component._id)
|
||||||
|
|
||||||
|
componentTreeNodesStore.expandNodes(componentPath)
|
||||||
} else if (type === "hover-component") {
|
} else if (type === "hover-component") {
|
||||||
hoverStore.hover(data.id, false)
|
hoverStore.hover(data.id, false)
|
||||||
} else if (type === "update-prop") {
|
} else if (type === "update-prop") {
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
selectedScreen,
|
selectedScreen,
|
||||||
componentStore,
|
componentStore,
|
||||||
selectedComponent,
|
selectedComponent,
|
||||||
|
componentTreeNodesStore
|
||||||
} from "stores/builder"
|
} from "stores/builder"
|
||||||
import { findComponent } from "helpers/components"
|
import { findComponent } from "helpers/components"
|
||||||
import { goto, isActive } from "@roxi/routify"
|
import { goto, isActive } from "@roxi/routify"
|
||||||
import { notifications } from "@budibase/bbui"
|
import { notifications } from "@budibase/bbui"
|
||||||
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
||||||
import componentTreeNodesStore from "stores/portal/componentTreeNodesStore"
|
|
||||||
|
|
||||||
let confirmDeleteDialog
|
let confirmDeleteDialog
|
||||||
let confirmEjectDialog
|
let confirmEjectDialog
|
||||||
|
@ -66,6 +66,7 @@
|
||||||
componentTreeNodesStore.expandNode(component._id)
|
componentTreeNodesStore.expandNode(component._id)
|
||||||
},
|
},
|
||||||
["ArrowLeft"]: component => {
|
["ArrowLeft"]: component => {
|
||||||
|
componentStore.select(component._id)
|
||||||
componentTreeNodesStore.collapseNode(component._id)
|
componentTreeNodesStore.collapseNode(component._id)
|
||||||
},
|
},
|
||||||
["Ctrl+ArrowRight"]: component => {
|
["Ctrl+ArrowRight"]: component => {
|
||||||
|
@ -83,6 +84,7 @@
|
||||||
expandChildren(component)
|
expandChildren(component)
|
||||||
},
|
},
|
||||||
["Ctrl+ArrowLeft"]: component => {
|
["Ctrl+ArrowLeft"]: component => {
|
||||||
|
componentStore.select(component._id)
|
||||||
componentTreeNodesStore.collapseNode(component._id)
|
componentTreeNodesStore.collapseNode(component._id)
|
||||||
|
|
||||||
const collapseChildren = component => {
|
const collapseChildren = component => {
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
componentStore,
|
componentStore,
|
||||||
userSelectedResourceMap,
|
userSelectedResourceMap,
|
||||||
selectedComponent,
|
selectedComponent,
|
||||||
selectedComponentPath,
|
|
||||||
hoverStore,
|
hoverStore,
|
||||||
|
componentTreeNodesStore
|
||||||
} from "stores/builder"
|
} from "stores/builder"
|
||||||
import {
|
import {
|
||||||
findComponentPath,
|
findComponentPath,
|
||||||
|
@ -17,7 +17,6 @@
|
||||||
} from "helpers/components"
|
} from "helpers/components"
|
||||||
import { get } from "svelte/store"
|
import { get } from "svelte/store"
|
||||||
import { dndStore } from "./dndStore"
|
import { dndStore } from "./dndStore"
|
||||||
import componentTreeNodesStore from "stores/portal/componentTreeNodesStore"
|
|
||||||
|
|
||||||
export let components = []
|
export let components = []
|
||||||
export let level = 0
|
export let level = 0
|
||||||
|
@ -64,14 +63,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const isOpen = (component, selectedComponentPath, openNodes) => {
|
const isOpen = (component, openNodes) => {
|
||||||
if (!component?._children?.length) {
|
if (!component?._children?.length) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (selectedComponentPath.slice(0, -1).includes(component._id)) {
|
return openNodes[`nodeOpen-${component._id}`] !== false
|
||||||
return true
|
|
||||||
}
|
|
||||||
return openNodes[`nodeOpen-${component._id}`]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const isChildOfSelectedComponent = component => {
|
const isChildOfSelectedComponent = component => {
|
||||||
|
@ -90,7 +86,7 @@
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<ul>
|
<ul>
|
||||||
{#each filteredComponents || [] as component, index (component._id)}
|
{#each filteredComponents || [] as component, index (component._id)}
|
||||||
{@const opened = isOpen(component, $selectedComponentPath, openNodes)}
|
{@const opened = isOpen(component, openNodes)}
|
||||||
<li
|
<li
|
||||||
on:click|stopPropagation={() => {
|
on:click|stopPropagation={() => {
|
||||||
componentStore.select(component._id)
|
componentStore.select(component._id)
|
||||||
|
|
|
@ -18,6 +18,14 @@ const expandNode = componentId => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const expandNodes = componentIds => {
|
||||||
|
baseStore.update(openNodes => {
|
||||||
|
const newNodes = Object.fromEntries(componentIds.map(id => ([`nodeOpen-${id}`, true])))
|
||||||
|
|
||||||
|
return { ...openNodes, ...newNodes };
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const collapseNode = componentId => {
|
const collapseNode = componentId => {
|
||||||
baseStore.update(openNodes => {
|
baseStore.update(openNodes => {
|
||||||
openNodes[`nodeOpen-${componentId}`] = false
|
openNodes[`nodeOpen-${componentId}`] = false
|
||||||
|
@ -30,6 +38,7 @@ const store = {
|
||||||
subscribe: baseStore.subscribe,
|
subscribe: baseStore.subscribe,
|
||||||
toggleNode,
|
toggleNode,
|
||||||
expandNode,
|
expandNode,
|
||||||
|
expandNodes,
|
||||||
collapseNode,
|
collapseNode,
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import {
|
||||||
appStore,
|
appStore,
|
||||||
previewStore,
|
previewStore,
|
||||||
tables,
|
tables,
|
||||||
|
componentTreeNodesStore
|
||||||
} from "stores/builder/index"
|
} from "stores/builder/index"
|
||||||
import { buildFormSchema, getSchemaForDatasource } from "dataBinding"
|
import { buildFormSchema, getSchemaForDatasource } from "dataBinding"
|
||||||
import {
|
import {
|
||||||
|
@ -29,7 +30,6 @@ import {
|
||||||
} from "constants/backend"
|
} from "constants/backend"
|
||||||
import BudiStore from "./BudiStore"
|
import BudiStore from "./BudiStore"
|
||||||
import { Utils } from "@budibase/frontend-core"
|
import { Utils } from "@budibase/frontend-core"
|
||||||
import componentTreeNodesStore from "stores/portal/componentTreeNodesStore"
|
|
||||||
|
|
||||||
export const INITIAL_COMPONENTS_STATE = {
|
export const INITIAL_COMPONENTS_STATE = {
|
||||||
components: {},
|
components: {},
|
||||||
|
@ -653,6 +653,16 @@ export class ComponentStore extends BudiStore {
|
||||||
this.update(state => {
|
this.update(state => {
|
||||||
state.selectedScreenId = targetScreenId
|
state.selectedScreenId = targetScreenId
|
||||||
state.selectedComponentId = newComponentId
|
state.selectedComponentId = newComponentId
|
||||||
|
|
||||||
|
const targetScreen = get(screenStore).screens.find(screen => screen.id === targetScreenId)
|
||||||
|
|
||||||
|
const componentPathIds = findComponentPath(
|
||||||
|
targetScreen?.props,
|
||||||
|
newComponentId
|
||||||
|
).map(component => component._id)
|
||||||
|
|
||||||
|
componentTreeNodesStore.expandNodes(componentPathIds)
|
||||||
|
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -680,16 +690,16 @@ export class ComponentStore extends BudiStore {
|
||||||
|
|
||||||
// If we have siblings above us, choose the sibling or a descendant
|
// If we have siblings above us, choose the sibling or a descendant
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
// If sibling before us accepts children, select a descendant
|
// If sibling before us accepts children, and is not collapsed, select a descendant
|
||||||
const previousSibling = parent._children[index - 1]
|
const previousSibling = parent._children[index - 1]
|
||||||
if (
|
if (
|
||||||
previousSibling._children?.length &&
|
previousSibling._children?.length &&
|
||||||
componentTreeNodes[`nodeOpen-${previousSibling._id}`]
|
componentTreeNodes[`nodeOpen-${previousSibling._id}`] !== false
|
||||||
) {
|
) {
|
||||||
let target = previousSibling
|
let target = previousSibling
|
||||||
while (
|
while (
|
||||||
target._children?.length &&
|
target._children?.length &&
|
||||||
componentTreeNodes[`nodeOpen-${target._id}`]
|
componentTreeNodes[`nodeOpen-${target._id}`] !== false
|
||||||
) {
|
) {
|
||||||
target = target._children[target._children.length - 1]
|
target = target._children[target._children.length - 1]
|
||||||
}
|
}
|
||||||
|
@ -720,11 +730,11 @@ export class ComponentStore extends BudiStore {
|
||||||
return navComponentId
|
return navComponentId
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have children, select first child
|
// If we have children, select first child, and the node is not collapsed
|
||||||
if (
|
if (
|
||||||
component._children?.length &&
|
component._children?.length &&
|
||||||
(state.selectedComponentId === navComponentId ||
|
(state.selectedComponentId === navComponentId ||
|
||||||
componentTreeNodes[`nodeOpen-${component._id}`])
|
componentTreeNodes[`nodeOpen-${component._id}`] !== false)
|
||||||
) {
|
) {
|
||||||
return component._children[0]._id
|
return component._children[0]._id
|
||||||
} else if (!parent) {
|
} else if (!parent) {
|
||||||
|
@ -784,6 +794,7 @@ export class ComponentStore extends BudiStore {
|
||||||
await screenStore.patch(screen => {
|
await screenStore.patch(screen => {
|
||||||
const componentId = component?._id
|
const componentId = component?._id
|
||||||
const parent = findComponentParent(screen.props, componentId)
|
const parent = findComponentParent(screen.props, componentId)
|
||||||
|
const componentTreeNodes = get(componentTreeNodesStore)
|
||||||
|
|
||||||
// Check we aren't right at the top of the tree
|
// Check we aren't right at the top of the tree
|
||||||
const index = parent?._children.findIndex(x => x._id === componentId)
|
const index = parent?._children.findIndex(x => x._id === componentId)
|
||||||
|
@ -803,7 +814,7 @@ export class ComponentStore extends BudiStore {
|
||||||
// sibling
|
// sibling
|
||||||
const previousSibling = parent._children[index - 1]
|
const previousSibling = parent._children[index - 1]
|
||||||
const definition = this.getDefinition(previousSibling._component)
|
const definition = this.getDefinition(previousSibling._component)
|
||||||
if (definition.hasChildren) {
|
if (definition.hasChildren && componentTreeNodes[`nodeOpen-${previousSibling._id}`] !== false) {
|
||||||
previousSibling._children.push(originalComponent)
|
previousSibling._children.push(originalComponent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -829,6 +840,8 @@ export class ComponentStore extends BudiStore {
|
||||||
await screenStore.patch(screen => {
|
await screenStore.patch(screen => {
|
||||||
const componentId = component?._id
|
const componentId = component?._id
|
||||||
const parent = findComponentParent(screen.props, componentId)
|
const parent = findComponentParent(screen.props, componentId)
|
||||||
|
const componentTreeNodes = get(componentTreeNodesStore)
|
||||||
|
|
||||||
|
|
||||||
// Sanity check parent is found
|
// Sanity check parent is found
|
||||||
if (!parent?._children?.length) {
|
if (!parent?._children?.length) {
|
||||||
|
@ -852,10 +865,10 @@ export class ComponentStore extends BudiStore {
|
||||||
|
|
||||||
// Move below the next sibling if we are not the last sibling
|
// Move below the next sibling if we are not the last sibling
|
||||||
if (index < parent._children.length) {
|
if (index < parent._children.length) {
|
||||||
// If the next sibling has children, become the first child
|
// If the next sibling has children, and is not collapsed, become the first child
|
||||||
const nextSibling = parent._children[index]
|
const nextSibling = parent._children[index]
|
||||||
const definition = this.getDefinition(nextSibling._component)
|
const definition = this.getDefinition(nextSibling._component)
|
||||||
if (definition.hasChildren) {
|
if (definition.hasChildren && componentTreeNodes[`nodeOpen-${nextSibling._id}`] !== false) {
|
||||||
nextSibling._children.splice(0, 0, originalComponent)
|
nextSibling._children.splice(0, 0, originalComponent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1151,13 +1164,3 @@ export const selectedComponent = derived(
|
||||||
return clone
|
return clone
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
export const selectedComponentPath = derived(
|
|
||||||
[componentStore, selectedScreen],
|
|
||||||
([$store, $selectedScreen]) => {
|
|
||||||
return findComponentPath(
|
|
||||||
$selectedScreen?.props,
|
|
||||||
$store.selectedComponentId
|
|
||||||
).map(component => component._id)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { appStore } from "./app.js"
|
||||||
import {
|
import {
|
||||||
componentStore,
|
componentStore,
|
||||||
selectedComponent,
|
selectedComponent,
|
||||||
selectedComponentPath,
|
|
||||||
} from "./components"
|
} from "./components"
|
||||||
import { navigationStore } from "./navigation.js"
|
import { navigationStore } from "./navigation.js"
|
||||||
import { themeStore } from "./theme.js"
|
import { themeStore } from "./theme.js"
|
||||||
|
@ -30,8 +29,10 @@ import { integrations } from "./integrations"
|
||||||
import { sortedIntegrations } from "./sortedIntegrations"
|
import { sortedIntegrations } from "./sortedIntegrations"
|
||||||
import { queries } from "./queries"
|
import { queries } from "./queries"
|
||||||
import { flags } from "./flags"
|
import { flags } from "./flags"
|
||||||
|
import componentTreeNodesStore from './componentTreeNodes';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
componentTreeNodesStore,
|
||||||
layoutStore,
|
layoutStore,
|
||||||
appStore,
|
appStore,
|
||||||
componentStore,
|
componentStore,
|
||||||
|
@ -50,7 +51,6 @@ export {
|
||||||
isOnlyUser,
|
isOnlyUser,
|
||||||
deploymentStore,
|
deploymentStore,
|
||||||
selectedComponent,
|
selectedComponent,
|
||||||
selectedComponentPath,
|
|
||||||
tables,
|
tables,
|
||||||
views,
|
views,
|
||||||
viewsV2,
|
viewsV2,
|
||||||
|
|
Loading…
Reference in New Issue