Skip to content

Commit

Permalink
Phani | A-1204405645434093 | Adds. Ability to capture Patient Allergi…
Browse files Browse the repository at this point in the history
…es (#674)

* WIP- initial

* WIP- Add Allergen search

* WIP- Add Severity

* Add Reaction

* Enable/Disable Save button

* Extract CSS to classes and reusable classes

* Add test for selecting Reactions

* Add tests for Allergen search

* Add tests for Save and close buttons

* Add tests for Add Allergy

* Add New lines at EOF

* Fix tests

* Refactor dashboardSection to make it reusable

* Change the cursor on hover for Add button
  • Loading branch information
Phanindra-tw authored Aug 22, 2023
1 parent 9e68996 commit b7f7e19
Show file tree
Hide file tree
Showing 32 changed files with 1,398 additions and 66 deletions.
8 changes: 6 additions & 2 deletions micro-frontends/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,17 @@
"sass-loader": "10.1.0"
},
"dependencies": {
"@carbon/icons-react": "^10.18.0",
"angular-component": "^0.1.3",
"react2angular": "^4.0.6",
"bahmni-carbon-ui": "0.1.0",
"bahmni-carbon-ui": "0.1.3",
"classnames": "2.3.1",
"carbon-components": "^10.19.0",
"carbon-components-react": "^7.25.0",
"prop-types": "^15.7.2",
"react": "16.14.0",
"react-dom": "16.14.0"
"react-dom": "16.14.0",
"react-intl": "^3.3.2"
},
"peerDependencies": {
"react-dom": "16.14.0",
Expand Down
81 changes: 81 additions & 0 deletions micro-frontends/src/next-ui/Components/AddAllergy/AddAllergy.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import React, {Fragment} from "react";
import propTypes from "prop-types";
import { Close24 } from "@carbon/icons-react";
import SaveAndCloseButtons from "../SaveAndCloseButtons/SaveAndCloseButtons.jsx";
import "./AddAllergy.scss";
import "../../../styles/common.scss";
import { SearchAllergen } from "../SearchAllergen/SearchAllergen.jsx";
import { isEmpty } from "lodash";
import {RadioButton, RadioButtonGroup, TextArea} from "carbon-components-react";
import { FormattedMessage } from "react-intl";
import { ArrowLeft } from "@carbon/icons-react/next";
import { SelectReactions } from "../SelectReactions/SelectReactions";

export function AddAllergy(props) {
const { onClose } = props;
const [allergen, setAllergen] = React.useState({});
const [reactions, setReactions] = React.useState([]);
const [severity, setSeverity] = React.useState("");
const [notes, setNotes] = React.useState("");
const mild = { label: <FormattedMessage id={"MILD"} defaultMessage={"Mild"}/>, uuid: "1498AAAAA"};
const moderate = {label: <FormattedMessage id={"MODERATE"} defaultMessage={"Moderate"}/>, uuid: "1499AAAAA"};
const severe = {label: <FormattedMessage id={"SEVERE"} defaultMessage={"Severe"}/>, uuid: "1500AAAAA"};
const backToAllergenText = <FormattedMessage id={"BACK_TO_ALLERGEN"} defaultMessage={"Back to Allergies"}/>;
const allergiesHeading = <FormattedMessage id={"ALLERGIES_HEADING"} defaultMessage={"Allergies and Reactions"}/>;
const [isSaveEnabled, setIsSaveEnabled] = React.useState(false);
const clearForm = () =>{
setAllergen({});
setReactions([]);
setNotes("");
setSeverity("");
}
return (
<div className={"next-ui"}>
<div className={"overlay-next-ui"}>
<div className={"heading"}>{allergiesHeading}</div>
<span className="close" onClick={onClose}>
<Close24/>
</span>
<div className={"add-allergy-container"}>
{ isEmpty(allergen) ?
<div data-testid={"search-allergen"} >
<SearchAllergen onChange={(allergen) => {setAllergen(allergen);}}/>
</div>
:<Fragment>
<div className={"back-button"}>
<ArrowLeft size={20} onClick={clearForm}/>
<div onClick={clearForm}>{backToAllergenText}</div>
</div>
<div data-testid={"select-reactions"}>
<SelectReactions onChange={(reactions) =>{
setReactions(reactions);
setIsSaveEnabled(reactions && reactions.length > 0)
}}/>
</div>

<div className={"section"}>
<div className={"font-large bold"}>
<FormattedMessage id={"SEVERITY"} defaultMessage={"Severity"}/>
</div>
<RadioButtonGroup name={"severity"}
key={"Severity"} onChange={(e) => {setSeverity(e);}}>
<RadioButton labelText={mild.label} value={mild.uuid}></RadioButton>
<RadioButton labelText={moderate.label} value={moderate.uuid}></RadioButton>
<RadioButton labelText={severe.label} value={severe.uuid}></RadioButton>
</RadioButtonGroup>
<TextArea labelText={""} placeholder={"Additional comments such as onset date etc."} onBlur={(e) => {setNotes(e.target.value);}}/>
</div>
</Fragment>
}
</div>
<div>
<SaveAndCloseButtons onSave={()=>{console.log("Saved",allergen, reactions, severity,notes)}} onClose={ onClose } isSaveDisabled={!isSaveEnabled}/>
</div>
</div>
</div>
);
}

AddAllergy.propTypes = {
onClose: propTypes.func.isRequired
}
26 changes: 26 additions & 0 deletions micro-frontends/src/next-ui/Components/AddAllergy/AddAllergy.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.close {
border: none;
position: absolute;
right: 16px;
top: 16px;
cursor: pointer;
}
.heading{
padding: 20px;
font-size: 20px;
}
.add-allergy-container{
padding: 0 20px;
margin-bottom: 80px;
max-width: 500px;
}
.back-button{
color: #0F62FE;
display: flex;
gap: 5px;
align-items: center;
padding-bottom: 10px;
> * {
cursor: pointer;
}
}
109 changes: 109 additions & 0 deletions micro-frontends/src/next-ui/Components/AddAllergy/AddAllergy.spec.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import React from "react";
import { render, fireEvent, screen } from "@testing-library/react";
import { AddAllergy } from "./AddAllergy";

describe("AddAllergy", () => {
const onClose = jest.fn();
const searchAllergen = () => {
const searchInput = screen.getByRole("searchbox");
fireEvent.change(searchInput, { target: { value: "pea" } });
}
const selectAllergen = () => {
const selectAllergen = screen.getByText("Reaction(s)");
fireEvent.click(selectAllergen);
}
const selectReaction = (container) => {
const severity = container.querySelectorAll(".bx--checkbox")[0];
fireEvent.click(severity);
expect(severity.checked).toEqual(true);
};

const selectSeverity = (container) => {
const selectSeverity = container.querySelectorAll(".bx--radio-button")[0];
fireEvent.click(selectSeverity);
expect(selectSeverity.checked).toEqual(true);
}
it("should render the component", () => {
const { container } = render(<AddAllergy onClose={onClose}/>);
expect(container).toMatchSnapshot();
});

it("should call onClose when close button is clicked", () => {
const {container} = render(<AddAllergy onClose={onClose}/>);
fireEvent.click(container.querySelector(".close"));
expect(onClose).toHaveBeenCalledTimes(1);
});

it('should show Search Allergen when allergen is empty', () => {
const { getByTestId } = render(<AddAllergy onClose={onClose}/>);
expect(getByTestId('search-allergen')).not.toBeNull();
});

it('should show Allergen List when Search is done', () => {
render(<AddAllergy onClose={onClose}/>);
searchAllergen();
expect(screen.getByText("Peanuts")).not.toBeNull();
expect(screen.getByText("Reaction(s)")).not.toBeNull();
});

it('should show select reactions when allergen is selected', () => {
render(<AddAllergy onClose={onClose}/>);
searchAllergen();
expect(screen.getByTestId("search-allergen")).not.toBeNull();
expect(screen.getByText("Reaction(s)")).not.toBeNull();

//select allergen
selectAllergen();

expect(() => screen.getByTestId("search-allergen")).toThrowError();
expect(screen.getByTestId("select-reactions")).not.toBeNull();

});

it('should show search Allergen ocClick of back button', () => {
render(<AddAllergy onClose={onClose}/>);
searchAllergen();
selectAllergen();
expect(() => screen.getByTestId("search-allergen")).toThrowError();
expect(screen.getByTestId("select-reactions")).not.toBeNull();
fireEvent.click(screen.getByText("Back to Allergies"));
expect(screen.getByTestId("search-allergen")).not.toBeNull();
expect(() => screen.getByTestId("select-reactions")).toThrowError();
});

it('should render severity after allergen is selected ', () => {
render(<AddAllergy onClose={onClose}/>);
searchAllergen();

//select allergen
selectAllergen();

expect(screen.getByText("Severity")).not.toBeNull();
});

it('should enable save button when reactions are selected', () => {
const { container} = render(<AddAllergy onClose={onClose}/>);
searchAllergen();
selectAllergen();
//select reaction
expect(screen.getByText("Save").getAttribute("disabled")).not.toBeNull();
selectReaction(container);
expect(screen.getByText("Save").getAttribute("disabled")).toBeNull();
});

it('should update severity when severity is changed', () => {
const { container } = render(<AddAllergy onClose={onClose}/>);
searchAllergen();
selectAllergen();
selectSeverity(container);
});

it('should render notes', () => {
const { container } = render(<AddAllergy onClose={onClose}/>);
searchAllergen();
selectAllergen();

const textArea = container.querySelector('.bx--text-area');
expect(textArea.placeholder).toBe("Additional comments such as onset date etc.");
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AddAllergy should render the component 1`] = `
<div>
<div
class="next-ui"
>
<div
class="overlay-next-ui"
>
<div
class="heading"
>
Allergies and Reactions
</div>
<span
class="close"
>
<svg
aria-hidden="true"
fill="currentColor"
focusable="false"
height="24"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 32 32"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M24 9.4L22.6 8 16 14.6 9.4 8 8 9.4 14.6 16 8 22.6 9.4 24 16 17.4 22.6 24 24 22.6 17.4 16 24 9.4z"
/>
</svg>
</span>
<div
class="add-allergy-container"
>
<div
data-testid="search-allergen"
>
<div
class="section"
>
<div
class="font-large bold"
>
Search Allergen
</div>
<div>
<div
aria-labelledby="allergen-search-search"
class="bx--search bx--search--xl"
role="search"
>
<div
class="bx--search-magnifier"
>
<svg
aria-hidden="true"
class="bx--search-magnifier-icon"
fill="currentColor"
focusable="false"
height="16"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M15,14.3L10.7,10c1.9-2.3,1.6-5.8-0.7-7.7S4.2,0.7,2.3,3S0.7,8.8,3,10.7c2,1.7,5,1.7,7,0l4.3,4.3L15,14.3z M2,6.5 C2,4,4,2,6.5,2S11,4,11,6.5S9,11,6.5,11S2,9,2,6.5z"
/>
</svg>
</div>
<label
class="bx--label"
for="allergen-search"
id="allergen-search-search"
/>
<input
autocomplete="off"
class="bx--search-input"
id="allergen-search"
placeholder="Type to search Allergen"
role="searchbox"
type="text"
/>
<button
aria-label="Clear search input"
class="bx--search-close bx--search-close--hidden"
type="button"
>
<svg
aria-hidden="true"
fill="currentColor"
focusable="false"
height="16"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 32 32"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M24 9.4L22.6 8 16 14.6 9.4 8 8 9.4 14.6 16 8 22.6 9.4 24 16 17.4 22.6 24 24 22.6 17.4 16 24 9.4z"
/>
</svg>
</button>
</div>
</div>
</div>
</div>
</div>
<div>
<div
class="footer"
>
<button
class="bx--btn bx--btn--secondary"
data-testid="cancel"
tabindex="0"
type="button"
>
<span>
Cancel
</span>
</button>
<button
class="bx--btn bx--btn--primary bx--btn--disabled"
disabled=""
tabindex="0"
type="button"
>
Save
</button>
</div>
</div>
</div>
</div>
</div>
`;
Loading

0 comments on commit b7f7e19

Please sign in to comment.