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.
320 lines
9.4 KiB
320 lines
9.4 KiB
import React, { useMemo, useState, useRef } from "react"; |
|
|
|
import "./index.scss"; |
|
|
|
import MOCK_DATA2 from "./MOCK_DATA2.json"; |
|
|
|
import { GlobalFilter } from "./GlobalFilter"; |
|
|
|
import { COLUMNS } from "./COLUMNS"; |
|
|
|
import grid from "./grid.svg"; |
|
import list from "./list.svg"; |
|
import graySearchIcon from "./gray-search-icon.svg"; |
|
|
|
import RenderRowSubComponent from "./RenderRowSubComponent"; |
|
import EditRow from "./EditRow"; |
|
|
|
import { |
|
useTable, |
|
useSortBy, |
|
useGlobalFilter, |
|
useFilters, |
|
usePagination, |
|
useRowSelect, |
|
useColumnOrder, |
|
useExpanded, |
|
} from "react-table"; |
|
import ButtonNewDesign from "../ButtonNewDesign"; |
|
|
|
export const 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]); |
|
|
|
return ( |
|
<select |
|
className="w-32 appearance-none text-xs flex flex-row items-start p-2 rounded focus:outline-none border focus:border-gray-200 focus:ring focus:ring-gray-200 focus:ring-opacity-20" |
|
style={{ borderColor: "#EEEEEE", color: "#00253A" }} |
|
name={id} |
|
id={id} |
|
value={filterValue} |
|
onChange={(e) => { |
|
setFilter(e.target.value || undefined); |
|
}} |
|
> |
|
<option |
|
className="text-white" |
|
value="" |
|
style={{ backgroundColor: "#65A9FF" }} |
|
> |
|
بر اساس نوع فایل |
|
</option> |
|
{options.map((option, i) => ( |
|
<option |
|
key={i} |
|
value={option} |
|
className="text-right text-white px-2" |
|
style={{ backgroundColor: "#65A9FF" }} |
|
> |
|
{(() => { |
|
if (option === 1) { |
|
return "JPG"; |
|
} else if (option === 2) { |
|
return "PNG"; |
|
} else if (option === 3) { |
|
return "PDF"; |
|
} else if (option === 4) { |
|
return "CSV"; |
|
} else if (option === 5) { |
|
return "PPT"; |
|
} else { |
|
return "MP4"; |
|
} |
|
})()}{" "} |
|
</option> |
|
))} |
|
</select> |
|
); |
|
}; |
|
|
|
const BasicTable = ({ addTab, activeTab }) => { |
|
const data = useMemo(() => MOCK_DATA2, []); |
|
// console.log(data); |
|
|
|
// const [filtering, setFiltering] = useState(false); |
|
const [chekedItems, setChekedItems] = useState([]); |
|
const refChekedItems = useRef(chekedItems); |
|
refChekedItems.current = chekedItems; |
|
const toggelChekedItems = (id) => { |
|
const check = refChekedItems.current.includes(id); |
|
setChekedItems( |
|
check |
|
? [...refChekedItems.current.filter((el) => el !== id)] |
|
: [...refChekedItems.current, id] |
|
); |
|
}; |
|
|
|
const columns = React.useMemo( |
|
() => COLUMNS({ toggelChekedItems, refChekedItems }), |
|
[] |
|
); |
|
|
|
const defaultColumn = useMemo(() => { |
|
return {}; |
|
}, []); |
|
|
|
// اگر بخواهیم ردیف های جدولمون یکی در میان زنگ پس زمینه اشون با هم فرق کند |
|
const isEven = (idx) => idx % 2 === 0; |
|
|
|
const { |
|
getTableProps, |
|
getTableBodyProps, |
|
headerGroups, |
|
rows, |
|
page, |
|
prepareRow, |
|
state, |
|
setGlobalFilter, |
|
} = useTable( |
|
{ |
|
columns, |
|
data, |
|
defaultColumn, |
|
}, |
|
useColumnOrder, |
|
useFilters, |
|
useGlobalFilter, |
|
useSortBy, |
|
useExpanded, |
|
usePagination, |
|
useRowSelect |
|
); |
|
|
|
const { globalFilter } = state; |
|
|
|
const [activeList, setActiveList] = useState(false); |
|
|
|
return ( |
|
<div className="bg-white p-4"> |
|
<div className="mb-7 flex flex-row items-center justify-between"> |
|
<div className="flex flex-row items-center gap-x-5"> |
|
<div className="flex flex-row items-center gap-x-2"> |
|
<img |
|
alt="" |
|
src={list} |
|
className="cursor-pointer" |
|
onClick={() => setActiveList(false)} |
|
/> |
|
<img |
|
alt="" |
|
src={grid} |
|
className="cursor-pointer" |
|
onClick={() => setActiveList(true)} |
|
/> |
|
</div> |
|
{headerGroups.map((headerGroup) => |
|
headerGroup.headers.map((column) => |
|
column.Filter ? ( |
|
<div className="mt-2 sm:mt-0" key={column.id}> |
|
{column.render("Filter")} |
|
</div> |
|
) : null |
|
) |
|
)} |
|
<ButtonNewDesign |
|
bgColor={"bg-blue-500"} |
|
icon={null} |
|
border={"border-0"} |
|
borderRadius={"rounded"} |
|
fontSize={"text-xs"} |
|
padding={"p-2"} |
|
text={ |
|
chekedItems.length < page.length ? "انتخاب همه" : "حذف انتخاب" |
|
} |
|
onClick={() => { |
|
setChekedItems( |
|
chekedItems.length < page.length |
|
? page.map((e) => e.original.id) |
|
: [] |
|
); |
|
}} |
|
/> |
|
</div> |
|
<div className="w-4/12 "> |
|
<GlobalFilter |
|
filter={globalFilter} |
|
setFilter={setGlobalFilter} |
|
searchIcon={graySearchIcon} |
|
bgColor={"bg-transparent"} |
|
borderColor={"border-[#EEEEEE]"} |
|
textColor={"text-gray-500"} |
|
borderRadius={"rounded"} |
|
focusBorder={"focus:border-gray-200"} |
|
focusRing={"focus:ring-gray-200"} |
|
/> |
|
</div> |
|
</div> |
|
{/* table LIST */} |
|
{activeTab === 0 ? ( |
|
<> |
|
{activeList === true && ( |
|
// table |
|
<table |
|
{...getTableProps()} |
|
className="min-w-full divide-y divide-gray-200 mb-5" |
|
> |
|
<tbody |
|
{...getTableBodyProps()} |
|
className={"divide-y divide-gray-200 "} |
|
> |
|
{page.map((row, idx) => { |
|
prepareRow(row); |
|
|
|
return ( |
|
<React.Fragment key={idx}> |
|
<tr |
|
{...row.getRowProps()} |
|
onClick={() => toggelChekedItems(row.original.id)} |
|
className={ |
|
(isEven(idx) ? " bg-gray-100 " : " bg-white ") + |
|
(chekedItems.includes(row.original.id) |
|
? isEven(idx) |
|
? "bg-blue-200" |
|
: "bg-blue-100" |
|
: "") |
|
} |
|
> |
|
{row.cells.map((cell, index) => { |
|
return ( |
|
<td |
|
{...cell.getCellProps({ |
|
className: cell.column.className, |
|
})} |
|
style={{ |
|
padding: "12px", |
|
fontSize: "13px", |
|
textAlign: "right", |
|
whiteSpace: "nowrap", |
|
}} |
|
key={index} |
|
{...cell.getCellProps()} |
|
role="cell" |
|
> |
|
{cell.render("Cell")} |
|
</td> |
|
); |
|
})} |
|
</tr> |
|
{row.isExpanded ? ( |
|
<tr> |
|
<td colSpan={headerGroups[0].headers.length}> |
|
<RenderRowSubComponent |
|
columns={columns} |
|
addTab={addTab} |
|
row={row.original} |
|
/> |
|
{console.log(row.original)} |
|
</td> |
|
</tr> |
|
) : null} |
|
</React.Fragment> |
|
); |
|
})} |
|
</tbody> |
|
</table> |
|
)} |
|
{/* GRID LIST */} |
|
{activeList === false && ( |
|
<div |
|
{...getTableBodyProps()} |
|
className="flex flex-row flex-wrap gap-4 items-center justify-center" |
|
> |
|
{page.map((row, index) => { |
|
prepareRow(row); |
|
return ( |
|
<div |
|
{...row.getRowProps()} |
|
className="flex flex-col px-4 py-5 rounded-md" |
|
key={index} |
|
style={{ backgroundColor: "#F3F3F3" }} |
|
> |
|
<input type="checkbox" /> |
|
<div className="bg-red-500"> {row.original.Checkbox}</div> |
|
<img |
|
src={row.original.filePic} |
|
alt={row.original.filePic} |
|
className="w-52" |
|
/> |
|
<p className="text-sm my-3">{row.original.fileName}</p> |
|
<span className="text-xs text-left text-gray-500"> |
|
{row.original.fileSize} |
|
</span> |
|
</div> |
|
); |
|
})} |
|
</div> |
|
)} |
|
</> |
|
) : ( |
|
<EditRow |
|
row={ |
|
rows.find((e) => e.original && +e.original.id === activeTab) |
|
?.original || {} |
|
} |
|
columns={defaultColumn} |
|
/> |
|
)} |
|
</div> |
|
); |
|
}; |
|
|
|
export default BasicTable; |
|
|
|
BasicTable.defaultProps = {};
|
|
|