diff --git a/src/components/CreationCohort/DiagramView/components/CriteriaCard/components/CriteriaCardContent/CriteriaCardContent.tsx b/src/components/CreationCohort/DiagramView/components/CriteriaCard/components/CriteriaCardContent/CriteriaCardContent.tsx index 907bc41ff..7a25bbba1 100644 --- a/src/components/CreationCohort/DiagramView/components/CriteriaCard/components/CriteriaCardContent/CriteriaCardContent.tsx +++ b/src/components/CreationCohort/DiagramView/components/CriteriaCard/components/CriteriaCardContent/CriteriaCardContent.tsx @@ -1,4 +1,4 @@ -import React, { Fragment, useState, useEffect, useRef } from 'react' +import React, { Fragment, useEffect, useRef, useState } from 'react' import moment from 'moment' import Chip from '@mui/material/Chip' @@ -10,11 +10,12 @@ import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp' import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown' import { useAppSelector } from 'state' -import { DocType, SearchByTypes, SelectedCriteriaType } from 'types' +import { DocType, ScopeTreeRow, SearchByTypes, SelectedCriteriaType } from 'types' import docTypes from 'assets/docTypes.json' import useStyles from './styles' +import { RESSOURCE_TYPE_PATIENT } from 'utils/cohortCreation' type CriteriaCardContentProps = { currentCriteria: SelectedCriteriaType @@ -917,6 +918,29 @@ const CriteriaCardContent: React.FC = ({ currentCriter ) ] } + const displaySelectedExecutiveUnits = (hospitalList: ScopeTreeRow[], tooltip?: boolean) => { + return hospitalList && hospitalList.length > 0 + ? hospitalList.map((item) => item.name).reduce(tooltip ? tooltipReducer : reducer) + : '' + } + + if (_currentCriteria.type !== RESSOURCE_TYPE_PATIENT) { + content = [ + ...content, + _currentCriteria && _currentCriteria?.encounterService && _currentCriteria?.encounterService.length > 0 && ( + + + {displaySelectedExecutiveUnits(_currentCriteria?.encounterService)} + + + } + /> + ) + ] + } content = content.filter((c) => c) // Filter null element return content diff --git a/src/components/CreationCohort/DiagramView/components/CriteriaCard/styles.ts b/src/components/CreationCohort/DiagramView/components/CriteriaCard/styles.ts index d0d0a1ca2..0965b0307 100644 --- a/src/components/CreationCohort/DiagramView/components/CriteriaCard/styles.ts +++ b/src/components/CreationCohort/DiagramView/components/CriteriaCard/styles.ts @@ -11,7 +11,7 @@ const useStyles = makeStyles((theme: Theme) => ({ padding: 8, marginTop: 12, minWidth: 400, - maxWidth: 800, + maxWidth: 850, position: 'relative', '&::before': { width: 38, diff --git a/src/components/CreationCohort/DiagramView/components/LogicalOperator/components/CriteriaRightPanel/AdvancedInputs/AdvancedInputs.tsx b/src/components/CreationCohort/DiagramView/components/LogicalOperator/components/CriteriaRightPanel/AdvancedInputs/AdvancedInputs.tsx index b099b6d4e..51138d876 100644 --- a/src/components/CreationCohort/DiagramView/components/LogicalOperator/components/CriteriaRightPanel/AdvancedInputs/AdvancedInputs.tsx +++ b/src/components/CreationCohort/DiagramView/components/LogicalOperator/components/CriteriaRightPanel/AdvancedInputs/AdvancedInputs.tsx @@ -1,12 +1,15 @@ import React, { useState } from 'react' -import { Collapse, Typography, Grid, IconButton } from '@mui/material' +import { Collapse, Grid, IconButton, Typography } from '@mui/material' import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp' import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown' import OccurrencesInputs from './OccurrencesInputs/OccurrencesInputs' import VisitInputs from './VisitInputs/VisitInputs' +import PopulationCard from '../../../../PopulationCard/PopulationCard' +import { UNITE_EXECUTRICE } from 'utils/cohortCreation' +import { ScopeTreeRow } from 'types' type AdvancedInputsProps = { form: 'cim10' | 'ccam' | 'ghm' | 'document' | 'medication' | 'biology' @@ -26,6 +29,10 @@ const AdvancedInputs: React.FC = (props) => { const [checked, setCheck] = useState(optionsIsUsed) + const _onSubmitExecutiveUnits = (_selectedExecutiveUnits: ScopeTreeRow[] | undefined) => { + onChangeValue('encounterService', _selectedExecutiveUnits) + } + return ( = (props) => { + + + + diff --git a/src/components/CreationCohort/DiagramView/components/LogicalOperator/components/CriteriaRightPanel/SupportedForm/SupportedForm.tsx b/src/components/CreationCohort/DiagramView/components/LogicalOperator/components/CriteriaRightPanel/SupportedForm/SupportedForm.tsx index 687eeb0ae..4ae906db1 100644 --- a/src/components/CreationCohort/DiagramView/components/LogicalOperator/components/CriteriaRightPanel/SupportedForm/SupportedForm.tsx +++ b/src/components/CreationCohort/DiagramView/components/LogicalOperator/components/CriteriaRightPanel/SupportedForm/SupportedForm.tsx @@ -11,9 +11,9 @@ import { IconButton, Slider, Switch, + TextField, Tooltip, - Typography, - TextField + Typography } from '@mui/material' import InfoIcon from '@mui/icons-material/Info' @@ -23,11 +23,11 @@ import ProvenanceDestinationInputs from './SupportedInputs/ProvenanceDestination import OtherInputs from './SupportedInputs/OtherInputs' import VisitInputs from '../AdvancedInputs/VisitInputs/VisitInputs' -// import { InputAutocompleteAsync as AutocompleteAsync } from 'components/Inputs' - import useStyles from './styles' -import { EncounterDataType } from 'types' +import { EncounterDataType, ScopeTreeRow } from 'types' +import PopulationCard from '../../../../PopulationCard/PopulationCard' +import { STRUCTURE_HOSPITALIERE_DE_PRIS_EN_CHARGE } from 'utils/cohortCreation' type SupportedFormProps = { criteria: any @@ -106,6 +106,10 @@ const SupportedForm: React.FC = (props) => { setDefaultValues(_defaultValues) } + const _onSubmitExecutiveUnits = (_selectedExecutiveUnits: ScopeTreeRow[] | undefined) => { + _onChangeValue('encounterService', _selectedExecutiveUnits) + } + if ( criteria?.data?.admissionModes === 'loading' || criteria?.data?.entryModes === 'loading' || @@ -194,6 +198,17 @@ const SupportedForm: React.FC = (props) => { /> + + + + Âge au moment de la prise en charge diff --git a/src/components/CreationCohort/DiagramView/components/PopulationCard/PopulationCard.tsx b/src/components/CreationCohort/DiagramView/components/PopulationCard/PopulationCard.tsx index efacad83c..3c8dff961 100644 --- a/src/components/CreationCohort/DiagramView/components/PopulationCard/PopulationCard.tsx +++ b/src/components/CreationCohort/DiagramView/components/PopulationCard/PopulationCard.tsx @@ -1,6 +1,6 @@ -import React, { useState, useEffect, useRef } from 'react' +import React, { useEffect, useRef, useState } from 'react' -import { Button, IconButton, Chip, CircularProgress, Typography } from '@mui/material' +import { Button, Chip, CircularProgress, IconButton, Tooltip, Typography } from '@mui/material' import EditIcon from '@mui/icons-material/Edit' import CloseIcon from '@mui/icons-material/Close' @@ -9,18 +9,31 @@ import MoreHorizIcon from '@mui/icons-material/MoreHoriz' import ModalRightError from './components/ModalRightError' import PopulationRightPanel from './components/PopulationRightPanel' -import { useAppSelector, useAppDispatch } from 'state' -import { CohortCreationState, buildCohortCreation } from 'state/cohortCreation' -import { ScopeState, fetchScopesList } from 'state/scope' +import { useAppDispatch, useAppSelector } from 'state' +import { buildCohortCreation, CohortCreationState } from 'state/cohortCreation' +import { fetchScopesList, ScopeState } from 'state/scope' import { MeState } from 'state/me' import { ScopeTreeRow } from 'types' -import { getSelectedScopes, filterScopeTree } from 'utils/scopeTree' +import { filterScopeTree, getSelectedScopes } from 'utils/scopeTree' import useStyles from './styles' +import InfoIcon from '@mui/icons-material/Info' +import scopeType from 'data/scope_type.json' + +export type populationCardPropsType = { + label?: string + title?: string + form?: 'cim10' | 'ccam' | 'ghm' | 'document' | 'medication' | 'biology' | 'supported' + executiveUnits?: (ScopeTreeRow | undefined)[] + isAcceptEmptySelection?: boolean + isDeleteIcon?: boolean + onChangeExecutiveUnits?: (_selectedPopulations: ScopeTreeRow[] | undefined) => void +} -const PopulationCard: React.FC = () => { - const classes = useStyles() +const PopulationCard: React.FC = (props) => { + const { label, title, form, executiveUnits, onChangeExecutiveUnits, isAcceptEmptySelection, isDeleteIcon } = props + const classes = useStyles(props) const dispatch = useAppDispatch() const isRendered = useRef(false) @@ -46,13 +59,24 @@ const PopulationCard: React.FC = () => { const [isExtended, onExtend] = useState(false) const [openDrawer, onChangeOpenDrawer] = useState(false) const [rightError, setRightError] = useState(false) + const [selectedItems, setSelectedItems] = useState( + (executiveUnits ?? selectedPopulation ?? []).filter((item): item is ScopeTreeRow => item !== undefined) + ) - const submitPopulation = async (_selectedPopulations: ScopeTreeRow[] | null) => { - if (_selectedPopulations === null) return + const _onChangePopulation = async (selectedPopulations: ScopeTreeRow[]) => { + dispatch(buildCohortCreation({ selectedPopulation: selectedPopulations })) + } - _selectedPopulations = filterScopeTree(_selectedPopulations) - _selectedPopulations = _selectedPopulations.map((_selectedPopulation: ScopeTreeRow) => ({ - ..._selectedPopulation, + const setUpdatedItems = (updatedSelection: ScopeTreeRow[]) => { + setSelectedItems(updatedSelection) + onChangeExecutiveUnits ? onChangeExecutiveUnits(updatedSelection) : _onChangePopulation(updatedSelection) + } + + const _onSubmit = async (updatedSelection: ScopeTreeRow[] | null) => { + if (updatedSelection === null && !executiveUnits) return + updatedSelection = filterScopeTree(updatedSelection ?? []) + updatedSelection = updatedSelection.map((selectedPopulations: ScopeTreeRow) => ({ + ...selectedPopulations, subItems: [] })) @@ -60,9 +84,15 @@ const PopulationCard: React.FC = () => { onChangeOpenDrawer(false) } + const _onDelete = (index: number) => { + const updatedSelection: ScopeTreeRow[] = [...selectedItems] + updatedSelection.splice(index, 1) + setUpdatedItems(updatedSelection) + } + const fetchScopeTree = () => { if (scopesList && scopesList.length === 0) { - dispatch(fetchScopesList()) + dispatch(fetchScopesList({})) } } @@ -73,26 +103,27 @@ const PopulationCard: React.FC = () => { useEffect(() => { let _rightError = false - const populationWithRightError = selectedPopulation - ? selectedPopulation.filter((selectedPopulation) => selectedPopulation === undefined) + const populationWithRightError = selectedItems + ? selectedItems.filter((selectedPopulation) => selectedPopulation === undefined) : [] if (populationWithRightError && populationWithRightError.length > 0) { _rightError = true } setRightError(_rightError) - }, [selectedPopulation]) + }, [selectedItems]) useEffect(() => { if ( !isRendered.current && + !executiveUnits && !openDrawer && scopesList?.length === 1 && requestState?.requestId && - (selectedPopulation === null || selectedPopulation?.length === 0) + (selectedItems === null || selectedItems?.length === 0) ) { const savedSelectedItems: ScopeTreeRow[] = getSelectedScopes(scopesList[0], [], scopesList) - submitPopulation(savedSelectedItems) + _onSubmit(savedSelectedItems) isRendered.current = true } else { isRendered.current = false @@ -107,19 +138,42 @@ const PopulationCard: React.FC = () => { - ) : selectedPopulation !== null ? ( + ) : selectedItems !== null ? (
- - Population source : + + {label ?? 'Population source'} + {form && ( + <> + + {'- Le niveau hiérarchique de rattachement est : ' + scopeType?.criteriaType[form] + '.'} +
+ {(form === 'supported' + ? '- La structure hospitalière de prise en charge' + : "- L'unité exécutrice") + + ' est la structure élémentaire de prise en charge des malades par une équipe soignante ou médico-technique identifiées par leurs fonctions et leur organisation.'} + + } + > + +
+ + )}
{isExtended ? ( <> - {selectedPopulation && - selectedPopulation.map((pop: any, index: number) => ( - + {selectedItems && + selectedItems.map((pop: any, index: number) => ( + _onDelete(index) : undefined} + /> ))} { ) : ( <> - {selectedPopulation && - selectedPopulation + {selectedItems && + selectedItems .slice(0, 4) .map((pop: any, index: number) => pop ? ( - + _onDelete(index) : undefined} + /> ) : ( - + _onDelete(index) : undefined} + /> ) )} - {selectedPopulation && selectedPopulation.length > 4 && ( + {selectedItems && selectedItems.length > 4 && ( {
) : (
-
)} - { - onChangeOpenDrawer(true) - setRightError(false) - }} - /> + onChangeOpenDrawer(true)} /> - onChangeOpenDrawer(false)} /> + onChangeOpenDrawer(false)} + /> ) } diff --git a/src/components/CreationCohort/DiagramView/components/PopulationCard/components/PopulationRightPanel.tsx b/src/components/CreationCohort/DiagramView/components/PopulationCard/components/PopulationRightPanel.tsx index d596943f9..447a0b22c 100644 --- a/src/components/CreationCohort/DiagramView/components/PopulationCard/components/PopulationRightPanel.tsx +++ b/src/components/CreationCohort/DiagramView/components/PopulationCard/components/PopulationRightPanel.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react' +import React, { useEffect, useState } from 'react' import Button from '@mui/material/Button' import Drawer from '@mui/material/Drawer' @@ -7,29 +7,30 @@ import Typography from '@mui/material/Typography' import ScopeTree from 'components/ScopeTree/ScopeTree' import { ScopeTreeRow } from 'types' -import { useAppSelector } from 'state' - import useStyles from './styles' import ScopeSearchBar from 'components/Inputs/ScopeSearchBar/ScopeSearchBar' type PopulationRightPanelProps = { open: boolean - onConfirm: (selectedPopulation: ScopeTreeRow[] | null) => void + title?: string + executiveUnitType?: string + selectedPopulation: ScopeTreeRow[] + isAcceptEmptySelection?: boolean + onConfirm: (selectedPopulation: ScopeTreeRow[]) => void onClose: () => void } const PopulationRightPanel: React.FC = (props) => { - const { open, onConfirm, onClose } = props + const { open, title, executiveUnitType, selectedPopulation, isAcceptEmptySelection, onConfirm, onClose } = props const classes = useStyles() - const { selectedPopulation = [] } = useAppSelector((state) => state.cohortCreation.request || {}) - const [_selectedPopulation, onChangeSelectedPopulation] = useState([]) + const [_selectedPopulation, _setSelectedPopulation] = useState(selectedPopulation) const [searchInput, setSearchInput] = useState('') useEffect(() => { - onChangeSelectedPopulation( - selectedPopulation !== null ? (selectedPopulation.filter((elem) => elem !== undefined) as ScopeTreeRow[]) : [] + _setSelectedPopulation( + selectedPopulation !== null ? (selectedPopulation?.filter((elem) => elem !== undefined) as ScopeTreeRow[]) : [] ) }, [open]) // eslint-disable-line @@ -40,7 +41,7 @@ const PopulationRightPanel: React.FC = (props) => {
- Structure hospitalière + {title ?? 'Structure hospitalière'}
@@ -48,9 +49,10 @@ const PopulationRightPanel: React.FC = (props) => {
@@ -59,7 +61,10 @@ const PopulationRightPanel: React.FC = (props) => { Annuler