mirror of https://github.com/Budibase/budibase.git
nocodelowcodelow-codedockerdocker-composeinternal-projectinternal-toolinternal-toolslow-code-developmentlow-code-development-platformopensourceselfhostedweb-devweb-developmentweb-development-toolswebdevwebdevelopmentworkflow-automationautomationdeveloper-tools
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
2.6 KiB
104 lines
2.6 KiB
import { writable, get } from "svelte/store"
|
|
import { store as frontendStore } from "builderStore"
|
|
import { findComponentPath } from "builderStore/storeUtils"
|
|
|
|
export const DropEffect = {
|
|
MOVE: "move",
|
|
COPY: "copy",
|
|
}
|
|
|
|
export const DropPosition = {
|
|
ABOVE: "above",
|
|
BELOW: "below",
|
|
INSIDE: "inside",
|
|
}
|
|
|
|
export default function() {
|
|
const store = writable({})
|
|
|
|
store.actions = {
|
|
dragstart: component => {
|
|
store.update(state => {
|
|
state.dragged = component
|
|
return state
|
|
})
|
|
},
|
|
dragover: ({
|
|
component,
|
|
index,
|
|
canHaveChildrenButIsEmpty,
|
|
mousePosition,
|
|
}) => {
|
|
store.update(state => {
|
|
state.targetComponent = component
|
|
// only allow dropping inside when container is empty
|
|
// if container has children, drag over them
|
|
|
|
if (canHaveChildrenButIsEmpty && index === 0) {
|
|
// hovered above center of target
|
|
if (mousePosition < 0.4) {
|
|
state.dropPosition = DropPosition.ABOVE
|
|
}
|
|
|
|
// hovered around bottom of target
|
|
if (mousePosition > 0.8) {
|
|
state.dropPosition = DropPosition.BELOW
|
|
}
|
|
|
|
// hovered in center of target
|
|
if (mousePosition > 0.4 && mousePosition < 0.8) {
|
|
state.dropPosition = DropPosition.INSIDE
|
|
}
|
|
return state
|
|
}
|
|
|
|
// bottom half
|
|
if (mousePosition > 0.5) {
|
|
state.dropPosition = DropPosition.BELOW
|
|
} else {
|
|
state.dropPosition = canHaveChildrenButIsEmpty
|
|
? DropPosition.INSIDE
|
|
: DropPosition.ABOVE
|
|
}
|
|
|
|
return state
|
|
})
|
|
},
|
|
reset: () => {
|
|
store.update(state => {
|
|
state.dropPosition = ""
|
|
state.targetComponent = null
|
|
state.dragged = null
|
|
return state
|
|
})
|
|
},
|
|
drop: () => {
|
|
const state = get(store)
|
|
|
|
// Stop if the target and source are the same
|
|
if (state.targetComponent === state.dragged) {
|
|
return
|
|
}
|
|
// Stop if the target or source are null
|
|
if (!state.targetComponent || !state.dragged) {
|
|
return
|
|
}
|
|
// Stop if the target is a child of source
|
|
const path = findComponentPath(state.dragged, state.targetComponent._id)
|
|
const ids = path.map(component => component._id)
|
|
if (ids.includes(state.targetComponent._id)) {
|
|
return
|
|
}
|
|
|
|
// Cut and paste the component
|
|
frontendStore.actions.components.copy(state.dragged, true)
|
|
frontendStore.actions.components.paste(
|
|
state.targetComponent,
|
|
state.dropPosition
|
|
)
|
|
store.actions.reset()
|
|
},
|
|
}
|
|
|
|
return store
|
|
}
|
|
|