You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
372 lines
10 KiB
372 lines
10 KiB
import React, { useMemo } from "react"; |
|
|
|
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 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 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 ( |
|
<> |
|
{headerGroups.map((headerGroup) => |
|
headerGroup.headers.map((column) => |
|
column.Filter ? ( |
|
<div className="mt-2 sm:mt-0" key={column.id}> |
|
{column.render("Filter")} |
|
</div> |
|
) : null |
|
) |
|
)} |
|
<div className="flex flex-row items-center justify-between 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 ( |
|
<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> |
|
); |
|
})} |
|
</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> |
|
</> |
|
); |
|
}; |
|
|
|
export default BasicTable;
|
|
|