diff --git a/targets/frontend/src/components/data/DataTable.tsx b/targets/frontend/src/components/data/DataTable.tsx new file mode 100644 index 0000000000..4683b3875c --- /dev/null +++ b/targets/frontend/src/components/data/DataTable.tsx @@ -0,0 +1,146 @@ +import * as React from "react"; +import { useState } from "react"; +import Box from "@mui/material/Box"; +import Table from "@mui/material/Table"; +import TableBody from "@mui/material/TableBody"; +import TableCell from "@mui/material/TableCell"; +import TableContainer from "@mui/material/TableContainer"; +import TableRow from "@mui/material/TableRow"; +import Checkbox from "@mui/material/Checkbox"; +import { Toolbar } from "./Toolbard"; +import { Head } from "./Head"; +import { Data, HeadCell, Source } from "./type"; +import { PublishModal } from "./PublishModal"; + +type Props = { + source: Source; + readonly headCells: HeadCell[]; + rows: T[]; + onClickItem: (id: string) => void; + onClickCreation: () => void; + setSearch: (value: string | undefined) => void; + customFilters?: React.ReactNode; +}; + +type ItemCheck = { + [id: string]: boolean; +}; + +export const DataTable = ({ + source, + headCells, + rows, + onClickItem, + onClickCreation, + setSearch, + customFilters, +}: Props) => { + const [itemsCheck, setItemCheck] = useState({}); + const [isOpen, showModal] = useState(false); + + const handleSelectAllClick = (event: React.ChangeEvent) => { + setItemCheck( + rows.reduce((acc, item) => { + acc[item.id] = event.target.checked; + return acc; + }, {} as ItemCheck) + ); + }; + + const handleItemCheck = (id: string, checked: boolean) => { + setItemCheck({ + ...itemsCheck, + [id]: checked, + }); + }; + + const handleClick = (id: string) => { + const atLeastOneChecked = Object.values(itemsCheck).some( + (checked) => checked + ); + if (atLeastOneChecked) { + handleItemCheck(id, !itemsCheck[id]); + } else { + onClickItem(id); + } + }; + + const numSelected = (): number => { + return Object.values(itemsCheck).filter((item) => item).length; + }; + + return ( + + showModal(true)} + onClickCreation={onClickCreation} + setSearch={setSearch} + customFilters={customFilters} + /> + + + + + {rows.map((row, index) => { + const isItemSelected = itemsCheck[row.id] ?? false; + const labelId = `${source}-table-checkbox-${index}`; + + return ( + + + + handleItemCheck(row.id, event.target.checked) + } + /> + + {headCells.map((head) => ( + handleClick(row.id)} + > + {head.render + ? head.render(row[head.dataIndex]) + : (row[head.dataIndex] as React.ReactNode)} + + ))} + + ); + })} + +
+
+ {isOpen && ( + value) + .map(([key, _]) => { + const find = rows.find((item) => item.id === key)!!; + return { + id: find.id, + title: find.title, + }; + })} + open={isOpen} + onCancel={() => showModal(false)} + onClose={() => showModal(false)} + /> + )} +
+ ); +}; diff --git a/targets/frontend/src/components/data/Head.tsx b/targets/frontend/src/components/data/Head.tsx index 56ce7bc71e..296078cc5f 100644 --- a/targets/frontend/src/components/data/Head.tsx +++ b/targets/frontend/src/components/data/Head.tsx @@ -5,19 +5,19 @@ import Checkbox from "@mui/material/Checkbox"; import * as React from "react"; import { Data, HeadCell } from "./type"; -export type EnhancedTableProps = { +export type HeadProps = { readonly headCells: HeadCell[]; numSelected: number; onSelectAllClick: (event: React.ChangeEvent) => void; rowCount: number; }; -export const EnhancedTableHead = ({ +export const Head = ({ onSelectAllClick, numSelected, rowCount, headCells, -}: EnhancedTableProps) => { +}: HeadProps) => { return ( diff --git a/targets/frontend/src/components/data/Toolbard.tsx b/targets/frontend/src/components/data/Toolbard.tsx index 4ed6682047..4a0d8fdd17 100644 --- a/targets/frontend/src/components/data/Toolbard.tsx +++ b/targets/frontend/src/components/data/Toolbard.tsx @@ -1,11 +1,15 @@ -import Toolbar from "@mui/material/Toolbar"; +import { + Button, + FormGroup, + TextField, + Toolbar as MuiToolbar, +} from "@mui/material"; import { alpha } from "@mui/material/styles"; import Typography from "@mui/material/Typography"; import PublishIcon from "@mui/icons-material/Publish"; import * as React from "react"; -import { Button, FormGroup, Stack, TextField } from "@mui/material"; -interface EnhancedTableToolbarProps { +interface ToolbarProps { numSelected: number; onClickPublish: () => void; onClickCreation: () => void; @@ -13,15 +17,15 @@ interface EnhancedTableToolbarProps { customFilters?: React.ReactNode; } -export const EnhancedTableToolbar = ({ +export const Toolbar = ({ numSelected, onClickPublish, onClickCreation, setSearch, customFilters = undefined, -}: EnhancedTableToolbarProps) => { +}: ToolbarProps) => { return ( - )} - + ); }; diff --git a/targets/frontend/src/components/data/index.tsx b/targets/frontend/src/components/data/index.tsx index e9bcb08f9b..4cb9855d0f 100644 --- a/targets/frontend/src/components/data/index.tsx +++ b/targets/frontend/src/components/data/index.tsx @@ -1,146 +1 @@ -import * as React from "react"; -import { useState } from "react"; -import Box from "@mui/material/Box"; -import Table from "@mui/material/Table"; -import TableBody from "@mui/material/TableBody"; -import TableCell from "@mui/material/TableCell"; -import TableContainer from "@mui/material/TableContainer"; -import TableRow from "@mui/material/TableRow"; -import Checkbox from "@mui/material/Checkbox"; -import { EnhancedTableToolbar } from "./Toolbard"; -import { EnhancedTableHead } from "./Head"; -import { Data, HeadCell, Source } from "./type"; -import { PublishModal } from "./PublishModal"; - -type Props = { - source: Source; - readonly headCells: HeadCell[]; - rows: T[]; - onClickItem: (id: string) => void; - onClickCreation: () => void; - setSearch: (value: string | undefined) => void; - customFilters?: React.ReactNode; -}; - -type ItemCheck = { - [id: string]: boolean; -}; - -export const EnhancedTable = ({ - source, - headCells, - rows, - onClickItem, - onClickCreation, - setSearch, - customFilters, -}: Props) => { - const [itemsCheck, setItemCheck] = useState({}); - const [isOpen, showModal] = useState(false); - - const handleSelectAllClick = (event: React.ChangeEvent) => { - setItemCheck( - rows.reduce((acc, item) => { - acc[item.id] = event.target.checked; - return acc; - }, {} as ItemCheck) - ); - }; - - const handleItemCheck = (id: string, checked: boolean) => { - setItemCheck({ - ...itemsCheck, - [id]: checked, - }); - }; - - const handleClick = (id: string) => { - const atLeastOneChecked = Object.values(itemsCheck).some( - (checked) => checked - ); - if (atLeastOneChecked) { - handleItemCheck(id, !itemsCheck[id]); - } else { - onClickItem(id); - } - }; - - const numSelected = (): number => { - return Object.values(itemsCheck).filter((item) => item).length; - }; - - return ( - - showModal(true)} - onClickCreation={onClickCreation} - setSearch={setSearch} - customFilters={customFilters} - /> - - - - - {rows.map((row, index) => { - const isItemSelected = itemsCheck[row.id] ?? false; - const labelId = `${source}-table-checkbox-${index}`; - - return ( - - - - handleItemCheck(row.id, event.target.checked) - } - /> - - {headCells.map((head) => ( - handleClick(row.id)} - > - {head.render - ? head.render(row[head.dataIndex]) - : (row[head.dataIndex] as React.ReactNode)} - - ))} - - ); - })} - -
-
- {isOpen && ( - value) - .map(([key, _]) => { - const find = rows.find((item) => item.id === key)!!; - return { - id: find.id, - title: find.title, - }; - })} - open={isOpen} - onCancel={() => showModal(false)} - onClose={() => showModal(false)} - /> - )} -
- ); -}; +export * from "./DataTable"; diff --git a/targets/frontend/src/modules/agreements/components/List/index.tsx b/targets/frontend/src/modules/agreements/components/List/index.tsx index dca75ce46d..a8438f97fe 100644 --- a/targets/frontend/src/modules/agreements/components/List/index.tsx +++ b/targets/frontend/src/modules/agreements/components/List/index.tsx @@ -2,10 +2,10 @@ import React, { useState } from "react"; import { useListAgreementQuery } from "./list.query"; import { useRouter } from "next/router"; -import { EnhancedTable } from "src/components/data"; import { Tooltip } from "@mui/material"; import GavelIcon from "@mui/icons-material/Gavel"; import Filter from "./Filter"; +import { DataTable } from "../../../../components/data"; type AgreementData = { id: string; @@ -22,7 +22,7 @@ export const AgreementList = (): JSX.Element => { isSupported, }); return ( - + source="conventions_collectives" headCells={[ { diff --git a/targets/frontend/src/modules/informations/components/List/index.tsx b/targets/frontend/src/modules/informations/components/List/index.tsx index 049e6aa50b..b47ad713a7 100644 --- a/targets/frontend/src/modules/informations/components/List/index.tsx +++ b/targets/frontend/src/modules/informations/components/List/index.tsx @@ -2,7 +2,7 @@ import { useState } from "react"; import { useRouter } from "next/router"; import { useInformationsListQuery } from "./list.query"; -import { EnhancedTable } from "src/components/data"; +import { DataTable } from "../../../../components/data"; type InfoData = { id: string; @@ -17,7 +17,7 @@ export const InformationList = (): JSX.Element => { }); return ( - + source="information" headCells={[ { diff --git a/targets/frontend/src/modules/models/components/List/index.tsx b/targets/frontend/src/modules/models/components/List/index.tsx index e7815a9e9d..bbe9bfc942 100644 --- a/targets/frontend/src/modules/models/components/List/index.tsx +++ b/targets/frontend/src/modules/models/components/List/index.tsx @@ -2,7 +2,7 @@ import { useRouter } from "next/router"; import { useState } from "react"; import { useListModelQuery } from "./list.query"; -import { EnhancedTable } from "src/components/data"; +import { DataTable } from "../../../../components/data"; type ModelData = { id: string; @@ -16,7 +16,7 @@ export const ModelList = (): JSX.Element => { search, }); return ( - + source="modeles_de_courriers" headCells={[ {