Skip to content

Commit

Permalink
feat: scope tree refacto - Ref gestion-de-projet#2449
Browse files Browse the repository at this point in the history
  • Loading branch information
FlorentGouyon authored and aetchego committed May 30, 2024
1 parent 2bb5d80 commit 5aff26c
Show file tree
Hide file tree
Showing 28 changed files with 1,314 additions and 374 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { ScopeTreeRow, ScopeType } from 'types'

import useStyles from './styles'
import ScopeTree from 'components/ScopeTree'
import { Grid } from '@mui/material'
import { SourceType } from 'types/scope'

type PopulationRightPanelProps = {
open: boolean
Expand All @@ -25,28 +27,31 @@ const PopulationRightPanel: React.FC<PopulationRightPanelProps> = (props) => {
const { classes } = useStyles()

const [_selectedPopulation, _setSelectedPopulation] = useState<ScopeTreeRow[]>(selectedPopulation)
const [openPopulation, setOpenPopulations] = useState<number[]>([])

/**
* Render
*/
return (
<Drawer anchor="right" open={open} onClose={onClose} className={classes.drawer}>
<div className={classes.root}>
<div className={classes.drawerTitleContainer}>
<Typography className={classes.title}>{title ?? 'Structure hospitalière'}</Typography>
</div>
<div className={classes.drawerContentContainer}>
<Drawer
anchor="right"
open={open}
PaperProps={{ style: { overflowY: 'unset', width: '650px' } }}
onClose={onClose}
className={classes.drawer}
>
<Grid container direction="column" flexWrap="nowrap" className={classes.root}>
<Grid item container flexDirection="column" height="100%" flexWrap="nowrap" overflow="auto">
<Grid item className={classes.drawerTitleContainer} width="100%">
<Typography className={classes.title}>{title ?? 'Structure hospitalière'}</Typography>
</Grid>
<ScopeTree
selectedItems={_selectedPopulation}
//selectedIds=""
selectedIds={'8312016825,8312077037,8312085055,8312016350,8312076084,16180131083'}
setSelectedItems={_setSelectedPopulation}
openPopulation={openPopulation}
setOpenPopulations={setOpenPopulations}
executiveUnitType={executiveUnitType}
sourceType={SourceType.ALL}
/>
</div>

<div className={classes.drawerActionContainer}>
</Grid>
<Grid item className={classes.drawerActionContainer} width="100%">
<Button onClick={onClose} variant="outlined">
Annuler
</Button>
Expand All @@ -60,8 +65,8 @@ const PopulationRightPanel: React.FC<PopulationRightPanelProps> = (props) => {
>
Confirmer
</Button>
</div>
</div>
</Grid>
</Grid>
</Drawer>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,24 @@ import { makeStyles } from 'tss-react/mui'

const useStyles = makeStyles()(() => ({
drawer: {
zIndex: 1300
zIndex: 1300,
overflowY: 'unset'
},
root: {
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
width: '95vw',
maxWidth: 650,
height: '100%'
},
drawerTitleContainer: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
borderBottom: '1px solid grey'
},
title: {
fontSize: 22,
margin: '12px 0'
},
drawerContentContainer: {
flex: '1 1 auto',
overflow: 'auto'
},
drawerContentContainer: {},
drawerActionContainer: {
display: 'flex',
alignItems: 'center',
Expand Down
32 changes: 11 additions & 21 deletions src/components/ScopeTree/ScopeTreeExploration/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,14 @@ import {
TableRow,
Typography
} from '@mui/material'
import React, { ReactElement, useEffect, useRef, useState } from 'react'
import React, { ReactElement, useRef, useState } from 'react'
import { AppDispatch, useAppDispatch, useAppSelector } from 'state'
import { ScopeTreeRow } from 'types'
import { getCurrentScopeList } from 'utils/scopeTree'
import ScopeTreeHierarchy from '../ScopeTreeHierarchy'
import EnhancedTable from '../ScopeTreeTable'
import { ScopeTreeExplorationProps } from '../index'
import {
getHeadCells,
init,
isSearchIndeterminate,
isSearchSelected,
onExpand,
Expand All @@ -50,10 +48,10 @@ const Index = (props: ScopeTreeExplorationProps) => {
const scopesList: ScopeTreeRow[] = getCurrentScopeList(scopeState.scopesList, isExecutiveUnit) ?? []
const [rootRows, setRootRows] = useState<ScopeTreeRow[]>(scopesList)
const [isSearchLoading, setIsSearchLoading] = useState<boolean>(false)
const [page, setPage] = useState(1)
const [count, setCount] = useState(0)
//const [page, setPage] = useState(1)
//const [count, setCount] = useState(0)
const [isEmpty, setIsEmpty] = useState<boolean>(!rootRows || rootRows.length === 0)
const [openPopulation, setOpenPopulations] = useState<number[]>([])
const [open, setOpen] = useState<number[]>([])

const isHeadChecked: boolean = rootRows.length > 0 && rootRows.every((item) => isSearchSelected(item, selectedItems))
const isHeadIndeterminate: boolean =
Expand All @@ -76,20 +74,20 @@ const Index = (props: ScopeTreeExplorationProps) => {
)
const headCells = getHeadCells(headCheckbox, executiveUnitType)

useEffect(() => {
/*useEffect(() => {
init(
setIsSearchLoading,
controllerRef,
rootRows,
setRootRows,
setOpenPopulations,
setOpen,
setCount,
setIsEmpty,
dispatch,
executiveUnitType,
!!executiveUnitType
)
}, [])
}, [])*/

return (
<div className={classes.container}>
Expand Down Expand Up @@ -127,14 +125,14 @@ const Index = (props: ScopeTreeExplorationProps) => {
row={row}
level={0}
parentAccess={row.access ?? '-'}
openPopulation={openPopulation}
openPopulation={open}
labelId={`enhanced-table-checkbox-${index}`}
onExpand={(rowId: number) =>
onExpand(
rowId,
controllerRef,
openPopulation,
setOpenPopulations,
open,
setOpen,
rootRows,
setRootRows,
selectedItems,
Expand Down Expand Up @@ -163,15 +161,7 @@ const Index = (props: ScopeTreeExplorationProps) => {
)
}}
</EnhancedTable>
{
<Pagination
className={classes.pagination}
count={Math.ceil((count ?? 0) / 100)}
shape="circular"
onChange={(event, page: number) => setPage && setPage(page)}
page={page}
/>
}
{}
</>
)}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,7 @@ const ScopeTreeTableRow: React.FC<ScopeTreeTableRowProps> = (props: ScopeTreeTab
</TableCell>
</TableRow>
) : (
<TableRow
hover
key={row.id}
classes={{
root: level % 2 === 0 ? classes.mainRow : classes.secondRow
}}
>
<TableRow hover key={row.id}>
<TableCell>
{(row.subItems?.length ?? 0) > 0 && (!isSearchMode || row.type !== executiveUnitType) && (
<IconButton
Expand Down
183 changes: 183 additions & 0 deletions src/components/ScopeTree/ScopeTreeTest.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
import React, { Fragment, useEffect, useState } from 'react'

import {
Breadcrumbs,
Checkbox,
ListItem,
Table,
TableBody,
TableCell,
TableHead,
TableRow,
Typography
} from '@mui/material'
import { ScopeElement, SelectedStatus } from 'types'
import { Hierarchy, NodeValidity } from 'types/hierarchy'
import { IndeterminateCheckBoxOutlined, KeyboardArrowDown, KeyboardArrowRight } from '@mui/icons-material'
import servicesPerimeters from 'services/aphp/servicePerimeters'
import displayDigit from 'utils/displayDigit'
import useStyles from './styles'
import { SourceType } from 'types/scope'

type HierarchyItemProps = {
item: Hierarchy<ScopeElement, string>
path: string[]
searchMode: boolean
onSelect: (node: Hierarchy<ScopeElement, string>, toAdd: boolean) => void
onExpand: (node: Hierarchy<ScopeElement, string>) => void
}

const ScopeTreeItem = ({ item, path, searchMode, onSelect, onExpand }: HierarchyItemProps) => {
const { classes } = useStyles()
const [open, setOpen] = useState(false)
const { id, name, subItems, status, source_value, cohort_size, full_path } = item
const canExpand =
!subItems || (subItems.length > -1 && !subItems.every((subItem) => subItem.validity === NodeValidity.NOT_VALID))
const canSearch = open === true && !subItems

useEffect(() => {
if (canSearch) onExpand(item)
}, [open])

return (
<Fragment>
<TableRow className={path.length % 2 === 0 ? classes.secondRow : classes.mainRow}>
<TableCell
width="42px"
className={classes.expandCell}
style={{ cursor: 'pointer', color: 'rgb(91, 197, 242)' }}
>
<ListItem
className={classes.expandIcon}
style={path.length > 1 ? { marginLeft: path.length * 24 - 24 + 'px' } : { margin: '0' }}
>
{canExpand && (
<>
{open && <KeyboardArrowDown onClick={() => setOpen(false)} />}
{!open && <KeyboardArrowRight onClick={() => setOpen(true)} />}
</>
)}
</ListItem>
</TableCell>
<TableCell width="42px" align="center" className={classes.checkbox}>
<Checkbox
checked={status === SelectedStatus.SELECTED}
indeterminate={status === SelectedStatus.INDETERMINATE}
color="secondary"
indeterminateIcon={<IndeterminateCheckBoxOutlined />}
onChange={(event, checked) => onSelect(item, checked)}
inputProps={{ 'aria-labelledby': name }}
/>
</TableCell>
{searchMode && full_path && (
<TableCell>
<Breadcrumbs maxItems={2}>
{(full_path.split('/').length > 1 ? full_path.split('/').slice(1) : full_path.split('/').slice(0)).map(
(full_path: string, index: number) => (
<Typography key={index} style={{ color: '#153D8A' }}>
{full_path}
</Typography>
)
)}
</Breadcrumbs>
</TableCell>
)}
{!searchMode && (
<TableCell style={{ cursor: 'pointer' }}>
<Typography onClick={() => setOpen(!open)}>{`${source_value} - ${name} - ${id}`}</Typography>
</TableCell>
)}
<TableCell align="center">
<Typography onClick={() => setOpen(!open)}>{displayDigit(+cohort_size)}</Typography>
</TableCell>
<TableCell align="center">
<Typography>{servicesPerimeters.getAccessFromScope(item)}</Typography>
</TableCell>
</TableRow>
{open &&
subItems &&
subItems.map((subItem: Hierarchy<ScopeElement, string>, currentIndex: number) => {
if (subItem.validity === NodeValidity.VALID)
return (
<ScopeTreeItem
path={[...path, id]}
searchMode={searchMode}
key={currentIndex}
item={subItem}
onSelect={onSelect}
onExpand={onExpand}
/>
)
})}
</Fragment>
)
}

type HierarchyProps = {
hierarchy: Hierarchy<ScopeElement, string>[]
searchMode: boolean
selectAllStatus: SelectedStatus
sourceType: SourceType
onExpand: (node: Hierarchy<ScopeElement, string>) => void
onSelect: (node: Hierarchy<ScopeElement, string>, toAdd: boolean) => void
onSelectAll: (toAdd: boolean) => void
}

const ScopeTree = ({
hierarchy,
searchMode,
selectAllStatus,
sourceType,
onSelect,
onSelectAll,
onExpand
}: HierarchyProps) => {
const { classes } = useStyles()

return (
<Table>
<TableHead>
<TableRow className={classes.tableHead}>
<TableCell className={classes.emptyTableHeadCell}></TableCell>
<TableCell align="center" className={classes.emptyTableHeadCell}>
<Checkbox
color="secondary"
checked={selectAllStatus === SelectedStatus.SELECTED}
indeterminate={selectAllStatus === SelectedStatus.INDETERMINATE}
indeterminateIcon={<IndeterminateCheckBoxOutlined style={{ color: 'rgba(0,0,0,0.6)' }} />}
onChange={(event, checked) => onSelectAll(checked)}
/>
</TableCell>
<TableCell align="left" className={classes.tableHeadCell}>
Nom
</TableCell>

<TableCell align="center" className={classes.tableHeadCell}>
Nombre de patients
</TableCell>

<TableCell align="center" className={classes.tableHeadCell}>
{sourceType === SourceType.ALL ? 'Accès' : 'Type'}
</TableCell>
</TableRow>
</TableHead>
<TableBody style={{ height: '100%' }}>
{hierarchy.map((item) => {
if (!item) return <h1>Missing</h1>

Check failure on line 166 in src/components/ScopeTree/ScopeTreeTest.tsx

View workflow job for this annotation

GitHub Actions / dependencies

Missing "key" prop for element in iterator
return (
<ScopeTreeItem
path={[item.id]}
searchMode={searchMode}
key={item.id}
item={item}
onExpand={onExpand}
onSelect={onSelect}
/>
)
})}
</TableBody>
</Table>
)
}

export default ScopeTree
Loading

0 comments on commit 5aff26c

Please sign in to comment.