import { KeyboardEvent, useState, useEffect, Fragment } from 'react'; import { DragDropContext, Droppable, Draggable, DropResult, } from 'react-beautiful-dnd'; import { Link } from 'react-router-dom'; // Redux import { connect } from 'react-redux'; import { pinCategory, deleteCategory, deleteBookmark, createNotification, reorderCategories, } from '../../../store/actions'; // Typescript import { Bookmark, Category, Config, GlobalState, NewNotification, } from '../../../interfaces'; import { ContentType } from '../Bookmarks'; // CSS import classes from './BookmarkTable.module.css'; // UI import Table from '../../UI/Table/Table'; import Icon from '../../UI/Icons/Icon/Icon'; interface ComponentProps { contentType: ContentType; categories: Category[]; config: Config; pinCategory: (category: Category) => void; deleteCategory: (id: number) => void; updateHandler: (data: Category | Bookmark) => void; deleteBookmark: (bookmarkId: number, categoryId: number) => void; createNotification: (notification: NewNotification) => void; reorderCategories: (categories: Category[]) => void; } const BookmarkTable = (props: ComponentProps): JSX.Element => { const [localCategories, setLocalCategories] = useState([]); const [isCustomOrder, setIsCustomOrder] = useState(false); // Copy categories array useEffect(() => { setLocalCategories([...props.categories]); }, [props.categories]); // Check ordering useEffect(() => { const order = props.config.useOrdering; if (order === 'orderId') { setIsCustomOrder(true); } }); const deleteCategoryHandler = (category: Category): void => { const proceed = window.confirm( `Are you sure you want to delete ${category.name}? It will delete ALL assigned bookmarks` ); if (proceed) { props.deleteCategory(category.id); } }; const deleteBookmarkHandler = (bookmark: Bookmark): void => { const proceed = window.confirm( `Are you sure you want to delete ${bookmark.name}?` ); if (proceed) { props.deleteBookmark(bookmark.id, bookmark.categoryId); } }; const keyboardActionHandler = ( e: KeyboardEvent, category: Category, handler: Function ) => { if (e.key === 'Enter') { handler(category); } }; const dragEndHanlder = (result: DropResult): void => { if (!isCustomOrder) { props.createNotification({ title: 'Error', message: 'Custom order is disabled', }); return; } if (!result.destination) { return; } const tmpCategories = [...localCategories]; const [movedApp] = tmpCategories.splice(result.source.index, 1); tmpCategories.splice(result.destination.index, 0, movedApp); setLocalCategories(tmpCategories); props.reorderCategories(tmpCategories); }; if (props.contentType === ContentType.category) { return (
{isCustomOrder ? (

You can drag and drop single rows to reorder categories

) : (

Custom order is disabled. You can change it in{' '} settings

)}
{(provided) => ( {localCategories.map( (category: Category, index): JSX.Element => { return ( {(provided, snapshot) => { const style = { border: snapshot.isDragging ? '1px solid var(--color-accent)' : 'none', borderRadius: '4px', ...provided.draggableProps.style, }; return ( {!snapshot.isDragging && ( )} ); }} ); } )}
{category.name}
deleteCategoryHandler(category) } onKeyDown={(e) => keyboardActionHandler( e, category, deleteCategoryHandler ) } tabIndex={0} >
props.updateHandler(category) } tabIndex={0} >
props.pinCategory(category)} onKeyDown={(e) => keyboardActionHandler( e, category, props.pinCategory ) } tabIndex={0} > {category.isPinned ? ( ) : ( )}
)}
); } else { const bookmarks: { bookmark: Bookmark; categoryName: string }[] = []; props.categories.forEach((category: Category) => { category.bookmarks.forEach((bookmark: Bookmark) => { bookmarks.push({ bookmark, categoryName: category.name, }); }); }); return ( {bookmarks.map( (bookmark: { bookmark: Bookmark; categoryName: string }) => { return ( ); } )}
{bookmark.bookmark.name} {bookmark.bookmark.url} {bookmark.bookmark.icon} {bookmark.categoryName}
deleteBookmarkHandler(bookmark.bookmark)} tabIndex={0} >
props.updateHandler(bookmark.bookmark)} tabIndex={0} >
); } }; const mapStateToProps = (state: GlobalState) => { return { config: state.config.config, }; }; const actions = { pinCategory, deleteCategory, deleteBookmark, createNotification, reorderCategories, }; export default connect(mapStateToProps, actions)(BookmarkTable);