mirror of
https://github.com/Shadowfita/docmost.git
synced 2025-11-24 05:31:19 +10:00
104 lines
2.8 KiB
TypeScript
104 lines
2.8 KiB
TypeScript
import { useMemo } from 'react';
|
|
import {
|
|
CreateHandler,
|
|
DeleteHandler,
|
|
MoveHandler,
|
|
RenameHandler,
|
|
SimpleTree,
|
|
} from 'react-arborist';
|
|
import { useAtom } from 'jotai';
|
|
import { treeDataAtom } from '@/features/page/tree/atoms/tree-data-atom';
|
|
import { createPage, deletePage, movePage, updatePage } from '@/features/page/services/page-service';
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
import { IMovePage } from '@/features/page/types/page.types';
|
|
import { useRouter } from 'next/navigation';
|
|
|
|
export function usePersistence<T>() {
|
|
const [data, setData] = useAtom<T[]>(treeDataAtom);
|
|
const router = useRouter();
|
|
|
|
const tree = useMemo(
|
|
() =>
|
|
new SimpleTree<// @ts-ignore
|
|
T>(data),
|
|
[data],
|
|
);
|
|
|
|
const onMove: MoveHandler<T> = (args: { parentId, index, parentNode, dragNodes, dragIds }) => {
|
|
for (const id of args.dragIds) {
|
|
tree.move({ id, parentId: args.parentId, index: args.index });
|
|
}
|
|
setData(tree.data);
|
|
|
|
const newDragIndex = tree.find(args.dragIds[0])?.childIndex;
|
|
|
|
const currentTreeData = args.parentId ? tree.find(args.parentId).children : tree.data;
|
|
const afterId = currentTreeData[newDragIndex - 1]?.id || null;
|
|
const beforeId = !afterId && currentTreeData[newDragIndex + 1]?.id || null;
|
|
|
|
const params: IMovePage= {
|
|
id: args.dragIds[0],
|
|
after: afterId,
|
|
before: beforeId,
|
|
parentId: args.parentId || null,
|
|
};
|
|
|
|
const payload = Object.fromEntries(
|
|
Object.entries(params).filter(([key, value]) => value !== null && value !== undefined)
|
|
);
|
|
|
|
try {
|
|
movePage(payload as IMovePage);
|
|
} catch (error) {
|
|
console.error('Error moving page:', error);
|
|
}
|
|
};
|
|
|
|
const onRename: RenameHandler<T> = ({ name, id }) => {
|
|
tree.update({ id, changes: { name } as any });
|
|
setData(tree.data);
|
|
|
|
try {
|
|
updatePage({ id, title: name });
|
|
} catch (error) {
|
|
console.error('Error updating page title:', error);
|
|
}
|
|
};
|
|
|
|
const onCreate: CreateHandler<T> = async ({ parentId, index, type }) => {
|
|
const data = { id: uuidv4(), name: '' } as any;
|
|
data.children = [];
|
|
tree.create({ parentId, index, data });
|
|
setData(tree.data);
|
|
|
|
const payload: { id: string; parentPageId?: string } = { id: data.id };
|
|
if (parentId) {
|
|
payload.parentPageId = parentId;
|
|
}
|
|
|
|
try {
|
|
await createPage(payload);
|
|
router.push(`/p/${payload.id}`);
|
|
} catch (error) {
|
|
console.error('Error creating the page:', error);
|
|
}
|
|
|
|
return data;
|
|
};
|
|
|
|
const onDelete: DeleteHandler<T> = async (args: { ids: string[] }) => {
|
|
args.ids.forEach((id) => tree.drop({ id }));
|
|
setData(tree.data);
|
|
|
|
try {
|
|
await deletePage(args.ids[0]);
|
|
} catch (error) {
|
|
console.error('Error deleting page:', error);
|
|
}
|
|
};
|
|
|
|
const controllers = { onMove, onRename, onCreate, onDelete };
|
|
|
|
return { data, setData, controllers } as const;
|
|
}
|