react-table#useTable JavaScript Examples

The following examples show how to use react-table#useTable. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Table.jsx    From token-factory with MIT License 6 votes vote down vote up
Table = ({ columns, data }) => {
  // Use the state and functions returned from useTable to build your UI
  const { getTableProps, headerGroups, rows, prepareRow } = useTable({
    columns,
    data,
  });

  return (
    <BTable striped bordered hover {...getTableProps()}>
      <thead>
        {headerGroups.map((headerGroup) => (
          <tr {...headerGroup.getHeaderGroupProps()}>
            {headerGroup.headers.map((column) => (
              <th {...column.getHeaderProps()}>{column.render("Header")}</th>
            ))}
          </tr>
        ))}
      </thead>
      <tbody>
        {rows.map((row, i) => {
          prepareRow(row);
          return (
            <tr {...row.getRowProps()}>
              {row.cells.map((cell) => {
                return <td {...cell.getCellProps()}>{cell.render("Cell")}</td>;
              })}
            </tr>
          );
        })}
      </tbody>
    </BTable>
  );
}
Example #2
Source File: App.js    From react-table-plugins with MIT License 5 votes vote down vote up
function Table({ columns, data }) {
  const defaultColumn = React.useMemo(
    () => ({
      // Let's set up our default Column Summary UI
      ColumnSummary: DefaultColumnSummary,
    }),
    []
  )

  // Use the state and functions returned from useTable to build your UI
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    footerGroups,
    rows,
    prepareRow,
    state: { columnSummary },
  } = useTable(
    {
      columns,
      data,
      defaultColumn,
      columnSummaryFns,
    },
    useColumnSummary
  )

  // Render the UI for your table
  return (
    <>
      <table {...getTableProps()}>
        <thead>
          {headerGroups.map(headerGroup => (
            <>
              <tr {...headerGroup.getHeaderGroupProps()}>
                {headerGroup.headers.map(column => (
                  <th {...column.getHeaderProps()}>
                    {column.render('Header')}
                  </th>
                ))}
              </tr>
            </>
          ))}
        </thead>
        <tbody {...getTableBodyProps()}>
          {rows.map((row, i) => {
            prepareRow(row)
            return (
              <tr {...row.getRowProps()}>
                {row.cells.map(cell => {
                  return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
                })}
              </tr>
            )
          })}
        </tbody>
        <tfoot>
          {footerGroups.slice(0, 1).map(group => (
            <tr {...group.getFooterGroupProps()}>
              {group.headers.map(column => (
                <td {...column.getFooterProps()}>
                  {column.hasColumnSummary && column.render('ColumnSummary')}
                </td>
              ))}
            </tr>
          ))}
        </tfoot>
      </table>
      <div>
        <pre>{JSON.stringify(columnSummary, null, 2)}</pre>
      </div>
    </>
  )
}
Example #3
Source File: RawTable.js    From covid19 with MIT License 5 votes vote down vote up
export default function RawTable(props) {
    const { columns, data, initialState, onRowClick, filterPlaceholder } = props

    const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = useTable(
        {
            columns,
            data,
            defaultColumn: { Filter: RegionFilter(filterPlaceholder), filter: flatten(textFilter) },
            initialState,
            getResetExpandedDeps: false
        },
        useFilters,
        useSortBy,
        useExpanded
    )

    return (
        <div className="data-table-wrap">
            {headerGroups[0].headers[1].render('Filter')}
            <table className="data-table" {...getTableProps()}>
                <thead>
                    {headerGroups.map((headerGroup, i) => (
                        <tr {...headerGroup.getHeaderGroupProps()}>
                            {headerGroup.headers.map((column, j) => (
                                <th {...column.getHeaderProps(column.getSortByToggleProps())}>
                                    {column.render('Header')}
                                </th>
                            ))}
                        </tr>
                    ))}
                </thead>
                <tbody {...getTableBodyProps()}>
                    {rows.map((row, i) => {
                        prepareRow(row)
                        return (
                            <tr id={`table-${row.original.region}`} {...row.getRowProps()}>
                                {row.cells.map((cell, cellIdx) => {
                                    return (
                                        <td
                                            {...cell.getCellProps()}
                                            onClick={cellIdx > 0 ? () => onRowClick(row) : null}
                                        >
                                            {cell.render('Cell')}
                                        </td>
                                    )
                                })}
                            </tr>
                        )
                    })}
                </tbody>
            </table>
            <div style={{ display: 'none' }}>{rows.length} regions</div>
        </div>
    )
}
Example #4
Source File: PoolPrizesTable.jsx    From v3-ui with MIT License 5 votes vote down vote up
PrizesTable = (props) => {
  const { t } = useTranslation()
  const { pool, prizes, querySymbol } = props

  const columns = useMemo(
    () => [
      {
        Header: '#',
        accessor: 'prizeNumber',
        className: 'text-left'
      },
      {
        Header: t('prize'),
        accessor: 'prizeAmount', // accessor is the "key" in the data
        className: 'text-left'
      },
      {
        Header: t('awardedOn'),
        accessor: 'awardedAt',
        className: 'text-left'
      },
      {
        Header: '',
        accessor: 'view',
        className: 'text-right',
        Cell: (row) => <div style={{ textAlign: 'right' }}>{row.value}</div>
      }
    ],
    []
  )

  const data = useMemo(() => {
    const isSohm =
      pool.prizePool.address.toLowerCase() === ETHEREUM_MAINNET_SOHM_POOL_ADDRESS.toLowerCase()

    const prizeRows = prizes.map((prize) => {
      return formatPrizeObject(t, pool, prize, querySymbol, isSohm)
    })

    const lastPrize = prizes[0]

    let currentPrize

    // If we have a prize amount then we know the last prize has been rewarded
    if (lastPrize.awardedBlock) {
      currentPrize = {
        prizeAmount: (
          <span className='text-flashy'>
            {isSohm ? (
              <>{numberWithCommas(pool.prize.amount)} sOHM</>
            ) : (
              <>${numberWithCommas(pool.prize.totalValueUsd, { precision: 2 })}</>
            )}
          </span>
        ),
        awardedAt: <span className='text-flashy'>{t('current')}</span>,
        view: (
          <Link
            href='/pools/[networkName]/[symbol]'
            as={`/pools/${pool.networkName}/${querySymbol}`}
            shallow
          >
            <a className='trans text-right w-full'>{t('viewDetails')}</a>
          </Link>
        )
      }

      prizeRows.unshift(currentPrize)
    }

    return prizeRows
  }, [pool, prizes])

  const tableInstance = useTable({
    columns,
    data
  })

  return <BasicTable tableInstance={tableInstance} />
}
Example #5
Source File: PlayersTable.jsx    From v3-ui with MIT License 5 votes vote down vote up
PlayersTable = (props) => {
  const { t } = useTranslation()

  let players = []
  if (props.balances) {
    players = props.balances
  }

  const { pool, prize } = props

  const columns = React.useMemo(
    () => [
      {
        Header: t('address'),
        accessor: 'address',
        className: 'td-address pb-2'
      },
      {
        Header: t('balance'),
        accessor: 'balance',
        className: 'td-balance pb-2'
      },
      {
        Header: '',
        accessor: 'view',
        className: 'td-view pb-2',
        Cell: (row) => <div style={{ textAlign: 'right' }}>{row.value}</div>
      }
    ],
    []
  )

  const winners = prize?.awardedControlledTokens.map((awardedControlledToken) => {
    return awardedControlledToken.winner
  })

  let data = React.useMemo(() => {
    return players.map((player) => {
      return formatPlayerObject(t, pool, player, winners)
    })
  }, [players, pool, pool.tokens.ticket.totalSupply])

  const tableInstance = useTable({
    columns,
    data
  })

  if (!players || players?.length === 0) {
    return null
  }

  return <BasicTable {...props} tableInstance={tableInstance} />
}
Example #6
Source File: Table.jsx    From token-factory with MIT License 5 votes vote down vote up
Table = ({columns, data, isDarkMode = false}) => {
    // Use the state and functions returned from useTable to build your UI
    const {getTableProps, headerGroups, rows, prepareRow} = useTable({
        columns,
        data,
    });

    return (
        <div className={styles.root}>
            <BTable striped bordered hover {...getTableProps()}>
                <thead style={{
                    backgroundColor: isDarkMode && Colors.lightBlack,
                    color: isDarkMode && Colors.white
                }}>
                { headerGroups.map((headerGroup, key) => (
                    <Fragment key={ key } >
                        <tr {...headerGroup.getHeaderGroupProps()}>
                            { headerGroup.headers.map((column, key) => (
                                <th key={ key } {...column.getHeaderProps()}>{ column.render("Header") }</th>
                            ))}
                        </tr>
                        <tr className={styles.spacer}/>
                    </Fragment>
                ))}
                </thead>
                <tbody>
                { rows.map((row, key) => {
                    prepareRow(row);
                    return (
                        <Fragment key={ key } >
                            <tr {...row.getRowProps()}>
                                { row.cells.map((cell, key) => {
                                    return (
                                        <td
                                            key={ key }
                                            style={{
                                                backgroundColor: isDarkMode && Colors.lightBlack,
                                                color: isDarkMode && Colors.white
                                            }}
                                            {...cell.getCellProps()}
                                        >
                                            { cell.render("Cell") }
                                        </td>);
                                })}
                            </tr>
                            <tr className={styles.spacer}/>
                        </Fragment>
                    );
                })}
                </tbody>
            </BTable>
        </div>
    );
}
Example #7
Source File: Table.js    From CampaignFinance with MIT License 5 votes vote down vote up
export default function Table({
  columns,
  data,
  onFetchData,
  initialSortBy,
  isLoading = false,
}) {
  const defaultColumn = React.useMemo(
    () => ({
      disableFilters: true,
      disableSortBy: true,
    }),
    []
  )

  // Use the useTable Hook to send the columns and data to build the table
  const {
    getTableProps, // table props from react-table
    getTableBodyProps, // table body props from react-table
    headerGroups, // headerGroups, if your table has groupings
    rows, // rows for the table based on the data passed
    prepareRow, // Prepare the row (this function needs to be called for each row before getting the row props)
    state: { sortBy, filters }, // track the current sort and filter state so we can call appropriate callbacks
  } = useTable(
    {
      columns,
      data,
      defaultColumn,
      initialState: initialSortBy ? { sortBy: initialSortBy } : undefined,
      disableMultiSort: true,
      manualSortBy: true,
      manualFilters: true,
    },
    useFilters,
    useGlobalFilter,
    useSortBy
  )

  // 250ms debounce
  const onFetchDataDebounced = useAsyncDebounce(onFetchData, 250)

  useEffect(() => {
    if (onFetchData) {
      onFetchDataDebounced({ filters, sortBy })
    }
  }, [onFetchData, onFetchDataDebounced, filters, sortBy])

  return (
    <USTable bordered={true} fullWidth={true} {...getTableProps()}>
      <thead>
        {headerGroups.map((headerGroup) => (
          <tr {...headerGroup.getHeaderGroupProps()}>
            {headerGroup.headers.map((column) => (
              <th {...column.getHeaderProps()}>
                <div {...column.getSortByToggleProps()}>
                  {column.render('Header')}
                  {column.isSortedDesc === true && (
                    <img
                      src={SortDescending}
                      alt="Descending"
                      style={{
                        verticalAlign: 'middle',
                        marginLeft: '2px',
                        position: 'absolute',
                        marginTop: '4px',
                      }}
                      height="18px"
                      width="18px"
                    />
                  )}
                  {column.isSortedDesc === false && (
                    <img
                      src={SortAscending}
                      alt="Ascending"
                      style={{
                        verticalAlign: 'middle',
                        marginLeft: '2px',
                        position: 'absolute',
                        marginTop: '4px',
                      }}
                      height="18px"
                      width="18px"
                    />
                  )}
                  {column.canSort && column.isSortedDesc === undefined && (
                    <img
                      src={SortUnsorted}
                      alt="Unsorted"
                      style={{
                        verticalAlign: 'middle',
                        marginLeft: '2px',
                        position: 'absolute',
                        marginTop: '4px',
                      }}
                      height="18px"
                      width="18px"
                    />
                  )}
                </div>
                <div>{column.canFilter && column.render('Filter')}</div>
              </th>
            ))}
          </tr>
        ))}
      </thead>
      <tbody {...getTableBodyProps()}>
        {isLoading ? (
          <tr>
            <td colSpan={columns.length}>
              <Spinner />
            </td>
          </tr>
        ) : (
          <>
            {rows.map((row, i) => {
              prepareRow(row)
              return (
                <tr {...row.getRowProps()}>
                  {row.cells.map((cell) => {
                    return (
                      <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
                    )
                  })}
                </tr>
              )
            })}
          </>
        )}
      </tbody>
    </USTable>
  )
}
Example #8
Source File: JobResultTable.js    From awsboilerplate with MIT License 5 votes vote down vote up
function JobResultTable({ tableData } ) {

   const columns = React.useMemo(
     () => [
       {
         Header: 'ID',
         accessor: 'id', // accessor is the "key" in the data
       },
       {
         Header: 'Number',
         accessor: 'input',
       },
       {
         Header: 'Prime',
         accessor: 'isPrime',
       }
     ],
     []
   )

   const {
     getTableProps,
     getTableBodyProps,
     headerGroups,
     rows,
     prepareRow,
   } = useTable({ columns, data: tableData })

   return (
     <table {...getTableProps()} style={{ border: 'solid 1px blue' }}>
       <thead>
         {headerGroups.map(headerGroup => (
           <tr {...headerGroup.getHeaderGroupProps()}>
             {headerGroup.headers.map(column => (
               <th
                 {...column.getHeaderProps()}
                 style={{
                   color: 'black',
                   fontWeight: 'bold',
                 }}
               >
                 {column.render('Header')}
               </th>
             ))}
           </tr>
         ))}
       </thead>
       <tbody {...getTableBodyProps()}>
         {rows.map(row => {
           prepareRow(row)
           return (
             <tr {...row.getRowProps()}>
               {row.cells.map(cell => {
                 return (
                   <td
                     {...cell.getCellProps()}
                     style={{
                       padding: '10px',
                       border: 'solid 1px gray',
                     }}
                   >
                     {cell.render('Cell')}
                   </td>
                 )
               })}
             </tr>
           )
         })}
       </tbody>
     </table>
   )
 }
