Skip to content

Commit

Permalink
fix: age range limit min max, fix displaying date filter Ref gestion-…
Browse files Browse the repository at this point in the history
…de-projet#1786

* fix: age range limit min max, fix displaying date filter - Ref gestion-de-projet#1786

* fix: typo in date error message

* fix: [age range] delete error message when trying to put a value lower than 0 - Ref gestion-de-projet#1786

* core: testing patients birthdates filters Ref gestion-de-projet#1786

* fix: fix format into patientSideBar Ref gestion-de-projet#1786

* fix: age range format

* chore: cleaning console.log Ref gestion-de-projet#1786

---------

Co-authored-by: msellam <mourad.sellam@open-groupe.com>
Co-authored-by: Manelle G <39384110+ManelleG@users.noreply.github.com>
Co-authored-by: manelleg <manelle.gueriouz@aphp.fr>
Co-authored-by: Salah-BOUYAHIA <salah.bouyahia-ext@aphp.fr>
Co-authored-by: Mehdi-BOUYAHIA <63298037+Mehdi-BOUYAHIA@users.noreply.github.com>
  • Loading branch information
6 people authored Mar 24, 2023
1 parent a647456 commit 16ee629
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 124 deletions.
11 changes: 8 additions & 3 deletions src/components/Dashboard/PatientList/PatientList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {

import { getGenderRepartitionSimpleData } from 'utils/graphUtils'
import { buildPatientFiltersChips } from 'utils/chips'
import { substructAgeString } from 'utils/age'
import { useDebounce } from 'utils/debounce'

type PatientListProps = {
Expand Down Expand Up @@ -64,7 +65,7 @@ const PatientList: React.FC<PatientListProps> = ({

const [filters, setFilters] = useState<PatientFiltersType>({
gender: PatientGenderKind._unknown,
birthdates: [moment().subtract(130, 'years').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')],
birthdatesRanges: ['', ''],
vitalStatus: VitalStatus.all
})

Expand Down Expand Up @@ -110,13 +111,17 @@ const PatientList: React.FC<PatientListProps> = ({
// Set search state
if (inputSearch !== searchInput) setSearchInput(inputSearch)
if (_searchBy !== searchBy) setSearchBy(_searchBy)
const birthdates: [string, string] = [
moment(substructAgeString(filters.birthdatesRanges[0])).format('MM/DD/YYYY'),
moment(substructAgeString(filters.birthdatesRanges[1])).format('MM/DD/YYYY')
]

const result = await services.cohorts.fetchPatientList(
pageValue,
_searchBy,
inputSearch,
filters.gender,
filters.birthdates,
birthdates,
filters.vitalStatus,
order.orderBy,
order.orderDirection,
Expand Down Expand Up @@ -167,7 +172,7 @@ const PatientList: React.FC<PatientListProps> = ({
case 'birthdates':
setFilters((prevFilters) => ({
...prevFilters,
birthdates: [moment().subtract(130, 'years').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')]
birthdatesRanges: [moment().subtract(130, 'years').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')]
}))
break
case 'vitalStatus':
Expand Down
23 changes: 16 additions & 7 deletions src/components/Filters/PatientFilters/PatientFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,17 @@ const PatientFilters: React.FC<PatientFiltersProps> = ({ open, onClose, onSubmit
const classes = useStyles()

const [_gender, setGender] = useState<PatientGenderKind>(filters.gender)
const [_birthdates, setBirthdates] = useState<[string, string]>(filters.birthdates)
const [birthdatesRanges, setBirthdatesRanges] = useState<[string, string]>(filters.birthdatesRanges)
const [_vitalStatus, setVitalStatus] = useState<VitalStatus>(filters.vitalStatus)

const [error, setError] = useState(false)
const [errorMessage, setErrorMessage] = useState('')

useEffect(() => {
setGender(filters.gender)
setBirthdates(filters.birthdates)
setBirthdatesRanges(filters.birthdatesRanges)
setVitalStatus(filters.vitalStatus)
_onError(false)
}, [open]) // eslint-disable-line

const _onChangeGender = (event: React.ChangeEvent<HTMLInputElement>, value: string) => {
Expand All @@ -53,13 +55,18 @@ const PatientFilters: React.FC<PatientFiltersProps> = ({ open, onClose, onSubmit
const _onSubmit = () => {
onChangeFilters({
gender: _gender,
birthdates: _birthdates,
birthdatesRanges: birthdatesRanges,
vitalStatus: _vitalStatus
})

onSubmit()
}

const _onError = (isError: boolean, errorMessage = '') => {
setError(isError)
setErrorMessage(errorMessage)
}

return (
<Dialog open={open} onClose={onClose}>
<DialogTitle className={classes.title}>Filtrer les patients :</DialogTitle>
Expand All @@ -75,10 +82,12 @@ const PatientFilters: React.FC<PatientFiltersProps> = ({ open, onClose, onSubmit
</Grid>
<Grid container direction="column" className={classes.filter}>
<InputAgeRange
error={error}
setError={setError}
birthdates={_birthdates}
onChangeBirthdates={(newBirthdates: [string, string]) => setBirthdates(newBirthdates)}
error={{ isError: error, errorMessage: errorMessage }}
onError={_onError}
birthdatesRanges={birthdatesRanges}
onChangeBirthdatesRanges={(newBirthdatesRanges: [string, string]) =>
setBirthdatesRanges(newBirthdatesRanges)
}
/>
</Grid>

Expand Down
160 changes: 81 additions & 79 deletions src/components/Inputs/InputAgeRange/InputAgeRange.tsx
Original file line number Diff line number Diff line change
@@ -1,99 +1,101 @@
import React, { useEffect, useState } from 'react'
import moment from 'moment'

import { useAppSelector } from 'state'

import { Grid, TextField, Typography } from '@material-ui/core'
import useStyles from './styles'
import { AgeRangeType, ErrorType } from 'types'
import { convertAgeRangeTypeToString, convertStringToAgeRangeType, substructAgeRangeType } from 'utils/age'

type InputAgeRangeAdvancedProps = {
birthdates: [string, string]
onChangeBirthdates: (newAge: [string, string]) => void
error: boolean
setError: (error: boolean) => void
birthdatesRanges: [string, string]
onChangeBirthdatesRanges: (newAge: [string, string]) => void
error: ErrorType
onError: (isError: boolean, errorMessage?: string) => void
}
type InputsStateType = {
year?: number
month?: number
days?: number
const defaultMinDate: AgeRangeType = {
year: 0,
month: 0,
days: 0
}
const InputAgeRange: React.FC<InputAgeRangeAdvancedProps> = ({ birthdates, onChangeBirthdates, error, setError }) => {
const defaultMaxDate: AgeRangeType = {
year: 130,
month: 0,
days: 0
}
const InputAgeRange: React.FC<InputAgeRangeAdvancedProps> = ({
birthdatesRanges,
onChangeBirthdatesRanges,
error,
onError
}) => {
const classes = useStyles()
const { deidentifiedBoolean = true } = useAppSelector((state) => state.exploredCohort)

const [minState, setMinState] = useState<InputsStateType>({
year: 0,
month: 0,
days: 0
})
const [maxState, setMaxState] = useState<InputsStateType>({
year: 0,
month: 0,
days: 0
})
const [minState, setMinState] = useState<AgeRangeType>(defaultMinDate)
const [maxState, setMaxState] = useState<AgeRangeType>(defaultMaxDate)

useEffect(() => {
const newMaxDate: InputsStateType = {
year: 0,
month: 0,
days: 0
}
const newMinDate: InputsStateType = {
year: 0,
month: 0,
days: 0
}

newMaxDate.year = moment().diff(moment(birthdates[0], 'YYYY-MM-DD'), 'year') || 0
newMaxDate.month = moment().subtract(newMaxDate.year, 'year').diff(moment(birthdates[0], 'YYYY-MM-DD'), 'month')
newMaxDate.days = moment()
.subtract(newMaxDate.year, 'year')
.subtract(newMaxDate.month, 'month')
.diff(moment(birthdates[0], 'YYYY-MM-DD'), 'days')

newMinDate.year = moment().diff(moment(birthdates[1], 'YYYY-MM-DD'), 'year') || 0
newMinDate.month = moment().subtract(newMinDate.year, 'year').diff(moment(birthdates[1], 'YYYY-MM-DD'), 'month')
newMinDate.days = moment()
.subtract(newMinDate.year, 'year')
.subtract(newMinDate.month, 'month')
.diff(moment(birthdates[1], 'YYYY-MM-DD'), 'days')

const newMaxDate: AgeRangeType = convertStringToAgeRangeType(birthdatesRanges[0]) ?? defaultMaxDate
const newMinDate: AgeRangeType = convertStringToAgeRangeType(birthdatesRanges[1]) ?? defaultMinDate
setMinState(newMinDate)
setMaxState(newMaxDate)
}, [birthdates])

useEffect(() => {
if (maxState.days === 0 && maxState.month === 0 && maxState.year === 0) {
setError(true)
} else {
setError(false)
}, [birthdatesRanges])

const checkRange = (key: string, value: number) => {
if (key === 'days' && value <= 31 && value >= 0) {
return true
} else if (key === 'month' && value <= 12 && value >= 0) {
return true
} else if (key === 'year' && value >= 0) {
return true
}
}, [maxState])

const _onChangeState = (stateName: 'minState' | 'maxState', key: 'year' | 'month' | 'days', value?: number) => {
const _minState = minState
const _maxState = maxState
return false
}

if (stateName === 'minState') {
_minState[key] = value
setMinState(_minState)
const _onChangeState = (stateName: 'minState' | 'maxState', key: 'year' | 'month' | 'days', value = 0) => {
const newMinState: AgeRangeType = { ...minState }
const newMaxState: AgeRangeType = { ...maxState }
let isError
if (!checkRange(key, value)) {
isError = true
} else {
_maxState[key] = value
setMaxState(_maxState)
if (stateName === 'minState') {
newMinState[key] = value
} else {
newMaxState[key] = value
}

const maxDate: Date = substructAgeRangeType(newMinState)
const minDate: Date = substructAgeRangeType(newMaxState)

if (minDate > maxDate) {
onError(true, 'La date maximale doit être supérieure à la date minimale.')
isError = true
} else if (newMaxState.days === 0 && newMaxState.month === 0 && newMaxState.year === 0) {
onError(true, 'Au moins une des valeurs maximales ne doit pas être égale à 0')
isError = true
}
}
const newMinDate = moment()
.subtract(_minState.days, 'days')
.subtract(_minState.month, 'month')
.subtract(_minState.year, 'year')
.format('YYYY-MM-DD')
const newMaxDate = moment()
.subtract(_maxState.days, 'days')
.subtract(_maxState.month, 'month')
.subtract(_maxState.year, 'year')
.format('YYYY-MM-DD')

if (birthdates[1] !== newMinDate || birthdates[0] !== newMaxDate) {
onChangeBirthdates([newMaxDate, newMinDate] as [string, string])
const oldBirthdatesRanges: [string, string] = [
convertAgeRangeTypeToString(maxState),
convertAgeRangeTypeToString(minState)
]
const newBirthdatesRanges: [string, string] = [
convertAgeRangeTypeToString(newMaxState),
convertAgeRangeTypeToString(newMinState)
]

if (isError) {
onChangeBirthdatesRanges(oldBirthdatesRanges)
} else if (birthdatesRanges[1] !== newBirthdatesRanges[1] || birthdatesRanges[0] !== newBirthdatesRanges[0]) {
onError(false)
if (stateName === 'minState') {
setMinState(newMinState)
} else {
setMaxState(newMaxState)
}
onChangeBirthdatesRanges(newBirthdatesRanges)
}
}

Expand Down Expand Up @@ -174,10 +176,10 @@ const InputAgeRange: React.FC<InputAgeRangeAdvancedProps> = ({ birthdates, onCha
)}
</Grid>

{error && (
<Typography style={{ color: '#f44336', marginTop: 4 }}>
Au moins une des valeurs maximales ne doit pas être égale à 0.
</Typography>
{error.isError && (
<Grid direction={'column'}>
<Typography style={{ color: '#f44336', marginTop: 4 }}>{error.errorMessage}</Typography>
</Grid>
)}
</div>
</>
Expand Down
13 changes: 9 additions & 4 deletions src/components/Patient/PatientSidebar/PatientSidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { useEffect, useState } from 'react'
import { useLocation } from 'react-router-dom'
import moment from 'moment'

import { CircularProgress, Divider, Drawer, Grid, IconButton, List, Typography } from '@material-ui/core'
import Pagination from '@material-ui/lab/Pagination'
Expand All @@ -10,12 +9,13 @@ import PatientSidebarItem from './PatientSidebarItem/PatientSidebarItem'

import ChevronRightIcon from '@material-ui/icons/ChevronRight'

import { getAge } from 'utils/age'
import { getAge, substructAgeString } from 'utils/age'
import services from 'services/aphp'
import { PatientGenderKind } from '@ahryman40k/ts-fhir-types/lib/R4'
import { CohortPatient, PatientFilters as PatientFiltersType, SearchByTypes, Sort, VitalStatus } from 'types'

import useStyles from './styles'
import moment from 'moment/moment'

type PatientSidebarTypes = {
total: number
Expand Down Expand Up @@ -51,7 +51,7 @@ const PatientSidebar: React.FC<PatientSidebarTypes> = ({

const [filters, setFilters] = useState<PatientFiltersType>({
gender: PatientGenderKind._unknown,
birthdates: [moment().subtract(130, 'years').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')],
birthdatesRanges: ['', ''],
vitalStatus: VitalStatus.all
})

Expand All @@ -67,12 +67,17 @@ const PatientSidebar: React.FC<PatientSidebarTypes> = ({

const onSearchPatient = async (sort: Sort, page = 1) => {
setLoadingStatus(true)
const birthdates: [string, string] = [
moment(substructAgeString(filters.birthdatesRanges[0])).format('MM/DD/YYYY'),
moment(substructAgeString(filters.birthdatesRanges[1])).format('MM/DD/YYYY')
]

const patientsResp = await services.cohorts.fetchPatientList(
page,
searchBy,
searchInput,
filters.gender,
filters.birthdates,
birthdates,
filters.vitalStatus,
sort.sortBy,
sort.sortDirection,
Expand Down
8 changes: 7 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ export type PMSIFilters = {

export type PatientFilters = {
gender: PatientGenderKind
birthdates: [string, string]
birthdatesRanges: [string, string]
vitalStatus: VitalStatus
}

Expand Down Expand Up @@ -755,3 +755,9 @@ export type IScope = {
previous: string | null
results: ScopePage[]
}
export type ErrorType = { isError: boolean; errorMessage?: string }
export type AgeRangeType = {
year?: number
month?: number
days?: number
}
Loading

0 comments on commit 16ee629

Please sign in to comment.