import React, { useState, useEffect, useContext } from 'react'; import { Link } from 'react-router-dom'; import styled from 'styled-components'; import { ModalStateContext } from '../../contexts/ModalContext'; import { NotificationDispatchContext } from '../../contexts/NotificationContext'; import Table from '../elements/Table.js'; import Button from '../elements/Button.js'; import Checkbox from '../elements/Checkbox.js'; import TableMenu from '../blocks/TableMenu.js'; import Loader from '../blocks/Loader.js'; import Modal from '../blocks/Modal.js'; import FormError from '../blocks/FormError.js'; const Td = styled.td` padding: 0.5rem 0; &:first-child { font-weight: 500; padding-right: 1.5rem; vertical-align: top; } & ul { margin: 0; padding-left: 1.25rem; } `; const TableContent = props => { const dispatch = useContext(NotificationDispatchContext); const modalOpen = useContext(ModalStateContext); const [ showTableLoader, setShowTableLoader ] = useState(true); const [ showModalLoader, setShowModalLoader ] = useState(false); const [ content, setContent ] = useState([]); const [ contentToDelete, setContentToDelete ] = useState({}); //============================================================================= // Get and sort content //============================================================================= const [ sort, setSort ] = useState({ column: props.columns[0].key, order: 'asc', }); const sortTableContent = ({ newContent, column }) => { const newSortOrder = sort.column === column ? sort.order === 'asc' ? 'desc' : 'asc' : 'asc'; column = column || sort.column; newContent = newContent || content; const sortedContent = [...newContent]; sortedContent.sort((a, b) => { let valA = (a[column] && a[column].toLowerCase()) || ''; let valB = (b[column] && b[column].toLowerCase()) || ''; if (newSortOrder === 'asc') { return valA > valB ? 1 : valA < valB ? -1 : 0; } else { return valA < valB ? 1 : valA > valB ? -1 : 0; } }); setContent(sortedContent); setSort({ column, order: newSortOrder }); }; useEffect(() => { const getNewContent = async () => { const newContent = await props.getContent(); sortTableContent({ newContent }); setShowTableLoader(false); }; getNewContent(); // eslint-disable-next-line }, []); //============================================================================= // Handle checkboxes //============================================================================= const [ selected, setSelected ] = useState([]); const checkboxesToggleAll = e => { if (content.length === selected.length) { setSelected([]); } else { setSelected(content.map(c => c.sid)); } }; const checkboxesToggleOne = e => { const sid = e.target.value; setSelected(prev => { if (prev.includes(sid)) { return prev.filter(p => p !== sid); } else { return [...prev, sid]; } }); }; const handleBulkAction = async (selected, i) => { setShowTableLoader(true); const success = await props.bulkAction(selected, i); if (success) { const newContent = await props.getContent(); sortTableContent({ newContent }); setSelected([]); dispatch({ type: 'ADD', level: 'success', message: 'Number routing updated', }); } setShowTableLoader(false); }; //============================================================================= // Handle Open Menus (i.e. bulk action menu or 3 dots on right of each row) //============================================================================= const [ menuOpen, setMenuOpen ] = useState(null); useEffect(() => { const hideMenu = () => setMenuOpen(null); window.addEventListener('click', hideMenu); return () => window.removeEventListener('click', hideMenu); }, []); const handleMenuOpen = sid => { if (menuOpen === sid) { setMenuOpen(null); } else { setMenuOpen(sid); } }; //============================================================================= // Handle Deleting content //============================================================================= const [ errorMessage, setErrorMessage ] = useState(''); const deleteContent = async () => { setShowModalLoader(true); const result = await props.deleteContent(contentToDelete); if (result === 'success') { const newContent = await props.getContent(); sortTableContent({ newContent }); setContentToDelete({}); dispatch({ type: 'ADD', level: 'success', message: `${props.name.charAt(0).toUpperCase()}${props.name.slice(1)} deleted successfully`, }); } else { setErrorMessage(result); } setSelected([]); setShowModalLoader(false); }; //============================================================================= // Render //============================================================================= return ( {contentToDelete && (contentToDelete.name || contentToDelete.number) && ( {props.formatContentToDelete(contentToDelete).map((d, i) => ( ))}
{d.name} {typeof d.content === 'string' ? d.content :
    {d.content.map((c, i) => (
  • {c}
  • ))}
}
{errorMessage && ( )} } handleCancel={() => { setContentToDelete({}); setErrorMessage(''); }} handleSubmit={deleteContent} actionText="Delete" /> )} {/* colgroup is used to set the width of the last column because the last two {props.withCheckboxes && ( )} {props.columns.map((c, i) => ( ))} {showTableLoader ? ( ) : ( !content || !content.length ? ( ) : ( content.map(a => ( {props.withCheckboxes && ( )} {props.columns.map((c, i) => ( ))} )) ) )}
are combined in a colSpan="2", preventing the columns from being given an expicit width (`table-layout: fixed;` requires setting column width in the first row) */}
{selected.length && i === props.columns.length - 1 ? (
({ name: i.name, type: 'button', action: () => handleBulkAction(selected, i), })) } />
) : ( )}
No {props.name}s
{i === 0 ? {a[c.key]} : {a[c.key]} } setContentToDelete(a), }, ]} />
); }; export default TableContent;