From 1305ad64fb130e514e00ba209f03632c093a7a3c Mon Sep 17 00:00:00 2001 From: Dennis Kigen Date: Thu, 6 Jan 2022 00:45:36 +0300 Subject: [PATCH 1/4] Enhancements to the Allergies Form --- __mocks__/allergies.mock.ts | 2 +- .../allergies-detailed-summary.component.tsx | 15 +- .../allergies-detailed-summary.test.tsx | 2 +- .../allergy-form.component.test.tsx | 175 ----- .../allergies-form/allergy-form.component.tsx | 603 +++++++++--------- .../allergies-form/allergy-form.resource.ts | 40 +- .../allergies-form/allergy-form.scss | 118 ++++ .../allergies-overview.component.tsx | 14 +- .../src/allergies/allergies-overview.test.tsx | 2 +- .../allergies/allergies-tile.component.tsx | 2 +- .../src/allergies/allergies.component.tsx | 6 +- ...ce.tsx => allergy-intolerance.resource.ts} | 76 +-- .../esm-patient-allergies-app/src/index.ts | 32 +- .../esm-patient-allergies-app/src/root.scss | 8 +- .../src/types/index.ts | 116 +--- .../translations/en.json | 18 +- .../biometrics/biometrics-base.component.tsx | 7 +- .../biometrics-chart.component.scss | 4 +- ...cs.resource.tsx => biometrics.resource.ts} | 6 +- .../src/biometrics/weight-tile.component.tsx | 4 +- .../src/vitals/vitals-chart.component.scss | 18 +- 21 files changed, 546 insertions(+), 722 deletions(-) delete mode 100644 packages/esm-patient-allergies-app/src/allergies/allergies-form/allergy-form.component.test.tsx create mode 100644 packages/esm-patient-allergies-app/src/allergies/allergies-form/allergy-form.scss rename packages/esm-patient-allergies-app/src/allergies/{allergy-intolerance.resource.tsx => allergy-intolerance.resource.ts} (73%) rename packages/esm-patient-biometrics-app/src/biometrics/{biometrics.resource.tsx => biometrics.resource.ts} (96%) diff --git a/__mocks__/allergies.mock.ts b/__mocks__/allergies.mock.ts index 81a14fdfaa..16bf2c5f9c 100644 --- a/__mocks__/allergies.mock.ts +++ b/__mocks__/allergies.mock.ts @@ -1730,7 +1730,7 @@ export const mockAllergenAndReactions = { { uuid: '162542AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', display: 'Adhesive tape' }, { uuid: '5622AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', display: 'Other' }, ], - allergyReaction: [ + allergicReactions: [ { uuid: '121677AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', display: 'Mental status change' }, { uuid: '121629AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', display: 'Anaemia' }, { uuid: '148888AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', display: 'Anaphylaxis' }, diff --git a/packages/esm-patient-allergies-app/src/allergies/allergies-detailed-summary.component.tsx b/packages/esm-patient-allergies-app/src/allergies/allergies-detailed-summary.component.tsx index ff18b3c0d2..f49c8a946e 100644 --- a/packages/esm-patient-allergies-app/src/allergies/allergies-detailed-summary.component.tsx +++ b/packages/esm-patient-allergies-app/src/allergies/allergies-detailed-summary.component.tsx @@ -2,7 +2,6 @@ import React from 'react'; import dayjs from 'dayjs'; import { useTranslation } from 'react-i18next'; import { CardHeader, EmptyState, ErrorState, launchPatientWorkspace } from '@openmrs/esm-patient-common-lib'; -import { useAllergies } from './allergy-intolerance.resource'; import Add16 from '@carbon/icons-react/es/add/16'; import { Button, @@ -18,19 +17,19 @@ import { TableRow, } from 'carbon-components-react'; import styles from './allergies-detailed-summary.scss'; +import { useAllergies } from './allergy-intolerance.resource'; import { patientAllergiesFormWorkspace } from '../constants'; interface AllergiesDetailedSummaryProps { patient: fhir.Patient; - showAddAllergy: boolean; + showAddAllergyButton: boolean; } -const AllergiesDetailedSummary: React.FC = ({ patient, showAddAllergy }) => { +const AllergiesDetailedSummary: React.FC = ({ patient, showAddAllergyButton }) => { const { t } = useTranslation(); const displayText = t('allergyIntolerances', 'allergy intolerances'); const headerTitle = t('allergies', 'Allergies'); - - const { data: allergies, isError, isLoading, isValidating } = useAllergies(patient.id); + const { allergies, isError, isLoading, isValidating } = useAllergies(patient.id); const launchAllergiesForm = React.useCallback(() => launchPatientWorkspace(patientAllergiesFormWorkspace), []); @@ -75,8 +74,8 @@ const AllergiesDetailedSummary: React.FC = ({ pat ), }, - recordedDate: dayjs(allergy.recordedDate).format('MMM-YYYY') ?? '-', - lastUpdated: dayjs(allergy.lastUpdated).format('DD-MMM-YYYY'), + recordedDate: dayjs(allergy.recordedDate).format('MMM-YYYY') ?? '--', + lastUpdated: allergy.lastUpdated ? dayjs(allergy.lastUpdated).format('DD-MMM-YYYY') : '--', })); }, [allergies]); @@ -87,7 +86,7 @@ const AllergiesDetailedSummary: React.FC = ({ pat
{isValidating ? : null} - {showAddAllergy && ( + {showAddAllergyButton && ( diff --git a/packages/esm-patient-allergies-app/src/allergies/allergies-detailed-summary.test.tsx b/packages/esm-patient-allergies-app/src/allergies/allergies-detailed-summary.test.tsx index 6ab15ca188..53294afd38 100644 --- a/packages/esm-patient-allergies-app/src/allergies/allergies-detailed-summary.test.tsx +++ b/packages/esm-patient-allergies-app/src/allergies/allergies-detailed-summary.test.tsx @@ -8,7 +8,7 @@ import AllergiesDetailedSummary from './allergies-detailed-summary.component'; const testProps = { patient: mockPatient, - showAddAllergy: false, + showAddAllergyButton: false, }; const mockOpenmrsFetch = openmrsFetch as jest.Mock; diff --git a/packages/esm-patient-allergies-app/src/allergies/allergies-form/allergy-form.component.test.tsx b/packages/esm-patient-allergies-app/src/allergies/allergies-form/allergy-form.component.test.tsx deleted file mode 100644 index 5fdb76599e..0000000000 --- a/packages/esm-patient-allergies-app/src/allergies/allergies-form/allergy-form.component.test.tsx +++ /dev/null @@ -1,175 +0,0 @@ -import React from 'react'; -import { screen, render, act, waitFor, fireEvent } from '@testing-library/react'; -import AllergyForm from './allergy-form.component'; -import { mockPatient } from '../../../../../__mocks__/patient.mock'; -import { useConfig, showNotification } from '@openmrs/esm-framework'; -import { savePatientAllergy, fetchAllergensAndReaction } from './allergy-form.resource'; -import { of, throwError } from 'rxjs'; -import { mockAllergenAndReactions } from '../../../../../__mocks__/allergies.mock'; -import userEvent from '@testing-library/user-event'; - -const mockedCloseWorkspace = jest.fn(); -const mockedShowNotification = showNotification as jest.Mock; -const mockedUseConfig = useConfig as jest.Mock; - -window.HTMLElement.prototype.scrollIntoView = jest.fn(); -const mockSavePatientAllergy = savePatientAllergy as jest.Mock; -const mockFetchAllergensAndReaction = fetchAllergensAndReaction as jest.Mock; - -const mockConcepts = { - concepts: { - drugAllergenUuid: '162552AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', - environmentalAllergenUuid: '162554AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', - foodAllergenUuid: '162553AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', - mildReactionUuid: '1498AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', - moderateReactionUuid: '1499AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', - severeReactionUuid: '1500AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', - allergyReactionUuid: '162555AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', - otherConceptUuid: '5622AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', - }, -}; - -jest.mock('./allergy-form.resource', () => ({ - savePatientAllergy: jest.fn(), - fetchAllergensAndReaction: jest.fn(), -})); - -describe('', () => { - const renderAllergyForm = () => { - mockedUseConfig.mockReturnValue(mockConcepts); - mockFetchAllergensAndReaction.mockReturnValue(of(mockAllergenAndReactions)); - render( - , - ); - }; - - afterEach(() => { - jest.resetAllMocks(); - }); - - it('should display allergy form correctly', async () => { - renderAllergyForm(); - expect(screen.getByRole('tab', { name: /Drug/i })).toBeInTheDocument(); - expect(screen.getByRole('tab', { name: /Food/i })).toBeInTheDocument(); - expect(screen.getByRole('tab', { name: /Environmental/i })).toBeInTheDocument(); - - // Display drug allergens - expect(screen.getByRole('radio', { name: /ACE inhibitors/i })).toBeInTheDocument(); - expect(screen.getByRole('radio', { name: /Aspirin/i })).toBeInTheDocument(); - expect(screen.getByRole('radio', { name: /Cephalosporins/i })).toBeInTheDocument(); - expect(screen.getByRole('radio', { name: /Codeine/i })).toBeInTheDocument(); - - // Display food allergen - const foodAllergen = screen.getByRole('tab', { name: /Food/i }); - userEvent.click(foodAllergen); - - expect(screen.getByRole('radio', { name: /Beef/i })).toBeInTheDocument(); - expect(screen.getByRole('radio', { name: /Caffeine/i })).toBeInTheDocument(); - expect(screen.getByRole('radio', { name: /Chocolate/i })).toBeInTheDocument(); - expect(screen.getByRole('radio', { name: /Strawberries/i })).toBeInTheDocument(); - - const beefAllergen = screen.getByRole('radio', { name: /Beef/i }); - userEvent.click(beefAllergen); - expect(beefAllergen).toBeChecked(); - - // Should display other text box when other allergen is selected - const otherAllergen = screen.getByRole('radio', { name: /Other/i }); - userEvent.click(otherAllergen); - expect(otherAllergen).toBeChecked(); - expect(screen.getByRole('textbox', { name: /Please specify other allergen/i })).toBeInTheDocument(); - const otherAllergenTextInput = screen.getByRole('textbox', { name: /Please specify other allergen/i }); - userEvent.type(otherAllergenTextInput, 'Other Allergen Text'); - - // should display reaction checkboxes - expect(screen.getByRole('checkbox', { name: /Anaemia/i })).toBeInTheDocument(); - expect(screen.getByRole('checkbox', { name: /Anaphylaxis/i })).toBeInTheDocument(); - expect(screen.getByRole('checkbox', { name: /Headache/i })).toBeInTheDocument(); - expect(screen.getByRole('checkbox', { name: /Hypertension/i })).toBeInTheDocument(); - - // should be able to change patient allergy reaction - const anaemiaReaction = screen.getByRole('checkbox', { name: /Anaemia/i }); - expect(anaemiaReaction).not.toBeChecked(); - userEvent.click(anaemiaReaction); - expect(anaemiaReaction).toBeChecked(); - - // uncheck selected anaemia reaction - userEvent.click(anaemiaReaction); - expect(anaemiaReaction).not.toBeChecked(); - - // should display other reaction checkboxes - const otherReaction = screen.getByRole('checkbox', { name: /Other/i }); - userEvent.click(otherReaction); - expect(screen.getByLabelText(/Please specify other reaction/)).toBeInTheDocument(); - const otherReactionTextInput = screen.getByLabelText(/Please specify other reaction/); - userEvent.type(otherReactionTextInput, 'Other Reaction'); - - expect(screen.getByRole('radio', { name: /Mild/i })).toBeInTheDocument(); - expect(screen.getByRole('radio', { name: /Moderate/i })).toBeInTheDocument(); - expect(screen.getByRole('radio', { name: /Severe/i })).toBeInTheDocument(); - const severeReactionRadio = screen.getByRole('radio', { name: /Severe/i }); - userEvent.click(severeReactionRadio); - expect(severeReactionRadio).toBeChecked(); - - const commentText = screen.getByRole('textbox', { name: /Comments/i }); - userEvent.type(commentText, 'patient test comment'); - - const dateOfFirstOnset = screen.getByRole('textbox', { name: /Date of first onset/i }); - fireEvent.change(dateOfFirstOnset, new Date('2021-12-12').toISOString()); - - // Save patient allergy - mockSavePatientAllergy.mockReturnValue(Promise.resolve({ status: 201 })); - const saveButton = screen.getByRole('button', { name: /Save and Close/i }); - userEvent.click(saveButton); - expect(mockSavePatientAllergy).toHaveBeenCalledWith( - { - allergen: { - allergenType: 'ENVIRONMENT', - codedAllergen: { uuid: '5622AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' }, - nonCodedAllergen: 'Other Allergen Text', - }, - comment: 'patient test comment', - reactions: [{ reaction: { uuid: '5622AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' }, reactionNonCoded: 'Other Reaction' }], - severity: { uuid: '1500AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' }, - }, - '8673ee4f-e2ab-4077-ba55-4980f408773e', - expect.anything(), - ); - }); - - it('should display an error when loading the form fails', () => { - mockedUseConfig.mockReturnValue(mockConcepts); - mockFetchAllergensAndReaction.mockReturnValue(throwError('loading error')); - render( - , - ); - - expect(screen.getByText(/Allergy Form Error/i)).toBeInTheDocument(); - }); - - it('should display an error message when error occurs while saving patient allergy', async () => { - renderAllergyForm(); - const promise = Promise.resolve(); - mockSavePatientAllergy.mockReturnValue(Promise.reject({ status: 500 })); - const saveButton = screen.getByRole('button', { name: /Save and Close/i }); - userEvent.click(saveButton); - await waitFor(() => - expect(mockedShowNotification).toHaveBeenCalledWith({ - critical: true, - description: undefined, - kind: 'error', - title: 'Error saving allergy', - }), - ); - await act(() => promise); - }); -}); diff --git a/packages/esm-patient-allergies-app/src/allergies/allergies-form/allergy-form.component.tsx b/packages/esm-patient-allergies-app/src/allergies/allergies-form/allergy-form.component.tsx index d029421af7..4875c4ad84 100644 --- a/packages/esm-patient-allergies-app/src/allergies/allergies-form/allergy-form.component.tsx +++ b/packages/esm-patient-allergies-app/src/allergies/allergies-form/allergy-form.component.tsx @@ -1,88 +1,50 @@ -import React from 'react'; -import { mutate } from 'swr'; -import styles from './allergy-form.component.scss'; -import AllergyFormTab from './allergy-form-tab.component'; -import { useTranslation } from 'react-i18next'; -import { fhirBaseUrl, showNotification, showToast, useConfig } from '@openmrs/esm-framework'; -import { AllergiesConfigObject } from '../../config-schema'; -import { fetchAllergensAndReaction, savePatientAllergy } from './allergy-form.resource'; -import { ErrorState } from '@openmrs/esm-patient-common-lib'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { - SearchSkeleton, - TextInput, - TextArea, + Button, + ButtonSet, Checkbox, - Tabs, - Tab, DatePicker, DatePickerInput, + Form, RadioButton, - Button, RadioButtonGroup, - ButtonSet, + Row, + Tab, + Tabs, + TextArea, + TextInput, } from 'carbon-components-react'; -import { OpenMRSResource } from '../../types'; - -enum ActionTypes { - pending = 'pending', - resolved = 'resolved', - error = 'error', -} -interface Pending { - type: ActionTypes.pending; -} -interface Error { - type: ActionTypes.error; - payload: Error; -} - -interface Resolved { - type: ActionTypes.resolved; - payload: AllergyAndReactions; -} - -type Action = Pending | Error | Resolved; +import { useTranslation } from 'react-i18next'; +import { first } from 'rxjs/operators'; +import { mutate } from 'swr'; +import { + ExtensionSlot, + FetchResponse, + fhirBaseUrl, + showNotification, + showToast, + useConfig, +} from '@openmrs/esm-framework'; +import { Allergens, fetchAllergensAndAllergicReactions, NewAllergy } from './allergy-form.resource'; +import { saveAllergy } from '../allergy-intolerance.resource'; +import styles from './allergy-form.scss'; -enum AllergenType { +enum AllergenTypes { FOOD = 'FOOD', DRUG = 'DRUG', ENVIRONMENT = 'ENVIRONMENT', } interface AllergyFormProps { + closeWorkspace: () => void; + isTablet: boolean; patient: fhir.Patient; patientUuid: string; - closeWorkspace(): void; - isTablet: boolean; } -interface AllergyAndReactions { - drugAllergens: Array; - foodAllergens: Array; - environmentalAllergens: Array; - allergyReaction: Array; -} - -interface PatientAllergenAndReactions { - status: 'pending' | 'resolved' | 'error'; - allergenAndReaction: AllergyAndReactions; - error?: null | Error; -} - -const formStatusReducer = (state: PatientAllergenAndReactions, action: Action): PatientAllergenAndReactions => { - switch (action.type) { - case 'pending': - return { ...state, status: action.type }; - case 'resolved': - return { allergenAndReaction: action.payload, status: action.type }; - case 'error': - return { ...state, error: action.payload, status: action.type }; - } -}; - -const AllergyForm: React.FC = ({ isTablet, closeWorkspace, patientUuid }) => { +const AllergyForm: React.FC = ({ closeWorkspace, isTablet, patientUuid }) => { const { t } = useTranslation(); - const { concepts } = useConfig() as AllergiesConfigObject; + const { concepts } = useConfig(); const { drugAllergenUuid, foodAllergenUuid, @@ -92,277 +54,282 @@ const AllergyForm: React.FC = ({ isTablet, closeWorkspace, pat severeReactionUuid, moderateReactionUuid, otherConceptUuid, - } = React.useMemo(() => concepts, [concepts]); - const [comment, setComment] = React.useState(); - const [patientReactions, setPatientReactions] = React.useState>([]); - const [selectedAllergen, setSelectedAllergen] = React.useState(); - const [severityOfReaction, setSeverityOfReaction] = React.useState(); - const [dateOfOnset, setDateOfOnset] = React.useState(); - const [{ status, allergenAndReaction, error }, dispatch] = React.useReducer(formStatusReducer, { - status: ActionTypes.pending, - allergenAndReaction: null, - }); - const [allergenType, setAllergenType] = React.useState(AllergenType.DRUG); - const [otherReaction, setOtherReaction] = React.useState(); - const [otherAllergen, setOtherAllergen] = React.useState(); + } = useMemo(() => concepts, [concepts]); + const patientState = useMemo(() => ({ patientUuid }), [patientUuid]); + const [allergens, setAllergens] = useState(null); + const [allergicReactions, setAllergicReactions] = useState>([]); + const [comment, setComment] = useState(''); + const [nonCodedAllergenType, setNonCodedAllergenType] = useState(''); + const [nonCodedAllergicReaction, setNonCodedAllergicReaction] = useState(''); + const [onsetDate, setOnsetDate] = useState(null); + const [selectedAllergen, setSelectedAllergen] = useState(''); + const [selectedAllergenType, setSelectedAllergenType] = useState(AllergenTypes.DRUG); + const [severityOfWorstReaction, setSeverityOfWorstReaction] = useState(''); + const allergenTypes = [t('drug', 'Drug'), t('food', 'Food'), t('environmental', 'Environmental')]; + const severityLevels = [t('mild', 'Mild'), t('moderate', 'Moderate'), t('severe', 'Severe')]; - React.useEffect(() => { - if (drugAllergenUuid && foodAllergenUuid && environmentalAllergenUuid) { - const sub = fetchAllergensAndReaction([ - drugAllergenUuid, - foodAllergenUuid, - environmentalAllergenUuid, - allergyReactionUuid, - ]).subscribe( - (data) => { - dispatch({ type: ActionTypes.resolved, payload: data }); - }, - (error) => { - dispatch({ type: ActionTypes.error, payload: error }); - }, - ); - return () => sub.unsubscribe(); - } - }, [drugAllergenUuid, environmentalAllergenUuid, foodAllergenUuid, allergyReactionUuid]); - - const handlePatientReactionChange = React.useCallback( - (value: boolean, id: string, event: React.ChangeEvent) => { - value - ? setPatientReactions((prevState) => [...prevState, id]) - : setPatientReactions((prevState) => prevState.filter((reaction) => reaction !== id)); - }, - [], - ); + useEffect(() => { + const allergenUuids = [drugAllergenUuid, foodAllergenUuid, environmentalAllergenUuid, allergyReactionUuid]; + fetchAllergensAndAllergicReactions(allergenUuids).pipe(first()).subscribe(setAllergens); + }, [allergyReactionUuid, drugAllergenUuid, environmentalAllergenUuid, foodAllergenUuid]); - const handleAllergenTypeChange = React.useCallback((index: number) => { + const handleTabChange = (index: number) => { switch (index) { case 0: - setAllergenType(AllergenType.DRUG); + setSelectedAllergenType(AllergenTypes.DRUG); + break; case 1: - setAllergenType(AllergenType.FOOD); + setSelectedAllergenType(AllergenTypes.FOOD); + break; case 2: - setAllergenType(AllergenType.ENVIRONMENT); + setSelectedAllergenType(AllergenTypes.ENVIRONMENT); + break; } + }; + + const handleAllergicReactionChange = useCallback((value: boolean, id: string) => { + value + ? setAllergicReactions((prevState) => [...prevState, id]) + : setAllergicReactions((prevState) => prevState.filter((reaction) => reaction !== id)); }, []); - const handleSavePatientAllergy = React.useCallback(() => { - const allergyPayload = { - allergen: - selectedAllergen === otherConceptUuid - ? { - allergenType: allergenType, - codedAllergen: { - uuid: selectedAllergen, - }, - nonCodedAllergen: otherAllergen, - } - : { - allergenType: allergenType, - codedAllergen: { - uuid: selectedAllergen, - }, - }, - severity: { - uuid: severityOfReaction, - }, - comment: comment, - reactions: patientReactions?.map((reaction) => { - return reaction === otherConceptUuid - ? { reaction: { uuid: reaction }, reactionNonCoded: otherReaction } - : { reaction: { uuid: reaction } }; - }), - }; + const handleSubmit = useCallback( + (event: React.SyntheticEvent) => { + event.preventDefault(); - const ac = new AbortController(); + let payload: NewAllergy = { + allergen: + selectedAllergen === otherConceptUuid + ? { + allergenType: selectedAllergenType, + codedAllergen: { + uuid: selectedAllergen, + }, + nonCodedAllergen: nonCodedAllergenType, + } + : { + allergenType: selectedAllergenType, + codedAllergen: { + uuid: selectedAllergen, + }, + }, + severity: { + uuid: severityOfWorstReaction, + }, + comment: comment, + reactions: allergicReactions?.map((reaction) => { + return reaction === otherConceptUuid + ? { reaction: { uuid: reaction }, reactionNonCoded: nonCodedAllergicReaction } + : { reaction: { uuid: reaction } }; + }), + }; - savePatientAllergy(allergyPayload, patientUuid, ac).then( - (response) => { - if (response.status === 201) { - closeWorkspace(); + const abortController = new AbortController(); + saveAllergy(payload, patientUuid, abortController) + .then( + (response: FetchResponse) => { + if (response.status === 201) { + closeWorkspace(); - showToast({ - critical: true, - kind: 'success', - title: t('allergySaved', 'Allergy saved'), - description: t('allergyNowVisible', 'It is now visible on the Allergies page'), - }); + showToast({ + critical: true, + kind: 'success', + title: t('allergySaved', 'Allergy saved'), + description: t('allergyNowVisible', 'It is now visible on the Allergies page'), + }); - mutate(`${fhirBaseUrl}/AllergyIntolerance?patient=${patientUuid}`); - } - }, - (err) => { - dispatch({ type: ActionTypes.error, payload: err }); - showNotification({ - title: t('allergySaveError', 'Error saving allergy'), - kind: 'error', - critical: true, - description: err?.message, - }); - }, - ); - return () => ac.abort(); - }, [ - selectedAllergen, - otherConceptUuid, - allergenType, - otherAllergen, - severityOfReaction, - comment, - patientReactions, - patientUuid, - otherReaction, - closeWorkspace, - t, - ]); + mutate(`${fhirBaseUrl}/AllergyIntolerance?patient=${patientUuid}`); + } + }, + (err) => { + showNotification({ + title: t('allergySaveError', 'Error saving allergy'), + kind: 'error', + critical: true, + description: err?.message, + }); + }, + ) + .finally(() => abortController.abort()); + }, + [ + selectedAllergen, + otherConceptUuid, + selectedAllergenType, + nonCodedAllergenType, + severityOfWorstReaction, + comment, + allergicReactions, + patientUuid, + nonCodedAllergicReaction, + closeWorkspace, + t, + ], + ); return ( -
- {status === ActionTypes.pending && } - {status === ActionTypes.resolved && ( -
-
-
-
- {t('allergenAndReaction', 'Allergen and reactions')} -
-
-
-
- {t('selectTheAllergens', 'Select the allergens')} -
- - - - - - - - - - - - {selectedAllergen === otherConceptUuid && ( - setOtherAllergen(event.target.value)} - placeholder={t('enterOtherReaction', 'Type in other Allergen')} - /> - )} -
-
-
- {t('selectTheReactions', 'Select the reactions')} -
-
- {allergenAndReaction?.allergyReaction?.map((reaction, index) => ( - - ))} +
+ {isTablet ? ( + + + + ) : null} +

{t('allergensAndReactions', 'Allergens and reactions')}

+
+
+

{t('selectAllergens', 'Select the allergens')}

+ + {allergenTypes.map((allergenType, index) => { + const allergenCategory = allergenType.toLowerCase() + 'Allergens'; + return ( + +
+ setSelectedAllergen(event.toString())} + valueSelected={selectedAllergen} + > + {allergens?.[allergenCategory]?.map((allergen) => ( + + ))} +
- {patientReactions.includes(otherConceptUuid) && ( - setOtherReaction(event.target.value)} - placeholder={t('enterOtherReaction', 'Type in other reaction')} - /> - )} -
-
+ + ); + })} + + {selectedAllergen === otherConceptUuid ? ( +
+ setNonCodedAllergenType(event.target.value)} + placeholder={t('typeAllergenName', 'Please type in the name of the allergen')} + />
-
-
- {t('severityAndDateOfOnset', 'Severity and date of onset')} -
-
-
-
- {t('severityOfWorstReaction', 'Severity of worst reaction')} -
- setSeverityOfReaction(event.toString())} - name="severityOfWorstReaction" - valueSelected={severityOfReaction} - > - - - - -
-
-
{t('dateAndComments', 'Date and comments')}
- - setDateOfOnset(event.target.valueAsDate)} - /> - -