@plone/volto
Version:
Volto
114 lines (93 loc) • 2.69 kB
JavaScript
import isArray from 'lodash/isArray';
import { getBlocksLayoutFieldname } from '@plone/volto/helpers/Blocks/Blocks';
function getDragDepth(offset, indentationWidth) {
return Math.round(offset / indentationWidth);
}
export function getProjection(
items,
activeId,
overId,
dragOffset,
indentationWidth,
arrayMove,
) {
const overItemIndex = items.findIndex(({ id }) => id === overId);
const activeItemIndex = items.findIndex(({ id }) => id === activeId);
const activeItem = items[activeItemIndex];
const newItems = arrayMove(items, activeItemIndex, overItemIndex);
const previousItem = newItems[overItemIndex - 1];
const nextItem = newItems[overItemIndex + 1];
const dragDepth = getDragDepth(dragOffset, indentationWidth);
const projectedDepth = activeItem.depth + dragDepth;
const maxDepth = getMaxDepth({
previousItem,
});
const minDepth = getMinDepth({ nextItem });
let depth = projectedDepth;
if (projectedDepth >= maxDepth) {
depth = maxDepth;
} else if (projectedDepth < minDepth) {
depth = minDepth;
}
return { depth, maxDepth, minDepth, parentId: getParentId() };
function getParentId() {
if (depth === 0 || !previousItem) {
return null;
}
if (depth <= previousItem.depth) {
return previousItem.parentId;
}
if (depth > previousItem.depth) {
return previousItem.id;
}
const newParent = newItems
.slice(0, overItemIndex)
.reverse()
.find((item) => item.depth === depth)?.parentId;
return newParent ?? null;
}
}
function getMaxDepth({ previousItem }) {
const blocksLayoutFieldname = getBlocksLayoutFieldname(
previousItem?.data || {},
);
if (previousItem) {
return isArray(previousItem.data?.[blocksLayoutFieldname]?.items)
? previousItem.depth + 1
: previousItem.depth;
}
return 0;
}
function getMinDepth({ nextItem }) {
if (nextItem) {
return nextItem.depth;
}
return 0;
}
function flatten(items = [], parentId = null, depth = 0) {
return items.reduce((acc, item, index) => {
return [
...acc,
{ ...item, parentId, depth, index },
...flatten(item.children, item.id, depth + 1),
];
}, []);
}
export function flattenTree(items) {
return flatten(items);
}
export function findItem(items, itemId) {
return items.find(({ id }) => id === itemId);
}
export function removeChildrenOf(items, ids) {
const excludeParentIds = [...ids];
return items.filter((item) => {
if (item.parentId && excludeParentIds.includes(item.parentId)) {
if (item.children.length) {
excludeParentIds.push(item.id);
}
return false;
}
return true;
});
}