Example #9
Source File: JobAcceptTable.js    From awsboilerplate with MIT License 5 votes vote down vote up
function JobAcceptTable({ tableData } ) {

   const columns = React.useMemo(
     () => [
       {
         Header: 'HRef',
         accessor: 'href', // accessor is the "key" in the data
       },
       {
         Header: 'ID',
         accessor: 'id',
       },
     ],
     []
   )

   const {
     getTableProps,
     getTableBodyProps,
     headerGroups,
     rows,
     prepareRow,
   } = useTable({ columns, data: tableData })

   return (
     <table {...getTableProps()} style={{ border: 'solid 1px blue' }}>
       <thead>
         {headerGroups.map(headerGroup => (
           <tr {...headerGroup.getHeaderGroupProps()}>
             {headerGroup.headers.map(column => (
               <th
                 {...column.getHeaderProps()}
                 style={{
                   color: 'black',
                   fontWeight: 'bold',
                 }}
               >
                 {column.render('Header')}
               </th>
             ))}
           </tr>
         ))}
       </thead>
       <tbody {...getTableBodyProps()}>
         {rows.map(row => {
           prepareRow(row)
           return (
             <tr {...row.getRowProps()}>
               {row.cells.map(cell => {
                 return (
                   <td
                     {...cell.getCellProps()}
                     style={{
                       padding: '10px',
                       border: 'solid 1px gray'
                     }}
                   >
                     {cell.render('Cell')}
                   </td>
                 )
               })}
             </tr>
           )
         })}
       </tbody>
     </table>
   )
 }
