move pages
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import { Copy, Trash, AddSquare, DocumentText } from 'iconsax-react'
|
import { Copy, Trash, AddSquare, DocumentText } from 'iconsax-react'
|
||||||
|
import { useState } from 'react'
|
||||||
import { useEditorStore } from '../store/editorStore'
|
import { useEditorStore } from '../store/editorStore'
|
||||||
import type { Page } from '../store/editorStore.types'
|
import type { Page } from '../store/editorStore.types'
|
||||||
import { clx } from '@/helpers/utils'
|
import { clx } from '@/helpers/utils'
|
||||||
@@ -25,7 +26,10 @@ const PagesPanel = ({ catalogSize }: PagesPanelProps) => {
|
|||||||
addPage,
|
addPage,
|
||||||
duplicatePage,
|
duplicatePage,
|
||||||
deletePage,
|
deletePage,
|
||||||
|
reorderPages,
|
||||||
} = useEditorStore()
|
} = useEditorStore()
|
||||||
|
const [draggedPageId, setDraggedPageId] = useState<string | null>(null)
|
||||||
|
const [dragOverPageId, setDragOverPageId] = useState<string | null>(null)
|
||||||
|
|
||||||
const handleAddPage = () => {
|
const handleAddPage = () => {
|
||||||
addPage()
|
addPage()
|
||||||
@@ -57,8 +61,33 @@ const PagesPanel = ({ catalogSize }: PagesPanelProps) => {
|
|||||||
<div
|
<div
|
||||||
key={page.id}
|
key={page.id}
|
||||||
onClick={() => setCurrentPage(page.id)}
|
onClick={() => setCurrentPage(page.id)}
|
||||||
|
draggable
|
||||||
|
onDragStart={() => {
|
||||||
|
setDraggedPageId(page.id)
|
||||||
|
}}
|
||||||
|
onDragOver={(e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
if (dragOverPageId !== page.id) {
|
||||||
|
setDragOverPageId(page.id)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onDrop={(e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
if (draggedPageId && draggedPageId !== page.id) {
|
||||||
|
reorderPages(draggedPageId, page.id)
|
||||||
|
}
|
||||||
|
setDraggedPageId(null)
|
||||||
|
setDragOverPageId(null)
|
||||||
|
}}
|
||||||
|
onDragEnd={() => {
|
||||||
|
setDraggedPageId(null)
|
||||||
|
setDragOverPageId(null)
|
||||||
|
}}
|
||||||
className={clx(
|
className={clx(
|
||||||
'flex flex-col gap-2 cursor-pointer transition-colors',
|
'flex flex-col gap-2 cursor-pointer transition-colors',
|
||||||
|
dragOverPageId === page.id &&
|
||||||
|
draggedPageId !== page.id &&
|
||||||
|
'ring-2 ring-blue-300 rounded-lg',
|
||||||
isSelected && ' rounded-lg p-0.5'
|
isSelected && ' rounded-lg p-0.5'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -67,11 +67,20 @@ export const createInitialPage = (name: string): Page => ({
|
|||||||
backgroundImageUrl: "",
|
backgroundImageUrl: "",
|
||||||
});
|
});
|
||||||
|
|
||||||
export const reorderByIds = (
|
export const getDefaultPageName = (index: number): string =>
|
||||||
items: EditorObject[],
|
index === 0 ? "جلد" : String(index + 1);
|
||||||
|
|
||||||
|
export const applyDefaultPageNames = (pages: Page[]): Page[] =>
|
||||||
|
pages.map((page, index) => ({
|
||||||
|
...page,
|
||||||
|
name: getDefaultPageName(index),
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const reorderByIds = <T extends { id: string }>(
|
||||||
|
items: T[],
|
||||||
draggedId: string,
|
draggedId: string,
|
||||||
targetId: string,
|
targetId: string,
|
||||||
) => {
|
): T[] => {
|
||||||
const fromIndex = items.findIndex((item) => item.id === draggedId);
|
const fromIndex = items.findIndex((item) => item.id === draggedId);
|
||||||
const toIndex = items.findIndex((item) => item.id === targetId);
|
const toIndex = items.findIndex((item) => item.id === targetId);
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
createTableCellId,
|
createTableCellId,
|
||||||
isInvalidPageId,
|
isInvalidPageId,
|
||||||
reorderByIds,
|
reorderByIds,
|
||||||
|
applyDefaultPageNames,
|
||||||
ungroupById,
|
ungroupById,
|
||||||
normalizePageObjects,
|
normalizePageObjects,
|
||||||
} from "./editorStore.helpers";
|
} from "./editorStore.helpers";
|
||||||
@@ -143,6 +144,7 @@ type EditorStoreType = {
|
|||||||
addPage: (name?: string) => void;
|
addPage: (name?: string) => void;
|
||||||
duplicatePage: (pageId: string) => void;
|
duplicatePage: (pageId: string) => void;
|
||||||
deletePage: (pageId: string) => void;
|
deletePage: (pageId: string) => void;
|
||||||
|
reorderPages: (draggedId: string, targetId: string) => void;
|
||||||
setCurrentPage: (pageId: string) => void;
|
setCurrentPage: (pageId: string) => void;
|
||||||
updatePageName: (pageId: string, name: string) => void;
|
updatePageName: (pageId: string, name: string) => void;
|
||||||
toggleObjectVisibility: (id: string) => void;
|
toggleObjectVisibility: (id: string) => void;
|
||||||
@@ -875,7 +877,7 @@ export const useEditorStore = create<EditorStoreType>((set, get) => {
|
|||||||
const newCurrentPage = newPages.find((p) => p.id === newCurrentPageId);
|
const newCurrentPage = newPages.find((p) => p.id === newCurrentPageId);
|
||||||
|
|
||||||
set({
|
set({
|
||||||
pages: newPages,
|
pages: applyDefaultPageNames(newPages),
|
||||||
currentPageId: newCurrentPageId,
|
currentPageId: newCurrentPageId,
|
||||||
objects: newCurrentPage?.objects || [],
|
objects: newCurrentPage?.objects || [],
|
||||||
guides: newCurrentPage?.guides || [],
|
guides: newCurrentPage?.guides || [],
|
||||||
@@ -884,6 +886,25 @@ export const useEditorStore = create<EditorStoreType>((set, get) => {
|
|||||||
objectHistoryFuture: [],
|
objectHistoryFuture: [],
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
reorderPages: (draggedId, targetId) => {
|
||||||
|
if (draggedId === targetId) return;
|
||||||
|
|
||||||
|
set((state) => {
|
||||||
|
const pagesWithCurrentObjects = state.currentPageId
|
||||||
|
? state.pages.map((p) =>
|
||||||
|
p.id === state.currentPageId
|
||||||
|
? { ...p, objects: state.objects, guides: state.guides }
|
||||||
|
: p,
|
||||||
|
)
|
||||||
|
: state.pages;
|
||||||
|
|
||||||
|
return {
|
||||||
|
pages: applyDefaultPageNames(
|
||||||
|
reorderByIds(pagesWithCurrentObjects, draggedId, targetId),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
setCurrentPage: (pageId) => {
|
setCurrentPage: (pageId) => {
|
||||||
const state = get();
|
const state = get();
|
||||||
const targetPage = state.pages.find((p) => p.id === pageId);
|
const targetPage = state.pages.find((p) => p.id === pageId);
|
||||||
|
|||||||
Reference in New Issue
Block a user