Newer
Older
import { Button, TablePagination, TextField } from '@mui/material'
import {
ColDef,
ColGroupDef,
CsvExportParams,
GridApi,
GridReadyEvent,
import { AgGridReact } from 'ag-grid-react'
import { DateTime } from 'luxon'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { useWhoAmI } from '../../API'
import { getAxiosXSRFHeader } from '../../axios.config'
import { IConsent } from '../../models/consent.model'
import { ConsentService } from '../../services/consent.service'
import DownloadModal from './DownloadModal'
import './muiPaginationOverrides.scss'
const Consents: React.FC = () => {
const [gridApi, setGridApi] = useState<GridApi | null>(null)
const [search, setSearch] = useState<string>('')
const [selectedNodes, setSelectedNodes] = useState<IRowNode[]>([])
const [isShowingSelection, setIsShowingSelection] = useState<boolean>(false)
const [openDownloadModal, setOpenDownloadModal] = useState<boolean>(false)
const [consents, setConsents] = useState<IConsent[]>([])
const [page, setPage] = useState<number>(0)
const [rowsPerPage, setRowsPerPage] = useState<number>(50)
const [totalRows, setTotalRows] = useState<number>(50)
const { data: user } = useWhoAmI()
const consentService = useMemo(() => {
return new ConsentService()
}, [])
const toggleOpenModal = useCallback(() => {
setOpenDownloadModal(prev => !prev)
}, [])
const defaultColDef = useMemo(
() => ({
sortable: true,
resizable: true,
}),
[]
)
const dateFormatter = (data: ValueFormatterParams): string => {
return (data.value as DateTime).toLocaleString()
}
const [columnDefs] = useState<(ColDef | ColGroupDef)[] | null>([
{
field: 'ID',
hide: true,
},
{
field: 'pointID',
headerName: 'N° PDL',
{
field: 'lastname',
headerName: 'Nom',
initialWidth: 180,
filter: true,
cellStyle: { textTransform: 'uppercase' },
},
{
field: 'firstname',
headerName: 'Prénom',
initialWidth: 180,
filter: true,
cellStyle: { textTransform: 'capitalize' },
},
{
field: 'address',
headerName: 'Adresse',
initialWidth: 300,
filter: true,
flex: 1,
},
{
field: 'postalCode',
headerName: 'CP',
{
field: 'city',
headerName: 'Ville',
},
{
field: 'safetyOnBoarding',
headerName: 'Secours',
const handleChangePage = useCallback(
(
_event: React.MouseEvent<HTMLButtonElement, MouseEvent> | null,
newPage: number
) => {
setPage(newPage)
},
[]
)
setRowsPerPage(event.target.value)
setPage(0)
}, [])
const checkSelectedNodes = useCallback(() => {
if (gridApi) {
const newNodes = gridApi.getRenderedNodes()
const idsToCheck: string[] = selectedNodes
.filter(node => node.isSelected)
.map(node => node.data.ID)
if (idsToCheck.includes(node.data.ID)) node.setSelected(true, false)
const searchConsents = async () => {
if (user) {
const consentPagination = await consentService.searchConsents(
search,
rowsPerPage,
page,
getAxiosXSRFHeader(user.xsrftoken)
)
if (consentPagination) {
setConsents(consentPagination.rows)
checkSelectedNodes()
setTotalRows(consentPagination.totalRows)
}
}
const handleSearchChange = (newSearch: string) => {
setSearch(newSearch)
setPage(0)
}
const resetSelection = useCallback(() => {
if (gridApi) {
setIsShowingSelection(false)
gridApi.setRowData(consents)
gridApi.deselectAll()
setSelectedNodes([])
}
}, [gridApi, consents])
const onRowSelected = useCallback(
(event: RowSelectedEvent) => {
if (event.node.isSelected()) {
const index = selectedNodes.findIndex(
return node.data.ID != event.node.data.ID
})
)
}
},
[selectedNodes]
)
const continueSelection = useCallback(() => {
if (gridApi) {
setIsShowingSelection(false)
gridApi?.setRowData(consents)
const newNodes = gridApi.getRenderedNodes()
// We have to select nodes that have already been selected since we cannot pass a Node array to init AgGrid
const idsToCheck: string[] = selectedNodes
.filter(node => node.isSelected)
.map(node => node.data.ID)
newNodes.forEach(node => {
if (idsToCheck.includes(node.data.ID)) node.setSelected(true)
})
}
}, [gridApi, consents, selectedNodes])
const showCurrentSelection = useCallback(() => {
setIsShowingSelection(true)
const dataFromNode = selectedNodes.map(item => item.data)
selectedNodes && gridApi?.setRowData(dataFromNode)
gridApi?.selectAll()
}, [gridApi, selectedNodes])
const exportData = useCallback(() => {
//You can change default column separator
const params: CsvExportParams = {
columnSeparator: ',',
}
gridApi?.exportDataAsCsv(params)
setOpenDownloadModal(false)
resetSelection()
}, [gridApi, resetSelection])
const onGridReady = ({ api }: GridReadyEvent) => {
//Grid init method
setGridApi(api)
api.sizeColumnsToFit()
}
useEffect(() => {
function handleResize() {
gridApi?.sizeColumnsToFit()
}
handleResize()
window.addEventListener('resize', handleResize)
return () => {
window.removeEventListener('resize', handleResize)
}
}, [gridApi])
/** Trigger search when page loads or when admin changes input or pagination */
// /!\ Do not change dependencies or effect will not trigger when pagination changes
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [rowsPerPage, page, search])
<h1>Gestion des consentements Enedis</h1>
<TextField
placeholder="N°PDL (14 chiffres)"
label="Recherche"
value={search}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
handleSearchChange(e.target.value)
}
disabled={isShowingSelection}
autoComplete="off"
/>
>
<AgGridReact
onGridReady={onGridReady}
defaultColDef={defaultColDef}
rowHeight={35}
rowData={consents}
columnDefs={columnDefs}
animateRows={true}
rowSelection="multiple"
allowDragFromColumnsToolPanel={false}
onRowSelected={onRowSelected}
sortingOrder={['asc', 'desc']}
rowMultiSelectWithClick={true}
pagination={false}
suppressCellFocus={true}
expired: params => params.data.endDate < DateTime.now(),
<TablePagination
labelRowsPerPage="Consentements par page"
component="div"
count={totalRows}
page={page}
onPageChange={handleChangePage}
rowsPerPage={rowsPerPage}
onRowsPerPageChange={handleChangeRowsPerPage}
rowsPerPageOptions={[10, 25, 50, 100]}
/>
)}
</div>
open={openDownloadModal}
toggleOpenModal={toggleOpenModal}
exportData={exportData}
/>
<Button
variant="outlined"
onClick={isShowingSelection ? continueSelection : resetSelection}
disabled={
!isShowingSelection && selectedNodes && selectedNodes.length === 0
}
>
{isShowingSelection
? 'Continuer ma sélection'
onClick={!isShowingSelection ? showCurrentSelection : toggleOpenModal}
disabled={selectedNodes && selectedNodes.length <= 0}
classes={{ contained: styles.btnText }}
>
{!isShowingSelection ? 'Voir mes sélections' : 'Télécharger'}
<div>{selectedNodes?.length}</div>
</Button>