OpenMAIC-React / src /lib /hooks /use-order-element.ts
muthuk1's picture
Convert OpenMAIC from Next.js to React (Vite)
f56a29b verified
raw
history blame
7.31 kB
import type { PPTElement } from '@/lib/types/slides';
export function useOrderElement() {
/**
* Get the z-order range of grouped elements
* @param elementList All elements on the page
* @param combineElementList Grouped elements list
*/
const getCombineElementLevelRange = (
elementList: PPTElement[],
combineElementList: PPTElement[],
) => {
return {
minLevel: elementList.findIndex((_element) => _element.id === combineElementList[0].id),
maxLevel: elementList.findIndex(
(_element) => _element.id === combineElementList[combineElementList.length - 1].id,
),
};
};
/**
* Move up one layer
* @param elementList All elements on the page
* @param element The element being operated on
*/
const moveUpElement = (elementList: PPTElement[], element: PPTElement) => {
const copyOfElementList: PPTElement[] = JSON.parse(JSON.stringify(elementList));
// If the element is a group member, all group members must be moved together
if (element.groupId) {
// Get all group members and their z-order range
const combineElementList = copyOfElementList.filter(
(_element) => _element.groupId === element.groupId,
);
const { minLevel, maxLevel } = getCombineElementLevelRange(elementList, combineElementList);
// Already at the top level, cannot move further
if (maxLevel >= elementList.length - 1) return;
const nextElement = copyOfElementList[maxLevel + 1];
const movedElementList = copyOfElementList.splice(minLevel, combineElementList.length);
if (nextElement.groupId) {
const nextCombineElementList = copyOfElementList.filter(
(_element) => _element.groupId === nextElement.groupId,
);
copyOfElementList.splice(minLevel + nextCombineElementList.length, 0, ...movedElementList);
} else copyOfElementList.splice(minLevel + 1, 0, ...movedElementList);
}
// If the element is not a group member
else {
// Get the element's z-level in the list
const level = elementList.findIndex((item) => item.id === element.id);
// Already at the top level, cannot move further
if (level === elementList.length - 1) return;
// Get the element above, remove this element from the list (cache removed element).
// If the above element is in a group, insert above that group.
// If the above element is not in any group, insert above that element.
const nextElement = copyOfElementList[level + 1];
const [movedElement] = copyOfElementList.splice(level, 1);
if (nextElement.groupId) {
const combineElementList = copyOfElementList.filter(
(_element) => _element.groupId === nextElement.groupId,
);
copyOfElementList.splice(level + combineElementList.length, 0, movedElement);
} else copyOfElementList.splice(level + 1, 0, movedElement);
}
return copyOfElementList;
};
/**
* Move down one layer, same approach as move up
* @param elementList All elements on the page
* @param element The element being operated on
*/
const moveDownElement = (elementList: PPTElement[], element: PPTElement) => {
const copyOfElementList: PPTElement[] = JSON.parse(JSON.stringify(elementList));
if (element.groupId) {
const combineElementList = copyOfElementList.filter(
(_element) => _element.groupId === element.groupId,
);
const { minLevel } = getCombineElementLevelRange(elementList, combineElementList);
if (minLevel === 0) return;
const prevElement = copyOfElementList[minLevel - 1];
const movedElementList = copyOfElementList.splice(minLevel, combineElementList.length);
if (prevElement.groupId) {
const prevCombineElementList = copyOfElementList.filter(
(_element) => _element.groupId === prevElement.groupId,
);
copyOfElementList.splice(minLevel - prevCombineElementList.length, 0, ...movedElementList);
} else copyOfElementList.splice(minLevel - 1, 0, ...movedElementList);
} else {
const level = elementList.findIndex((item) => item.id === element.id);
if (level === 0) return;
const prevElement = copyOfElementList[level - 1];
const movedElement = copyOfElementList.splice(level, 1)[0];
if (prevElement.groupId) {
const combineElementList = copyOfElementList.filter(
(_element) => _element.groupId === prevElement.groupId,
);
copyOfElementList.splice(level - combineElementList.length, 0, movedElement);
} else copyOfElementList.splice(level - 1, 0, movedElement);
}
return copyOfElementList;
};
/**
* Bring to front
* @param elementList All elements on the page
* @param element The element being operated on
*/
const moveTopElement = (elementList: PPTElement[], element: PPTElement) => {
const copyOfElementList: PPTElement[] = JSON.parse(JSON.stringify(elementList));
// If the element is a group member, all group members must be moved together
if (element.groupId) {
// Get all group members and their z-order range
const combineElementList = copyOfElementList.filter(
(_element) => _element.groupId === element.groupId,
);
const { minLevel, maxLevel } = getCombineElementLevelRange(elementList, combineElementList);
// Already at the top level, cannot move further
if (maxLevel === elementList.length - 1) return null;
// Remove the group from the list, then append removed elements to the top
const movedElementList = copyOfElementList.splice(minLevel, combineElementList.length);
copyOfElementList.push(...movedElementList);
}
// If the element is not a group member
else {
// Get the element's z-level in the list
const level = elementList.findIndex((item) => item.id === element.id);
// Already at the top level, cannot move further
if (level === elementList.length - 1) return null;
// Remove the element from the list, then append it to the top
copyOfElementList.splice(level, 1);
copyOfElementList.push(element);
}
return copyOfElementList;
};
/**
* Send to back, same approach as bring to front
* @param elementList All elements on the page
* @param element The element being operated on
*/
const moveBottomElement = (elementList: PPTElement[], element: PPTElement) => {
const copyOfElementList: PPTElement[] = JSON.parse(JSON.stringify(elementList));
if (element.groupId) {
const combineElementList = copyOfElementList.filter(
(_element) => _element.groupId === element.groupId,
);
const { minLevel } = getCombineElementLevelRange(elementList, combineElementList);
if (minLevel === 0) return;
const movedElementList = copyOfElementList.splice(minLevel, combineElementList.length);
copyOfElementList.unshift(...movedElementList);
} else {
const level = elementList.findIndex((item) => item.id === element.id);
if (level === 0) return;
copyOfElementList.splice(level, 1);
copyOfElementList.unshift(element);
}
return copyOfElementList;
};
return {
moveUpElement,
moveDownElement,
moveTopElement,
moveBottomElement,
};
}