|
|
|
@ -1,79 +1,118 @@ |
|
|
|
|
import React, {useMemo} from 'react'; |
|
|
|
|
import React, { useMemo } from "react"; |
|
|
|
|
|
|
|
|
|
import {useTable, useSortBy, useGlobalFilter, useFilters, usePagination} from 'react-table'; |
|
|
|
|
import { |
|
|
|
|
useTable, |
|
|
|
|
useSortBy, |
|
|
|
|
useGlobalFilter, |
|
|
|
|
useFilters, |
|
|
|
|
usePagination, |
|
|
|
|
useRowSelect, |
|
|
|
|
useColumnOrder, |
|
|
|
|
} from "react-table"; |
|
|
|
|
|
|
|
|
|
import {COLUMNS} from './columns'; |
|
|
|
|
import { COLUMNS } from "./columns"; |
|
|
|
|
|
|
|
|
|
import {GlobalFilter} from './GlobalFilter'; |
|
|
|
|
import { GlobalFilter } from "./GlobalFilter"; |
|
|
|
|
|
|
|
|
|
import MOCK_DATA from './MOCK_DATA.json'; |
|
|
|
|
|
|
|
|
|
const BasicTable = () => { |
|
|
|
|
import { Checkbox } from "./Checkbox"; |
|
|
|
|
|
|
|
|
|
import MOCK_DATA from "./MOCK_DATA.json"; |
|
|
|
|
|
|
|
|
|
const columns = React.useMemo(() => COLUMNS, []) |
|
|
|
|
const data = useMemo(() => MOCK_DATA,[]) |
|
|
|
|
|
|
|
|
|
const { |
|
|
|
|
getTableProps, |
|
|
|
|
getTableBodyProps, |
|
|
|
|
headerGroups, |
|
|
|
|
footerGroups, |
|
|
|
|
rows, |
|
|
|
|
page, |
|
|
|
|
nextPage, |
|
|
|
|
previousPage, |
|
|
|
|
canNextPage, |
|
|
|
|
canPreviousPage, |
|
|
|
|
pageOptions, |
|
|
|
|
gotoPage, |
|
|
|
|
pageCount, |
|
|
|
|
setPageSize, |
|
|
|
|
prepareRow, |
|
|
|
|
state, |
|
|
|
|
setGlobalFilter, |
|
|
|
|
} = useTable({ |
|
|
|
|
columns, |
|
|
|
|
data, |
|
|
|
|
// initialState: { pageIndex: 2 }
|
|
|
|
|
const BasicTable = () => { |
|
|
|
|
const columns = React.useMemo(() => COLUMNS, []); |
|
|
|
|
const data = useMemo(() => MOCK_DATA, []); |
|
|
|
|
|
|
|
|
|
const { |
|
|
|
|
getTableProps, |
|
|
|
|
getTableBodyProps, |
|
|
|
|
headerGroups, |
|
|
|
|
footerGroups, |
|
|
|
|
rows, |
|
|
|
|
page, |
|
|
|
|
nextPage, |
|
|
|
|
previousPage, |
|
|
|
|
canNextPage, |
|
|
|
|
canPreviousPage, |
|
|
|
|
pageOptions, |
|
|
|
|
gotoPage, |
|
|
|
|
pageCount, |
|
|
|
|
setPageSize, |
|
|
|
|
prepareRow, |
|
|
|
|
selectedFlatRows, |
|
|
|
|
state, |
|
|
|
|
setGlobalFilter, |
|
|
|
|
} = useTable( |
|
|
|
|
{ |
|
|
|
|
columns, |
|
|
|
|
data, |
|
|
|
|
// initialState: { pageIndex: 2 }
|
|
|
|
|
}, |
|
|
|
|
useFilters, |
|
|
|
|
useGlobalFilter, |
|
|
|
|
useSortBy, |
|
|
|
|
usePagination, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const { globalFilter, pageIndex, pageSize } = state |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
|
|
|
|
|
<> |
|
|
|
|
|
|
|
|
|
<GlobalFilter filter={globalFilter} setFilter={setGlobalFilter} /> |
|
|
|
|
|
|
|
|
|
<table {...getTableProps()} className="min-w-full divide-y divide-gray-200"> |
|
|
|
|
|
|
|
|
|
<thead className="bg-gray-300"> |
|
|
|
|
{headerGroups.map((headerGroup) => ( |
|
|
|
|
<tr {...headerGroup.getHeaderGroupProps()}> |
|
|
|
|
{headerGroup.headers.map((column) => ( |
|
|
|
|
<th {...column.getHeaderProps(column.getSortByToggleProps())} scope="col" className="cursor-pointer px-4 py-2 text-right text-xs" style={{color: '#3287B9'}}> |
|
|
|
|
{column.render('Header')} |
|
|
|
|
<span> |
|
|
|
|
{column.isSorted ? (column.isSortedDesc ? ' 🔽' : ' 🔼') : ''} |
|
|
|
|
</span> |
|
|
|
|
{/* <div> |
|
|
|
|
useFilters, |
|
|
|
|
useGlobalFilter, |
|
|
|
|
useSortBy, |
|
|
|
|
usePagination, |
|
|
|
|
useRowSelect, |
|
|
|
|
(hooks) => { |
|
|
|
|
hooks.visibleColumns.push((columns) => { |
|
|
|
|
return [ |
|
|
|
|
{ |
|
|
|
|
id: "selection", |
|
|
|
|
Header: ({ getToggleAllRowsSelectedProps }) => ( |
|
|
|
|
<Checkbox {...getToggleAllRowsSelectedProps()} /> |
|
|
|
|
), |
|
|
|
|
Cell: ({ row }) => ( |
|
|
|
|
<Checkbox {...row.getToggleRowSelectedProps()} /> |
|
|
|
|
), |
|
|
|
|
}, |
|
|
|
|
...columns, |
|
|
|
|
]; |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const { globalFilter, pageIndex, pageSize } = state; |
|
|
|
|
const firstPageRows = rows.slice(0, 10); |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<> |
|
|
|
|
<GlobalFilter filter={globalFilter} setFilter={setGlobalFilter} /> |
|
|
|
|
|
|
|
|
|
<table |
|
|
|
|
{...getTableProps()} |
|
|
|
|
className="min-w-full divide-y divide-gray-200" |
|
|
|
|
> |
|
|
|
|
<thead className="bg-gray-300"> |
|
|
|
|
{headerGroups.map((headerGroup) => ( |
|
|
|
|
<tr {...headerGroup.getHeaderGroupProps()}> |
|
|
|
|
{headerGroup.headers.map((column) => ( |
|
|
|
|
<th |
|
|
|
|
{...column.getHeaderProps(column.getSortByToggleProps())} |
|
|
|
|
scope="col" |
|
|
|
|
className="cursor-pointer px-4 py-2 text-right text-xs" |
|
|
|
|
style={{ color: "#3287B9" }} |
|
|
|
|
> |
|
|
|
|
{column.render("Header")} |
|
|
|
|
<span> |
|
|
|
|
{column.isSorted |
|
|
|
|
? column.isSortedDesc |
|
|
|
|
? " 🔽" |
|
|
|
|
: " 🔼" |
|
|
|
|
: ""} |
|
|
|
|
</span> |
|
|
|
|
{/* <div> |
|
|
|
|
{column.canFilter ? column.render('Filter') : null } |
|
|
|
|
</div> */} |
|
|
|
|
</th> |
|
|
|
|
))} |
|
|
|
|
</tr> |
|
|
|
|
))}
|
|
|
|
|
</thead> |
|
|
|
|
|
|
|
|
|
<tbody {...getTableBodyProps()} className="bg-white divide-y divide-gray-200"> |
|
|
|
|
{/* {rows.map((row) => { |
|
|
|
|
</th> |
|
|
|
|
))} |
|
|
|
|
</tr> |
|
|
|
|
))} |
|
|
|
|
</thead> |
|
|
|
|
|
|
|
|
|
<tbody |
|
|
|
|
{...getTableBodyProps()} |
|
|
|
|
className="bg-white divide-y divide-gray-200" |
|
|
|
|
> |
|
|
|
|
{/* {rows.map((row) => { |
|
|
|
|
prepareRow(row) |
|
|
|
|
return( |
|
|
|
|
<tr {...row.getRowProps()}> |
|
|
|
@ -85,97 +124,140 @@ const BasicTable = () => { |
|
|
|
|
</tr> |
|
|
|
|
) |
|
|
|
|
})} */} |
|
|
|
|
{page.map((row) => { |
|
|
|
|
prepareRow(row) |
|
|
|
|
return( |
|
|
|
|
<tr {...row.getRowProps()}> |
|
|
|
|
{row.cells.map((cell) => { |
|
|
|
|
return <td {...cell.getCellProps()} className="px-4 py-4 whitespace-nowrap text-sm" role="cell" style={{color:'#00253A'}}> |
|
|
|
|
{cell.render('Cell')} |
|
|
|
|
</td> |
|
|
|
|
})} |
|
|
|
|
</tr> |
|
|
|
|
) |
|
|
|
|
})} |
|
|
|
|
</tbody> |
|
|
|
|
|
|
|
|
|
<tfoot className={`bg-gray-300 ${rows.length > 10 ? 'w-full' : 'hidden'}`} > |
|
|
|
|
{ |
|
|
|
|
footerGroups.map(footerGroup => ( |
|
|
|
|
<tr {...footerGroup.getFooterGroupProps()}> |
|
|
|
|
{ |
|
|
|
|
footerGroup.headers.map(column => ( |
|
|
|
|
<td {...column.getFooterProps} className="px-4 py-2 text-right text-xs" style={{color: '#3287B9'}}> |
|
|
|
|
{ |
|
|
|
|
column.render('Footer') |
|
|
|
|
} |
|
|
|
|
</td> |
|
|
|
|
)) |
|
|
|
|
} |
|
|
|
|
</tr> |
|
|
|
|
)) |
|
|
|
|
} |
|
|
|
|
</tfoot> |
|
|
|
|
|
|
|
|
|
</table> |
|
|
|
|
|
|
|
|
|
<div> |
|
|
|
|
|
|
|
|
|
<span> |
|
|
|
|
|
|
|
|
|
Page{' '} |
|
|
|
|
|
|
|
|
|
<strong> |
|
|
|
|
{pageIndex + 1} of {pageOptions.length} |
|
|
|
|
</strong>{''} |
|
|
|
|
|
|
|
|
|
</span> |
|
|
|
|
|
|
|
|
|
<span> |
|
|
|
|
|
|
|
|
|
| Go to Page: {' '} |
|
|
|
|
|
|
|
|
|
<input type='number' |
|
|
|
|
defaultValue={ pageIndex + 1 } |
|
|
|
|
onChange={ (e) => { |
|
|
|
|
const pageNumber = e.target.value ? Number(e.target.value) - 1 : 0 |
|
|
|
|
gotoPage(pageNumber)
|
|
|
|
|
} }
|
|
|
|
|
style={{ width: '50px' }} |
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
</span> |
|
|
|
|
|
|
|
|
|
<select
|
|
|
|
|
value={pageSize} |
|
|
|
|
onChange={ (e) => setPageSize(Number(e.target.value)) }
|
|
|
|
|
{page.map((row) => { |
|
|
|
|
prepareRow(row); |
|
|
|
|
return ( |
|
|
|
|
<tr {...row.getRowProps()}> |
|
|
|
|
{row.cells.map((cell) => { |
|
|
|
|
return ( |
|
|
|
|
<td |
|
|
|
|
{...cell.getCellProps()} |
|
|
|
|
className="px-4 py-4 whitespace-nowrap text-sm" |
|
|
|
|
role="cell" |
|
|
|
|
style={{ color: "#00253A" }} |
|
|
|
|
> |
|
|
|
|
{cell.render("Cell")} |
|
|
|
|
</td> |
|
|
|
|
); |
|
|
|
|
})} |
|
|
|
|
</tr> |
|
|
|
|
); |
|
|
|
|
})} |
|
|
|
|
|
|
|
|
|
{/* {firstPageRows.map((row) => { |
|
|
|
|
prepareRow(row); |
|
|
|
|
return ( |
|
|
|
|
<tr {...row.getRowProps()}> |
|
|
|
|
{row.cells.map((cell) => { |
|
|
|
|
return ( |
|
|
|
|
<td |
|
|
|
|
{...cell.getCellProps()} |
|
|
|
|
className="px-4 py-4 whitespace-nowrap text-sm" |
|
|
|
|
role="cell" |
|
|
|
|
style={{ color: "#00253A" }} |
|
|
|
|
> |
|
|
|
|
{cell.render("Cell")} |
|
|
|
|
</td> |
|
|
|
|
); |
|
|
|
|
})} |
|
|
|
|
</tr> |
|
|
|
|
); |
|
|
|
|
})} */} |
|
|
|
|
</tbody> |
|
|
|
|
|
|
|
|
|
<tfoot |
|
|
|
|
className={`bg-gray-300 ${rows.length > 10 ? "w-full" : "hidden"}`} |
|
|
|
|
> |
|
|
|
|
{footerGroups.map((footerGroup) => ( |
|
|
|
|
<tr {...footerGroup.getFooterGroupProps()}> |
|
|
|
|
{footerGroup.headers.map((column) => ( |
|
|
|
|
<td |
|
|
|
|
{...column.getFooterProps} |
|
|
|
|
className="px-4 py-2 text-right text-xs" |
|
|
|
|
style={{ color: "#3287B9" }} |
|
|
|
|
> |
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
[7, 10, 25, 50].map(pageSize => ( |
|
|
|
|
|
|
|
|
|
<option key={ pageSize } value={ pageSize }> |
|
|
|
|
Show { pageSize } |
|
|
|
|
</option> |
|
|
|
|
|
|
|
|
|
)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
</select> |
|
|
|
|
|
|
|
|
|
<button onClick={() => gotoPage(0)} disabled={!canPreviousPage}> { '<<' } </button> |
|
|
|
|
|
|
|
|
|
<button className="bg-blue-400 m-2 rounded text-white p-2" onClick={() => previousPage() } disabled={!canPreviousPage} >Previous</button> |
|
|
|
|
<button className="bg-blue-400 m-2 rounded text-white p-2" onClick={() => nextPage() } disabled={!canNextPage}>Next</button> |
|
|
|
|
|
|
|
|
|
<button onClick={() => gotoPage( pageCount - 1 )} disabled={!canNextPage}> { '>>' } </button> |
|
|
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
</> |
|
|
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
{column.render("Footer")} |
|
|
|
|
</td> |
|
|
|
|
))} |
|
|
|
|
</tr> |
|
|
|
|
))} |
|
|
|
|
</tfoot> |
|
|
|
|
</table> |
|
|
|
|
|
|
|
|
|
<pre> |
|
|
|
|
<code> |
|
|
|
|
{JSON.stringify( |
|
|
|
|
{ |
|
|
|
|
selectedFlatRows: selectedFlatRows.map((row) => row.original), |
|
|
|
|
}, |
|
|
|
|
null, |
|
|
|
|
2 |
|
|
|
|
)} |
|
|
|
|
</code> |
|
|
|
|
</pre> |
|
|
|
|
|
|
|
|
|
<div> |
|
|
|
|
<span> |
|
|
|
|
Page{" "} |
|
|
|
|
<strong> |
|
|
|
|
{pageIndex + 1} of {pageOptions.length} |
|
|
|
|
</strong> |
|
|
|
|
{""} |
|
|
|
|
</span> |
|
|
|
|
|
|
|
|
|
<span> |
|
|
|
|
| Go to Page:{" "} |
|
|
|
|
<input |
|
|
|
|
type="number" |
|
|
|
|
defaultValue={pageIndex + 1} |
|
|
|
|
onChange={(e) => { |
|
|
|
|
const pageNumber = e.target.value |
|
|
|
|
? Number(e.target.value) - 1 |
|
|
|
|
: 0; |
|
|
|
|
gotoPage(pageNumber); |
|
|
|
|
}} |
|
|
|
|
style={{ width: "50px" }} |
|
|
|
|
/> |
|
|
|
|
</span> |
|
|
|
|
|
|
|
|
|
<select |
|
|
|
|
value={pageSize} |
|
|
|
|
onChange={(e) => setPageSize(Number(e.target.value))} |
|
|
|
|
> |
|
|
|
|
{[7, 10, 25, 50].map((pageSize) => ( |
|
|
|
|
<option key={pageSize} value={pageSize}> |
|
|
|
|
Show {pageSize} |
|
|
|
|
</option> |
|
|
|
|
))} |
|
|
|
|
</select> |
|
|
|
|
|
|
|
|
|
<button onClick={() => gotoPage(0)} disabled={!canPreviousPage}> |
|
|
|
|
{" "} |
|
|
|
|
{"<<"}{" "} |
|
|
|
|
</button> |
|
|
|
|
|
|
|
|
|
<button |
|
|
|
|
className="bg-blue-400 m-2 rounded text-white p-2" |
|
|
|
|
onClick={() => previousPage()} |
|
|
|
|
disabled={!canPreviousPage} |
|
|
|
|
> |
|
|
|
|
Previous |
|
|
|
|
</button> |
|
|
|
|
<button |
|
|
|
|
className="bg-blue-400 m-2 rounded text-white p-2" |
|
|
|
|
onClick={() => nextPage()} |
|
|
|
|
disabled={!canNextPage} |
|
|
|
|
> |
|
|
|
|
Next |
|
|
|
|
</button> |
|
|
|
|
|
|
|
|
|
<button onClick={() => gotoPage(pageCount - 1)} disabled={!canNextPage}> |
|
|
|
|
{" "} |
|
|
|
|
{">>"}{" "} |
|
|
|
|
</button> |
|
|
|
|
</div> |
|
|
|
|
</> |
|
|
|
|
); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
export default BasicTable; |
|
|
|
|