Skip to content

Commit 443c1ea

Browse files
Kavitha | Upgrade allergies, OT notes and default locale support (#1008)
* Kavitha|add allergy changes and locale support * Removing locale param from concept search by SearchByFullName api call * Remove duplicate imports * fix update notes api call * fix. add Allergy test * add getByTestId import in test --------- Co-authored-by: Arjun-Go <arjun.g@thoughtworks.com>
1 parent e84c014 commit 443c1ea

File tree

19 files changed

+392
-102
lines changed

19 files changed

+392
-102
lines changed

micro-frontends/src/next-ui/Components/AddAllergy/AddAllergy.jsx

Lines changed: 30 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
import React, {Fragment, useEffect} from "react";
2-
import propTypes from "prop-types";
31
import { Close24 } from "@carbon/icons-react";
4-
import SaveAndCloseButtons from "../SaveAndCloseButtons/SaveAndCloseButtons.jsx";
52
import "./AddAllergy.scss";
63
import "../../../styles/common.scss";
7-
import { SearchAllergen } from "../SearchAllergen/SearchAllergen.jsx";
84
import { isEmpty } from "lodash";
95
import {
106
RadioButton,
@@ -13,9 +9,16 @@ import {
139
} from "carbon-components-react";
1410
import { FormattedMessage, useIntl } from "react-intl";
1511
import { ArrowLeft } from "@carbon/icons-react/next";
12+
import propTypes from "prop-types";
13+
import React, { Fragment, useEffect } from "react";
14+
import "../../../styles/common.scss";
15+
import {
16+
saveAllergiesAPICall
17+
} from "../../utils/PatientAllergiesControl/AllergyControlUtils";
18+
import SaveAndCloseButtons from "../SaveAndCloseButtons/SaveAndCloseButtons.jsx";
19+
import { SearchAllergen } from "../SearchAllergen/SearchAllergen.jsx";
1620
import { SelectReactions } from "../SelectReactions/SelectReactions";
17-
import { bahmniEncounter, getEncounterType } from "../../utils/PatientAllergiesControl/AllergyControlUtils";
18-
import { getCookies } from "../../utils/cookieHandler/cookieHandler";
21+
import "./AddAllergy.scss";
1922

2023
export function AddAllergy(props) {
2124
const { patient, provider, onClose, allergens, reaction, severityOptions, onSave } = props;
@@ -25,62 +28,46 @@ export function AddAllergy(props) {
2528
const [notes, setNotes] = React.useState("");
2629
const intl = useIntl();
2730
const backToAllergenText = (
28-
<FormattedMessage
29-
id={"BACK_TO_ALLERGEN"}
30-
defaultMessage={"Back to Allergies"}
31-
/>
31+
<FormattedMessage id={"BACK_TO_ALLERGEN"} defaultMessage={"Back to Allergies"} />
3232
);
3333
const allergiesHeading = (
34-
<FormattedMessage
35-
id={"ALLERGIES_HEADING"}
36-
defaultMessage={"Allergies and Reactions"}
37-
/>
34+
<FormattedMessage id={"ALLERGIES_HEADING"} defaultMessage={"Allergies and Reactions"} />
3835
);
3936
const additionalComments = (
4037
intl.formatMessage({ id: "ADDITIONAL_COMMENT_ALLERGY", defaultMessage: "Additional comments such as onset date etc."})
4138
);
4239
const [isSaveEnabled, setIsSaveEnabled] = React.useState(false);
4340
const [isSaveSuccess, setIsSaveSuccess] = React.useState(null);
44-
const [error, setError] = React.useState(null);
4541
const clearForm = () => {
4642
setAllergen({});
4743
setReactions([]);
4844
setNotes("");
4945
setSeverity("");
50-
setError(null);
5146
};
5247
const saveAllergies = async (allergen, reactions, severity, notes) => {
53-
const {uuid: consultationUuid} = await getEncounterType('Consultation');
54-
const cookies = getCookies();
55-
const {uuid:locationUuid} = JSON.parse(cookies["bahmni.user.location"])
5648
const allergyReactions = reactions.map((reaction) => {
57-
return {reaction: reaction}
49+
return { reaction: { uuid: reaction } };
5850
});
5951
const payload = {
60-
locationUuid,
61-
patientUuid: patient.uuid,
62-
providers: [{uuid: provider.uuid}],
63-
encounterTypeUuid: consultationUuid,
64-
allergy:{
65-
allergen:{
66-
allergenKind: allergen.kind.toUpperCase(),
67-
codedAllergen: allergen.uuid
52+
allergen: {
53+
allergenType: allergen.kind.toUpperCase(),
54+
codedAllergen: {
55+
uuid: allergen.uuid,
6856
},
69-
reactions: allergyReactions,
70-
severity: severity,
71-
comment: notes
72-
}
73-
}
74-
const response = await bahmniEncounter(payload);
75-
if(response.status === 200){
57+
},
58+
reactions: allergyReactions,
59+
severity: { uuid: severity },
60+
comment: notes,
61+
};
62+
const response = await saveAllergiesAPICall(payload, patient.uuid);
63+
if (response.status === 201) {
7664
setIsSaveSuccess(true);
77-
}else{
78-
setError(response.response.data.error.message)
65+
} else {
7966
setIsSaveSuccess(false);
8067
}
81-
}
68+
};
8269
useEffect(() => {
83-
onSave(isSaveSuccess, error);
70+
onSave(isSaveSuccess);
8471
}, [isSaveSuccess]);
8572
return (
8673
<div className={"next-ui"}>
@@ -118,10 +105,7 @@ export function AddAllergy(props) {
118105

119106
<div className={"section-next-ui"}>
120107
<div className={"font-large bold"}>
121-
<FormattedMessage
122-
id={"SEVERITY"}
123-
defaultMessage={"Severity"}
124-
/>
108+
<FormattedMessage id={"SEVERITY"} defaultMessage={"Severity"} />
125109
<span className={"red-text"}>&nbsp;*</span>
126110
</div>
127111
<RadioButtonGroup
@@ -134,6 +118,7 @@ export function AddAllergy(props) {
134118
setSeverity(e);
135119
setIsSaveEnabled(reactions && reactions.length > 0 && e);
136120
}}
121+
className={"severity-options-group"}
137122
>
138123
{severityOptions.map((option) => {
139124
return (
@@ -160,7 +145,7 @@ export function AddAllergy(props) {
160145
<div>
161146
<SaveAndCloseButtons
162147
onSave={async () => {
163-
await saveAllergies( allergen, reactions, severity, notes);
148+
await saveAllergies(allergen, reactions, severity, notes);
164149
}}
165150
onClose={onClose}
166151
isSaveDisabled={!isSaveEnabled}
@@ -178,5 +163,5 @@ AddAllergy.propTypes = {
178163
onSave: propTypes.func.isRequired,
179164
patient: propTypes.object.isRequired,
180165
provider: propTypes.object.isRequired,
181-
severityOptions: propTypes.array.isRequired
166+
severityOptions: propTypes.array.isRequired,
182167
};

micro-frontends/src/next-ui/Components/AddAllergy/AddAllergy.spec.jsx

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import React from "react";
2-
import { render, fireEvent, screen, getByTestId, waitFor } from "@testing-library/react";
2+
import { render, fireEvent, screen, waitFor, getByTestId } from "@testing-library/react";
33
import { AddAllergy } from "./AddAllergy";
4+
import {
5+
saveAllergiesAPICall
6+
} from "../../utils/PatientAllergiesControl/AllergyControlUtils";
7+
8+
jest.mock('../../utils/PatientAllergiesControl/AllergyControlUtils', () => ({
9+
saveAllergiesAPICall: jest.fn(),
10+
}));
411
import { IntlProvider } from "react-intl";
512

613
const mockAllergensData = [
@@ -267,4 +274,74 @@ describe("AddAllergy", () => {
267274
"Additional comments such as onset date etc."
268275
);
269276
});
277+
278+
it("should save allergies successfully and set isSaveSuccess to true", async () => {
279+
const { container } = render(
280+
<IntlProvider locale="en">
281+
<AddAllergy
282+
onClose={onClose}
283+
onSave={onSave}
284+
patient={patient}
285+
provider={provider}
286+
severityOptions={mockSeverityData}
287+
allergens={mockAllergensData}
288+
reaction={mockReactionsData}
289+
/>
290+
</IntlProvider>
291+
);
292+
saveAllergiesAPICall.mockResolvedValueOnce({ status: 201 });
293+
searchAllergen();
294+
selectAllergen();
295+
selectReaction(container);
296+
selectSeverity(container);
297+
const textArea = screen.getByPlaceholderText("Additional comments such as onset date etc.");
298+
expect(textArea).toBeTruthy();
299+
fireEvent.change(textArea, { target: { value: "New notes" } });
300+
fireEvent.blur(textArea);
301+
fireEvent.click(screen.getByText("Save"));
302+
303+
expect(saveAllergiesAPICall).toHaveBeenCalledWith({
304+
allergen: {
305+
allergenType: "FOOD",
306+
codedAllergen : {uuid: "162302AAAAAA"}
307+
},
308+
reactions: [{reaction: { uuid: "101AA"}}],
309+
severity: { uuid: "162301AAAAAA"},
310+
comment: "New notes",
311+
}, "patient#1");
312+
});
313+
314+
it("should set isSaveSuccess to false if saveAllergiesAPICall fails", async () => {
315+
const { container } = render(
316+
<IntlProvider locale="en">
317+
<AddAllergy
318+
onClose={onClose}
319+
onSave={onSave}
320+
patient={patient}
321+
provider={provider}
322+
severityOptions={mockSeverityData}
323+
allergens={mockAllergensData}
324+
reaction={mockReactionsData}
325+
/>
326+
</IntlProvider>
327+
);
328+
searchAllergen();
329+
selectAllergen();
330+
selectReaction(container);
331+
selectSeverity(container);
332+
333+
saveAllergiesAPICall.mockResolvedValueOnce({ status: 400 });
334+
335+
fireEvent.click(screen.getByText("Save"));
336+
expect(saveAllergiesAPICall).toHaveBeenCalledWith({
337+
allergen: {
338+
allergenType: "FOOD",
339+
codedAllergen : {uuid: "162302AAAAAA"}
340+
},
341+
reactions: [{reaction: { uuid: "101AA"}}],
342+
severity: { uuid: "162301AAAAAA"},
343+
comment: "",
344+
}, "patient#1");
345+
346+
});
270347
});

micro-frontends/src/next-ui/Components/SearchAllergen/SearchAllergen.spec.jsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,24 @@ describe("SearchAllergen", function () {
8787
fireEvent.click(searchBarCloseIcon);
8888
expect(() => screen.getByText("No Allergen found")).toThrowError();
8989
});
90+
it('should call onChange function when an allergen is clicked', function () {
91+
const { container } = render(
92+
<IntlProvider locale="en">
93+
<SearchAllergen onChange={onChange} allergens={mockAllergensData} />
94+
</IntlProvider>
95+
);
96+
97+
const searchInput = container.querySelector('.bx--search-input');
98+
fireEvent.change(searchInput, { target: { value: 'nu' } });
99+
100+
const allergen = screen.getByText('Peanuts');
101+
fireEvent.click(allergen);
102+
103+
expect(onChange).toHaveBeenCalledTimes(1);
104+
expect(onChange).toHaveBeenCalledWith({
105+
name: 'Peanuts',
106+
kind: 'Food',
107+
uuid: '162302AAAAAA'
108+
});
109+
});
90110
});

micro-frontends/src/next-ui/Components/SelectReactions/SelectReactions.jsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ export const SelectReactions = (props) => {
1616
const [isSearchResultEmpty, setIsSearchResultEmpty] = useState(true);
1717
const [selectedReactions, setSelectedReactions] = useState([]);
1818
const [allReactions] = useState(cloneDeep(reactions));
19+
const [searchKey, setSearchKey] = useState("");
1920

2021
const search = (key) => {
22+
setSearchKey(key)
2123
if (!key) {
2224
setIsSearchResultEmpty(true);
2325
setSearchResults(initialReactionIds);
@@ -48,6 +50,9 @@ export const SelectReactions = (props) => {
4850
}
4951
};
5052
useEffect(() => {
53+
if(selectedReactions.length > 0){
54+
setSearchKey("")
55+
}
5156
onChange(selectedReactions);
5257
}, [selectedReactions]);
5358

@@ -60,6 +65,7 @@ export const SelectReactions = (props) => {
6065
<Search
6166
id={"reaction-search"}
6267
placeholder={"Type to search Reactions"}
68+
value={searchKey}
6369
onChange={(e) => {
6470
search(e.target.value);
6571
}}

micro-frontends/src/next-ui/Components/SelectReactions/SelectReactions.spec.jsx

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from "react";
2-
import { fireEvent, render, screen } from "@testing-library/react";
2+
import { fireEvent, render, screen, act } from "@testing-library/react";
33
import { SelectReactions } from "./SelectReactions";
44

55
describe("Select reactions", function () {
@@ -107,11 +107,27 @@ describe("Select reactions", function () {
107107
/>
108108
);
109109
const searchInput = container.querySelector(".bx--search-input");
110-
fireEvent.change(searchInput, { target: { value: "GI" } });
110+
fireEvent.change(searchInput, { target: { value: "set" } });
111111
expect(screen.getByText("GI Upset")).toBeTruthy();
112112
expect(() => screen.getByText("Fever")).toThrowError();
113113
});
114114

115+
it("should set isSearchResultEmpty to true and reset searchResults when key is empty", () => {
116+
const { container } = render(
117+
<SelectReactions
118+
onChange={onChange}
119+
reactions={mockReactions}
120+
selectedAllergen={mockSelectedAllergen}
121+
/>
122+
);
123+
const searchInput = container.querySelector(".bx--search-input");
124+
125+
fireEvent.change(searchInput, { target: { value: "vw" } });
126+
127+
const allCheckboxes = container.querySelectorAll(".bx--checkbox");
128+
expect(allCheckboxes).toHaveLength(5); // Assuming mockReactions has 5 reactions
129+
});
130+
115131
it("should show chiclets for selected reactions", function () {
116132
const { container, getAllByText } = render(
117133
<SelectReactions
@@ -125,4 +141,43 @@ describe("Select reactions", function () {
125141
expect(tag).toBeTruthy();
126142
expect(getAllByText("GI Upset").length).toEqual(2);
127143
});
144+
145+
it("should set searchKey correctly", () => {
146+
const { container } = render(
147+
<SelectReactions
148+
onChange={onChange}
149+
reactions={mockReactions}
150+
selectedAllergen={mockSelectedAllergen}
151+
/>
152+
);
153+
const searchInput = container.querySelector(".bx--search-input");
154+
155+
fireEvent.change(searchInput, { target: { value: "GI" } });
156+
expect(searchInput.value).toBe("GI");
157+
});
158+
159+
it("should reset isSearchResultEmpty and searchResults when key is empty", () => {
160+
const { container, rerender } = render(
161+
<SelectReactions
162+
onChange={onChange}
163+
reactions={mockReactions}
164+
selectedAllergen={mockSelectedAllergen}
165+
/>
166+
);
167+
const searchInput = container.querySelector(".bx--search-input");
168+
169+
fireEvent.change(searchInput, { target: { value: "GI" } });
170+
expect(container.querySelectorAll(".bx--checkbox")).toHaveLength(1);
171+
172+
fireEvent.change(searchInput, { target: { value: "" } });
173+
rerender(
174+
<SelectReactions
175+
onChange={onChange}
176+
reactions={mockReactions}
177+
selectedAllergen={mockSelectedAllergen}
178+
/>
179+
);
180+
181+
expect(container.querySelectorAll(".bx--checkbox")).toHaveLength(5);
182+
});
128183
});

micro-frontends/src/next-ui/Components/SelectReactions/__snapshots__/SelectReactions.spec.jsx.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ exports[`Select reactions should render SelectReactions 1`] = `
5959
placeholder="Type to search Reactions"
6060
role="searchbox"
6161
type="text"
62+
value=""
6263
/>
6364
<button
6465
aria-label="Clear search input"

micro-frontends/src/next-ui/Components/ViewAllergiesAndReactions/ViewAllergiesAndReactions.jsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ export const ViewAllergiesAndReactions = (props) => {
1616
<div>
1717
{allergies.map((allergy, index) => {
1818
const title = <div key={index}
19-
className={` allergies-row ${showTextAsAbnormal ? "allergies-red-text"
20-
: allergy.severity === "severe" ? "allergies-red-text": ""}`}>
19+
className={` allergies-row ${showTextAsAbnormal ? "red-text" : allergy.severity === "severe" ? "red-text": ""}`}>
2120
<div>{allergy.allergen}</div>
2221
<div>{allergy.reactions.join(", ")}</div>
2322
<div className={"capitalize"}>{allergy.severity}</div>
@@ -31,7 +30,7 @@ export const ViewAllergiesAndReactions = (props) => {
3130
{allergy.note}</div>}
3231
</div>
3332
<div className={"allergy-provider"}>
34-
{allergy.provider + " " + allergy.datetime}
33+
{allergy.provider}
3534
</div>
3635
</div>
3736
</AccordionItem>

0 commit comments

Comments
 (0)