@seasketch/geoprocessing
Version:
Geoprocessing and reporting framework for SeaSketch 2.0
186 lines (175 loc) • 7.64 kB
JavaScript
/* eslint-disable @typescript-eslint/no-unused-vars */
import React, { useMemo } from "react";
import { useTable, usePagination, useSortBy } from "react-table";
import { styled } from "styled-components";
import { ChevronLeft } from "@styled-icons/bootstrap/ChevronLeft/ChevronLeft.esm.js";
import { ChevronRight } from "@styled-icons/bootstrap/ChevronRight/ChevronRight.esm.js";
import DataDownload from "../DataDownload.js";
import Toolbar from "../Toolbar.js";
const Button = styled.button `
display: inline;
color: #777;
font-size: 1em;
margin: 0px;
padding: 0px;
background-color: transparent;
border: 1px solid #ccc;
border-radius: 0.2rem;
&:disabled {
color: #ccc;
}
`;
export const TableStyled = styled.div `
margin: 10px 0px 20px 0px;
table {
font-family: sans-serif;
width: 100%;
border-collapse: collapse;
th {
padding-top: 8px;
padding: 5px;
font-weight: bolder;
}
.up-arrow {
position: relative;
}
.up-arrow::before {
content: "â–²";
position: absolute;
left: 2px;
bottom: 3px;
font-size: 8px;
color: #bbb;
}
.down-arrow {
position: relative;
}
.down-arrow::before {
content: "â–¼";
position: absolute;
left: 2px;
bottom: 3px;
font-size: 8px;
color: #bbb;
}
tr {
font-size: 1em;
text-align: left;
width: 100%;
padding: 2px 5px;
}
td {
padding: 3px 5px;
}
}
.pagination {
font-family: sans-serif;
padding: 0.5rem;
color: #999;
}
.gp-table-toolbar {
margin-top: -10px;
}
.gp-table-toolbar h2 {
flex-grow: 1;
}
`;
const defaultPropGetter = () => ({});
/**
* Table component suited to geoprocessing client reports.
* Builds on the `react-table` useTable hook and re-exports its interface,
* so reference those API docs to suit your needs.
* @param props
* @returns
*/
export function Table(props) {
const defaultColumn = useMemo(() => ({
Filter: undefined, // default filter UI
Cell: undefined, // default editable cell
}), []);
const { headerProps = defaultPropGetter, columnProps = defaultPropGetter, rowProps = defaultPropGetter, cellProps = defaultPropGetter, title, downloadEnabled, downloadFilename, downloadFormats, data, ...otherProps } = props;
// Default table options and state, caller can override and extend this via props
const defaultState = {
disableMultiSort: true,
defaultColumn,
initialState: {
pageSize: 20, // No paging when lower than that
},
};
const { getTableProps, getTableBodyProps, headerGroups, prepareRow, page, // Instead of 'rows', page just has rows for the active page
rows, canPreviousPage, canNextPage, pageOptions, pageCount, gotoPage, nextPage, previousPage, setPageSize, state: { pageIndex, pageSize, sortBy, groupBy, expanded, filters, selectedRowIds, }, } = useTable({
...defaultState,
...otherProps,
data,
}, useSortBy, usePagination);
return (React.createElement(TableStyled, null,
(title || downloadEnabled) && (React.createElement(Toolbar, { variant: "dense", useGutters: false, toolbarCls: "gp-table-toolbar" },
typeof title === "string" ? React.createElement("h2", null, title) : title,
downloadEnabled && (React.createElement("div", null,
React.createElement(DataDownload, { filename: downloadFilename, formats: downloadFormats, data: data }))))),
React.createElement("table", { className: props.className, ...getTableProps() },
React.createElement("thead", null, headerGroups.map((headerGroup) => {
const { key: headerGroupPropKey, ...otherHeaderGroupProps } = headerGroup.getHeaderGroupProps();
return (React.createElement("tr", { key: headerGroupPropKey, ...otherHeaderGroupProps }, headerGroup.headers.map((column) => {
const { key: headerPropKey, ...otherHeaderProps } = column.getHeaderProps([
{
className: column.className,
style: column.style,
},
columnProps(column), // user passed
headerProps(column), // user passed
]);
return (React.createElement("th", { ...otherHeaderProps, key: headerPropKey },
React.createElement("div", null,
column.canGroupBy ? (React.createElement("span", { ...column.getGroupByToggleProps() }, column.isGrouped ? "🛑 " : "👊 ")) : null,
React.createElement("span", { ...column.getSortByToggleProps() },
column.render("Header"),
column.isSorted ? (column.isSortedDesc ? (React.createElement("span", { className: "up-arrow" })) : (React.createElement("span", { className: "down-arrow" }))) : ("")))));
})));
})),
React.createElement("tbody", { ...getTableBodyProps() }, page.map((row) => {
prepareRow(row);
const { key: otherRowPropKey, ...otherRowProps } = row.getRowProps(rowProps(row) || {});
return (React.createElement("tr", { key: otherRowPropKey, ...otherRowProps }, row.cells.map((cell) => {
const cellVal = cell.value;
const { key: otherCellPropKey, ...otherCellProps } = cell.getCellProps([
{
className: cell.column.className,
style: cell.column.style,
},
columnProps(cell.column),
cellProps(cell),
]);
return (React.createElement("td", { key: otherCellPropKey, ...otherCellProps }, cell.isGrouped ? (
// If it's a grouped cell, add an expander and row count
React.createElement(React.Fragment, null,
React.createElement("span", { ...row.getToggleRowExpandedProps() }, row.isExpanded ? "👇" : "👉"),
" ",
cell.render("Cell", { editable: false }),
" (",
row.subRows.length,
")")) : cell.isAggregated ? (
// If the cell is aggregated, use the Aggregated
// renderer for cell
cell.render("Aggregated")) : cell.isPlaceholder ? null : ( // For cells with repeated values, render null
// Otherwise, just render the regular cell
cellVal)));
})));
}))),
React.createElement("div", { className: "pagination", style: !canNextPage && !canPreviousPage
? { display: "none" }
: { display: "block" } },
React.createElement(Button, { onClick: () => previousPage(), disabled: !canPreviousPage },
React.createElement(ChevronLeft, { size: 24 })),
" ",
React.createElement(Button, { onClick: () => nextPage(), disabled: !canNextPage },
React.createElement(ChevronRight, { size: 24 })),
" ",
React.createElement("span", { style: { paddingLeft: "5px" } },
"Page ",
pageIndex + 1,
" of ",
pageOptions.length))));
}
export default Table;
//# sourceMappingURL=Table.js.map