import React, { useState, useMemo, useRef } from "react"; import { ModuleId, ModuleLookup, NavLeftHandSideItemParent } from "./types"; import TopListItemInner from "./TopListItemInner"; import UnpinnedDropZone from "./UnpinnedDropZone"; import rbd, { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd"; import DragAndDropGripper from "./DragAndDropGripper"; import { Dropzones } from "./types"; import UnpinnedMenu from "./UnpinnedMenu"; const makeParentItemWithChildren = ( lookup: ModuleLookup, id: ModuleId ): NavLeftHandSideItemParent => { const parentItem = lookup[id]; const subItems = parentItem && parentItem.subItems && parentItem.subItems.map(subId => makeParentItemWithChildren(lookup, subId)); return { ...parentItem, id, subItems }; }; export interface Props { selectedModuleId?: ModuleId | null; moduleLookup: ModuleLookup; pinnedIds: ModuleId[]; onModuleClick: (moduleId: ModuleId) => void; onPinnedItemsChange?: (moduleIds: ModuleId[]) => void; children: React.ReactNode; BottomComponent?: React.ReactNode; } export default function NavLeftHandSide({ selectedModuleId, moduleLookup, pinnedIds, onPinnedItemsChange, children, onModuleClick, BottomComponent }: Props) { const [isDraggingAny, setIsDraggingAny] = useState(false); const navRef = useRef(); const unpinnedIds = useMemo(() => { const childIds = Object.values(moduleLookup).reduce( (acc: ModuleId[], { subItems }) => acc.concat(subItems || []), [] ); return Object.keys(moduleLookup).filter( (id: ModuleId) => !(pinnedIds.includes(id) || childIds.includes(id)) ) as ModuleId[]; }, [moduleLookup, pinnedIds]); function reorder(list: any[], startIndex: number, endIndex: number) { const result = list; const [removed] = result.splice(startIndex, 1); result.splice(endIndex, 0, removed); return result; } const onDragStart: rbd.OnDragStartResponder = () => { setIsDraggingAny(true); }; const onDragEnd: rbd.OnDragEndResponder = ({ destination, source }) => { setIsDraggingAny(false); if ( !destination || (destination.index === source.index && destination.droppableId === source.droppableId) ) { return; } let newPinnedIds; if (destination.droppableId === Dropzones.MODULES_DROP_ZONE) { newPinnedIds = reorder(pinnedIds, source.index, destination.index); } else { newPinnedIds = [...pinnedIds]; newPinnedIds.splice(source.index, 1); } onPinnedItemsChange(newPinnedIds); }; return ( ); }