|
|
import React, { useMemo } from "react"; |
|
|
|
|
|
import "./index.scss"; |
|
|
|
|
|
import { |
|
|
useTable, |
|
|
useSortBy, |
|
|
useGlobalFilter, |
|
|
useFilters, |
|
|
usePagination, |
|
|
useRowSelect, |
|
|
useColumnOrder, |
|
|
useExpanded, |
|
|
useResizeColumns, |
|
|
} from "react-table"; |
|
|
|
|
|
import { COLUMNS } from "./columns"; |
|
|
import { GlobalFilter } from "./GlobalFilter"; |
|
|
import { Checkbox } from "./Checkbox"; |
|
|
import MOCK_DATA from "./MOCK_DATA.json"; |
|
|
|
|
|
// This is a custom filter UI for selecting |
|
|
// a unique option from a list |
|
|
export function SelectColumnFilter({ |
|
|
column: { filterValue, setFilter, preFilteredRows, id, render }, |
|
|
}) { |
|
|
const options = React.useMemo(() => { |
|
|
const options = new Set(); |
|
|
preFilteredRows.forEach((row) => { |
|
|
options.add(row.values[id]); |
|
|
}); |
|
|
return [...options.values()]; |
|
|
}, [id, preFilteredRows]); |
|
|
|
|
|
// Render a multi-select box |
|
|
return ( |
|
|
<label className="flex gap-x-2 items-baseline"> |
|
|
<span className="text-gray-700">{render("Header")}: </span> |
|
|
<select |
|
|
className="rounded-md border-gray-300 shadow-sm text-xs focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" |
|
|
name={id} |
|
|
id={id} |
|
|
value={filterValue} |
|
|
onChange={(e) => { |
|
|
setFilter(e.target.value || undefined); |
|
|
}} |
|
|
> |
|
|
<option className="text-xs" value=""> |
|
|
همه |
|
|
</option> |
|
|
{options.map((option, i) => ( |
|
|
<option key={i} value={option} className="text-xs"> |
|
|
{(() => { |
|
|
if (option === 1) { |
|
|
return "وضعیت عادی"; |
|
|
} else if (option === 2) { |
|
|
return "اعلان سطح هشدار"; |
|
|
} else if (option === 3) { |
|
|
return "بررسی و پیگیری"; |
|
|
} else if (option === 4) { |
|
|
return "وضعیت بحرانی"; |
|
|
} else { |
|
|
return " وضعیت پایدار"; |
|
|
} |
|
|
})()}{" "} |
|
|
</option> |
|
|
))} |
|
|
</select> |
|
|
</label> |
|
|
); |
|
|
} |
|
|
|
|
|
const BasicTable = () => { |
|
|
const columns = React.useMemo(() => COLUMNS, []); |
|
|
const data = useMemo(() => MOCK_DATA, []); |
|
|
|
|
|
// اگر بخواهیم ردیف های جدولمون یکی در میان زنگ پس زمینه اشون با هم فرق کند |
|
|
const isEven = (idx) => idx % 2 === 0; |
|
|
|
|
|
const { |
|
|
getTableProps, |
|
|
getTableBodyProps, |
|
|
headerGroups, |
|
|
footerGroups, |
|
|
rows, |
|
|
page, |
|
|
nextPage, |
|
|
previousPage, |
|
|
canNextPage, |
|
|
canPreviousPage, |
|
|
pageOptions, |
|
|
gotoPage, |
|
|
pageCount, |
|
|
setPageSize, |
|
|
prepareRow, |
|
|
allColumns, |
|
|
getToggleHideAllColumnsProps, |
|
|
setColumnOrder, |
|
|
selectedFlatRows, |
|
|
state, |
|
|
setGlobalFilter, |
|
|
resetResizing, |
|
|
} = useTable( |
|
|
{ |
|
|
columns, |
|
|
data, |
|
|
// initialState: { pageIndex: 2 } |
|
|
}, |
|
|
useColumnOrder, |
|
|
useFilters, |
|
|
useGlobalFilter, |
|
|
useSortBy, |
|
|
useExpanded, |
|
|
usePagination, |
|
|
useRowSelect, |
|
|
(hooks) => { |
|
|
hooks.visibleColumns.push((columns) => { |
|
|
return [ |
|
|
{ |
|
|
id: "selection", |
|
|
Header: ({ getToggleAllRowsSelectedProps }) => ( |
|
|
<Checkbox {...getToggleAllRowsSelectedProps()} /> |
|
|
), |
|
|
Cell: ({ row }) => ( |
|
|
<Checkbox {...row.getToggleRowSelectedProps()} /> |
|
|
), |
|
|
}, |
|
|
...columns, |
|
|
]; |
|
|
}); |
|
|
} |
|
|
); |
|
|
|
|
|
const changeOrder = () => { |
|
|
setColumnOrder([ |
|
|
"name", |
|
|
"order-number", |
|
|
"user-job", |
|
|
"order-level", |
|
|
"order-status", |
|
|
"order-price", |
|
|
]); |
|
|
}; |
|
|
|
|
|
const { globalFilter, pageIndex, pageSize } = state; |
|
|
// const firstPageRows = rows.slice(0, 10); |
|
|
console.log(rows.length); |
|
|
return ( |
|
|
<> |
|
|
<div className="customeClass1"> |
|
|
{headerGroups.map((headerGroup) => |
|
|
headerGroup.headers.map((column) => |
|
|
column.Filter ? ( |
|
|
<div className="mt-2 sm:mt-0 customeClass2" key={column.id}> |
|
|
{column.render("Filter")} |
|
|
</div> |
|
|
) : null |
|
|
) |
|
|
)} |
|
|
</div> |
|
|
<div className="flex flex-row items-center justify-end mb-3 mx-4"> |
|
|
{/* search box */} |
|
|
{/* <GlobalFilter filter={globalFilter} setFilter={setGlobalFilter} /> */} |
|
|
{/* pagination */} |
|
|
<div |
|
|
className="border border-blue-400 rounded-sm py-1 px-2 flex flex-items-center" |
|
|
style={{}} |
|
|
> |
|
|
{/* go to page */} |
|
|
<div> |
|
|
<input |
|
|
className="ml-1 text-xs p-1 rounded border-blue-400" |
|
|
type="number" |
|
|
defaultValue={pageIndex + 1} |
|
|
onChange={(e) => { |
|
|
const pageNumber = e.target.value |
|
|
? Number(e.target.value) - 1 |
|
|
: 0; |
|
|
gotoPage(pageNumber); |
|
|
}} |
|
|
style={{ width: "50px" }} |
|
|
/> |
|
|
<span className={`text-xs`} style={{ color: "#65A9FF" }}> |
|
|
{" "} |
|
|
برو به صفحه{" "} |
|
|
</span> |
|
|
</div> |
|
|
{/* */} |
|
|
<div className={`bg-gray-400 w-0.5 my-2 mx-1`}></div> |
|
|
{/* arrows */} |
|
|
<button |
|
|
className="rounded py-1 px-2 mx-1 text-xs" |
|
|
style={{ backgroundColor: "#F5F9FF", color: "#65A9FF" }} |
|
|
onClick={() => gotoPage(0)} |
|
|
disabled={!canPreviousPage} |
|
|
> |
|
|
{"<<"} |
|
|
</button> |
|
|
<button |
|
|
className="rounded py-1 px-2 mx-1 text-xs" |
|
|
style={{ backgroundColor: "#F5F9FF", color: "#65A9FF" }} |
|
|
onClick={() => previousPage()} |
|
|
disabled={!canPreviousPage} |
|
|
> |
|
|
{"<"} |
|
|
</button> |
|
|
<button |
|
|
className="rounded py-1 px-2 mx-1 text-xs" |
|
|
style={{ backgroundColor: "#F5F9FF", color: "#65A9FF" }} |
|
|
onClick={() => nextPage()} |
|
|
disabled={!canNextPage} |
|
|
> |
|
|
{">"} |
|
|
</button> |
|
|
<button |
|
|
className="rounded py-1 px-2 mx-1 text-xs" |
|
|
style={{ backgroundColor: "#F5F9FF", color: "#65A9FF" }} |
|
|
onClick={() => gotoPage(pageCount - 1)} |
|
|
disabled={!canNextPage} |
|
|
> |
|
|
{">>"} |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
{/* */} |
|
|
{/* toggle columns */} |
|
|
{/* <div> |
|
|
<div> |
|
|
<Checkbox {...getToggleHideAllColumnsProps()} /> Toggle All |
|
|
</div> |
|
|
{allColumns.map((column) => ( |
|
|
<div key={column.id}> |
|
|
<label> |
|
|
<input type="checkbox" {...column.getToggleHiddenProps()} /> |
|
|
{column.Header} |
|
|
</label> |
|
|
</div> |
|
|
))} |
|
|
</div> */} |
|
|
{/* Change Column Order */} |
|
|
{/* <button onClick={changeOrder}> Change Column Order </button> */} |
|
|
<table |
|
|
{...getTableProps()} |
|
|
className="min-w-full divide-y divide-gray-200" |
|
|
> |
|
|
<thead className="" style={{ backgroundColor: "#F3F8FF" }}> |
|
|
{headerGroups.map((headerGroup) => ( |
|
|
<tr {...headerGroup.getHeaderGroupProps()}> |
|
|
{headerGroup.headers.map((column) => ( |
|
|
<th |
|
|
{...column.getHeaderProps(column.getSortByToggleProps())} |
|
|
scope="col" |
|
|
className="cursor-pointer p-4 text-right text-sm font-medium" |
|
|
style={{ color: "#3287B9" }} |
|
|
> |
|
|
{column.render("Header")} |
|
|
<span> |
|
|
{column.isSorted |
|
|
? column.isSortedDesc |
|
|
? " 🔽" |
|
|
: " 🔼" |
|
|
: ""} |
|
|
</span> |
|
|
</th> |
|
|
))} |
|
|
</tr> |
|
|
))} |
|
|
</thead> |
|
|
|
|
|
<tbody |
|
|
{...getTableBodyProps()} |
|
|
className="divide-y divide-gray-200 bg-white" |
|
|
> |
|
|
{page.map((row, idx) => { |
|
|
prepareRow(row); |
|
|
return ( |
|
|
<React.Fragment> |
|
|
<tr |
|
|
{...row.getRowProps()} |
|
|
// className={isEven(idx) ? "bg-gray-600" : "bg-white"} |
|
|
> |
|
|
{row.cells.map((cell) => { |
|
|
return ( |
|
|
<td |
|
|
{...cell.getCellProps()} |
|
|
className="p-4 whitespace-nowrap text-xs" |
|
|
role="cell" |
|
|
style={{ color: "#00253A" }} |
|
|
> |
|
|
{cell.render("Cell")} |
|
|
</td> |
|
|
); |
|
|
})} |
|
|
</tr> |
|
|
{row.isExpanded ? ( |
|
|
<tr> |
|
|
<td colSpan={headerGroups[0].headers.length}> |
|
|
{renderRowSubComponent({ row: row.values })} |
|
|
</td> |
|
|
</tr> |
|
|
) : null} |
|
|
</React.Fragment> |
|
|
); |
|
|
})} |
|
|
</tbody> |
|
|
|
|
|
<tfoot |
|
|
className={`bg-blue-900 ${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: "#fff" }} |
|
|
> |
|
|
{column.render("Footer")} |
|
|
</td> |
|
|
))} |
|
|
</tr> |
|
|
))} |
|
|
</tfoot> |
|
|
</table> |
|
|
<pre> |
|
|
<code> |
|
|
{JSON.stringify( |
|
|
{ |
|
|
selectedFlatRows: selectedFlatRows.map((row) => row.original), |
|
|
}, |
|
|
null, |
|
|
2 |
|
|
)} |
|
|
</code> |
|
|
</pre> |
|
|
|
|
|
<div className="mt-3 "> |
|
|
<span className="text-sm ml-4"> |
|
|
صفحه{" "} |
|
|
<strong className="text-indigo-500"> |
|
|
{pageIndex + 1} از {pageOptions.length} |
|
|
</strong> |
|
|
{""} |
|
|
</span> |
|
|
|
|
|
<select |
|
|
className="text-white text-sm rounded cursor-pointer" |
|
|
style={{ |
|
|
backgroundColor: "#65A9FF", |
|
|
borderColor: "#65A9FF", |
|
|
}} |
|
|
value={pageSize} |
|
|
onChange={(e) => setPageSize(Number(e.target.value))} |
|
|
> |
|
|
{[7, 10, 25, 50].map((pageSize) => ( |
|
|
<option |
|
|
key={pageSize} |
|
|
value={pageSize} |
|
|
className=" text-sm" |
|
|
style={{ |
|
|
direction: "ltr", |
|
|
textAlign: "right", |
|
|
}} |
|
|
> |
|
|
نمایش {pageSize} |
|
|
</option> |
|
|
))} |
|
|
</select> |
|
|
</div> |
|
|
</> |
|
|
); |
|
|
}; |
|
|
function renderRowSubComponent({ row }) { |
|
|
return ( |
|
|
<div className="pl-2 pr-5 bg-blue-200"> |
|
|
نام: {row.name} |
|
|
<br /> |
|
|
<button className="bg-blue-400">ویرایش</button> |
|
|
</div> |
|
|
); |
|
|
} |
|
|
export default BasicTable;
|
|
|
|