2021-05-13 14:30:42 +00:00
|
|
|
import React, { useMemo, useEffect, useCallback } from "react";
|
2021-04-14 16:52:15 +00:00
|
|
|
import PropTypes from "prop-types";
|
2021-05-13 14:30:42 +00:00
|
|
|
import { useTable, useSortBy, useRowSelect } from "react-table";
|
2021-04-04 12:45:24 +00:00
|
|
|
|
2021-04-14 16:52:15 +00:00
|
|
|
import Spinner from "components/loaders/Spinner";
|
2021-05-13 14:30:42 +00:00
|
|
|
import Button from "../../buttons/Button";
|
2021-04-04 12:45:24 +00:00
|
|
|
|
2021-04-14 16:52:15 +00:00
|
|
|
const baseClass = "data-table-container";
|
2021-04-04 12:45:24 +00:00
|
|
|
|
|
|
|
|
// This data table uses react-table for implementation. The relevant documentation of the library
|
|
|
|
|
// can be found here https://react-table.tanstack.com/docs/api/useTable
|
|
|
|
|
const DataTable = (props) => {
|
|
|
|
|
const {
|
|
|
|
|
columns: tableColumns,
|
|
|
|
|
data: tableData,
|
|
|
|
|
isLoading,
|
|
|
|
|
sortHeader,
|
|
|
|
|
sortDirection,
|
|
|
|
|
onSort,
|
2021-05-13 14:30:42 +00:00
|
|
|
onSelectActionClick,
|
2021-04-04 12:45:24 +00:00
|
|
|
} = props;
|
|
|
|
|
|
|
|
|
|
const columns = useMemo(() => {
|
|
|
|
|
return tableColumns;
|
|
|
|
|
}, [tableColumns]);
|
|
|
|
|
|
|
|
|
|
// The table data needs to be ordered by the order we received from the API.
|
|
|
|
|
const data = useMemo(() => {
|
|
|
|
|
return tableData;
|
|
|
|
|
}, [tableData]);
|
|
|
|
|
|
2021-05-13 14:30:42 +00:00
|
|
|
const {
|
|
|
|
|
headerGroups,
|
|
|
|
|
rows,
|
|
|
|
|
prepareRow,
|
|
|
|
|
selectedFlatRows,
|
|
|
|
|
toggleAllRowsSelected,
|
|
|
|
|
state: tableState,
|
|
|
|
|
} = useTable(
|
2021-04-04 12:45:24 +00:00
|
|
|
{
|
|
|
|
|
columns,
|
|
|
|
|
data,
|
|
|
|
|
initialState: {
|
|
|
|
|
sortBy: useMemo(() => {
|
2021-04-14 16:52:15 +00:00
|
|
|
return [{ id: sortHeader, desc: sortDirection === "desc" }];
|
2021-04-04 12:45:24 +00:00
|
|
|
}, [sortHeader, sortDirection]),
|
|
|
|
|
},
|
|
|
|
|
disableMultiSort: true,
|
|
|
|
|
},
|
2021-05-13 14:30:42 +00:00
|
|
|
useSortBy,
|
|
|
|
|
useRowSelect
|
2021-04-04 12:45:24 +00:00
|
|
|
);
|
|
|
|
|
|
2021-05-13 14:30:42 +00:00
|
|
|
const { sortBy, selectedRowIds } = tableState;
|
2021-04-04 12:45:24 +00:00
|
|
|
|
2021-05-13 14:30:42 +00:00
|
|
|
// This is used to listen for changes to sort. If there is a change
|
|
|
|
|
// Then the sortHandler change is fired.
|
2021-04-04 12:45:24 +00:00
|
|
|
useEffect(() => {
|
|
|
|
|
const column = sortBy[0];
|
|
|
|
|
if (column !== undefined) {
|
2021-04-14 16:52:15 +00:00
|
|
|
if (
|
|
|
|
|
column.id !== sortHeader ||
|
|
|
|
|
column.desc !== (sortDirection === "desc")
|
|
|
|
|
) {
|
2021-04-04 12:45:24 +00:00
|
|
|
onSort(column.id, column.desc);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
onSort(undefined);
|
|
|
|
|
}
|
2021-05-13 14:30:42 +00:00
|
|
|
}, [sortBy, sortHeader, onSort, sortDirection]);
|
|
|
|
|
|
|
|
|
|
const onSelectActionButtonClick = useCallback(() => {
|
|
|
|
|
const entityIds = selectedFlatRows.map((row) => row.original.id);
|
|
|
|
|
onSelectActionClick(entityIds);
|
|
|
|
|
}, [onSelectActionClick, selectedFlatRows]);
|
|
|
|
|
|
|
|
|
|
const onClearSelectionClick = useCallback(() => {
|
|
|
|
|
toggleAllRowsSelected(false);
|
|
|
|
|
}, [toggleAllRowsSelected]);
|
2021-04-04 12:45:24 +00:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className={baseClass}>
|
2021-04-14 16:52:15 +00:00
|
|
|
<div className={"data-table data-table__wrapper"}>
|
|
|
|
|
{isLoading && (
|
|
|
|
|
<div className={"loading-overlay"}>
|
2021-04-04 12:45:24 +00:00
|
|
|
<Spinner />
|
|
|
|
|
</div>
|
2021-04-14 16:52:15 +00:00
|
|
|
)}
|
|
|
|
|
<table className={"data-table__table"}>
|
2021-05-13 14:30:42 +00:00
|
|
|
{Object.keys(selectedRowIds).length !== 0 && (
|
|
|
|
|
<thead className={"active-selection"}>
|
|
|
|
|
<tr {...headerGroups[0].getHeaderGroupProps()}>
|
|
|
|
|
<th
|
|
|
|
|
{...headerGroups[0].headers[0].getHeaderProps(
|
|
|
|
|
headerGroups[0].headers[0].getSortByToggleProps()
|
|
|
|
|
)}
|
|
|
|
|
>
|
|
|
|
|
{headerGroups[0].headers[0].render("Header")}
|
|
|
|
|
</th>
|
|
|
|
|
<th className={"active-selection__container"}>
|
|
|
|
|
<div className={"active-selection__inner"}>
|
|
|
|
|
<p>
|
|
|
|
|
<span>{selectedFlatRows.length}</span> selected
|
|
|
|
|
</p>
|
|
|
|
|
<Button
|
|
|
|
|
onClick={onClearSelectionClick}
|
|
|
|
|
variant={"text-link"}
|
|
|
|
|
>
|
|
|
|
|
Clear selection
|
|
|
|
|
</Button>
|
|
|
|
|
<Button onClick={onSelectActionButtonClick}>
|
|
|
|
|
Transfer to team
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
)}
|
2021-04-04 12:45:24 +00:00
|
|
|
<thead>
|
2021-04-14 16:52:15 +00:00
|
|
|
{headerGroups.map((headerGroup) => (
|
2021-04-04 12:45:24 +00:00
|
|
|
<tr {...headerGroup.getHeaderGroupProps()}>
|
2021-04-14 16:52:15 +00:00
|
|
|
{headerGroup.headers.map((column) => (
|
2021-04-04 12:45:24 +00:00
|
|
|
<th {...column.getHeaderProps(column.getSortByToggleProps())}>
|
2021-04-14 16:52:15 +00:00
|
|
|
{column.render("Header")}
|
2021-04-04 12:45:24 +00:00
|
|
|
</th>
|
|
|
|
|
))}
|
|
|
|
|
</tr>
|
|
|
|
|
))}
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
|
|
|
|
{rows.map((row) => {
|
|
|
|
|
prepareRow(row);
|
|
|
|
|
return (
|
|
|
|
|
<tr {...row.getRowProps()}>
|
|
|
|
|
{row.cells.map((cell) => {
|
|
|
|
|
return (
|
2021-04-14 16:52:15 +00:00
|
|
|
<td {...cell.getCellProps()}>{cell.render("Cell")}</td>
|
2021-04-04 12:45:24 +00:00
|
|
|
);
|
|
|
|
|
})}
|
|
|
|
|
</tr>
|
|
|
|
|
);
|
2021-04-14 16:52:15 +00:00
|
|
|
})}
|
2021-04-04 12:45:24 +00:00
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
DataTable.propTypes = {
|
|
|
|
|
columns: PropTypes.arrayOf(PropTypes.object), // TODO: create proper interface for this
|
|
|
|
|
data: PropTypes.arrayOf(PropTypes.object), // TODO: create proper interface for this
|
|
|
|
|
isLoading: PropTypes.bool,
|
|
|
|
|
sortHeader: PropTypes.string,
|
|
|
|
|
sortDirection: PropTypes.string,
|
|
|
|
|
onSort: PropTypes.func,
|
2021-05-13 14:30:42 +00:00
|
|
|
onSelectActionClick: PropTypes.func,
|
2021-04-04 12:45:24 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default DataTable;
|