import { FC, useCallback, useState } from 'react'; import { FaCaretDown, FaCaretRight, FaEyeSlash, FaGripVertical } from 'react-icons/fa'; import { ICatalogNode } from '../../../../api'; import { CatalogIconView } from '../catalog-icon/CatalogIconView'; export interface CatalogAdminPageTreeItemProps { node: ICatalogNode; depth?: number; selectedPageId?: number; onSelect: (node: ICatalogNode) => void; onReorder: (pageId: number, newParentId: number, newIndex: number) => void; } export const CatalogAdminPageTreeItem: FC = props => { const { node, depth = 0, selectedPageId, onSelect, onReorder } = props; const [ isOpen, setIsOpen ] = useState(node.isOpen); const [ isDragOver, setIsDragOver ] = useState<'above' | 'on' | 'below' | null>(null); const isSelected = selectedPageId === node.pageId; const isHidden = !node.isVisible; const hasBranch = node.children && node.children.length > 0; const handleDragStart = useCallback((e: React.DragEvent) => { e.dataTransfer.setData('text/plain', JSON.stringify({ pageId: node.pageId, parentId: node.parent?.pageId ?? -1 })); e.dataTransfer.effectAllowed = 'move'; }, [ node ]); const handleDragOver = useCallback((e: React.DragEvent) => { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; const rect = (e.currentTarget as HTMLElement).getBoundingClientRect(); const y = e.clientY - rect.top; const third = rect.height / 3; if(y < third) setIsDragOver('above'); else if(y > third * 2) setIsDragOver('below'); else setIsDragOver('on'); }, []); const handleDrop = useCallback((e: React.DragEvent) => { e.preventDefault(); setIsDragOver(null); try { const data = JSON.parse(e.dataTransfer.getData('text/plain')); if(!data.pageId || data.pageId === node.pageId) return; if(isDragOver === 'on' && hasBranch) { onReorder(data.pageId, node.pageId, 0); } else { const parentId = node.parent?.pageId ?? -1; const index = node.parent?.children?.indexOf(node) ?? 0; const targetIndex = isDragOver === 'below' ? index + 1 : index; onReorder(data.pageId, parentId, targetIndex); } } catch {} }, [ node, isDragOver, hasBranch, onReorder ]); return (
{ isDragOver === 'above' &&
}
onSelect(node) } onDragLeave={ () => setIsDragOver(null) } onDragOver={ handleDragOver } onDragStart={ handleDragStart } onDrop={ handleDrop } > { hasBranch ? { e.stopPropagation(); setIsOpen(!isOpen); } } > { isOpen ? : } : }
{ node.localization } { isHidden && } #{ node.pageId }
{ isDragOver === 'below' &&
} { isOpen && hasBranch && node.children.map((child, index) => ) }
); };