Invert some client store dependencies to improve performance and prevent dependency cycles
This commit is contained in:
parent
4e94b6633f
commit
2ffb29dddf
|
@ -85,6 +85,10 @@
|
||||||
"icon": "Selection",
|
"icon": "Selection",
|
||||||
"hasChildren": true,
|
"hasChildren": true,
|
||||||
"showSettingsBar": true,
|
"showSettingsBar": true,
|
||||||
|
"size": {
|
||||||
|
"width": 400,
|
||||||
|
"height": 200
|
||||||
|
},
|
||||||
"styles": [
|
"styles": [
|
||||||
"padding",
|
"padding",
|
||||||
"size",
|
"size",
|
||||||
|
|
|
@ -21,14 +21,14 @@
|
||||||
devToolsStore,
|
devToolsStore,
|
||||||
componentStore,
|
componentStore,
|
||||||
appStore,
|
appStore,
|
||||||
isDragging,
|
dndIsDragging,
|
||||||
|
dndComponentPath,
|
||||||
} from "stores"
|
} from "stores"
|
||||||
import { Helpers } from "@budibase/bbui"
|
import { Helpers } from "@budibase/bbui"
|
||||||
import { getActiveConditions, reduceConditionActions } from "utils/conditions"
|
import { getActiveConditions, reduceConditionActions } from "utils/conditions"
|
||||||
import Placeholder from "components/app/Placeholder.svelte"
|
import Placeholder from "components/app/Placeholder.svelte"
|
||||||
import ScreenPlaceholder from "components/app/ScreenPlaceholder.svelte"
|
import ScreenPlaceholder from "components/app/ScreenPlaceholder.svelte"
|
||||||
import ComponentPlaceholder from "components/app/ComponentPlaceholder.svelte"
|
import ComponentPlaceholder from "components/app/ComponentPlaceholder.svelte"
|
||||||
import { DNDPlaceholderID } from "constants"
|
|
||||||
|
|
||||||
export let instance = {}
|
export let instance = {}
|
||||||
export let isLayout = false
|
export let isLayout = false
|
||||||
|
@ -105,7 +105,7 @@
|
||||||
$builderStore.inBuilder && $builderStore.selectedComponentId === id
|
$builderStore.inBuilder && $builderStore.selectedComponentId === id
|
||||||
$: inSelectedPath = $componentStore.selectedComponentPath?.includes(id)
|
$: inSelectedPath = $componentStore.selectedComponentPath?.includes(id)
|
||||||
$: inDragPath = inSelectedPath && $builderStore.editMode
|
$: inDragPath = inSelectedPath && $builderStore.editMode
|
||||||
$: inDndPath = $componentStore.dndPath?.includes(id)
|
$: inDndPath = $dndComponentPath?.includes(id)
|
||||||
|
|
||||||
// Derive definition properties which can all be optional, so need to be
|
// Derive definition properties which can all be optional, so need to be
|
||||||
// coerced to booleans
|
// coerced to booleans
|
||||||
|
@ -162,7 +162,7 @@
|
||||||
// nested layers. Only reset this when dragging stops.
|
// nested layers. Only reset this when dragging stops.
|
||||||
let pad = false
|
let pad = false
|
||||||
$: pad = pad || (interactive && hasChildren && inDndPath)
|
$: pad = pad || (interactive && hasChildren && inDndPath)
|
||||||
$: $isDragging, (pad = false)
|
$: $dndIsDragging, (pad = false)
|
||||||
|
|
||||||
// Update component context
|
// Update component context
|
||||||
$: store.set({
|
$: store.set({
|
||||||
|
@ -471,7 +471,6 @@
|
||||||
class:pad
|
class:pad
|
||||||
class:parent={hasChildren}
|
class:parent={hasChildren}
|
||||||
class:block={isBlock}
|
class:block={isBlock}
|
||||||
class:placeholder={id === DNDPlaceholderID}
|
|
||||||
data-id={id}
|
data-id={id}
|
||||||
data-name={name}
|
data-name={name}
|
||||||
data-icon={icon}
|
data-icon={icon}
|
||||||
|
@ -502,7 +501,7 @@
|
||||||
display: contents;
|
display: contents;
|
||||||
}
|
}
|
||||||
.component :global(> *) {
|
.component :global(> *) {
|
||||||
transition: padding 260ms ease-in, border 260ms ease-in;
|
transition: padding 260ms ease-out, border 260ms ease-out;
|
||||||
}
|
}
|
||||||
.component.pad :global(> *) {
|
.component.pad :global(> *) {
|
||||||
padding: 12px !important;
|
padding: 12px !important;
|
||||||
|
|
|
@ -4,14 +4,15 @@
|
||||||
import IndicatorSet from "./IndicatorSet.svelte"
|
import IndicatorSet from "./IndicatorSet.svelte"
|
||||||
import {
|
import {
|
||||||
builderStore,
|
builderStore,
|
||||||
componentStore,
|
screenStore,
|
||||||
dndStore,
|
dndStore,
|
||||||
dndParent,
|
dndParent,
|
||||||
isDragging,
|
dndIsDragging,
|
||||||
} from "stores"
|
} from "stores"
|
||||||
import DNDPlaceholderOverlay from "./DNDPlaceholderOverlay.svelte"
|
import DNDPlaceholderOverlay from "./DNDPlaceholderOverlay.svelte"
|
||||||
import { Utils } from "@budibase/frontend-core"
|
import { Utils } from "@budibase/frontend-core"
|
||||||
import { findComponentById } from "utils/components.js"
|
import { findComponentById } from "utils/components.js"
|
||||||
|
import { DNDPlaceholderID } from "constants"
|
||||||
|
|
||||||
const ThrottleRate = 130
|
const ThrottleRate = 130
|
||||||
|
|
||||||
|
@ -69,13 +70,13 @@
|
||||||
const id = component.dataset.id
|
const id = component.dataset.id
|
||||||
const parentId = component.dataset.parent
|
const parentId = component.dataset.parent
|
||||||
const parent = findComponentById(
|
const parent = findComponentById(
|
||||||
get(componentStore).currentAsset.props,
|
get(screenStore).activeScreen?.props,
|
||||||
parentId
|
parentId
|
||||||
)
|
)
|
||||||
const index = parent._children.findIndex(
|
const index = parent._children.findIndex(
|
||||||
x => x._id === component.dataset.id
|
x => x._id === component.dataset.id
|
||||||
)
|
)
|
||||||
dndStore.actions.startDragging({
|
dndStore.actions.startDraggingExistingComponent({
|
||||||
id,
|
id,
|
||||||
bounds: component.children[0].getBoundingClientRect(),
|
bounds: component.children[0].getBoundingClientRect(),
|
||||||
parent: parentId,
|
parent: parentId,
|
||||||
|
@ -127,7 +128,7 @@
|
||||||
let ephemeralDiv
|
let ephemeralDiv
|
||||||
if (node.children.length === 1) {
|
if (node.children.length === 1) {
|
||||||
ephemeralDiv = document.createElement("div")
|
ephemeralDiv = document.createElement("div")
|
||||||
ephemeralDiv.classList.add("placeholder")
|
ephemeralDiv.dataset.id = DNDPlaceholderID
|
||||||
node.appendChild(ephemeralDiv)
|
node.appendChild(ephemeralDiv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +139,7 @@
|
||||||
const child = node.children?.[0] || node
|
const child = node.children?.[0] || node
|
||||||
const bounds = child.getBoundingClientRect()
|
const bounds = child.getBoundingClientRect()
|
||||||
return {
|
return {
|
||||||
placeholder: node.classList.contains("placeholder"),
|
placeholder: node.dataset.id === DNDPlaceholderID,
|
||||||
centerX: bounds.left + bounds.width / 2,
|
centerX: bounds.left + bounds.width / 2,
|
||||||
centerY: bounds.top + bounds.height / 2,
|
centerY: bounds.top + bounds.height / 2,
|
||||||
left: bounds.left,
|
left: bounds.left,
|
||||||
|
@ -249,7 +250,7 @@
|
||||||
// Convert parent + index into target + mode
|
// Convert parent + index into target + mode
|
||||||
let legacyDropTarget, legacyDropMode
|
let legacyDropTarget, legacyDropMode
|
||||||
const parent = findComponentById(
|
const parent = findComponentById(
|
||||||
get(componentStore).currentAsset?.props,
|
get(screenStore).activeScreen?.props,
|
||||||
drop.parent
|
drop.parent
|
||||||
)
|
)
|
||||||
if (!parent) {
|
if (!parent) {
|
||||||
|
@ -263,7 +264,7 @@
|
||||||
|
|
||||||
// Filter out source component and placeholder from consideration
|
// Filter out source component and placeholder from consideration
|
||||||
const children = parent._children?.filter(
|
const children = parent._children?.filter(
|
||||||
x => x._id !== "placeholder" && x._id !== source.id
|
x => x._id !== DNDPlaceholderID && x._id !== source.id
|
||||||
)
|
)
|
||||||
|
|
||||||
// Use inside if no existing children
|
// Use inside if no existing children
|
||||||
|
@ -316,6 +317,6 @@
|
||||||
prefix="Inside"
|
prefix="Inside"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{#if $isDragging}
|
{#if $dndIsDragging}
|
||||||
<DNDPlaceholderOverlay />
|
<DNDPlaceholderOverlay />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { onMount, onDestroy } from "svelte"
|
import { onMount, onDestroy } from "svelte"
|
||||||
import IndicatorSet from "./IndicatorSet.svelte"
|
import IndicatorSet from "./IndicatorSet.svelte"
|
||||||
import { builderStore, isDragging } from "stores"
|
import { builderStore, dndIsDragging } from "stores"
|
||||||
|
|
||||||
let componentId
|
let componentId
|
||||||
$: zIndex = componentId === $builderStore.selectedComponentId ? 900 : 920
|
$: zIndex = componentId === $builderStore.selectedComponentId ? 900 : 920
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<IndicatorSet
|
<IndicatorSet
|
||||||
componentId={$isDragging ? null : componentId}
|
componentId={$dndIsDragging ? null : componentId}
|
||||||
color="var(--spectrum-global-color-static-blue-200)"
|
color="var(--spectrum-global-color-static-blue-200)"
|
||||||
transition
|
transition
|
||||||
{zIndex}
|
{zIndex}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { builderStore, isDragging } from "stores"
|
import { builderStore, dndIsDragging } from "stores"
|
||||||
import IndicatorSet from "./IndicatorSet.svelte"
|
import IndicatorSet from "./IndicatorSet.svelte"
|
||||||
|
|
||||||
$: color = $builderStore.editMode
|
$: color = $builderStore.editMode
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<IndicatorSet
|
<IndicatorSet
|
||||||
componentId={$isDragging ? null : $builderStore.selectedComponentId}
|
componentId={$dndIsDragging ? null : $builderStore.selectedComponentId}
|
||||||
{color}
|
{color}
|
||||||
zIndex="910"
|
zIndex="910"
|
||||||
transition
|
transition
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
import SettingsButton from "./SettingsButton.svelte"
|
import SettingsButton from "./SettingsButton.svelte"
|
||||||
import SettingsColorPicker from "./SettingsColorPicker.svelte"
|
import SettingsColorPicker from "./SettingsColorPicker.svelte"
|
||||||
import SettingsPicker from "./SettingsPicker.svelte"
|
import SettingsPicker from "./SettingsPicker.svelte"
|
||||||
import { builderStore, componentStore, isDragging } from "stores"
|
import { builderStore, componentStore, dndIsDragging } from "stores"
|
||||||
import { domDebounce } from "utils/domDebounce"
|
import { domDebounce } from "utils/domDebounce"
|
||||||
|
|
||||||
const verticalOffset = 36
|
const verticalOffset = 36
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
let measured = false
|
let measured = false
|
||||||
|
|
||||||
$: definition = $componentStore.selectedComponentDefinition
|
$: definition = $componentStore.selectedComponentDefinition
|
||||||
$: showBar = definition?.showSettingsBar && !$isDragging
|
$: showBar = definition?.showSettingsBar && !$dndIsDragging
|
||||||
$: settings = getBarSettings(definition)
|
$: settings = getBarSettings(definition)
|
||||||
|
|
||||||
const getBarSettings = definition => {
|
const getBarSettings = definition => {
|
||||||
|
|
|
@ -64,20 +64,11 @@ const loadBudibase = async () => {
|
||||||
} else if (name === "dragging-new-component") {
|
} else if (name === "dragging-new-component") {
|
||||||
const { dragging, component } = payload
|
const { dragging, component } = payload
|
||||||
if (dragging) {
|
if (dragging) {
|
||||||
dndStore.actions.startDragging({
|
const definition =
|
||||||
id: null,
|
componentStore.actions.getComponentDefinition(component)
|
||||||
parent: null,
|
dndStore.actions.startDraggingNewComponent({ component, definition })
|
||||||
bounds: {
|
|
||||||
height: 64,
|
|
||||||
width: 128,
|
|
||||||
},
|
|
||||||
index: null,
|
|
||||||
newComponentType: component,
|
|
||||||
})
|
|
||||||
builderStore.actions.setDraggingNewComponent(true)
|
|
||||||
} else {
|
} else {
|
||||||
dndStore.actions.reset()
|
dndStore.actions.reset()
|
||||||
builderStore.actions.setDraggingNewComponent(false)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ const createBuilderStore = () => {
|
||||||
theme: null,
|
theme: null,
|
||||||
customTheme: null,
|
customTheme: null,
|
||||||
previewDevice: "desktop",
|
previewDevice: "desktop",
|
||||||
draggingNewComponent: false,
|
|
||||||
navigation: null,
|
navigation: null,
|
||||||
hiddenComponentIds: [],
|
hiddenComponentIds: [],
|
||||||
usedPlugins: null,
|
usedPlugins: null,
|
||||||
|
@ -68,19 +67,12 @@ const createBuilderStore = () => {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
dropNewComponent: (component, parent, index) => {
|
dropNewComponent: (component, parent, index) => {
|
||||||
console.log("dispatch", component, parent, index)
|
|
||||||
dispatchEvent("drop-new-component", {
|
dispatchEvent("drop-new-component", {
|
||||||
component,
|
component,
|
||||||
parent,
|
parent,
|
||||||
index,
|
index,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
setDraggingNewComponent: draggingNewComponent => {
|
|
||||||
if (draggingNewComponent === get(store).draggingNewComponent) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
store.update(state => ({ ...state, draggingNewComponent }))
|
|
||||||
},
|
|
||||||
setEditMode: enabled => {
|
setEditMode: enabled => {
|
||||||
if (enabled === get(store).editMode) {
|
if (enabled === get(store).editMode) {
|
||||||
return
|
return
|
||||||
|
|
|
@ -4,7 +4,6 @@ import { findComponentById, findComponentPathById } from "../utils/components"
|
||||||
import { devToolsStore } from "./devTools"
|
import { devToolsStore } from "./devTools"
|
||||||
import { screenStore } from "./screens"
|
import { screenStore } from "./screens"
|
||||||
import { builderStore } from "./builder"
|
import { builderStore } from "./builder"
|
||||||
import { dndParent } from "./dnd.js"
|
|
||||||
import Router from "../components/Router.svelte"
|
import Router from "../components/Router.svelte"
|
||||||
import DNDPlaceholder from "../components/preview/DNDPlaceholder.svelte"
|
import DNDPlaceholder from "../components/preview/DNDPlaceholder.svelte"
|
||||||
import * as AppComponents from "../components/app/index.js"
|
import * as AppComponents from "../components/app/index.js"
|
||||||
|
@ -20,28 +19,22 @@ const createComponentStore = () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const derivedStore = derived(
|
const derivedStore = derived(
|
||||||
[store, builderStore, devToolsStore, screenStore, dndParent],
|
[store, builderStore, devToolsStore, screenStore],
|
||||||
([$store, $builderState, $devToolsState, $screenState, $dndParent]) => {
|
([$store, $builderStore, $devToolsStore, $screenStore]) => {
|
||||||
|
const { inBuilder, selectedComponentId } = $builderStore
|
||||||
|
|
||||||
// Avoid any of this logic if we aren't in the builder preview
|
// Avoid any of this logic if we aren't in the builder preview
|
||||||
if (!$builderState.inBuilder && !$devToolsState.visible) {
|
if (!inBuilder && !$devToolsStore.visible) {
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Derive the selected component instance and definition
|
const root = $screenStore.activeScreen?.props
|
||||||
let asset
|
const component = findComponentById(root, selectedComponentId)
|
||||||
const { screen, selectedComponentId } = $builderState
|
|
||||||
if ($builderState.inBuilder) {
|
|
||||||
asset = screen
|
|
||||||
} else {
|
|
||||||
asset = $screenState.activeScreen
|
|
||||||
}
|
|
||||||
const component = findComponentById(asset?.props, selectedComponentId)
|
|
||||||
const definition = getComponentDefinition(component?._component)
|
const definition = getComponentDefinition(component?._component)
|
||||||
|
|
||||||
// Derive the selected component path
|
// Derive the selected component path
|
||||||
const selectedPath =
|
const selectedPath =
|
||||||
findComponentPathById(asset?.props, selectedComponentId) || []
|
findComponentPathById(root, selectedComponentId) || []
|
||||||
const dndPath = findComponentPathById(asset?.props, $dndParent) || []
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
customComponentManifest: $store.customComponentManifest,
|
customComponentManifest: $store.customComponentManifest,
|
||||||
|
@ -51,9 +44,6 @@ const createComponentStore = () => {
|
||||||
selectedComponentDefinition: definition,
|
selectedComponentDefinition: definition,
|
||||||
selectedComponentPath: selectedPath?.map(component => component._id),
|
selectedComponentPath: selectedPath?.map(component => component._id),
|
||||||
mountedComponentCount: Object.keys($store.mountedComponents).length,
|
mountedComponentCount: Object.keys($store.mountedComponents).length,
|
||||||
currentAsset: asset,
|
|
||||||
dndPath: dndPath?.map(component => component._id),
|
|
||||||
dndDepth: dndPath?.length || 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -101,8 +91,8 @@ const createComponentStore = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const getComponentById = id => {
|
const getComponentById = id => {
|
||||||
const asset = get(derivedStore).currentAsset
|
const root = get(screenStore).activeScreen?.props
|
||||||
return findComponentById(asset?.props, id)
|
return findComponentById(root, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getComponentDefinition = type => {
|
const getComponentDefinition = type => {
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { derived } from "svelte/store"
|
||||||
|
import { findComponentPathById } from "utils/components.js"
|
||||||
|
import { dndParent } from "../dnd.js"
|
||||||
|
import { screenStore } from "../screens.js"
|
||||||
|
|
||||||
|
export const dndComponentPath = derived(
|
||||||
|
[dndParent, screenStore],
|
||||||
|
([$dndParent, $screenStore]) => {
|
||||||
|
const root = $screenStore.activeScreen?.props
|
||||||
|
const path = findComponentPathById(root, $dndParent) || []
|
||||||
|
return path?.map(component => component._id)
|
||||||
|
}
|
||||||
|
)
|
|
@ -1,2 +1,5 @@
|
||||||
export { isDragging } from "./isDragging.js"
|
// These derived stores are pulled out from their parent stores to avoid
|
||||||
|
// dependency loops. By inverting store dependencies and extracting them
|
||||||
|
// separately we can keep our actual stores lean and performant.
|
||||||
export { currentRole } from "./currentRole.js"
|
export { currentRole } from "./currentRole.js"
|
||||||
|
export { dndComponentPath } from "./dndComponentPath.js"
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
import { derived } from "svelte/store"
|
|
||||||
import { dndStore } from "../dnd"
|
|
||||||
import { builderStore } from "../builder.js"
|
|
||||||
|
|
||||||
// Derive whether we are dragging or not
|
|
||||||
export const isDragging = derived(
|
|
||||||
[dndStore, builderStore],
|
|
||||||
([$dndStore, $builderStore]) =>
|
|
||||||
$dndStore.source != null || $builderStore.draggingNewComponent
|
|
||||||
)
|
|
|
@ -2,6 +2,10 @@ import { writable, derived } from "svelte/store"
|
||||||
|
|
||||||
const createDndStore = () => {
|
const createDndStore = () => {
|
||||||
const initialState = {
|
const initialState = {
|
||||||
|
// Flags for whether we are inserting a new component or not
|
||||||
|
isNewComponent: false,
|
||||||
|
newComponentType: null,
|
||||||
|
|
||||||
// Info about the dragged component
|
// Info about the dragged component
|
||||||
source: null,
|
source: null,
|
||||||
|
|
||||||
|
@ -13,12 +17,32 @@ const createDndStore = () => {
|
||||||
}
|
}
|
||||||
const store = writable(initialState)
|
const store = writable(initialState)
|
||||||
|
|
||||||
// newComponentType is an optional field to signify we are creating a new
|
const startDraggingExistingComponent = ({ id, parent, bounds, index }) => {
|
||||||
// component rather than moving an existing one
|
|
||||||
const startDragging = ({ id, parent, bounds, index, newComponentType }) => {
|
|
||||||
store.set({
|
store.set({
|
||||||
...initialState,
|
...initialState,
|
||||||
source: { id, parent, bounds, index, newComponentType },
|
source: { id, parent, bounds, index },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const startDraggingNewComponent = ({ type, definition }) => {
|
||||||
|
if (!type || !definition) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get size of new component so we can show a properly sized placeholder
|
||||||
|
const width = definition.size?.width || 128
|
||||||
|
const height = definition.size?.height || 64
|
||||||
|
|
||||||
|
store.set({
|
||||||
|
...initialState,
|
||||||
|
isNewComponent: true,
|
||||||
|
newComponentType: type,
|
||||||
|
source: {
|
||||||
|
id: null,
|
||||||
|
parent: null,
|
||||||
|
bounds: { height, width },
|
||||||
|
index: null,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +67,8 @@ const createDndStore = () => {
|
||||||
return {
|
return {
|
||||||
subscribe: store.subscribe,
|
subscribe: store.subscribe,
|
||||||
actions: {
|
actions: {
|
||||||
startDragging,
|
startDraggingExistingComponent,
|
||||||
|
startDraggingNewComponent,
|
||||||
updateTarget,
|
updateTarget,
|
||||||
updateDrop,
|
updateDrop,
|
||||||
reset,
|
reset,
|
||||||
|
@ -52,9 +77,19 @@ const createDndStore = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const dndStore = createDndStore()
|
export const dndStore = createDndStore()
|
||||||
|
|
||||||
|
// The DND store is updated extremely frequently, so we can greatly improve
|
||||||
|
// performance by deriving any state that needs to be externally observed.
|
||||||
|
// By doing this and using primitives, we can avoid invalidating other stores
|
||||||
|
// or components which depend on DND state unless values actually change.
|
||||||
|
export const dndIsDragging = derived(dndStore, $dndStore => !!$dndStore.source)
|
||||||
export const dndParent = derived(dndStore, $dndStore => $dndStore.drop?.parent)
|
export const dndParent = derived(dndStore, $dndStore => $dndStore.drop?.parent)
|
||||||
export const dndIndex = derived(dndStore, $dndStore => $dndStore.drop?.index)
|
export const dndIndex = derived(dndStore, $dndStore => $dndStore.drop?.index)
|
||||||
export const dndBounds = derived(
|
export const dndBounds = derived(
|
||||||
dndStore,
|
dndStore,
|
||||||
$dndStore => $dndStore.source?.bounds
|
$dndStore => $dndStore.source?.bounds
|
||||||
)
|
)
|
||||||
|
export const dndIsNewComponent = derived(
|
||||||
|
dndStore,
|
||||||
|
$dndStore => $dndStore.isNewComponent
|
||||||
|
)
|
||||||
|
|
|
@ -15,7 +15,14 @@ export { uploadStore } from "./uploads.js"
|
||||||
export { rowSelectionStore } from "./rowSelection.js"
|
export { rowSelectionStore } from "./rowSelection.js"
|
||||||
export { blockStore } from "./blocks.js"
|
export { blockStore } from "./blocks.js"
|
||||||
export { environmentStore } from "./environment"
|
export { environmentStore } from "./environment"
|
||||||
export { dndStore, dndIndex, dndParent, dndBounds } from "./dnd"
|
export {
|
||||||
|
dndStore,
|
||||||
|
dndIndex,
|
||||||
|
dndParent,
|
||||||
|
dndBounds,
|
||||||
|
dndIsNewComponent,
|
||||||
|
dndIsDragging,
|
||||||
|
} from "./dnd"
|
||||||
|
|
||||||
// Context stores are layered and duplicated, so it is not a singleton
|
// Context stores are layered and duplicated, so it is not a singleton
|
||||||
export { createContextStore } from "./context"
|
export { createContextStore } from "./context"
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { derived } from "svelte/store"
|
||||||
import { routeStore } from "./routes"
|
import { routeStore } from "./routes"
|
||||||
import { builderStore } from "./builder"
|
import { builderStore } from "./builder"
|
||||||
import { appStore } from "./app"
|
import { appStore } from "./app"
|
||||||
import { dndIndex, dndParent } from "./dnd.js"
|
import { dndIndex, dndParent, dndIsNewComponent } from "./dnd.js"
|
||||||
import { RoleUtils } from "@budibase/frontend-core"
|
import { RoleUtils } from "@budibase/frontend-core"
|
||||||
import { findComponentById, findComponentParent } from "../utils/components.js"
|
import { findComponentById, findComponentParent } from "../utils/components.js"
|
||||||
import { Helpers } from "@budibase/bbui"
|
import { Helpers } from "@budibase/bbui"
|
||||||
|
@ -10,8 +10,22 @@ import { DNDPlaceholderID, DNDPlaceholderType } from "constants"
|
||||||
|
|
||||||
const createScreenStore = () => {
|
const createScreenStore = () => {
|
||||||
const store = derived(
|
const store = derived(
|
||||||
[appStore, routeStore, builderStore, dndParent, dndIndex],
|
[
|
||||||
([$appStore, $routeStore, $builderStore, $dndParent, $dndIndex]) => {
|
appStore,
|
||||||
|
routeStore,
|
||||||
|
builderStore,
|
||||||
|
dndParent,
|
||||||
|
dndIndex,
|
||||||
|
dndIsNewComponent,
|
||||||
|
],
|
||||||
|
([
|
||||||
|
$appStore,
|
||||||
|
$routeStore,
|
||||||
|
$builderStore,
|
||||||
|
$dndParent,
|
||||||
|
$dndIndex,
|
||||||
|
$dndIsNewComponent,
|
||||||
|
]) => {
|
||||||
let activeLayout, activeScreen
|
let activeLayout, activeScreen
|
||||||
let screens
|
let screens
|
||||||
|
|
||||||
|
@ -50,8 +64,8 @@ const createScreenStore = () => {
|
||||||
if (activeScreen && $dndParent && $dndIndex != null) {
|
if (activeScreen && $dndParent && $dndIndex != null) {
|
||||||
// Remove selected component from tree if we are moving an existing
|
// Remove selected component from tree if we are moving an existing
|
||||||
// component
|
// component
|
||||||
const { selectedComponentId, draggingNewComponent } = $builderStore
|
const { selectedComponentId } = $builderStore
|
||||||
if (!draggingNewComponent) {
|
if (!$dndIsNewComponent) {
|
||||||
let selectedParent = findComponentParent(
|
let selectedParent = findComponentParent(
|
||||||
activeScreen.props,
|
activeScreen.props,
|
||||||
selectedComponentId
|
selectedComponentId
|
||||||
|
|
Loading…
Reference in New Issue