Skip to content

Commit

Permalink
feat: preload EU selected items - Ref gestion-de-projet#1603
Browse files Browse the repository at this point in the history
  • Loading branch information
mourads committed May 18, 2023
1 parent b962d3d commit d03b939
Show file tree
Hide file tree
Showing 13 changed files with 217 additions and 101 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ import KeyboardBackspaceIcon from '@mui/icons-material/KeyboardBackspace'
import { useAppDispatch, useAppSelector } from 'state'
import { BiologyListType } from 'state/biology'

import { checkIfIndeterminated, expandItem, findEquivalentRowInItemAndSubItems, getSelectedPmsi } from 'utils/pmsi'
import {
checkIfIndeterminated,
expandItem,
findEquivalentRowInItemAndSubItems,
getHierarchySelection
} from 'utils/pmsi'

import useStyles from './styles'
import { PmsiListType } from 'state/pmsi'
Expand Down Expand Up @@ -71,7 +76,7 @@ const BiologyListItem: React.FC<BiologyListItemProps> = (props) => {
const handleClickOnHierarchy = async (biologyItem: PmsiListType) => {
if (isLoadingsyncHierarchyTable > 0 || isLoadingPmsi > 0) return
dispatch(incrementLoadingSyncHierarchyTable())
const newSelectedItems = getSelectedPmsi(biologyItem, selectedItems || [], biologyHierarchy)
const newSelectedItems = getHierarchySelection(biologyItem, selectedItems || [], biologyHierarchy)
await handleClick(newSelectedItems)
dispatch(decrementLoadingSyncHierarchyTable())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ import KeyboardBackspaceIcon from '@mui/icons-material/KeyboardBackspace'
import { useAppDispatch, useAppSelector } from 'state'
import { PmsiListType } from 'state/pmsi'

import { checkIfIndeterminated, expandItem, findEquivalentRowInItemAndSubItems, getSelectedPmsi } from 'utils/pmsi'
import {
checkIfIndeterminated,
expandItem,
findEquivalentRowInItemAndSubItems,
getHierarchySelection
} from 'utils/pmsi'

import useStyles from './styles'
import { decrementLoadingSyncHierarchyTable, incrementLoadingSyncHierarchyTable } from 'state/syncHierarchyTable'
Expand Down Expand Up @@ -74,7 +79,7 @@ const ProcedureListItem: React.FC<ProcedureListItemProps> = (props) => {
const handleClickOnHierarchy = async (procedureItem: PmsiListType) => {
if (isLoadingsyncHierarchyTable > 0 || isLoadingPmsi > 0) return
dispatch(incrementLoadingSyncHierarchyTable())
const newSelectedItems = getSelectedPmsi(procedureItem, selectedItems || [], procedureHierarchy)
const newSelectedItems = getHierarchySelection(procedureItem, selectedItems || [], procedureHierarchy)
await handleClick(newSelectedItems)
dispatch(decrementLoadingSyncHierarchyTable())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ import KeyboardBackspaceIcon from '@mui/icons-material/KeyboardBackspace'
import { useAppDispatch, useAppSelector } from 'state'
import { PmsiListType } from 'state/pmsi'

import { checkIfIndeterminated, expandItem, findEquivalentRowInItemAndSubItems, getSelectedPmsi } from 'utils/pmsi'
import {
checkIfIndeterminated,
expandItem,
findEquivalentRowInItemAndSubItems,
getHierarchySelection
} from 'utils/pmsi'

import useStyles from './styles'
import { findSelectedInListAndSubItems } from 'utils/cohortCreation'
Expand Down Expand Up @@ -70,7 +75,7 @@ const CimListItem: React.FC<CimListItemProps> = (props) => {
const handleClickOnHierarchy = async (cim10Item: PmsiListType) => {
if (isLoadingsyncHierarchyTable > 0 || isLoadingPmsi > 0) return
dispatch(incrementLoadingSyncHierarchyTable())
const newSelectedItems = getSelectedPmsi(cim10Item, selectedItems || [], cim10Hierarchy)
const newSelectedItems = getHierarchySelection(cim10Item, selectedItems || [], cim10Hierarchy)
await handleClick(newSelectedItems)
dispatch(decrementLoadingSyncHierarchyTable())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ import KeyboardBackspaceIcon from '@mui/icons-material/KeyboardBackspace'
import { useAppDispatch, useAppSelector } from 'state'
import { PmsiListType } from 'state/pmsi'

import { checkIfIndeterminated, expandItem, findEquivalentRowInItemAndSubItems, getSelectedPmsi } from 'utils/pmsi'
import {
checkIfIndeterminated,
expandItem,
findEquivalentRowInItemAndSubItems,
getHierarchySelection
} from 'utils/pmsi'

import useStyles from './styles'
import { decrementLoadingSyncHierarchyTable, incrementLoadingSyncHierarchyTable } from 'state/syncHierarchyTable'
Expand Down Expand Up @@ -64,7 +69,7 @@ const GhmListItem: React.FC<GhmListItemProps> = (props) => {
const handleClickOnHierarchy = async (ghmItem: PmsiListType) => {
if (isLoadingsyncHierarchyTable > 0 || isLoadingPmsi > 0) return
dispatch(incrementLoadingSyncHierarchyTable())
const newSelectedItems = getSelectedPmsi(ghmItem, selectedItems || [], ghmHierarchy)
const newSelectedItems = getHierarchySelection(ghmItem, selectedItems || [], ghmHierarchy)
await handleClick(newSelectedItems)
dispatch(decrementLoadingSyncHierarchyTable())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ import KeyboardBackspaceIcon from '@mui/icons-material/KeyboardBackspace'
import { useAppDispatch, useAppSelector } from 'state'
import { MedicationListType } from 'state/medication'

import { checkIfIndeterminated, expandItem, findEquivalentRowInItemAndSubItems, getSelectedPmsi } from 'utils/pmsi'
import {
checkIfIndeterminated,
expandItem,
findEquivalentRowInItemAndSubItems,
getHierarchySelection
} from 'utils/pmsi'

import useStyles from './styles'
import { findSelectedInListAndSubItems } from 'utils/cohortCreation'
Expand Down Expand Up @@ -77,7 +82,7 @@ const MedicationListItem: React.FC<MedicationListItemProps> = (props) => {
const handleClickOnHierarchy = (medicationItem: MedicationListType) => {
if (isLoadingsyncHierarchyTable > 0 || isLoadingMedication > 0) return
dispatch(incrementLoadingSyncHierarchyTable())
const newSelectedItems = getSelectedPmsi(medicationItem, selectedItems || [], medicationHierarchy)
const newSelectedItems = getHierarchySelection(medicationItem, selectedItems || [], medicationHierarchy)
handleClick(newSelectedItems)
dispatch(decrementLoadingSyncHierarchyTable())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ const SupportedForm: React.FC<SupportedFormProps> = (props) => {
title={STRUCTURE_HOSPITALIERE_DE_PRIS_EN_CHARGE}
executiveUnits={defaultValues?.encounterService ?? []}
isAcceptEmptySelection={true}
isDeleteIcon={true}
onChangeExecutiveUnits={_onSubmitExecutiveUnits}
/>
</Grid>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ const PopulationCard: React.FC<populationCardPropsType> = (props) => {
...selectedPopulations,
subItems: []
}))

dispatch(buildCohortCreation({ selectedPopulation: _selectedPopulations }))
setUpdatedItems(updatedSelection)
onChangeOpenDrawer(false)
}

Expand Down
179 changes: 123 additions & 56 deletions src/components/ScopeTree/ScopeTree.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import React, { useEffect, useRef, useState } from 'react'

import {
Breadcrumbs,
Checkbox,
CircularProgress,
Grid,
IconButton,
Skeleton,
TableCell,
TableRow,
Typography,
Breadcrumbs,
Pagination,
Paper,
Skeleton,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
Pagination
TableRow,
Typography
} from '@mui/material'

import KeyboardArrowRightIcon from '@mui/icons-material/ChevronRight'
Expand All @@ -24,14 +24,19 @@ import EnhancedTable from 'components/ScopeTree/ScopeTreeTable'
import { ScopeTreeRow, TreeElement } from 'types'

import { useAppDispatch, useAppSelector } from 'state'
import { expandScopeElement, fetchScopesList, ScopeState } from 'state/scope'
import { expandScopeElement, fetchScopesList, ScopeState, updateScopeList } from 'state/scope'

import displayDigit from 'utils/displayDigit'
import { useDebounce } from 'utils/debounce'

import useStyles from './styles'
import { findEquivalentRowInItemAndSubItems, getSelectedPmsi } from 'utils/pmsi'
import servicesPerimeters from '../../services/aphp/servicePerimeters'
import {
checkIfIndeterminated,
findEquivalentRowInItemAndSubItems,
getHierarchySelection,
optimizeHierarchySelection
} from 'utils/pmsi'
import servicesPerimeters, { loadingItem } from '../../services/aphp/servicePerimeters'
import { findSelectedInListAndSubItems } from '../../utils/cohortCreation'

type ScopeTreeListItemProps = {
Expand Down Expand Up @@ -95,6 +100,7 @@ const ScopeTreeListItem: React.FC<ScopeTreeListItemProps> = (props) => {
</IconButton>
)}
</TableCell>

<TableCell align="center" padding="checkbox">
<Checkbox
color="secondary"
Expand Down Expand Up @@ -176,9 +182,15 @@ const ScopeTree: React.FC<ScopeTreeProps> = ({
const [count, setCount] = useState(0)
const [isAllSelected, setIsAllSelected] = useState(false)
const controllerRef = useRef<AbortController | null>()
const isHeadChecked: boolean =
isAllSelected ||
scopesList.filter((row) => selectedItems.find((item: { id: any }) => item.id === row.id) !== undefined).length ===
scopesList.length
const isHeadIndetermined: boolean =
!isAllSelected && selectedItems && selectedItems.length > 0 && rootRows && !isHeadChecked

const fetchScopeTree = async (signal?: AbortSignal) => {
return dispatch(fetchScopesList(signal)).unwrap()
const fetchScopeTree = async (executiveUnitType?: string, signal?: AbortSignal) => {
return dispatch(fetchScopesList({ signal })).unwrap()
}

const _cancelPendingRequest = () => {
Expand All @@ -191,17 +203,108 @@ const ScopeTree: React.FC<ScopeTreeProps> = ({
const _init = async () => {
setSearchLoading(true)
_cancelPendingRequest()
const fetchScopeTreeResponse = await fetchScopeTree(controllerRef.current?.signal)

let newPerimetersList: ScopeTreeRow[] = []
const fetchScopeTreeResponse = await fetchScopeTree(executiveUnitType, controllerRef.current?.signal)
if (fetchScopeTreeResponse && !fetchScopeTreeResponse.aborted) {
const newPerimetersList = fetchScopeTreeResponse.scopesList
newPerimetersList = fetchScopeTreeResponse.scopesList
setRootRows(newPerimetersList)
setOpenPopulations([])
setCount(newPerimetersList?.length)
setIsEmpty(!newPerimetersList || newPerimetersList.length < 0)
}
await _expandSelectedItems(newPerimetersList ?? rootRows)
setSearchLoading(false)
}

const getFetchedSelectedItems = (selectedItems: ScopeTreeRow[], rootRows: ScopeTreeRow[]) => {
const fetchedSelectedItems: ScopeTreeRow[] = []
const notFetchedSelectedItemsIds: string[] = []
selectedItems.forEach((item: ScopeTreeRow) => {
if (findEquivalentRowInItemAndSubItems({ id: item.id }, rootRows).equivalentRow) {
fetchedSelectedItems.push(item)
} else {
notFetchedSelectedItemsIds.push(item.id)
}
})
return {
fetchedSelectedItems: fetchedSelectedItems,
notFetchedSelectedItemsIds: notFetchedSelectedItemsIds
}
}

const getAllParentsIds = async (selectedItems: ScopeTreeRow[], rootRows: ScopeTreeRow[]) => {
const { fetchedSelectedItems: fetchedSelectedItems, notFetchedSelectedItemsIds: notFetchedSelectedItemsIds } =
getFetchedSelectedItems(selectedItems, rootRows)

const notFetchedSelectedItems: ScopeTreeRow[] =
notFetchedSelectedItemsIds?.length > 0
? await servicesPerimeters.buildScopeTreeRowList(
await servicesPerimeters.getPerimeters(notFetchedSelectedItemsIds)
)
: []
const allParentsIds: string[] = [...fetchedSelectedItems, ...notFetchedSelectedItems]
.map((item: ScopeTreeRow) => (item?.above_levels_ids ?? '').split(','))
.flat()
?.filter((idValue, index, array) => {
return idValue && array.indexOf(idValue) === index
})
return allParentsIds
}

const getParents = async (allParentsIds: string[]) => {
const fetchedParents: ScopeTreeRow[] = []
const notFetchedSubItemsIds: string[] = []
const notFetchedParentsIds: string[] = allParentsIds.filter((parentId) => {
const foundItem = findEquivalentRowInItemAndSubItems({ id: parentId }, rootRows).equivalentRow
if (!foundItem) return true
fetchedParents.push(foundItem)
if (!foundItem.subItems || foundItem.subItems.length < 1 || foundItem.subItems[0]?.id === loadingItem.id) {
notFetchedSubItemsIds.push(foundItem?.inferior_levels_ids?.split(','))
}
return false
})
const notFetchedItems: string[] = [...notFetchedParentsIds, ...notFetchedSubItemsIds]?.filter(
(idValue, index, array) => {
return idValue && array.indexOf(idValue) === index
}
)
const notFetchedParents: ScopeTreeRow[] =
notFetchedItems?.length > 0
? await servicesPerimeters.buildScopeTreeRowList(await servicesPerimeters.getPerimeters(notFetchedItems))
: []
return [...fetchedParents, ...notFetchedParents]
}

const _updateRootRows = (newRootRows: ScopeTreeRow[], parents: ScopeTreeRow[]) => {
for (let i = 0; i < newRootRows.length; i++) {
const updatedSubItems: ScopeTreeRow[] = parents?.filter((item) => newRootRows[i].id === item.parentId)
if (updatedSubItems?.length > 0) {
const newSubItems = newRootRows[i].subItems?.filter(
(item) => item.id !== loadingItem.id && !updatedSubItems?.map((item) => item.id).includes(item?.id)
)
newRootRows[i] = { ...newRootRows[i], subItems: [...newSubItems, ...updatedSubItems] }
}
if (newRootRows[i]?.subItems?.length > 0 && newRootRows[i]?.subItems[0]?.id !== 'loading') {
_updateRootRows(newRootRows[i].subItems, parents)
}
}
}

const _expandSelectedItems = async (rootRows: ScopeTreeRow[]) => {
if (!selectedItems || selectedItems.length < 1) return

const allParentsIds: string[] = await getAllParentsIds(selectedItems, rootRows)

const parents: ScopeTreeRow[] = await getParents(allParentsIds)
parents.push(...selectedItems)

const newRootRows: ScopeTreeRow[] = [...rootRows]

_updateRootRows(newRootRows, parents)
dispatch(updateScopeList(newRootRows))
}

const _searchInPerimeters = async (_isAllSelected?: boolean) => {
setSearchLoading(true)
_cancelPendingRequest()
Expand Down Expand Up @@ -274,10 +377,11 @@ const ScopeTree: React.FC<ScopeTreeProps> = ({
return findSelectedInListAndSubItems(selectedItems, searchedItem, allItems)
}
const _onSelect = (row: ScopeTreeRow) => {
const savedSelectedItems: any[] = getSelectedPmsi(row, selectedItems, scopesList)
const hierarchySelection: any[] = getHierarchySelection(row, selectedItems, scopesList)
const optimizedHierarchySelection: any[] = optimizeHierarchySelection(hierarchySelection, scopesList)

onChangeSelectedItem(savedSelectedItems)
return savedSelectedItems
onChangeSelectedItem(optimizedHierarchySelection)
return optimizedHierarchySelection
}

const _onSelectAll = () => {
Expand All @@ -304,34 +408,7 @@ const ScopeTree: React.FC<ScopeTreeProps> = ({
onChangeSelectedItem(results)
}

const _isIndeterminated: (_row: any) => boolean | undefined = (_row) => {
// Si que un loading => false
if (_row.subItems && _row.subItems.length > 0 && _row.subItems[0].id === 'loading') {
return false
}
const checkChild: (item: any) => boolean = (item) => {
const numberOfSubItemsSelected = item.subItems?.filter((subItem: any) =>
selectedItems.find((item: { id: any }) => item.id === subItem.id)
)?.length

if (numberOfSubItemsSelected && numberOfSubItemsSelected !== item.subItems.length) {
// Si un des sub elem qui est check => true
return true
} else if (item.subItems?.length >= numberOfSubItemsSelected) {
// Si un des sub-sub (ou sub-sub-sub ...) elem qui est check => true
let isCheck = false
for (const child of item.subItems) {
if (isCheck) continue
isCheck = !!checkChild(child)
}
return isCheck
} else {
// Sinon => false
return false
}
}
return checkChild(_row)
}
const _isIndeterminated: (_row: any) => boolean | undefined = (_row) => checkIfIndeterminated(_row, selectedItems)

useEffect(() => {
if (debouncedSearchTerm) {
Expand Down Expand Up @@ -376,18 +453,8 @@ const ScopeTree: React.FC<ScopeTreeProps> = ({
<div style={{ padding: '0 0 0 4px' }}>
<Checkbox
color="secondary"
indeterminate={
!isAllSelected &&
selectedItems &&
selectedItems.length > 0 &&
rootRows &&
selectedItems.length !== rootRows.length
}
checked={
isAllSelected ||
scopesList.filter((row) => selectedItems.find((item: { id: any }) => item.id === row.id) !== undefined)
.length === scopesList.length
}
checked={isHeadChecked}
indeterminate={isHeadIndetermined}
onClick={_onSelectAll}
/>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/data/scope_type.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
"document": "Hôpital",
"supported": "AP-HP"
},
"typeLevel": [["AP-HP"], ["GH", "GHU"], ["Hôpital"], ["Pôle/DMU"], ["Unité Fonctionnelle (UF)"]]
"typeLevel": [["AP-HP"], ["Groupe hospitalier (GH)", "GHU"], ["Hôpital"], ["Pôle/DMU"], ["Unité Fonctionnelle (UF)"]]
}
Loading

0 comments on commit d03b939

Please sign in to comment.