import { DropTargetMonitor , useDrop } from 'react-dnd' ; import { NativeTypes } from 'react-dnd-html5-backend' ; import { useAppDispatch , useAppSelector } from 'app/store/hooks' ; import storageSelectors from 'app/store/slices/storage/storage.selectors' ; import storageThunks from 'app/store/slices/storage/storage.thunks' ; import { BreadcrumbItemData } from '../Breadcrumbs' ; import { transformDraggedItems } from 'app/core/services/drag-and-drop.service' ; import { DragAndDropType } from 'app/core/types' ; import { DriveItemData } from 'app/drive/types' ; interface BreadcrumbsItemProps { item : BreadcrumbItemData ; } const BreadcrumbsItem = ( props ) : JSX . Element => { const dispatch = useAppDispatch ( ) ; const namePath = useAppSelector ( ( state ) => state . storage . namePath ) ; const isSomeItemSelected = useAppSelector ( storageSelectors . isSomeItemSelected ) ; const selectedItems = useAppSelector ( ( state ) => state . storage . selectedItems ) ; const onItemDropped = ( item , monitor ) => { const droppedType = monitor . getItemType ( ) ; const droppedData = monitor . getItem ( ) ; const breadcrumbIndex = namePath . findIndex ( ( level ) => level . id === props . item . id ) ; const namePathDestinationArray = namePath . slice ( 0 , breadcrumbIndex + 1 ) . map ( ( level ) => level . name ) ; namePathDestinationArray [ 0 ] = '' ; const folderPath = namePathDestinationArray . join ( '/' ) ; if ( droppedType === DragAndDropType . DriveItem ) { const itemsToMove = isSomeItemSelected ? [ ... selectedItems , droppedData as DriveItemData ] . filter ( ( a , index , self ) => index === self . findIndex ( ( b ) => a . id === b . id && a . isFolder === b . isFolder ) ) : [ droppedData ] ; dispatch ( storageThunks . moveItemsThunk ( { items : itemsToMove as DriveItemData [ ] , destinationFolderId : props . item . id , } ) ) ; } else if ( droppedType === NativeTypes . FILE ) { transformDraggedItems ( ( droppedData as { files : File [ ] ; items : DataTransferItemList ; } ) . items , folderPath ) . then ( async ( { rootList , files } ) => { if ( files . length ) { await dispatch ( storageThunks . uploadItemsThunk ( { files , parentFolderId : props . item . id } ) ) ; } if ( rootList . length ) { for ( const root of rootList ) { await dispatch ( storageThunks . uploadFolderThunk ( { root , currentFolderId : props . item . id } ) ) ; } } } ) ; } } ; const [ { isOver , canDrop } , drop ] = useDrop ( ( ) => ( { accept : [ NativeTypes . FILE , DragAndDropType . DriveItem ] , collect : ( monitor ) => ( { isOver : monitor . isOver ( ) , canDrop : monitor . canDrop ( ) , } ) , canDrop : ( item , monitor ) : boolean => { const droppedType = monitor . getItemType ( ) ; const droppedDataParentId = item . parentId || item . folderId || - 1 ; return droppedType === NativeTypes . FILE || droppedDataParentId !== props . item . id ; } , drop : onItemDropped , } ) , [ selectedItems ] ) ; const onItemClicked = ( item ) : void => { if ( item . active ) { item . onClick && item . onClick ( ) ; } } ; const isDraggingOverClassNames = isOver && canDrop ? 'drag-over-effect' : '' ; return ( < li ref = { drop } className = { `p-1 flex items-center ${ isDraggingOverClassNames } ${ props . item . active ? 'active' : '' }` } key = { props . item . id } onClick = { ( ) => onItemClicked ( props . item ) } > { props . item . icon ? props . item . icon : null } { props . item . label ? < span className = "label" > { props . item . label } < /span> : null} < /li>); } ; export default BreadcrumbsItem ;