Skip to content

Commit

Permalink
feat: add export one file and xlsx format file - Ref gestion-de-proje…
Browse files Browse the repository at this point in the history
…t#2610 (#1017)

* feat: add export one file and xlsx format file - Ref gestion-de-projet#2610

* feat: add export one file and xlsx format file - Ref gestion-de-projet#2610

* fix: fix lint error
  • Loading branch information
Mehdi-BOUYAHIA authored Jul 16, 2024
1 parent 79510b6 commit bb3af3c
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 30 deletions.
89 changes: 82 additions & 7 deletions src/components/Dashboard/ExportModal/ExportModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,20 @@ import {
Typography,
Autocomplete,
RadioGroup,
Radio
Radio,
Select,
MenuItem,
Tooltip
} from '@mui/material'

import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
import CancelIcon from '@mui/icons-material/Cancel'
import WarningIcon from '@mui/icons-material/Warning'
import InfoIcon from '@mui/icons-material/Info'

import useStyles from './styles'

import export_table from './export_table'
import export_table, { label } from './export_table'
import services from 'services/aphp'
import { ExportCSVForm, ExportCSVTable, SavedFilter } from 'types'
import { useAppSelector } from 'state'
Expand All @@ -49,7 +51,7 @@ const initialState: ExportCSVForm = {
conditions: false,
tables: export_table.map<ExportCSVTable>((table) => ({
...table,
checked: table.label === 'person' ? true : false,
checked: table.label === 'person',
fhir_filter: null,
respect_table_relationships: true,
count: 0
Expand Down Expand Up @@ -131,6 +133,37 @@ const ExportModal: React.FC<ExportModalProps> = ({ cohortId, fhirGroupId, open,
}
}

const [isChecked, setIsChecked] = useState(false)
const [selectState, setSelectState] = useState<'csv' | 'xlsx'>('csv')

const compatibilities = (exportTable: ExportCSVTable) => {
const checkedResources = checkedTables.map((table) => {
const com = table.compatibleResourceTypes
return com
})
const findCompatibilities = (checkedResourcesCompatibilities: label[][]) => {
let smallestArray = checkedResourcesCompatibilities[0]
for (let i = 1; i < checkedResourcesCompatibilities.length; i++) {
if (checkedResourcesCompatibilities[i].length < smallestArray.length) {
smallestArray = checkedResourcesCompatibilities[i]
}
}
return smallestArray
}
const resourceCompatibilities = findCompatibilities(checkedResources)

return !resourceCompatibilities.includes(exportTable.label)
}

const resetSelectedTables = () => {
const newSelectedTables = settings.tables.map<ExportCSVTable>((table) => ({
...table,
checked: table.label === 'person'
}))
handleChangeSettings('tables', newSelectedTables)
setExpandedTableIds([])
}

const handleSelectAllTables = () => {
const newSelectedTables = settings.tables.map<ExportCSVTable>((table) => ({
...table,
Expand Down Expand Up @@ -191,7 +224,9 @@ const ExportModal: React.FC<ExportModalProps> = ({ cohortId, fhirGroupId, open,
const response = await services.cohorts.createExport({
cohortId,
motivation: settings?.motif,
tables: (settings?.tables || []).filter((table) => table.checked)
tables: (settings?.tables || []).filter((table) => table.checked),
outputFormat: selectState,
group_tables: isChecked
})

if (isAxiosError(response)) {
Expand All @@ -205,7 +240,7 @@ const ExportModal: React.FC<ExportModalProps> = ({ cohortId, fhirGroupId, open,
function renderExportTable(exportTable: ExportCSVTable) {
const { name, checked, label, resourceType, count } = exportTable
const isItemExpanded = expandedTableIds.includes(label)
const _countLoading = (countLoading && typeof countLoading === 'boolean') || countLoading === label ? true : false
const _countLoading = !!((countLoading && typeof countLoading === 'boolean') || countLoading === label)
const setLimitError = resourceType === ResourceType.DOCUMENTS ? 5000 : EXPORT_LINES_LIMIT

return (
Expand All @@ -214,7 +249,7 @@ const ExportModal: React.FC<ExportModalProps> = ({ cohortId, fhirGroupId, open,
style={resourcesWithNoFilters.includes(resourceType) ? { cursor: 'default' } : {}}
expandIcon={
<Checkbox
disabled={label === 'person'}
disabled={isChecked ? compatibilities(exportTable) || label === 'person' : label === 'person'}
color="secondary"
checked={checked}
className={classes.checkbox}
Expand Down Expand Up @@ -365,6 +400,32 @@ const ExportModal: React.FC<ExportModalProps> = ({ cohortId, fhirGroupId, open,
onChange={(e) => handleChangeSettings('motif', e.target.value)}
/>

<Grid>
<FormControlLabel
control={
<Checkbox
checked={isChecked}
onClick={() => {
setIsChecked(!isChecked)
resetSelectedTables()
}}
/>
}
label={'Regrouper plusieurs tables en un seul fichier'}
/>
<Tooltip
title={
<span>
Par exemple, il coche prescription, alors seules les tables person et visit_occurrence restent cochables
Par exemple, il coche person, alors tout est cochable, mais si ensuite il coche prescription, alors
seule visit_occurrence reste cochable, le reste se grise
</span>
}
>
<InfoIcon fontSize="small" color="primary" style={{ marginLeft: 4 }} />
</Tooltip>
</Grid>

<Grid container py="28px" gap="16px">
<Grid item container alignItems="center" flexWrap="nowrap" pr="33px">
<Grid item container>
Expand Down Expand Up @@ -407,6 +468,20 @@ const ExportModal: React.FC<ExportModalProps> = ({ cohortId, fhirGroupId, open,
</Grid>
</Grid>

<Grid container className={classes.referentielContainer}>
<Typography variant="h3">Type de fichier : </Typography>
<Select
className={classes.select}
style={{ height: 32 }}
id="file-type-selector"
value={selectState}
onChange={(event) => setSelectState(event.target.value as 'csv' | 'xlsx')}
>
<MenuItem value={'csv'}>{'Fichier csv'}</MenuItem>
<MenuItem value={'xlsx'}>{'Fichier xlsx'}</MenuItem>
</Select>
</Grid>

<Grid container gap="12px" pb="10px">
<Typography className={classes.dialogHeader} variant="h5">
Conditions de l'EDS
Expand Down
83 changes: 68 additions & 15 deletions src/components/Dashboard/ExportModal/export_table.ts
Original file line number Diff line number Diff line change
@@ -1,90 +1,142 @@
import { ResourceType } from 'types/requestCriterias'

export type label =
| 'person'
| 'iris'
| 'visit_occurrence'
| 'visit_detail'
| 'condition_occurrence'
| 'procedure_occurrence'
| 'cost'
| 'note'
| 'drug_exposure_prescription'
| 'drug_exposure_administration'
| 'measurement'
| 'care_site - fact_relationship'
| 'imaging_study - imaging_series'
| 'questionnaire - questionnaire__item - questionnaireresponse - questionnaireresponse__item - questionnaireresponse__item__answer'

export type ExportTableType = {
id: string[]
name: string
label: string
label: label
resourceType: ResourceType
compatibleResourceTypes: label[]
}

const exportTable: ExportTableType[] = [
{
id: ['person'],
name: 'Patient',
label: 'person',
resourceType: ResourceType.PATIENT
resourceType: ResourceType.PATIENT,
compatibleResourceTypes: [
'person',
'visit_occurrence',
'condition_occurrence',
'procedure_occurrence',
'cost',
'note',
'drug_exposure_prescription',
'drug_exposure_administration',
'measurement',
'imaging_study - imaging_series'
]
},
{
id: ['iris'],
name: 'Zone géographique',
label: 'iris',
resourceType: ResourceType.UNKNOWN
resourceType: ResourceType.UNKNOWN,
compatibleResourceTypes: []
},
{
id: ['visit_occurrence'],
name: 'Prise en charge',
label: 'visit_occurrence',
resourceType: ResourceType.ENCOUNTER
resourceType: ResourceType.ENCOUNTER,
compatibleResourceTypes: [
'visit_occurrence',
'person',
'condition_occurrence',
'procedure_occurrence',
'cost',
'note',
'drug_exposure_prescription',
'drug_exposure_administration',
'measurement',
'imaging_study - imaging_series'
]
},
{
id: ['visit_detail'],
name: 'Détail de prise en charge',
label: 'visit_detail',
resourceType: ResourceType.ENCOUNTER
resourceType: ResourceType.ENCOUNTER,
compatibleResourceTypes: []
},
{
id: ['condition_occurrence'],
name: 'Fait - PMSI - Diagnostics',
label: 'condition_occurrence',
resourceType: ResourceType.CONDITION
resourceType: ResourceType.CONDITION,
compatibleResourceTypes: ['condition_occurrence', 'person', 'visit_occurrence']
},
{
id: ['procedure_occurrence'],
name: 'Fait - PMSI - Actes',
label: 'procedure_occurrence',
resourceType: ResourceType.PROCEDURE
resourceType: ResourceType.PROCEDURE,
compatibleResourceTypes: ['procedure_occurrence', 'person', 'visit_occurrence']
},
{
id: ['cost'],
name: 'Fait - PMSI - GHM',
label: 'cost',
resourceType: ResourceType.CLAIM
resourceType: ResourceType.CLAIM,
compatibleResourceTypes: ['cost', 'person', 'visit_occurrence']
},
{
id: ['note'],
name: 'Fait - Documents cliniques',
label: 'note',
resourceType: ResourceType.DOCUMENTS
resourceType: ResourceType.DOCUMENTS,
compatibleResourceTypes: ['note', 'person', 'visit_occurrence']
},
{
id: ['drug_exposure_prescription'],
name: 'Fait - Médicaments - Prescription',
label: 'drug_exposure_prescription',
resourceType: ResourceType.MEDICATION_REQUEST
resourceType: ResourceType.MEDICATION_REQUEST,
compatibleResourceTypes: ['drug_exposure_prescription', 'person', 'visit_occurrence']
},
{
id: ['drug_exposure_administration'],
name: 'Fait - Médicaments - Administration',
label: 'drug_exposure_administration',
resourceType: ResourceType.MEDICATION_ADMINISTRATION
resourceType: ResourceType.MEDICATION_ADMINISTRATION,
compatibleResourceTypes: ['drug_exposure_administration', 'person', 'visit_occurrence']
},
{
id: ['measurement'],
name: 'Fait - Biologie',
label: 'measurement',
resourceType: ResourceType.OBSERVATION
resourceType: ResourceType.OBSERVATION,
compatibleResourceTypes: ['measurement', 'person', 'visit_occurrence']
},
{
id: ['care_site', 'fact_relationship'],
name: 'Référentiel - Structure hospitalière',
label: 'care_site - fact_relationship',
resourceType: ResourceType.UNKNOWN
resourceType: ResourceType.UNKNOWN,
compatibleResourceTypes: []
},
{
id: ['imaging_study', 'imaging_series'],
name: 'Fait - Imagerie - Étude & Séries',
label: 'imaging_study - imaging_series',
resourceType: ResourceType.IMAGING
resourceType: ResourceType.IMAGING,
compatibleResourceTypes: ['imaging_study - imaging_series', 'person', 'visit_occurrence']
},
{
id: [
Expand All @@ -97,7 +149,8 @@ const exportTable: ExportTableType[] = [
name: 'Formulaires',
label:
'questionnaire - questionnaire__item - questionnaireresponse - questionnaireresponse__item - questionnaireresponse__item__answer',
resourceType: ResourceType.QUESTIONNAIRE_RESPONSE
resourceType: ResourceType.QUESTIONNAIRE_RESPONSE,
compatibleResourceTypes: []
}
]

Expand Down
13 changes: 13 additions & 0 deletions src/components/Dashboard/ExportModal/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,19 @@ const useStyles = makeStyles()(() => ({
color: '#ed6c02',
fontSize: '12px',
fontWeight: '600'
},
referentielContainer: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
},
select: {
marginLeft: 8,
borderRadius: 25,
backgroundColor: '#FFF',
'& .MuiSelect-select': {
borderRadius: 25
}
}
}))

Expand Down
9 changes: 6 additions & 3 deletions src/services/aphp/serviceCohorts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import {
} from './callApi'

import apiBackend from '../apiBackend'
import { Binary, DocumentReference, Extension, ImagingStudy, ParametersParameter, Patient } from 'fhir/r4'
import { Binary, DocumentReference, ImagingStudy, ParametersParameter, Patient } from 'fhir/r4'
import { AxiosError, AxiosResponse, CanceledError, isAxiosError } from 'axios'
import {
VitalStatus,
Expand Down Expand Up @@ -213,6 +213,8 @@ export interface IServiceCohorts {
cohortId: string
motivation: string
tables: ExportCSVTable[]
outputFormat: 'csv' | 'xlsx'
group_tables: boolean
}) => Promise<AxiosResponse<Export> | AxiosError>
}

Expand Down Expand Up @@ -667,7 +669,7 @@ const servicesCohorts: IServiceCohorts = {

createExport: async (args): Promise<AxiosResponse<Export> | AxiosError> => {
try {
const { cohortId, motivation, tables } = args
const { cohortId, motivation, tables, outputFormat, group_tables } = args

return await apiBackend.post<Export>('/exports/', {
motivation,
Expand All @@ -678,7 +680,8 @@ const servicesCohorts: IServiceCohorts = {
...(table.fhir_filter && { fhir_filter: table.fhir_filter?.uuid })
})),
nominative: true, // Nominative should always be true when exporting a CSV (see issue #1113)
output_format: 'csv'
output_format: outputFormat,
group_tables: group_tables
})
} catch (error) {
if (isAxiosError(error)) return error
Expand Down
Loading

0 comments on commit bb3af3c

Please sign in to comment.