Example #10
Source File: MemberTable.js    From foster-together-fe with MIT License 5 votes vote down vote up
function Table({ columns, data, props }) {
  const { push } = useHistory();
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow
  } = useTable(
    {
      columns,
      data
    },
    useSortBy
  );

  const firstPageRows = rows.slice(0, 15);

  return (
    <TableContain>
      <TableHtml {...getTableProps()}>
        <thead>
          {headerGroups.map(headerGroup => (
            <TableRow {...headerGroup.getHeaderGroupProps()}>
              {headerGroup.headers.map(column => (
                <TableHeader
                  {...column.getHeaderProps(column.getSortByToggleProps())}
                >
                  {column.render("Header")}
                  <span>
                    {column.isSorted
                      ? column.isSortedDesc
                        ? " ?"
                        : " ?"
                      : ""}
                  </span>
                </TableHeader>
              ))}
            </TableRow>
          ))}
        </thead>
        <tbody {...getTableBodyProps()}>
          {firstPageRows.map(row => {
            prepareRow(row);
            return (
              <TableRow {...row.getRowProps()}>
                {row.cells.map(cell => {
                  return (
                    <TableData
                      onClick={() =>
                        push(
                          `/${cell.row.original.userType}/${cell.row.original.id}`
                        )
                      }
                      {...cell.getCellProps()}
                    >
                      {cell.render("Cell")}
                    </TableData>
                  );
                })}
              </TableRow>
            );
          })}
        </tbody>
      </TableHtml>
      <br />
    </TableContain>
  );
}
Example #11
Source File: BuilderListView.jsx    From scaffold-directory with MIT License 4 votes vote down vote up
export default function BuilderListView({ serverUrl, mainnetProvider, userRole }) {
  const [builders, setBuilders] = useState([]);
  const [isLoadingBuilders, setIsLoadingBuilders] = useState(false);
  const { secondaryFontColor } = useCustomColorModes();
  const isAdmin = userRole === USER_ROLES.admin;

  const columns = useMemo(
    () => [
      {
        Header: "Builder",
        accessor: "builder",
        disableSortBy: true,
        Cell: ({ value }) => <BuilderAddressCell builderId={value} mainnetProvider={mainnetProvider} />,
      },
      {
        Header: "Challenges",
        accessor: "challenges",
        sortDescFirst: true,
      },
      {
        Header: "Socials",
        accessor: "socials",
        disableSortBy: true,
        Cell: ({ value }) => <BuilderSocialLinksCell builder={value} isAdmin={isAdmin} />,
      },
      {
        Header: "Last Activity",
        accessor: "lastActivity",
        sortDescFirst: true,
        Cell: ({ value }) => <DateWithTooltip timestamp={value} />,
      },
    ],
    // eslint-disable-next-line
    [userRole],
  );

  useEffect(() => {
    async function fetchBuilders() {
      setIsLoadingBuilders(true);
      const fetchedBuilders = await axios.get(serverUrl + serverPath);

      const processedBuilders = fetchedBuilders.data.map(builder => ({
        builder: builder.id,
        challenges: getAcceptedChallenges(builder?.challenges)?.length ?? 0,
        socials: builder,
        lastActivity: builderLastActivity(builder),
      }));

      setBuilders(processedBuilders);
      setIsLoadingBuilders(false);
    }

    fetchBuilders();
  }, [serverUrl]);

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    prepareRow,
    page,
    canPreviousPage,
    canNextPage,
    pageOptions,
    pageCount,
    gotoPage,
    nextPage,
    previousPage,
    setPageSize,
    state: { pageIndex, pageSize },
  } = useTable(
    {
      columns,
      data: builders,
      initialState: { pageIndex: 0, pageSize: 25, sortBy: useMemo(() => [{ id: "lastActivity", desc: true }], []) },
    },
    useSortBy,
    usePagination,
  );

  return (
    <Container maxW="container.lg">
      <Container maxW="container.md" centerContent>
        <Heading as="h1" mb="4">
          All Builders
        </Heading>
        <Text color={secondaryFontColor} textAlign="center" mb="10">
          List of Ethereum builders creating products, prototypes, and tutorials with{" "}
          <Link href="https://github.com/scaffold-eth/scaffold-eth" color="teal.500" isExternal>
            scaffold-eth
          </Link>
          .
        </Text>
      </Container>
      {isLoadingBuilders ? (
        <BuilderListSkeleton />
      ) : (
        <Box overflowX="auto" mb={8}>
          <Center mb={5}>
            <chakra.strong mr={2}>Total builders:</chakra.strong> {builders.length}
          </Center>
          <Table {...getTableProps()}>
            <Thead>
              {headerGroups.map(headerGroup => (
                <Tr {...headerGroup.getHeaderGroupProps()}>
                  {headerGroup.headers.map(column => (
                    <Th {...column.getHeaderProps(column.getSortByToggleProps())}>
                      {column.render("Header")}
                      <chakra.span pl="4">
                        {column.isSorted ? (
                          column.isSortedDesc ? (
                            <TriangleDownIcon aria-label="sorted descending" />
                          ) : (
                            <TriangleUpIcon aria-label="sorted ascending" />
                          )
                        ) : null}
                      </chakra.span>
                    </Th>
                  ))}
                </Tr>
              ))}
            </Thead>
            <Tbody {...getTableBodyProps()}>
              {page.map(row => {
                prepareRow(row);
                return (
                  <Tr {...row.getRowProps()}>
                    {row.cells.map(cell => (
                      <Td {...cell.getCellProps()}>{cell.render("Cell")}</Td>
                    ))}
                  </Tr>
                );
              })}
            </Tbody>
          </Table>

          <Center mt={4}>
            <ButtonGroup>
              <Button onClick={() => gotoPage(0)} disabled={!canPreviousPage}>
                {"<<"}
              </Button>
              <Button onClick={() => previousPage()} disabled={!canPreviousPage}>
                {"<"}
              </Button>
              <Button onClick={() => nextPage()} disabled={!canNextPage}>
                {">"}
              </Button>
              <Button onClick={() => gotoPage(pageCount - 1)} disabled={!canNextPage}>
                {">>"}
              </Button>
            </ButtonGroup>
          </Center>
          <Center mt={4}>
            <Text mr={4}>
              Page{" "}
              <strong>
                {pageIndex + 1} of {pageOptions.length}
              </strong>{" "}
            </Text>
            <Box>
              <Select
                isFullWidth={false}
                value={pageSize}
                onChange={e => {
                  setPageSize(Number(e.target.value));
                }}
              >
                {[25, 50, 100].map(pageSizeOption => (
                  <option key={pageSizeOption} value={pageSizeOption}>
                    Show {pageSizeOption}
                  </option>
                ))}
              </Select>
            </Box>
          </Center>
        </Box>
      )}
    </Container>
  );
}
Example #12
Source File: index.jsx    From react-firebase-admin with MIT License 4 votes vote down vote up
Table = ({ columns, data }) => {
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    page,
    prepareRow,
    pageCount,
    state: { pageIndex, pageSize },
    gotoPage,
    previousPage,
    nextPage,
    setPageSize,
    canPreviousPage,
    canNextPage,
  } = useTable(
    {
      columns,
      data,
    },
    useSortBy,
    usePagination
  );

  const perPage = useFormatMessage('Table.perPage');

  return (
    <div className="table-wrapper">
      <table
        className="table is-striped has-mobile-cards is-hoverable"
        {...getTableProps()}
      >
        <thead>
          {headerGroups.map((headerGroup) => (
            <tr {...headerGroup.getHeaderGroupProps()}>
              {headerGroup.headers.map((column) => (
                <th
                  className={classNames(
                    { [classes.isCurrentSort]: column.isSorted },
                    { [classes.isSortable]: column.canSort }
                  )}
                  {...column.getHeaderProps(column.getSortByToggleProps())}
                >
                  <div className="th-wrap">
                    {column.render('Header')}
                    {column.isSorted && (
                      <span className="icon is-small">
                        <i
                          className={classNames(
                            'mdi',
                            classes.tableIcon,
                            { 'mdi-arrow-down': column.isSortedDesc },
                            { 'mdi-arrow-up': !column.isSortedDesc }
                          )}
                        />
                      </span>
                    )}
                  </div>
                </th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody {...getTableBodyProps()}>
          {page.map((row) => {
            prepareRow(row);
            return (
              <tr {...row.getRowProps()}>
                {row.cells.map((cell) => {
                  return (
                    <td
                      className={classNames(
                        { 'is-actions-cell': cell.column.id === 'actions' },
                        {
                          'has-no-head-mobile is-image-cell':
                            cell.column.id === 'logoUrl',
                        }
                      )}
                      data-label={cell.column.Header}
                      {...cell.getCellProps()}
                    >
                      {cell.render('Cell')}
                    </td>
                  );
                })}
              </tr>
            );
          })}
        </tbody>
      </table>
      <div className={classNames('level', classes.level)}>
        <div className="level-left">
          <div className="control">
            <span className="select">
              <select
                value={pageSize}
                onChange={(e) => {
                  setPageSize(Number(e.target.value));
                }}
              >
                {[5, 10, 15, 20, 50].map((size) => (
                  <option key={size} value={size}>
                    {size} {perPage}
                  </option>
                ))}
              </select>
            </span>
          </div>
        </div>
        <div className="level-right">
          <div className="level-item">
            <nav className="pagination">
              <button
                type="button"
                className="pagination-link pagination-previous"
                onClick={() => previousPage()}
                disabled={!canPreviousPage}
              >
                <span className="icon" aria-hidden="true">
                  <i className="mdi mdi-chevron-left mdi-24px" />
                </span>
              </button>
              <button
                type="button"
                className="pagination-link pagination-next"
                onClick={() => nextPage()}
                disabled={!canNextPage}
              >
                <span className="icon" aria-hidden="true">
                  <i className="mdi mdi-chevron-right mdi-24px" />
                </span>
              </button>
              <ul className="pagination-list">
                {pageIndex !== 0 && (
                  <li>
                    <button
                      type="button"
                      className="pagination-link"
                      onClick={() => gotoPage(0)}
                    >
                      1
                    </button>
                  </li>
                )}
                {pageIndex > 3 && (
                  <li>
                    <span className="pagination-ellipsis">…</span>
                  </li>
                )}
                {pageIndex === 3 && (
                  <li>
                    <button
                      type="button"
                      className="pagination-link"
                      onClick={() => gotoPage(1)}
                    >
                      2
                    </button>
                  </li>
                )}
                {pageIndex - 1 > 0 && (
                  <li>
                    <button
                      type="button"
                      className="pagination-link"
                      onClick={() => previousPage()}
                    >
                      {pageIndex}
                    </button>
                  </li>
                )}
                <li>
                  <button
                    type="button"
                    className={classNames(
                      'pagination-link',
                      classes.currentPage
                    )}
                    aria-current="true"
                  >
                    {pageIndex + 1}
                  </button>
                </li>
                {canNextPage && (
                  <li>
                    <button
                      type="button"
                      className="pagination-link"
                      onClick={() => nextPage()}
                    >
                      {pageIndex + 2}
                    </button>
                  </li>
                )}
                {pageCount - pageIndex === 4 && (
                  <li>
                    <button
                      type="button"
                      className="pagination-link"
                      onClick={() => gotoPage(pageCount - 2)}
                    >
                      {pageCount - 1}
                    </button>
                  </li>
                )}
                {pageCount - pageIndex > 4 && (
                  <li>
                    <span className="pagination-ellipsis">…</span>
                  </li>
                )}
                {pageIndex + 2 < pageCount && (
                  <li>
                    <button
                      type="button"
                      className="pagination-link"
                      onClick={() => gotoPage(pageCount - 1)}
                    >
                      {pageCount}
                    </button>
                  </li>
                )}
              </ul>
            </nav>
          </div>
        </div>
      </div>
    </div>
  );
}
Example #13
Source File: auth.js    From peppermint with GNU Affero General Public License v3.0 4 votes vote down vote up
function Table({ columns, data }) {
  const filterTypes = React.useMemo(
    () => ({
      // Add a new fuzzyTextFilterFn filter type.
      // fuzzyText: fuzzyTextFilterFn,
      // Or, override the default text filter to use
      // "startWith"
      text: (rows, id, filterValue) =>
        rows.filter((row) => {
          const rowValue = row.values[id];
          return rowValue !== undefined
            ? String(rowValue)
                .toLowerCase()
                .startsWith(String(filterValue).toLowerCase())
            : true;
        }),
    }),
    []
  );

  const defaultColumn = React.useMemo(
    () => ({
      // Let's set up our default Filter UI
      Filter: DefaultColumnFilter,
    }),
    []
  );

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    page,
    prepareRow,
    canPreviousPage,
    canNextPage,
    pageCount,
    gotoPage,
    nextPage,
    previousPage,
    setPageSize,
    state: { pageIndex, pageSize },
  } = useTable(
    {
      columns,
      data,
      defaultColumn, // Be sure to pass the defaultColumn option
      filterTypes,
      initialState: {
        pageIndex: 0,
      },
    },
    useFilters, // useFilters!
    useGlobalFilter,
    usePagination
  );

  return (
    <div className="overflow-x-auto md:-mx-6 lg:-mx-8">
      <div className="py-2 align-middle inline-block min-w-full md:px-6 lg:px-8">
        <div className="shadow overflow-hidden border-b border-gray-200 md:rounded-lg">
          <table
            {...getTableProps()}
            className="min-w-full divide-y divide-gray-200"
          >
            <thead className="bg-gray-50">
              {headerGroups.map((headerGroup) => (
                <tr
                  {...headerGroup.getHeaderGroupProps()}
                  key={headerGroup.headers.map((header) => header.id)}
                >
                  {headerGroup.headers.map((column) =>
                    column.hideHeader === false ? null : (
                      <th
                        {...column.getHeaderProps()}
                        className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
                      >
                        {column.render("Header")}
                        {/* Render the columns filter UI */}
                        <div>
                          {column.canFilter ? column.render("Filter") : null}
                        </div>
                      </th>
                    )
                  )}
                </tr>
              ))}
            </thead>
            <tbody {...getTableBodyProps()}>
              {page.map((row, i) => {
                prepareRow(row);
                return (
                  <tr {...row.getRowProps()} className="bg-white">
                    {row.cells.map((cell) => (
                      <td
                        className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900"
                        {...cell.getCellProps()}
                      >
                        {cell.render("Cell")}
                      </td>
                    ))}
                  </tr>
                );
              })}
            </tbody>
          </table>

          <nav
            className="bg-white px-4 py-3 flex items-center justify-between border-t border-gray-200 sm:px-6"
            aria-label="Pagination"
          >
            <div className="hidden sm:block">
              <div className="flex flex-row flex-nowrap w-full space-x-2">
                <p
                  htmlFor="location"
                  className="block text-sm font-medium text-gray-700 mt-4"
                >
                  Show
                </p>
                <select
                  id="location"
                  name="location"
                  className="block w-full pl-3 pr-10 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md"
                  value={pageSize}
                  onChange={(e) => {
                    setPageSize(Number(e.target.value));
                  }}
                >
                  {[10, 20, 30, 40, 50].map((pageSize) => (
                    <option key={pageSize} value={pageSize}>
                      {pageSize}
                    </option>
                  ))}
                </select>
              </div>
            </div>
            <div className="flex-1 flex justify-between sm:justify-end">
              <button
                className="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50"
                type="button"
                onClick={() => previousPage()}
                disabled={!canPreviousPage}
              >
                Previous
              </button>
              <button
                className="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50"
                type="button"
                onClick={() => nextPage()}
                disabled={!canNextPage}
              >
                Next
              </button>
            </div>
          </nav>
        </div>
      </div>
    </div>
  );
}
Example #14
Source File: clients.js    From peppermint with GNU Affero General Public License v3.0 4 votes vote down vote up
function Table({ columns, data }) {
  const filterTypes = React.useMemo(
    () => ({
      // Add a new fuzzyTextFilterFn filter type.
      // fuzzyText: fuzzyTextFilterFn,
      // Or, override the default text filter to use
      // "startWith"
      text: (rows, id, filterValue) =>
        rows.filter((row) => {
          const rowValue = row.values[id];
          return rowValue !== undefined
            ? String(rowValue)
                .toLowerCase()
                .startsWith(String(filterValue).toLowerCase())
            : true;
        }),
    }),
    []
  );

  const defaultColumn = React.useMemo(
    () => ({
      // Let's set up our default Filter UI
      Filter: DefaultColumnFilter,
    }),
    []
  );

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    page,
    prepareRow,
    canPreviousPage,
    canNextPage,
    pageCount,
    gotoPage,
    nextPage,
    previousPage,
    setPageSize,
    state: { pageIndex, pageSize },
  } = useTable(
    {
      columns,
      data,
      defaultColumn, // Be sure to pass the defaultColumn option
      filterTypes,
      initialState: {
        pageIndex: 0,
      },
    },
    useFilters, // useFilters!
    useGlobalFilter,
    usePagination
  );

  return (
    <div className="overflow-x-auto md:-mx-6 lg:-mx-8">
      <div className="py-2 align-middle inline-block min-w-full md:px-6 lg:px-8">
        <div className="shadow overflow-hidden border-b border-gray-200 md:rounded-lg">
          <table
            {...getTableProps()}
            className="min-w-full divide-y divide-gray-200"
          >
            <thead className="bg-gray-50">
              {headerGroups.map((headerGroup) => (
                <tr
                  {...headerGroup.getHeaderGroupProps()}
                  key={headerGroup.headers.map((header) => header.id)}
                >
                  {headerGroup.headers.map((column) =>
                    column.hideHeader === false ? null : (
                      <th
                        {...column.getHeaderProps()}
                        className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
                      >
                        {column.render("Header")}
                        {/* Render the columns filter UI */}
                        <div>
                          {column.canFilter ? column.render("Filter") : null}
                        </div>
                      </th>
                    )
                  )}
                </tr>
              ))}
            </thead>
            <tbody {...getTableBodyProps()}>
              {page.map((row, i) => {
                prepareRow(row);
                return (
                  <tr {...row.getRowProps()} className="bg-white">
                    {row.cells.map((cell) => (
                      <td
                        className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900"
                        {...cell.getCellProps()}
                      >
                        {cell.render("Cell")}
                      </td>
                    ))}
                  </tr>
                );
              })}
            </tbody>
          </table>

          <nav
            className="bg-white px-4 py-3 flex items-center justify-between border-t border-gray-200 sm:px-6"
            aria-label="Pagination"
          >
            <div className="hidden sm:block">
              <div className="flex flex-row flex-nowrap w-full space-x-2">
                <p
                  htmlFor="location"
                  className="block text-sm font-medium text-gray-700 mt-4"
                >
                  Show
                </p>
                <select
                  id="location"
                  name="location"
                  className="block w-full pl-3 pr-10 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md"
                  value={pageSize}
                  onChange={(e) => {
                    setPageSize(Number(e.target.value));
                  }}
                >
                  {[10, 20, 30, 40, 50].map((pageSize) => (
                    <option key={pageSize} value={pageSize}>
                      {pageSize}
                    </option>
                  ))}
                </select>
              </div>
            </div>
            <div className="flex-1 flex justify-between sm:justify-end">
              <button
                className="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50"
                type="button"
                onClick={() => previousPage()}
                disabled={!canPreviousPage}
              >
                Previous
              </button>
              <button
                className="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50"
                type="button"
                onClick={() => nextPage()}
                disabled={!canNextPage}
              >
                Next
              </button>
            </div>
          </nav>
        </div>
      </div>
    </div>
  );
}
Example #15
Source File: VotersTable.jsx    From pooltogether-governance-ui with MIT License 4 votes vote down vote up
VotersTable = (props) => {
  const { id } = props

  const { t } = useTranslation()
  const router = useRouter()

  const { data: totalPages, isFetched: totalPagesIsFetched } = useProposalVotesTotalPages(id)
  const currentPage = router?.query?.page ? parseInt(router.query.page, 10) : 1
  const baseAsPath = `/proposals/${id}`
  const baseHref = '/proposals/[id]'

  const { data, isFetching, isFetched } = useProposalVotes(id, currentPage)

  const columns = React.useMemo(() => {
    return [
      {
        Header: t('voter'),
        accessor: 'voter',
        Cell: VoterCell,
        headerClassName: 'text-xs text-accent-1 font-light pb-2'
      },
      {
        Header: t('votingWeight'),
        accessor: 'votes',
        className: 'text-xxs xs:text-sm text-accent-1 pb-auto',
        headerClassName: 'text-xs text-accent-1 font-light pb-2'
      },
      {
        Header: t('decision'),
        accessor: 'support',
        Cell: SupportCell,
        className: 'text-xxs xs:text-sm text-accent-1 pb-auto',
        headerClassName: 'text-xs text-accent-1 font-light pb-2'
      }
    ]
  }, [])

  const rowData = React.useMemo(() => {
    if (!data || !data.votes) {
      return []
    }

    return data.votes.map((vote) => ({
      voter: vote.voter.id,
      votes: formatVotes(vote.votesRaw),
      support: vote.support
    }))
  }, [data])

  const tableInstance = useTable({
    columns,
    data: rowData
  })

  if (!totalPagesIsFetched) return null

  return (
    <>
      {totalPages === 0 ? (
        <BlankStateMessage>{t('noVotesHaveBeenCastYet')}</BlankStateMessage>
      ) : (
        <>
          <div className='basic-table-min-height'>
            {isFetching && !isFetched ? (
              <LoadingDots />
            ) : (
              <BasicTable tableInstance={tableInstance} />
            )}
          </div>

          <DefaultPaginationButtons
            currentPage={currentPage}
            totalPages={totalPages}
            baseAsPath={baseAsPath}
            baseHref={baseHref}
          />
        </>
      )}
    </>
  )
}
Example #16
Source File: Table.js    From os-league-tools with MIT License 4 votes vote down vote up
export default function Table({
    columns,
    data,
    filters = [],
    filterState,
    globalFilter,
    defaultColumn,
    initialState,
    ExpandedRow,
    customFilterProps = {},
    enableResizeColumns = true,
}) {
    const [records, setRecords] = useState(data);

    useEffect(() => {
        if (filters.length) {
            setRecords(data.filter(record => filters.every(filter => filter(record, filterState, customFilterProps))));
        } else {
            setRecords(data);
        }
    }, [filterState, data, customFilterProps]);

    const table = useTable(
        {
            initialState: { pageSize: 25, ...initialState },
            columns,
            data: records,
            defaultColumn,
            globalFilter,
            manualFilters: true,
            autoResetGlobalFilter: false,
            autoResetSortBy: false,
            autoResetPage: false,
            autoResetExpanded: false,
            getRowId: useCallback(row => row.id, []),
        },
        useFlexLayout,
        useResizeColumns,
        useGlobalFilter,
        useSortBy,
        useExpanded,
        usePagination
    );

    useEffect(() => {
        // Reset to first page when filters are changed
        table.gotoPage(0);
    }, [filterState]);

    const moveRow = (dragIndex, hoverIndex) => {
        const dragRecord = records[dragIndex];
        setRecords(
            update(records, {
                $splice: [
                    [dragIndex, 1],
                    [hoverIndex, 0, dragRecord],
                ],
            })
        );
    };

    return (
        <>
            <div className='flex flex-row flex-wrap justify-between pb-3 px-3 items-end'>
                <span className='italic text-sm'>Showing: {table.page.length} rows</span>
                <SearchBox globalFilter={table.state.globalFilter} setGlobalFilter={table.setGlobalFilter} />
            </div>
            <div className='overflow-auto px-3'>
                <DndProvider backend={HTML5Backend}>
                    <div {...table.getTableProps()} style={{ minWidth: 'min-content' }}>
                        <div>
                            {table.headerGroups.map(headerGroup => (
                                <div
                                    {...headerGroup.getHeaderGroupProps()}
                                    className='heading-accent-md leading-loose border-b border-accent w-full'
                                >
                                    {headerGroup.headers.map(column => (
                                        <div
                                            {...column.getHeaderProps(column.getSortByToggleProps())}
                                            className='relative font-bold text-center'
                                        >
                                            {column.render('Header')}
                                            {column.isSorted && (
                                                <span className='icon-base absolute'>
                                                    {column.isSortedDesc ? 'arrow_drop_down' : 'arrow_drop_up'}
                                                </span>
                                            )}
                                            {enableResizeColumns && (
                                                <span {...column.getResizerProps()} className='resizer icon-lg'>
                                                    drag_handle
                                                </span>
                                            )}
                                        </div>
                                    ))}
                                </div>
                            ))}
                        </div>
                        <div {...table.getTableBodyProps()}>
                            {table.page.map(
                                (row, index) =>
                                    table.prepareRow(row) || (
                                        <Row
                                            index={index}
                                            row={row}
                                            moveRow={moveRow}
                                            isReorderEnabled={filterState?.reorderEnabled}
                                            ExpandedRow={ExpandedRow}
                                            {...row.getRowProps()}
                                        />
                                    )
                            )}
                        </div>
                        <div className='flex flex-col justify-center text-center'>
                            <div>
                                <PageButton
                                    onClick={() => table.gotoPage(0)}
                                    disabled={!table.canPreviousPage}
                                    text='<<'
                                />
                                <PageButton
                                    onClick={() => table.previousPage()}
                                    disabled={!table.canPreviousPage}
                                    text='<'
                                />
                                <span className='text-xs'>
                                    {table.state.pageIndex + 1} of {table.pageOptions.length}
                                </span>
                                <PageButton onClick={() => table.nextPage()} disabled={!table.canNextPage} text='>' />
                                <PageButton
                                    onClick={() => table.gotoPage(table.pageCount - 1)}
                                    disabled={!table.canNextPage}
                                    text='>>'
                                />
                            </div>

                            <span className='text-xs'>
                                Show:
                                <select
                                    className='input-primary text-xs p-0 ml-1 text-center'
                                    value={table.state.pageSize}
                                    onChange={e => {
                                        table.setPageSize(Number(e.target.value));
                                    }}
                                >
                                    {[25, 50, 100, 200].map(pageSize => (
                                        <option key={pageSize} value={pageSize}>
                                            {pageSize}
                                        </option>
                                    ))}
                                </select>
                            </span>
                        </div>
                    </div>
                </DndProvider>
            </div>
        </>
    );
}
Example #17
Source File: Table.jsx    From frontend-app-support-tools with GNU Affero General Public License v3.0 4 votes vote down vote up
export default function Table({
  columns, data, renderRowSubComponent, styleName, isResponsive, defaultSortColumn,
}) {
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
    visibleColumns,
  } = useTable(
    {
      columns,
      data,
      initialState: {
        sortBy: defaultSortColumn,
      },
    },
    useSortBy,
    useExpanded, // Using useExpanded to track the expanded state
  );

  return (
    <div className={isResponsive ? 'table-responsive' : ''}>
      <table {...getTableProps()} className={styleName}>
        <thead>
          {headerGroups.map(headerGroup => (
            <tr {...headerGroup.getHeaderGroupProps()}>
              {headerGroup.headers.map(column => (
                <th {...column.getHeaderProps(column.sortable && column.getSortByToggleProps())}>
                  {column.render('Header')}
                  <span>
                    {/* eslint-disable-next-line no-nested-ternary */}
                    {column.isSorted
                      ? column.isSortedDesc
                        ? <FontAwesomeIcon icon={faSortDown} />
                        : <FontAwesomeIcon icon={faSortUp} />
                      : ''}
                  </span>
                </th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody {...getTableBodyProps()}>
          {rows.map((row) => {
            prepareRow(row);
            return (
              <React.Fragment key={row.id}>
                <tr>
                  {row.cells.map(cell => (
                    <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
                  ))}
                </tr>
                {/*
                    If the row is in an expanded state, render a row with a
                    column that fills the entire length of the table.
                  */}
                {row.isExpanded ? (
                  <tr>
                    <td colSpan={visibleColumns.length}>
                      {/*
                          Inside it, call our renderRowSubComponent function. In reality,
                          you could pass whatever you want as props to
                          a component like this, including the entire
                          table instance.
                          it's merely a rendering option we created for ourselves
                        */}
                      {renderRowSubComponent({ row })}
                    </td>
                  </tr>
                ) : null}
              </React.Fragment>
            );
          })}
        </tbody>
      </table>
      <br />
    </div>
  );
}
Example #18
Source File: history.js    From peppermint with GNU Affero General Public License v3.0 4 votes vote down vote up
function Table({ columns, data }) {
  const filterTypes = React.useMemo(
    () => ({
      // // Add a new fuzzyTextFilterFn filter type.
      // fuzzyText: fuzzyTextFilterFn,
      // // Or, override the default text filter to use
      // // "startWith"
      text: (rows, id, filterValue) =>
        rows.filter((row) => {
          const rowValue = row.values[id];
          return rowValue !== undefined
            ? String(rowValue)
                .toLowerCase()
                .startsWith(String(filterValue).toLowerCase())
            : true;
        }),
    }),
    []
  );

  const defaultColumn = React.useMemo(
    () => ({
      // Let's set up our default Filter UI
      Filter: DefaultColumnFilter,
    }),
    []
  );

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    page,
    prepareRow,
    canPreviousPage,
    canNextPage,
    pageCount,
    gotoPage,
    nextPage,
    previousPage,
    setPageSize,
    state: { pageIndex, pageSize },
  } = useTable(
    {
      columns,
      data,
      defaultColumn, // Be sure to pass the defaultColumn option
      filterTypes,
      initialState: {
        pageIndex: 0,
      },
    },
    useFilters, // useFilters!
    useGlobalFilter,
    usePagination
  );

  return (
    <div className="overflow-x-auto md:-mx-6 lg:-mx-8">
      <div className="py-2 align-middle inline-block min-w-full md:px-6 lg:px-8">
        <div className="shadow overflow-hidden border-b border-gray-200 md:rounded-lg">
          <table
            {...getTableProps()}
            className="min-w-full divide-y divide-gray-200"
          >
            <thead className="bg-gray-50">
              {headerGroups.map((headerGroup) => (
                <tr
                  {...headerGroup.getHeaderGroupProps()}
                  key={headerGroup.headers.map((header) => header.id)}
                >
                  {headerGroup.headers.map((column) =>
                    column.hideHeader === false ? null : (
                      <th
                        {...column.getHeaderProps()}
                        className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
                      >
                        {column.render("Header")}
                        {/* Render the columns filter UI */}
                        <div>
                          {column.canFilter ? column.render("Filter") : null}
                        </div>
                      </th>
                    )
                  )}
                </tr>
              ))}
            </thead>
            <tbody {...getTableBodyProps()}>
              {page.map((row, i) => {
                prepareRow(row);
                return (
                  <tr {...row.getRowProps()} className="bg-white">
                    {row.cells.map((cell) => (
                      <td
                        className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900"
                        {...cell.getCellProps()}
                      >
                        {cell.render("Cell")}
                      </td>
                    ))}
                  </tr>
                );
              })}
            </tbody>
          </table>

          <nav
            className="bg-white px-4 py-3 flex items-center justify-between border-t border-gray-200 sm:px-6"
            aria-label="Pagination"
          >
            <div className="hidden sm:block">
              <div className="flex flex-row flex-nowrap w-full space-x-2">
                <p
                  htmlFor="location"
                  className="block text-sm font-medium text-gray-700 mt-4"
                >
                  Show
                </p>
                <select
                  id="location"
                  name="location"
                  className="block w-full pl-3 pr-10 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md"
                  value={pageSize}
                  onChange={(e) => {
                    setPageSize(Number(e.target.value));
                  }}
                >
                  {[10, 20, 30, 40, 50].map((pageSize) => (
                    <option key={pageSize} value={pageSize}>
                      {pageSize}
                    </option>
                  ))}
                </select>
              </div>
            </div>
            <div className="flex-1 flex justify-between sm:justify-end">
              <button
                className="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50"
                type="button"
                onClick={() => previousPage()}
                disabled={!canPreviousPage}
              >
                Previous
              </button>
              <button
                className="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50"
                type="button"
                onClick={() => nextPage()}
                disabled={!canNextPage}
              >
                Next
              </button>
            </div>
          </nav>
        </div>
      </div>
    </div>
  );
}
Example #19
Source File: index.js    From peppermint with GNU Affero General Public License v3.0 4 votes vote down vote up
function Table({ columns, data }) {
  const filterTypes = React.useMemo(
    () => ({
      // Add a new fuzzyTextFilterFn filter type.
      // fuzzyText: fuzzyTextFilterFn,
      // Or, override the default text filter to use
      // "startWith"
      text: (rows, id, filterValue) =>
        rows.filter((row) => {
          const rowValue = row.values[id];
          return rowValue !== undefined
            ? String(rowValue)
                .toLowerCase()
                .startsWith(String(filterValue).toLowerCase())
            : true;
        }),
    }),
    []
  );

  const defaultColumn = React.useMemo(
    () => ({
      // Let's set up our default Filter UI
      Filter: DefaultColumnFilter,
    }),
    []
  );

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    page,
    prepareRow,
    canPreviousPage,
    canNextPage,
    pageCount,
    gotoPage,
    nextPage,
    previousPage,
    setPageSize,
    state: { pageIndex, pageSize },
  } = useTable(
    {
      columns,
      data,
      defaultColumn, // Be sure to pass the defaultColumn option
      filterTypes,
      initialState: {
        pageIndex: 0,
      },
    },
    useFilters, // useFilters!
    useGlobalFilter,
    usePagination
  );

  return (
    <div className="overflow-x-auto md:-mx-6 lg:-mx-8">
      <div className="py-2 align-middle inline-block min-w-full md:px-6 lg:px-8">
        <div className="shadow overflow-hidden border-b border-gray-200 md:rounded-lg">
          <table
            {...getTableProps()}
            className="min-w-full divide-y divide-gray-200"
          >
            <thead className="bg-gray-50">
              {headerGroups.map((headerGroup) => (
                <tr
                  {...headerGroup.getHeaderGroupProps()}
                  key={headerGroup.headers.map((header) => header.id)}
                >
                  {headerGroup.headers.map((column) =>
                    column.hideHeader === false ? null : (
                      <th
                        {...column.getHeaderProps()}
                        className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
                      >
                        {column.render("Header")}
                        <div>
                          {column.canFilter ? column.render("Filter") : null}
                        </div>
                      </th>
                    )
                  )}
                </tr>
              ))}
            </thead>
            <tbody {...getTableBodyProps()}>
              {page.map((row, i) => {
                prepareRow(row);
                return (
                  <tr {...row.getRowProps()} className="bg-white">
                    {row.cells.map((cell) => (
                      <td
                        className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900"
                        {...cell.getCellProps()}
                      >
                        {cell.render("Cell")}
                      </td>
                    ))}
                  </tr>
                );
              })}
            </tbody>
          </table>

          <nav
            className="bg-white px-4 py-3 flex items-center justify-between border-t border-gray-200 sm:px-6"
            aria-label="Pagination"
          >
            <div className="hidden sm:block">
              <div className="flex flex-row flex-nowrap w-full space-x-2">
                <p
                  htmlFor="location"
                  className="block text-sm font-medium text-gray-700 mt-4"
                >
                  Show
                </p>
                <select
                  id="location"
                  name="location"
                  className="block w-full pl-3 pr-10 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md"
                  value={pageSize}
                  onChange={(e) => {
                    setPageSize(Number(e.target.value));
                  }}
                >
                  {[10, 20, 30, 40, 50].map((pageSize) => (
                    <option key={pageSize} value={pageSize}>
                      {pageSize}
                    </option>
                  ))}
                </select>
              </div>
            </div>
            <div className="flex-1 flex justify-between sm:justify-end">
              <button
                className="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50"
                type="button"
                onClick={() => previousPage()}
                disabled={!canPreviousPage}
              >
                Previous
              </button>
              <button
                className="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50"
                type="button"
                onClick={() => nextPage()}
                disabled={!canNextPage}
              >
                Next
              </button>
            </div>
          </nav>
        </div>
      </div>
    </div>
  );
}
Example #20
Source File: Table.js    From plenty-interface with GNU General Public License v3.0 4 votes vote down vote up
Table = ({ searchQuery, columns, data, className }) => {
  useEffect(() => {
    setFilter('token', searchQuery);
  }, [searchQuery]);

  const {
    getTableProps,
    headerGroups,
    page,
    prepareRow,
    gotoPage,
    pageCount,
    state: { pageIndex },
    setFilter,
  } = useTable(
    {
      columns,
      data,
      initialState: {
        pageIndex: 0,
        pageSize: 10,
        sortBy: [
          {
            id: 'liquidity',
            desc: true,
          },
        ],
      },
      autoResetPage: false,
      autoResetExpanded: false,
      autoResetGroupBy: false,
      autoResetSelectedRows: false,
      autoResetSortBy: false,
      autoResetFilters: false,
      autoResetRowState: false,
    },
    useFilters,
    useSortBy,
    usePagination,
  );

  return (
    <>
      <div className={styles.tableContainer}>
        <div {...getTableProps()} className={clsx(styles.table, className)}>
          <div className={styles.thead}>
            {headerGroups.map((headerGroup) => (
              <div
                key={'will be overridden'}
                {...headerGroup.getHeaderGroupProps()}
                className={styles.th}
              >
                {headerGroup.headers.map((column) => (
                  <div
                    key={'will be overridden'}
                    {...column.getHeaderProps(column.getSortByToggleProps())}
                    className={styles.td}
                  >
                    <div className="flex flex-row align-items-center">
                      <span className="mx-1">{column.render('Header')}</span>

                      {column.id !== 'favorite' && (
                        <span>
                          {column.isSorted ? (
                            column.isSortedDesc ? (
                              <span className="material-icons flex">keyboard_arrow_down</span>
                            ) : (
                              <span className="material-icons flex">keyboard_arrow_up</span>
                            )
                          ) : (
                            <span className="material-icons invisible">keyboard_arrow_up</span>
                          )}
                        </span>
                      )}
                    </div>
                  </div>
                ))}
              </div>
            ))}
          </div>
          <div className={styles.tbody}>
            {page.map((row) => {
              prepareRow(row);
              return (
                <div key={'will be overridden'} {...row.getRowProps()} className={styles.tr}>
                  {row.cells.map((cell) => {
                    return (
                      <div
                        key={'will be overridden'}
                        {...cell.getCellProps()}
                        className={styles.td}
                      >
                        <span className="mx-1">{cell.render('Cell')}</span>
                      </div>
                    );
                  })}
                </div>
              );
            })}
          </div>
        </div>
      </div>

      <div className="d-flex justify-content-center mt-2">
        {Array(pageCount)
          .fill(0)
          .map((x, i) => (
            <div
              key={i}
              className={clsx(styles.page, {
                [styles.selected]: i === pageIndex,
              })}
              onClick={() => gotoPage(i)}
            >
              {i + 1}
            </div>
          ))}
      </div>
    </>
  );
}
Example #21
Source File: Table.js    From datapass with GNU Affero General Public License v3.0 4 votes vote down vote up
Table = ({
  columns,
  data,
  initialState = {},
  updateData,
  filterTypes,
  skipReset,
}) => {
  const defaultColumn = useMemo(
    () => ({
      Filter: () => null,
    }),
    []
  );

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    prepareRow,
    page,
    canPreviousPage,
    canNextPage,
    pageOptions,
    pageCount,
    gotoPage,
    nextPage,
    previousPage,
    state: { pageIndex },
  } = useTable(
    {
      columns,
      data,
      initialState,
      defaultColumn,
      autoResetPage: !skipReset,
      autoResetFilters: !skipReset,
      updateData,
      filterTypes,
    },
    useFilters,
    usePagination
  );

  return (
    <>
      <div className="admin-table-wrapper">
        <div className="admin-table">
          <table {...getTableProps()}>
            <thead>
              {headerGroups.map((headerGroup) => (
                <tr {...headerGroup.getHeaderGroupProps()}>
                  {headerGroup.headers.map((column) => (
                    <th {...column.getHeaderProps()}>
                      {column.render('Header')}
                      {column.canFilter && column.render('Filter')}
                    </th>
                  ))}
                </tr>
              ))}
            </thead>
            <tbody {...getTableBodyProps()}>
              {page.map((row, i) => {
                prepareRow(row);
                return (
                  <tr {...row.getRowProps()}>
                    {row.cells.map((cell) => (
                      <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
                    ))}
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>
      <div>
        <button onClick={() => gotoPage(0)} disabled={!canPreviousPage}>
          {'<<'}
        </button>{' '}
        <button onClick={() => previousPage()} disabled={!canPreviousPage}>
          {'<'}
        </button>{' '}
        <button onClick={() => nextPage()} disabled={!canNextPage}>
          {'>'}
        </button>{' '}
        <button onClick={() => gotoPage(pageCount - 1)} disabled={!canNextPage}>
          {'>>'}
        </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>
      </div>
    </>
  );
}
Example #22
Source File: Masks.js    From mailmask with GNU Affero General Public License v3.0 4 votes vote down vote up
MaskTable = ({ items, setMaskStatus, me }) => {
  const data = useMemo(() => items.map(({ name, enabled, stats, username }) => {
    return {
      name,
      enabled,
      username: username.username,
      ...stats,
    }
  }), [ items ])

  const columns = useMemo(() => [
    {
      Header: 'Alias',
      accessor: 'name',
    },
    {
      Header: 'Enabled',
      accessor: 'enabled',
      hint: (
        <HeaderHint>
          <p>Whether email will be forwarded to your real email address.</p>
          <p>If ON then email will be forwarded.</p>
          <p>If OFF then email will be silently discarded. Any replies you send will still work.</p>
        </HeaderHint>
      )
    },
    {
      Header: 'Count',
      accessor: 'numMessages',
      hint: (
        <HeaderHint>
          <p>The number of emails sent and received this calendar month ({thisMonthPeriodStr()}).</p>
        </HeaderHint>
      )
    },
    {
      Header: 'Bandwidth',
      accessor: 'numBytes',
      hint: (
        <HeaderHint>
          <p>The amount of email data (text, html, attachments, etc) sent and received this calendar month ({thisMonthPeriodStr()}).</p>
        </HeaderHint>
      )
    },
    {
      Header: 'Latest',
      accessor: 'lastReceived',
      hint: (
        <HeaderHint>
          <p>When the latest email was sent or received this calendar month ({thisMonthPeriodStr()}).</p>
        </HeaderHint>
      )
    },
  ], [])

  const filterTypes = React.useMemo(
    () => ({
      // Add a new fuzzyTextFilterFn filter type.
      fuzzyText: fuzzyTextFilterFn,
    }),
    []
  )

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    state,
    prepareRow,
    preGlobalFilteredRows,
    setGlobalFilter,
  } = useTable({
    columns,
    data,
    defaultColumn,
    filterTypes,
    setMaskStatus,
    me,
  }, useGlobalFilter, useSortBy)

  return (
    <div>
      <GlobalFilter
        preGlobalFilteredRows={preGlobalFilteredRows}
        globalFilter={state.globalFilter}
        setGlobalFilter={setGlobalFilter}
      />
      <TableContainer>
        <Table {...getTableProps()} cellSpacing="20">
          <thead>
            {headerGroups.map(headerGroup => (
              <tr {...headerGroup.getHeaderGroupProps()}>
                {headerGroup.headers.map(column => (
                  <HeaderCell {...column.getHeaderProps(column.getSortByToggleProps())}>
                    {column.render('Header')}
                    <span>
                      {column.hint ? (
                        <HeaderHintButton
                          tooltip={column.hint}
                        />
                      ) : null}
                      {/* eslint-disable-next-line no-nested-ternary */}
                      {column.isSorted
                        ? column.isSortedDesc
                          ? <DownArrow />
                          : <UpArrow />
                        : ''}
                    </span>
                  </HeaderCell>
                ))}
              </tr>
            ))}
          </thead>
          <tbody {...getTableBodyProps()}>
            {rows.map((row, index) => {
              prepareRow(row)
              return (
                <DataRow {...row.getRowProps()} isEven={index % 2 === 0}>
                  {row.cells.map(cell => {
                    return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
                  })}
                </DataRow>
              )
            })}
          </tbody>
        </Table>
      </TableContainer>
    </div>
  )
}
Example #23
Source File: TableContainer.js    From RT7-example with MIT License 4 votes vote down vote up
TableContainer = ({ columns, data, renderRowSubComponent }) => {
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    page,
    prepareRow,
    visibleColumns,
    canPreviousPage,
    canNextPage,
    pageOptions,
    pageCount,
    gotoPage,
    nextPage,
    previousPage,
    setPageSize,
    state: { pageIndex, pageSize },
  } = useTable(
    {
      columns,
      data,
      defaultColumn: { Filter: DefaultColumnFilter },
      initialState: { pageIndex: 0, pageSize: 10 },
    },
    useFilters,
    useSortBy,
    useExpanded,
    usePagination
  );

  const generateSortingIndicator = (column) => {
    return column.isSorted ? (column.isSortedDesc ? ' ?' : ' ?') : '';
  };

  const onChangeInSelect = (event) => {
    setPageSize(Number(event.target.value));
  };

  const onChangeInInput = (event) => {
    const page = event.target.value ? Number(event.target.value) - 1 : 0;
    gotoPage(page);
  };

  return (
    <Fragment>
      <Table bordered hover {...getTableProps()}>
        <thead>
          {headerGroups.map((headerGroup) => (
            <tr {...headerGroup.getHeaderGroupProps()}>
              {headerGroup.headers.map((column) => (
                <th {...column.getHeaderProps()}>
                  <div {...column.getSortByToggleProps()}>
                    {column.render('Header')}
                    {generateSortingIndicator(column)}
                  </div>
                  <Filter column={column} />
                </th>
              ))}
            </tr>
          ))}
        </thead>

        <tbody {...getTableBodyProps()}>
          {page.map((row) => {
            prepareRow(row);
            return (
              <Fragment key={row.getRowProps().key}>
                <tr>
                  {row.cells.map((cell) => {
                    return (
                      <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
                    );
                  })}
                </tr>
                {row.isExpanded && (
                  <tr>
                    <td colSpan={visibleColumns.length}>
                      {renderRowSubComponent(row)}
                    </td>
                  </tr>
                )}
              </Fragment>
            );
          })}
        </tbody>
      </Table>

      <Row style={{ maxWidth: 1000, margin: '0 auto', textAlign: 'center' }}>
        <Col md={3}>
          <Button
            color='primary'
            onClick={() => gotoPage(0)}
            disabled={!canPreviousPage}
          >
            {'<<'}
          </Button>
          <Button
            color='primary'
            onClick={previousPage}
            disabled={!canPreviousPage}
          >
            {'<'}
          </Button>
        </Col>
        <Col md={2} style={{ marginTop: 7 }}>
          Page{' '}
          <strong>
            {pageIndex + 1} of {pageOptions.length}
          </strong>
        </Col>
        <Col md={2}>
          <Input
            type='number'
            min={1}
            style={{ width: 70 }}
            max={pageOptions.length}
            defaultValue={pageIndex + 1}
            onChange={onChangeInInput}
          />
        </Col>
        <Col md={2}>
          <CustomInput
            type='select'
            value={pageSize}
            onChange={onChangeInSelect}
          >
            >
            {[10, 20, 30, 40, 50].map((pageSize) => (
              <option key={pageSize} value={pageSize}>
                Show {pageSize}
              </option>
            ))}
          </CustomInput>
        </Col>
        <Col md={3}>
          <Button color='primary' onClick={nextPage} disabled={!canNextPage}>
            {'>'}
          </Button>
          <Button
            color='primary'
            onClick={() => gotoPage(pageCount - 1)}
            disabled={!canNextPage}
          >
            {'>>'}
          </Button>
        </Col>
      </Row>
    </Fragment>
  );
}
Example #24
Source File: TransactionHistoryTable.js    From ucurtmetre with GNU General Public License v3.0 4 votes vote down vote up
function TransactionHistoryTable({ data }) {
  const breakpoint = useBreakpoints();
  const isMobile = breakpoint === 'isMobile';

  const columns = useMemo(
    () => [
      {
        Header: 'Kimden',
        accessor: 'from.name',
        Cell: ({ value }) => (
          <div className="person with-icon">
            <div>{value || 'Anonim'}</div>
            <div className="icon">
              <ArrowRight />
            </div>
          </div>
        ),
      },

      {
        Header: 'Kime',
        accessor: 'to.name',
        Cell: ({
          value,
          row: {
            original: { to },
          },
        }) => {
          let Element = 'div';
          let linkProps;
          if (to.campaignCode && to.campaignCode !== 'donate-all') {
            Element = 'a';
            linkProps = {
              href: `https://www.ucurtmaprojesi.com/campaign/${to.campaignCode}`,
            };
          }
          return (
            <Element className="person" {...linkProps}>
              {value}
            </Element>
          );
        },
      },
      {
        Header: 'Ne Zaman',
        accessor: 'when',
        id: 'when',
        Cell: ({ value }) => <div>{dayjs().to(dayjs(value * 1000))}</div>,
      },
      {
        Header: 'Ne Kadar',
        accessor: 'amount',
        Cell: ({
          value,
          row: {
            original: { tokenName },
          },
        }) => (
          <div className="amount">{`${
            typeof value === 'number' ? Math.floor(value) : value
          } ${tokenName}`}</div>
        ),
      },
    ],
    []
  );

  const defaultSort = useMemo(() => [{ id: 'when', desc: true }], []);

  const tableInstance = useTable(
    {
      columns,
      data,
      initialState: { sortBy: defaultSort, pageSize: 10, pageIndex: 0 },
      disableMultiSort: true,
      disableSortRemove: true,
    },
    useFlexLayout,
    useSortBy,
    usePagination
  );
  const {
    getTableProps,
    headerGroups,
    prepareRow,
    page,
    canPreviousPage,
    canNextPage,
    pageOptions,
    pageCount,
    gotoPage,
    nextPage,
    previousPage,
    state: { pageIndex },
  } = tableInstance;

  return (
    <div className="table-wrapper">
      <div {...(!isMobile && getTableProps())} className="table">
        {!isMobile &&
          headerGroups.map(headerGroup => (
            <div {...headerGroup.getHeaderGroupProps({})} className="tr">
              {headerGroup.headers.map(column => (
                <div
                  {...column.getHeaderProps(column.getSortByToggleProps())}
                  className="th title"
                >
                  {column.render('Header')}
                  {column.isSorted ? (
                    column.isSortedDesc ? (
                      <ChevronDown />
                    ) : (
                      <ChevronUp />
                    )
                  ) : (
                    ''
                  )}
                </div>
              ))}
            </div>
          ))}
        <div className="tbody">
          {page.map(row => {
            prepareRow(row);
            return (
              <div {...row.getRowProps()} className="tr">
                {row.cells.map(cell => {
                  return (
                    <div {...cell.getCellProps()} className="td">
                      {isMobile && (
                        <div className="td-header">{cell.render('Header')}</div>
                      )}
                      <div className="td-content">{cell.render('Cell')}</div>
                    </div>
                  );
                })}
              </div>
            );
          })}
        </div>
      </div>
      <div className="pagination">
        <div>
          <button
            className="button icon-button"
            type="button"
            onClick={() => gotoPage(0)}
            disabled={!canPreviousPage}
          >
            <ChevronsLeft />
          </button>
          <button
            className="button icon-button"
            type="button"
            onClick={() => previousPage()}
            disabled={!canPreviousPage}
          >
            <ChevronLeft />
          </button>
          <button
            className="button icon-button"
            type="button"
            onClick={() => nextPage()}
            disabled={!canNextPage}
          >
            <ChevronRight />
          </button>
          <button
            className="button icon-button"
            type="button"
            onClick={() => gotoPage(pageCount - 1)}
            disabled={!canNextPage}
          >
            <ChevronsRight />
          </button>
        </div>
        <span>
          Toplam {pageOptions.length} sayfadan
          <strong>{pageIndex + 1}.</strong>
          sayfayı görüntülüyorsunuz.
        </span>
      </div>
    </div>
  );
}
Example #25
Source File: App.js    From react-table-plugins with MIT License 4 votes vote down vote up
function Table({ columns, data }) {
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
    exportData,
  } = useTable(
    {
      columns,
      data,
      defaultColumn,
      getExportFileBlob,
    },
    useFilters,
    useSortBy,
    useExportData
  );

  return (
    <>
      <button
        onClick={() => {
          exportData("csv", true);
        }}
      >
        Export All as CSV
      </button>
      <button
        onClick={() => {
          exportData("csv", false);
        }}
      >
        Export Current View as CSV
      </button>
      <button
        onClick={() => {
          exportData("xlsx", true);
        }}
      >
        Export All as xlsx
      </button>
      <button
        onClick={() => {
          exportData("xlsx", false);
        }}
      >
        Export Current View as xlsx
      </button>
      <button
        onClick={() => {
          exportData("pdf", true);
        }}
      >
        Export All as PDF
      </button>{" "}
      <button
        onClick={() => {
          exportData("pdf", false);
        }}
      >
        Export Current View as PDF
      </button>
      <table {...getTableProps()}>
        <thead>
          {headerGroups.map((headerGroup) => (
            <tr {...headerGroup.getHeaderGroupProps()}>
              {headerGroup.headers.map((column) => (
                // Add the sorting props to control sorting. For this example
                // we can add them into the header props
                <th {...column.getHeaderProps()}>
                  <span {...column.getSortByToggleProps()}>
                    {column.render("Header")}
                  </span>
                  <div>
                    {column.canFilter ? column.render("Filter") : null}
                    <span>
                      {column.isSorted
                        ? column.isSortedDesc
                          ? " ?"
                          : " ?"
                        : ""}
                    </span>
                  </div>
                </th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody {...getTableBodyProps()}>
          {rows.map((row, i) => {
            prepareRow(row);
            return (
              <tr {...row.getRowProps()}>
                {row.cells.map((cell) => {
                  return (
                    <td {...cell.getCellProps()}>{cell.render("Cell")}</td>
                  );
                })}
              </tr>
            );
          })}
        </tbody>
      </table>
      <br />
      <div>Showing the first 20 results of {rows.length} rows</div>
    </>
  );
}
Example #26
Source File: Table.jsx    From editable-react-table with MIT License 4 votes vote down vote up
export default function Table({
  columns,
  data,
  dispatch: dataDispatch,
  skipReset,
}) {
  const sortTypes = useMemo(
    () => ({
      alphanumericFalsyLast(rowA, rowB, columnId, desc) {
        if (!rowA.values[columnId] && !rowB.values[columnId]) {
          return 0;
        }

        if (!rowA.values[columnId]) {
          return desc ? -1 : 1;
        }

        if (!rowB.values[columnId]) {
          return desc ? 1 : -1;
        }

        return isNaN(rowA.values[columnId])
          ? rowA.values[columnId].localeCompare(rowB.values[columnId])
          : rowA.values[columnId] - rowB.values[columnId];
      },
    }),
    []
  );

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
    totalColumnsWidth,
  } = useTable(
    {
      columns,
      data,
      defaultColumn,
      dataDispatch,
      autoResetSortBy: !skipReset,
      autoResetFilters: !skipReset,
      autoResetRowState: !skipReset,
      sortTypes,
    },
    useBlockLayout,
    useResizeColumns,
    useSortBy
  );

  const RenderRow = React.useCallback(
    ({ index, style }) => {
      const row = rows[index];
      prepareRow(row);
      return (
        <div {...row.getRowProps({ style })} className="tr">
          {row.cells.map(cell => (
            <div {...cell.getCellProps()} className="td">
              {cell.render('Cell')}
            </div>
          ))}
        </div>
      );
    },
    [prepareRow, rows]
  );

  function isTableResizing() {
    for (let headerGroup of headerGroups) {
      for (let column of headerGroup.headers) {
        if (column.isResizing) {
          return true;
        }
      }
    }

    return false;
  }

  return (
    <>
      <div
        {...getTableProps()}
        className={clsx('table', isTableResizing() && 'noselect')}
      >
        <div>
          {headerGroups.map(headerGroup => (
            <div {...headerGroup.getHeaderGroupProps()} className="tr">
              {headerGroup.headers.map(column => column.render('Header'))}
            </div>
          ))}
        </div>
        <div {...getTableBodyProps()}>
          <FixedSizeList
            height={window.innerHeight - 100}
            itemCount={rows.length}
            itemSize={40}
            width={totalColumnsWidth + scrollbarWidth}
          >
            {RenderRow}
          </FixedSizeList>
          <div
            className="tr add-row"
            onClick={() => dataDispatch({ type: ActionTypes.ADD_ROW })}
          >
            <span className="svg-icon svg-gray icon-margin">
              <PlusIcon />
            </span>
            New
          </div>
        </div>
      </div>
    </>
  );
}
Example #27
Source File: App.js    From react-table-plugins with MIT License 4 votes vote down vote up
function Table ({ columns, data }) {
  // Use the state and functions returned from useTable to build your UI
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
    // currentSelectedCellIds: cells of a current selected range
    // selectedCellIds: All previously selected cells
    state: { selectedCellIds, currentSelectedCellIds, isSelectingCells },
    // getCellsBetweenId (Fn): Pass two cell Ids to get all cell Ids between them
    getCellsBetweenId,
    setSelectedCellIds,
    cellsById
  } = useTable(
    {
      columns,
      data,
      // cellIdSplitBy (string): Cell id is split by column.id + cellIdSplitBy + row.id
      cellIdSplitBy: 'cols_rows',
      initialState: {
        selectedCellIds: {}
      }
    },
    useCellRangeSelection
  )

  let cellsSelected = { ...currentSelectedCellIds, ...selectedCellIds }

  // returns two random cell ids, this is just for the demo.
  const getRandomCellIds = React.useCallback(() => {
    let cloneCellIds = Object.keys(cellsById)
    let randomCellId = () =>
      cloneCellIds[(cloneCellIds.length * Math.random()) << 0]
    return [randomCellId(), randomCellId()]
  }, [cellsById])

  // getCellsBetweenId returns all cell Ids between two cell Id, and then setState for selectedCellIds
  const selectRandomCells = React.useCallback(() => {
    const cellsBetween = getCellsBetweenId(...getRandomCellIds())
    setSelectedCellIds(cellsBetween)
  }, [getCellsBetweenId, setSelectedCellIds, getRandomCellIds])

  // 'useScrollOnEdges' hook helps us when we have height or width set to the table
  // and when user is selecting cells and is near any of the edges, table will scroll by itself.
  const getEdgeScrollingProps = useScrollOnEdges({
    canAnimate: isSelectingCells // Scroll when user `isSelectingCells` is True
    // scrollSpeed: 15, -> Optional, default is 12,
    // edgeSize: 30     -> Optional, default is 25
  })

  return (
    <>
      <button onClick={selectRandomCells}>Select cells randomly</button>
      <Usage></Usage>
      <div
        {...getEdgeScrollingProps({
          style: {
            height: '400px'
          }
        })}
      >
        <table {...getTableProps()}>
          <thead>
            {headerGroups.map(headerGroup => (
              <tr {...headerGroup.getHeaderGroupProps()}>
                {headerGroup.headers.map(column => (
                  <th {...column.getHeaderProps()}>
                    {column.render('Header')}
                  </th>
                ))}
              </tr>
            ))}
          </thead>
          <tbody {...getTableBodyProps()}>
            {rows.map((row, i) => {
              prepareRow(row)
              return (
                <tr {...row.getRowProps()}>
                  {row.cells.map(cell => {
                    return (
                      <td
                        {...cell.getCellRangeSelectionProps()}
                        {...cell.getCellProps()}
                        style={
                          cellsSelected[cell.id]
                            ? { backgroundColor: '#6beba8', userSelect: 'none' }
                            : { backgroundColor: 'white', userSelect: 'none' }
                        }
                      >
                        {cell.render('Cell')}
                      </td>
                    )
                  })}
                </tr>
              )
            })}
          </tbody>
        </table>
      </div>
      <pre>
        <code>
          {JSON.stringify({ selectedCellIds, currentSelectedCellIds }, null, 2)}
        </code>
      </pre>
    </>
  )
}
Example #28
Source File: index.js    From ThreatMapper with Apache License 2.0 4 votes vote down vote up
DfTableV2 = ({
  columns,
  data,
  renderRowSubComponent,
  showPagination,
  manual,
  totalRows,
  page,
  defaultPageSize,
  onPageChange,
  enableSorting,
  onSortChange,
  noDataText,
  disableResizing,
  columnCustomizable,
  name,
  loading,
  noMargin,
  multiSelectOptions,
  onRowClick,
  onCellClick,
  getRowStyle,
  getCellStyle,
}) => {
  defaultPageSize = getDefaultPageSize({
    showPagination,
    inputDefaultPageSize: defaultPageSize,
    data
  });

  const rtColumns = useColumnFilter({
    columns,
    columnCustomizable,
    renderRowSubComponent,
    name,
    multiSelectOptions,
  });

  const defaultColumn = React.useMemo(
    () => ({
      // When using the useFlexLayout:
      minWidth: 30, // minWidth is only used as a limit for resizing
      width: 100, // width is used for both the flex-basis and flex-grow
      maxWidth: 500, // maxWidth is only used as a limit for resizing
    }),
    []
  )

  const additionalTableParams = {};

  if (manual) {
    additionalTableParams.pageCount = getPageCount({
      manual,
      showPagination,
      defaultPageSize,
      totalRows,
      data
    });
  } else if (showPagination) {
    additionalTableParams.initialState = {
      pageSize: defaultPageSize
    };
  }

  const tableInstance = useTable(
    {
      columns: rtColumns,
      data,
      defaultColumn,
      autoResetExpanded: false,
      autoResetPage: false,
      manualPagination: !!manual,
      paginateExpandedRows: false,
      disableSortBy: !enableSorting,
      manualSortBy: !!manual,
      autoResetSortBy: false,
      disableMultiSort: true,
      autoResetSelectedRows: false,
      ...additionalTableParams
    },
    useResizeColumns,
    useFlexLayout,
    useSortBy,
    useExpanded,
    usePagination,
    useRowSelect
  );
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    prepareRow,
    visibleColumns,
    page: rtPage,
    gotoPage,
    pageCount,
    state: {
      pageIndex,
      sortBy,
    },
    toggleAllRowsExpanded,
    setPageSize,
    toggleAllPageRowsSelected,
    selectedFlatRows
  } = tableInstance;

  useEffect(() => {
    // in case of manual pagination, parent should be passing current page number
    if (manual && page !== null && page !== undefined) gotoPage(page);
  }, [page]);

  useEffect(() => {
    // whenever pageIndex changes, existing expanded rows should be collapsed
    // all rows are deselected
    toggleAllRowsExpanded(false);
    toggleAllPageRowsSelected(false);
  }, [pageIndex]);

  useEffect(() => {
    // reset page index to 0 when number of rows shown in the page changes
    gotoPage(0);
  }, [defaultPageSize]);

  useEffect(() => {
    if (defaultPageSize !== data.length) {
      setPageSize(defaultPageSize);
    }
  }, [defaultPageSize, data]);

  useEffect(() => {
    if (manual && onSortChange) onSortChange(sortBy);
  }, [sortBy]);

  return (
    <div className={styles.tableContainer}>
      <div className={classNames(styles.table, {
        [styles.noMargin]: noMargin
      })} {...getTableProps()}>
        {
          loading ? <AppLoader small className={styles.loader} /> : <>
            <div>
              {
                headerGroups.map(headerGroup => {
                  const { key, ...rest } = headerGroup.getHeaderGroupProps();
                  return <div key={key} {...rest}>
                    {
                      headerGroup.headers.map(column => {
                        const { key, onClick, ...rest } = column.getHeaderProps(enableSorting ? column.getSortByToggleProps() : undefined);
                        return <div className={classNames(styles.headerCell, {
                          [styles.headerOverflowShown]: !!column.showOverflow
                        })} key={key} {...rest}>
                          <span className={styles.headerContent} onClick={onClick}>
                            <span>
                              {column.render('Header')}
                            </span>
                            <span className={`${styles.sortIndicator}`}>
                              {
                                column.isSorted
                                  ? column.isSortedDesc
                                    ? <i className="fa fa-angle-down" />
                                    : <i className="fa fa-angle-up" />
                                  : null
                              }
                            </span>
                          </span>
                          {column.canResize && !disableResizing ? (
                            <div
                              {...column.getResizerProps()}
                              className={styles.headerCellResizer}
                            />
                          ) : null}
                        </div>
                      })}
                  </div>
                })}
            </div>
            <div {...getTableBodyProps()}>
              {
                rtPage.map((row, index) => {
                  prepareRow(row);
                  const { key, style, ...rest } = row.getRowProps();
                  return (
                    <React.Fragment key={key} >
                      <div
                        className={classNames(styles.row, {
                          [styles.oddRow]: index % 2 !== 0,
                          [styles.expandableRow]: !!renderRowSubComponent,
                          [styles.clickableRow]: !!onRowClick
                        })}
                        onClick={() => {
                          if (renderRowSubComponent) {
                            row.toggleRowExpanded();
                          } else if (onRowClick) {
                            onRowClick(row);
                          }
                        }}
                        style={{ ...(getRowStyle ? getRowStyle(row) : {}), ...style }}
                        {...rest}
                      >
                        {
                          row.cells.map(cell => {
                            const { key, style, ...rest } = cell.getCellProps();
                            const { column } = cell;
                            return (
                              <div
                                className={classNames(styles.cell, {
                                  [styles.wrap]: !column.noWrap
                                })}
                                key={key}
                                onClick={() => {
                                  if (onCellClick) {
                                    onCellClick(cell);
                                  }
                                }}
                                style={{ ...(getCellStyle ? getCellStyle(cell) : {}), ...style }}
                                {...rest}>
                                {
                                  cell.render('Cell')
                                }
                              </div>
                            )
                          })
                        }
                      </div>
                      {
                        row.isExpanded ? (
                          <div>
                            <div colSpan={visibleColumns.length}>
                              {renderRowSubComponent({ row })}
                            </div>
                          </div>
                        ) : null
                      }
                    </React.Fragment>
                  )
                })}
            </div>
          </>
        }
        {
          !data.length && !loading ? (
            <div className={styles.noDataPlaceholder}>
              {noDataText || 'No rows found'}
            </div>
          ) : null
        }
      </div>
      {
        showPagination && data.length && !loading ? (
          <div className={styles.paginationWrapper}>
            <Pagination
              pageCount={pageCount}
              pageIndex={pageIndex}
              onPageChange={(selectedIndex) => {
                if (manual && onPageChange) {
                  onPageChange(selectedIndex);
                }
                if (!manual) {
                  gotoPage(selectedIndex);
                }
              }}
            />
          </div>
        ) : null
      }
      {(multiSelectOptions && selectedFlatRows.length) ? (<div className={styles.multiSelectActions}>
        <MultiselectActions
          toggleAllPageRowsSelected={toggleAllPageRowsSelected}
          selectedFlatRows={selectedFlatRows ?? []}
          multiSelectOptions={multiSelectOptions}
          data={data}
        />
      </div>) : null}
    </div>
  );
}
Example #29
Source File: resourcetable.js    From covid19Nepal-react with MIT License 4 votes vote down vote up
function ResourceTable({
  columns,
  data,
  isDesktop,
  totalCount,
  onScrollUpdate,
  city,
  category,
  nepalstate,
}) {
  const classesPannelSummary = usePanelSummaryStyles();
  const classesPanel = usePanelStyles();
  const classesListItemText = useItemTextStyles();
  const classesPanelDetails = usePanelDetailsStyles();
  const classesList = useListStyles();
  const [expanded, setExpanded] = React.useState(false);
  const defaultColumn = React.useMemo(
    () => ({
      Cell: FormattedCell,
    }),
    []
  );
  const handleExpansionChange = (panel) => (event, isExpanded) => {
    setExpanded(isExpanded ? panel : false);
  };

  const [searchValue, setSearchValue] = useState('');
  const [suggestions, setSuggestions] = useState(data);

  const prevNepalState = useRef('');
  const prevCity = useRef('');
  const prevCategory = useRef('');

  useEffect(() => {
    if (
      prevCategory.current === category &&
      prevNepalState.current === nepalstate &&
      prevCity.current === city
    ) {
      setSuggestions(getSuggestions(searchValue, data));
    } else {
      setSuggestions(data);
      setSearchValue('');
      prevCategory.current = category;
      prevNepalState.current = nepalstate;
      prevCity.current = city;
    }
  }, [searchValue, data, category, nepalstate, city]);

  const onChange = (event, {newValue}) => {
    setSearchValue(newValue);
  };

  const onSuggestionsFetchRequested = ({value}) => {
    setSuggestions(getSuggestions(value, data));
  };

  const inputProps = {
    placeholder: '',
    value: searchValue,
    onChange: onChange,
  };

  const renderInputComponent = (inputProps) => (
    <TextField
      id="outlined-number"
      label="Search keyword"
      fullWidth={true}
      InputLabelProps={{
        shrink: true,
      }}
      style={{
        width: '100%',
      }}
      variant="outlined"
      InputProps={{
        startAdornment: (
          <InputAdornment position="start">
            <SearchOutlinedIcon style={{fontSize: '0.7rem'}} />
          </InputAdornment>
        ),
      }}
      {...inputProps}
    />
  );

  const parseText = function (text, limit) {
    if (text.length > limit) {
      for (let i = limit; i > 0; i--) {
        if (
          text.charAt(i) === ' ' &&
          (text.charAt(i - 1) !== ',' ||
            text.charAt(i - 1) !== '.' ||
            text.charAt(i - 1) !== ';')
        ) {
          return text.substring(0, i) + '...';
        }
      }
      return text.substring(0, limit) + '...';
    } else return text;
  };

  // Use the state and functions returned from useTable to build your UI
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    prepareRow,
    rows,
  } = useTable({
    columns,
    data: suggestions,
    defaultColumn,
    initialState: {hiddenColumns: 'contact'},
  });

  // Render the UI for your table
  if (isDesktop === true)
    return (
      <>
        <div className="searchbar">
          <Autosuggest
            suggestions={suggestions}
            onSuggestionsFetchRequested={onSuggestionsFetchRequested}
            getSuggestionValue={getSuggestionValue}
            renderSuggestion={renderSuggestion}
            inputProps={inputProps}
            alwaysRenderSuggestions={true}
            renderInputComponent={renderInputComponent}
          />
        </div>
        <div className="tableandcontrols">
          <InfiniteScroll
            dataLength={data.length}
            hasMore={data.length < totalCount}
            next={onScrollUpdate}
            loader={<h4>Fetching more information, please wait.</h4>}
          >
            <table {...getTableProps()}>
              <thead>
                {headerGroups.map((headerGroup) => (
                  <tr
                    key={headerGroup.id}
                    {...headerGroup.getHeaderGroupProps()}
                  >
                    {headerGroup.headers.map((column, i) => (
                      <th
                        key={column.id}
                        {...column.getHeaderProps()}
                        className={i === 3 ? 'descriptionCol sticky' : 'sticky'}
                      >
                        {column.render('Header')}
                      </th>
                    ))}
                  </tr>
                ))}
              </thead>
              <tbody {...getTableBodyProps()}>
                {rows.map((row, i) => {
                  prepareRow(row);
                  return (
                    <tr key={row.id} {...row.getRowProps()}>
                      {row.cells.map((cell, cellindex) => {
                        return (
                          <td key={cellindex} {...cell.getCellProps()}>
                            {cell.render(rendercell)}
                          </td>
                        );
                      })}
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </InfiniteScroll>
        </div>
      </>
    );
  else
    return (
      <>
        <div className="searchbar">
          <Autosuggest
            suggestions={suggestions}
            onSuggestionsFetchRequested={onSuggestionsFetchRequested}
            getSuggestionValue={getSuggestionValue}
            renderSuggestion={renderSuggestion}
            inputProps={inputProps}
            alwaysRenderSuggestions={true}
            renderInputComponent={renderInputComponent}
          />
        </div>
        <div
          className="resourcesaccordion"
          style={{
            display: 'flex',
            flexDirection: 'column',
            width: '100%',
            alignItems: 'center',
          }}
        >
          <InfiniteScroll
            dataLength={data.length}
            hasMore={data.length < totalCount}
            next={onScrollUpdate}
            loader={<h4>Fetching more information, please wait.</h4>}
            style={{width: '100%', maxWidth: '335px', overflow: 'hidden'}} // for large texts
          >
            {rows.map((row, i) => {
              prepareRow(row);
              return (
                <ExpansionPanel
                  key={row.id}
                  classes={{root: classesPanel.root}}
                  expanded={expanded === `panel-${i}`}
                  onChange={handleExpansionChange(`panel-${i}`)}
                >
                  <ExpansionPanelSummary
                    classes={{
                      content: classesPannelSummary.content,
                      root: classesPannelSummary.root,
                    }}
                  >
                    {/* <div className="expanelheading"
                                 style={{display: 'flex',
                                         flexDirection: 'row',
                                         justifyContent: 'space-between',
                                         backgroundColor: 'blue'}}> */}
                    <div
                      className="orgname"
                      style={{
                        maxWidth: '10rem',
                        textAlign: 'start',
                        color: '#201aa2dd',
                      }}
                    >
                      <h6>
                        {parseText(row.values['nameoftheorganisation'], 50)}
                      </h6>
                    </div>
                    <div
                      className="orgcategory"
                      style={{maxWidth: '10.9rem', textAlign: 'end'}}
                    >
                      <h6>{row.values['category']}</h6>
                    </div>
                    {/* </div> */}
                  </ExpansionPanelSummary>
                  <ExpansionPanelDetails
                    classes={{root: classesPanelDetails.root}}
                  >
                    <List
                      disablePadding={true}
                      dense={true}
                      classes={{root: classesList.root}}
                    >
                      <ListItem
                        alignItems="flex-start"
                        dense={true}
                        divider={true}
                      >
                        <ListItemText
                          primary="Organisation Name"
                          secondary={row.values['nameoftheorganisation']}
                          classes={{
                            primary: classesListItemText.primary,
                            secondary: classesListItemText.secondary,
                          }}
                        />
                      </ListItem>
                      <ListItem
                        alignItems="flex-start"
                        dense={true}
                        divider={true}
                      >
                        <ListItemText
                          primary="Location"
                          secondary={row.values['city']}
                          classes={{
                            primary: classesListItemText.primary,
                            secondary: classesListItemText.secondary,
                          }}
                        />
                      </ListItem>
                      <ListItem
                        alignItems="flex-start"
                        dense={true}
                        divider={true}
                      >
                        <ListItemText
                          primary="Description"
                          secondary={
                            row.values['descriptionandorserviceprovided']
                          }
                          classes={{
                            primary: classesListItemText.primary,
                            secondary: classesListItemText.secondary,
                          }}
                        />
                      </ListItem>
                      <ListItem
                        alignItems="flex-start"
                        dense={true}
                        divider={true}
                      >
                        <ListItemText
                          primary="Service"
                          secondary={row.values['category']}
                          classes={{
                            primary: classesListItemText.primary,
                            secondary: classesListItemText.secondary,
                          }}
                        />
                      </ListItem>
                      <ListItem
                        alignItems="flex-start"
                        dense={true}
                        divider={true}
                      >
                        <ListItemText
                          primary="Phonenumber"
                          secondary={getFormattedLinkForAccordion(
                            row.values['phonenumber']
                          )}
                          classes={{
                            primary: classesListItemText.primary,
                            secondary: classesListItemText.secondary,
                          }}
                        />
                      </ListItem>
                      <ListItem
                        alignItems="flex-start"
                        dense={true}
                        divider={true}
                      >
                        <ListItemText
                          primary="Website"
                          secondary={getFormattedLinkForAccordion(
                            row.values['contact']
                          )}
                          classes={{
                            primary: classesListItemText.primary,
                            secondary: classesListItemText.secondary,
                          }}
                        />
                      </ListItem>
                    </List>
                  </ExpansionPanelDetails>
                </ExpansionPanel>
              );
            })}
          </InfiniteScroll>
        </div>
      </>
    );
}