Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React, { useState, useEffect, useRef } from "react";
- //import makeData from "../makeData";
- import { useTableState } from "react-table";
- import Table from "../TransactionPanelTable";
- // Simulate a server
- const getServerData = async ({ filters, sortBy, pageSize, pageIndex }) => {
- await new Promise(resolve => setTimeout(resolve, 500));
- // Ideally, you would pass this info to the server, but we'll do it here for convenience
- const filtersArr = Object.entries(filters);
- // Get our base data
- let rows = [];
- rows.push({
- transaction_seq: 5418862,
- record_count: 300,
- user_id: "test",
- updated_at: "09-MAY-19 10.01.45.371373000 PM",
- duration: 5.7
- });
- // Apply Filters
- if (filtersArr.length) {
- rows = rows.filter(row =>
- filtersArr.every(([key, value]) => row[key].includes(value))
- );
- }
- // Apply Sorting
- if (sortBy.length) {
- const [{ id, desc }] = sortBy;
- rows = [...rows].sort(
- (a, b) => (a[id] > b[id] ? 1 : a[id] === b[id] ? 0 : -1) * (desc ? -1 : 1)
- );
- }
- // Get page counts
- const pageCount = Math.ceil(rows.length / pageSize);
- const rowStart = pageSize * pageIndex;
- const rowEnd = rowStart + pageSize;
- // Get the current page
- rows = rows.slice(rowStart, rowEnd);
- return {
- rows,
- pageCount
- };
- };
- export default function({ infinite }) {
- const [checkedMap, setCheckedMap] = useState(new Map());
- const [data, setData] = useState([]);
- const [loading, setLoading] = useState(false);
- const currentRequestRef = useRef();
- const fetchData = async () => {
- setLoading(true);
- // We can use a ref to disregard any outdated requests
- const id = Date.now();
- currentRequestRef.current = id;
- // Call our server for the data
- const { rows, pageCount } = await getServerData({
- filters,
- sortBy,
- pageSize,
- pageIndex
- });
- let newMap = new Map();
- rows.forEach(row => newMap.set(row, false));
- setCheckedMap(newMap);
- // If this is an outdated request, disregard the results
- if (currentRequestRef.current !== id) {
- return;
- }
- // Set the data and pageCount
- setData(rows);
- setState(old => ({
- ...old,
- pageCount
- }));
- setLoading(false);
- };
- const handleCheckedChange = row => {
- let modifiedMap = checkedMap;
- modifiedMap.set(row, !checkedMap.get(row));
- setCheckedMap(modifiedMap);
- console.log(checkedMap);
- };
- const columns = [
- {
- Header: "Transaction(s)",
- className: "left",
- columns: [
- {
- id: "checkbox",
- accessor: "checkbox",
- key: "transaction_seq",
- Cell: ({ original }) => {
- return (
- <input
- type="checkbox"
- className="checkbox"
- checked={checkedMap.get(original)} //again, use a key
- onChange={() => handleCheckedChange(original)}
- />
- );
- },
- sortable: false,
- width: 45
- },
- {
- Header: "Transaction Sequence",
- accessor: "transaction_seq",
- id: "transaction_seq",
- minWidth: 200,
- maxWidth: 300
- },
- {
- Header: "Record count",
- accessor: "record_count",
- width: 300
- },
- {
- Header: "User Id",
- accessor: "user_id",
- width: 300
- },
- {
- Header: "Updated At",
- accessor: "updated_at",
- width: 400
- },
- {
- Header: "Duration",
- accessor: "duration",
- width: 400
- }
- ]
- }
- ];
- // Make a new controllable table state instance
- const state = useTableState({ pageCount: 0 });
- const [{ sortBy, filters, pageIndex, pageSize }, setState] = state;
- // When sorting, filters, pageSize, or pageIndex change, fetch new data
- useEffect(() => {
- fetchData();
- }, [sortBy, filters, pageIndex, pageSize]);
- return (
- <React.Fragment>
- <Table
- {...{
- data,
- checkedMap,
- columns,
- infinite,
- state, // Pass the state to the table
- loading,
- manualSorting: true, // Manual sorting
- manualFilters: true, // Manual filters
- manualPagination: true, // Manual pagination
- disableMultiSort: true, // Disable multi-sort
- disableGrouping: true, // Disable grouping
- debug: true
- }}
- />
- </React.Fragment>
- );
- }
- import styled, { css } from "styled-components";
- import React, { useRef, useState, useEffect, useLayoutEffect } from "react";
- import { FixedSizeList as List } from "react-window";
- import {
- useTable,
- useColumns,
- useRows,
- useFilters,
- useSortBy,
- useExpanded,
- usePagination,
- useFlexLayout
- } from "react-table";
- const Table = styled.div`
- display: block;
- border-radius: 5px;
- border: solid 1px #ddd;
- overflow-x: auto;
- `;
- const RowBase = styled.div`
- display: flex;
- border-bottom: solid 1px #ddd;
- :last-child {
- border-bottom: 0;
- }
- `;
- const Row = styled(RowBase)`
- ${props =>
- props.even &&
- css`
- background: rgba(42, 117, 146, 0.12);
- `}
- `;
- const HeaderRow = styled(RowBase)`
- background: rgba(42, 117, 146, 1);
- border-bottom: solid 1px rgba(0, 0, 0, 0.2);
- color: white;
- `;
- const Pagination = styled(RowBase)`
- background: rgba(42, 117, 146, 1);
- color: white;
- `;
- const Cell = styled.div`
- border-right: solid 1px rgba(0, 0, 0, 0.1);
- padding: 0.6rem;
- :last-child {
- border-right: 0;
- }
- `;
- const Header = styled(Cell)`
- font-weight: bold;
- ${props => {
- const width = (props.sortedIndex + 1) * 5;
- return (
- props.sorted &&
- (props.sortedDesc
- ? css`
- box-shadow: inset 0 ${width}px hsla(0, 100%, 40%);
- `
- : css`
- box-shadow: inset 0 -${width}px hsl(55, 100%, 50%);
- `)
- );
- }};
- `;
- const Button = styled.button`
- font-size: 1rem;
- padding: 0.5rem 0.7rem;
- background: white;
- border-radius: 5px;
- cursor: pointer;
- :disabled {
- opacity: 0.3;
- }
- `;
- const Select = styled.select`
- appearance: none;
- background: white;
- border: 0;
- margin: 0;
- color: black;
- font-size: 1rem;
- border-radius: 5px;
- padding: 0.5rem 0.7rem;
- border: 0;
- cursor: pointer;
- `;
- const Input = styled.input`
- font-size: 1rem;
- padding: 0.5rem 0.7rem;
- background: white;
- border-radius: 5px;
- border: 1px solid rgba(0, 0, 0, 0.2);
- max-width: 100%;
- `;
- const useInfiniteScroll = ({
- enabled,
- sortBy,
- filters,
- pageIndex,
- pageSize
- }) => {
- const listRef = useRef();
- const [scrollToIndex, setScrollToIndex] = useState(0);
- const [rowHeight, setRowHeight] = useState(40);
- const [height, setHeight] = useState(500);
- const [overscan, setOverscan] = useState(25);
- useEffect(() => {
- if (!enabled) {
- return;
- }
- if (listRef.current) {
- listRef.current.scrollToItem(scrollToIndex, "start");
- }
- }, [scrollToIndex]);
- useEffect(() => {}, []);
- useLayoutEffect(() => {
- if (!enabled) {
- return;
- }
- if (listRef.current) {
- listRef.current.scrollToItem(0, "start");
- }
- }, [sortBy, filters]);
- return {
- listRef,
- scrollToIndex,
- setScrollToIndex,
- rowHeight,
- setRowHeight,
- height,
- setHeight,
- overscan,
- setOverscan
- };
- };
- export default function MyTable({ loading, infinite, ...props }) {
- const instance = useTable(
- {
- ...props
- },
- useColumns,
- useRows,
- useFilters,
- useSortBy,
- useExpanded,
- usePagination,
- useFlexLayout
- );
- const {
- getTableProps,
- headerGroups,
- rows,
- getRowProps,
- pageOptions,
- page,
- state: [{ pageIndex, pageSize, sortBy, filters }],
- gotoPage,
- prepareRow,
- previousPage,
- nextPage,
- setPageSize,
- canPreviousPage,
- canNextPage
- } = instance;
- const { listRef, rowHeight, height, overscan } = useInfiniteScroll({
- enabled: infinite,
- sortBy,
- filters,
- pageIndex,
- pageSize
- });
- let tableBody;
- const renderRow = (row, index, style = {}) => {
- if (!row) {
- return (
- <Row {...{ style, even: index % 2 }}>
- <Cell>Loading more...</Cell>
- </Row>
- );
- }
- prepareRow(row);
- return (
- <Row {...row.getRowProps({ style, even: index % 2 })}>
- {row.cells.map(cell => {
- const isPivot = row.groupByID === cell.column.id;
- const showAggregate = row.subRows && !isPivot;
- return (
- <Cell {...cell.getCellProps()}>
- {showAggregate ? (
- cell.column.aggregate ? (
- cell.render("Aggregated")
- ) : null
- ) : (
- <span>
- {isPivot ? (
- <span
- style={{
- cursor: "pointer",
- paddingLeft: `${row.depth * 2}rem`,
- paddingRight: "1rem",
- whiteSpace: "nowrap"
- }}
- onClick={() => row.toggleExpanded()}
- />
- ) : null}
- {cell.render("Cell")}
- {isPivot ? <span> ({row.subRows.length})</span> : null}
- <checkbox />
- </span>
- )}
- </Cell>
- );
- })}
- </Row>
- );
- };
- if (infinite) {
- tableBody = (
- <List
- ref={listRef}
- height={height}
- itemCount={rows.length + 1}
- itemSize={rowHeight}
- overscanCount={overscan}
- scrollToAlignment="start"
- {...getRowProps()}
- >
- {({ index, style }) => {
- const row = rows[index];
- return renderRow(row, index, style);
- }}
- </List>
- );
- } else {
- tableBody =
- page && page.length ? page.map((row, i) => renderRow(row, i)) : null;
- }
- let pagination;
- pagination = pageOptions.length ? (
- <Pagination {...getRowProps()}>
- <Cell>
- <Button onClick={() => previousPage()} disabled={!canPreviousPage}>
- Previous
- </Button>{" "}
- <Button onClick={() => nextPage()} disabled={!canNextPage}>
- Next
- </Button>{" "}
- <span>
- Page{" "}
- <strong>
- {pageIndex + 1} of {pageOptions.length}
- </strong>{" "}
- </span>
- <span>
- | Go to page:{" "}
- <Input
- type="number"
- defaultValue={pageIndex + 1}
- onChange={e => {
- const page = e.target.value ? Number(e.target.value) - 1 : 0;
- gotoPage(page);
- }}
- style={{ width: "100px" }}
- />
- </span>{" "}
- <Select
- value={pageSize}
- onChange={e => {
- setPageSize(Number(e.target.value));
- }}
- >
- {[10, 20, 30, 40, 50].map(pageSize => (
- <option key={pageSize} value={pageSize}>
- Show {pageSize}
- </option>
- ))}
- </Select>{" "}
- <Button onClick={() => reprocessConfirmation()}>Reprocess</Button>
- </Cell>
- </Pagination>
- ) : null;
- function reprocessConfirmation() {
- let confirmation = window.confirm("Do you want to reprocess transaction");
- if (confirmation === true) console.log("OK");
- else console.log("CANCEL");
- }
- return (
- <React.Fragment>
- <Table {...getTableProps()}>
- {headerGroups.map(headerGroup => (
- <HeaderRow {...headerGroup.getRowProps()}>
- {headerGroup.headers.map(column => (
- <Header
- {...column.getHeaderProps()}
- sorted={column.sorted}
- sortedDesc={column.sortedDesc}
- sortedIndex={column.sortedIndex}
- >
- <div>
- <span {...column.getSortByToggleProps()}>
- {column.render("Header")}
- </span>{" "}
- </div>
- {column.canFilter ? <div>{column.render("Filter")}</div> : null}
- </Header>
- ))}
- </HeaderRow>
- ))}
- {tableBody}
- <Row {...getRowProps()}>
- {loading ? (
- <Cell>
- <strong>Loading...</strong>
- </Cell>
- ) : (
- <Cell>{rows.length} Total Records</Cell>
- )}
- </Row>
- {pagination}
- </Table>
- </React.Fragment>
- );
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement