Merge pull request #84 from Haiti-Distributed-Healthcare-System/feature/diagnosis_form_t48

Diagnosis Form Component
This commit is contained in:
Meghan McLaughlin authored and GitHub committed 2020-04-29 09:45:28 -05:00
commit ebb7c08dcf
6 files changed
+465 -9

No files matched your search

+9 -9
View File
@@ -2198,9 +2198,9 @@
},
"dependencies": {
"acorn": {
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz",
"integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw=="
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
"integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA=="
}
}
},
@@ -7866,9 +7866,9 @@
},
"dependencies": {
"acorn": {
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz",
"integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw=="
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
"integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA=="
},
"jsdom": {
"version": "14.1.0",
@@ -8807,9 +8807,9 @@
},
"dependencies": {
"acorn": {
"version": "5.7.3",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz",
"integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw=="
"version": "5.7.4",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz",
"integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg=="
}
}
},
+10
View File
@@ -8,6 +8,7 @@ import Login from './components/Login'
import LandingPage from './components/LandingPage'
import Wrapper from './Wrapper'
import PatientInfoForm from './components/PatientInfoForm'
import DiagnosisForm from './components/DiagnosisForm'
import './scss/App.scss'
import './antd-mobile.css'
@@ -33,6 +34,15 @@ const App: React.FunctionComponent = () => {
<PatientInfoForm />
</Wrapper>
</Route>
<Route path="/diagnosis">
<Wrapper
navTitle="Diagnosis"
leftArrowText="Patient Info"
leftArrowRoute="/patientinfo"
>
<DiagnosisForm />
</Wrapper>
</Route>
<Route path="/easy-peasy">
<DebugShowEasyPeasy />
</Route>
+189
View File
@@ -0,0 +1,189 @@
{
"diagnoses": [
{
"name": "Asthma",
"id": "asthma"
},
{
"name": "Allergies",
"id": "allergies"
},
{
"name": "Anemia",
"id": "anemia"
},
{
"name": "Malnutrition",
"id": "malnutrition"
},
{
"name": "Depression",
"id": "depression"
},
{
"name": "Diabetes",
"id": "diabetes"
},
{
"id": "eye",
"group-title": "Eye",
"group": [
{
"name": "Ptergium",
"id": "ptergium"
},
{
"name": "Cataract",
"id": "cataract"
},
{
"name": "Dry Eye",
"id": "dry-eye"
},
{
"name": "Conjuntivitis",
"id": "conjuntivitis"
}
]
},
{
"name": "Fever",
"id": "fever"
},
{
"name": "Possible Malaria",
"id": "malaria"
},
{
"name": "Filariasis",
"id": "filariasis"
},
{
"id": "intestinal",
"group-title": "Intestinal",
"group": [
{ "name": "Gastritis", "id": "gastritis" },
{ "name": "GERD", "id": "gerd" },
{ "name": "Gastroenteritis", "id": "gastroenteritis" },
{ "name": "Dysentery", "id": "dysentery" },
{ "name": "Possible Cholera", "id": "cholera" }
]
},
{
"name": "Headache",
"id": "headache"
},
{
"group-title": "Hernia",
"id": "hernia",
"group": [
{ "name": "Inguinal", "id": "inguinal" },
{ "name": "Umbilical", "id": "umbilical" }
]
},
{
"id": "cardiovascular",
"group-title": "Cardiovascular",
"group": [
{ "name": "Hypertension", "id": "hypertension" },
{ "name": "Stroke", "id": "stroke" },
{ "name": "Angina", "id": "angina" },
{ "name": "CHF", "id": "chf" }
]
},
{
"name": "Healthy",
"id": "healthy"
},
{
"name": "Musculoskeletal Pain",
"id": "musculoskeletal"
},
{
"group-title": "Otitis",
"id": "otitis",
"group": [
{ "name": "Right", "id": "otitis-right" },
{ "name": "Left", "id": "otitis-left" }
]
},
{
"name": "Pneumonia",
"id": "pneumonia"
},
{
"id": "sinusitis",
"name": "Sinusitis"
},
{
"name": "URI",
"id": "uri"
},
{
"name": "Pregnancy",
"id": "pregnancy",
"text-input-title": "Weeks",
"text-input-type": "number",
"max-length": 2,
"text-input-id": "pregnancy-weeks"
},
{
"group-title": "Dermatological",
"id": "dermatological",
"group": [
{ "name": "Atopic Derm", "id": "atopic-derm" },
{ "name": "Fungal", "id": "fungal" },
{ "name": "Scabies", "id": "scabies" },
{ "name": "Impetigo", "id": "Impetigo" },
{ "name": "Tinea Capitus (kerion)", "id": "tinea-capitus" }
]
},
{
"name": "Possible STD",
"id": "std"
},
{
"name": "Possible TB",
"id": "tb"
},
{
"name": "Possible Parasites",
"id": "parasites"
},
{
"name": "UTI",
"id": "uti"
},
{
"group-title": "Vaginal",
"id": "vaginal",
"group": [
{ "name": "Vaginitis", "id": "vaginitis" },
{ "name": "Candidal", "id": "candidal" },
{ "name": "Trich", "id": "trich" },
{ "name": "BV", "id": "bv" }
]
},
{
"name": "Needs to see Dentist",
"id": "dentist"
},
{
"name": "Needs to see Eye Doctor",
"id": "eye-doctor"
},
{
"name": "Surgical candidate",
"id": "surgical-candidate"
},
{
"text-input-title": "Other Diagnosis",
"text-input-id": "other-diagnosis"
},
{
"text-input-title": "Diagnoses Comments",
"text-input-id": "comments"
}
]
}
+135
View File
@@ -0,0 +1,135 @@
import React from 'react'
import { render, fireEvent } from '@testing-library/react'
import DiagnosisForm from './DiagnosisForm'
import * as data from './DiagnosisFields.json'
/*
Diagnosis Fields are stored in DiagnosisFields.json in the format:
{
"diagnoses" : [
{
"name": "Name",
"id": "id",
"text-input-title": "Title",
"text-input-type": "type" (i.e. number)
"group-title": "Group Title",
"group": [
{ "name": "Name1", "id": "id1" },
{ "name": "Name2", "id": "id2" }
]
},
{...}
]
}
*/
const diagnosisFields = data.diagnoses
test('renders the form', async () => {
const dom = render(<DiagnosisForm />)
expect(dom.getByTestId('diagnosis-form-wrapper')).toBeTruthy()
})
test('renders each diagnoses.name data field', () => {
const { getByText } = render(<DiagnosisForm />)
diagnosisFields.forEach((diagnosis) => {
if (diagnosis.name != null) {
const re = new RegExp(diagnosis.name, 'gi')
const field = getByText(re)
expect(field).toBeInTheDocument()
}
})
})
test(' each diagnoses.name has a corresponding checkbox and is able to be checked/unchecked', () => {
const { getByTestId } = render(<DiagnosisForm />)
diagnosisFields.forEach((diagnosis) => {
if (diagnosis.name != null && diagnosis.id != null) {
const re = new RegExp(diagnosis.id, 'gi')
const checkboxItem = getByTestId(re)
expect(checkboxItem).toHaveClass('am-checkbox-item')
const checkBox = checkboxItem.getElementsByTagName('span')[0]
expect(checkBox).not.toHaveClass('am-checkbox-checked')
const checkBoxInput = checkboxItem.getElementsByClassName(
'am-checkbox-input',
)[0]
fireEvent.click(checkBoxInput)
expect(checkBox).toHaveClass('am-checkbox-checked')
}
})
})
test('renders each diagnoses.text-input-title data field as a text entry field', () => {
const { getByTestId } = render(<DiagnosisForm />)
diagnosisFields.forEach((diagnosis) => {
if (
diagnosis['text-input-title'] != null &&
diagnosis['text-input-title'] != null
) {
const re = new RegExp(diagnosis['text-input-id'], 'gi')
const field = getByTestId(re)
expect(field).toBeInTheDocument()
expect(field).toHaveAttribute('type', 'text')
}
})
})
test('renders each diagnoses.group-title data field as a header', () => {
const { getByText } = render(<DiagnosisForm />)
diagnosisFields.forEach((diagnosis) => {
if (diagnosis['group-title'] != null && diagnosis.group != null) {
const re = new RegExp(`\^${diagnosis['group-title']}\$`, 'gi')
const field = getByText(re)
expect(field).toBeInTheDocument()
expect(field).toHaveClass('am-list-header')
}
})
})
test('renders each diagnoses.group entry in the same list element', () => {
const { getByTestId } = render(<DiagnosisForm />)
diagnosisFields.forEach((diagnosis) => {
if (diagnosis.group != null && diagnosis.id != null) {
// get the list by diagnosis.id
const re = new RegExp(`\^${diagnosis.id}\$`, 'gi')
const field = getByTestId(re)
expect(field).toBeInTheDocument()
expect(field).toHaveClass('am-list')
// For each element in the group, ensure it is contained in the list
diagnosis.group.forEach((groupElement) => {
const el = getByTestId(groupElement.id)
expect(field).toContainElement(el)
})
}
})
})
test('renders each diagnoses.[el] as a checkbox that can be checked/unchecked', () => {
const { getByTestId } = render(<DiagnosisForm />)
diagnosisFields.forEach((diagnosis) => {
if (diagnosis.group != null) {
diagnosis.group.forEach((groupElement) => {
const re = new RegExp(groupElement.id, 'gi')
const groupCheckboxItem = getByTestId(re)
expect(groupCheckboxItem).toBeInTheDocument()
expect(groupCheckboxItem).toHaveClass('am-checkbox-item')
const checkBox = groupCheckboxItem.getElementsByTagName(
'span',
)[0]
expect(checkBox).not.toHaveClass('am-checkbox-checked')
const checkBoxInput = groupCheckboxItem.getElementsByClassName(
'am-checkbox-input',
)[0]
fireEvent.click(checkBoxInput)
expect(checkBox).toHaveClass('am-checkbox-checked')
})
}
})
})
+117
View File
@@ -0,0 +1,117 @@
import React, { ReactElement } from 'react'
import { List, Checkbox, InputItem, WhiteSpace } from 'antd-mobile'
import '../scss/DiagnosisForm.scss'
import * as data from './DiagnosisFields.json'
/*
Diagnosis Fields are stored in DiagnosisFields.json in the format:
{
"diagnoses" : [
{
"name": "Name",
"id": "id",
"text-input-title": "Title",
"text-input-id": "id" for `id` and `data-testid` attributes
"text-input-type": "type" (i.e. number)
"max-length": 3
"group-title": "Group Title",
"group": [
{ "name": "Name1", "id": "id1" },
{ "name": "Name2", "id": "id2" }
]
},
{...}
]
}
*/
const CheckboxItem = Checkbox.CheckboxItem
const diagnosisFields = data.diagnoses
export default function DiagnosisForm(): ReactElement {
return (
<div id="diagnosis-form-wrapper" data-testid="diagnosis-form-wrapper">
{diagnosisFields.map((field) => {
const formElements: ReactElement[] = []
if (field.name != null) {
formElements.push(
<List>
<CheckboxItem
id={field.id}
data-testid={field.id}
key={field.id}
>
{field.name}
</CheckboxItem>
</List>,
)
}
if (
field['text-input-title'] != null &&
field['text-input-id'] != null
) {
formElements.push(
<List renderHeader={() => field['text-input-title']}>
<InputItem
id={field['text-input-id']}
data-testid={field['text-input-id']}
key={field['text-input-id']}
type={
field['text-input-type'] === 'number'
? 'number'
: 'text'
}
maxLength={
field['max-length']
? field['max-length']
: null
}
/>
</List>,
)
}
if (field.group != null) {
const groupElements: ReactElement[] = []
// add each group element to the internalElement array
field.group.forEach((ele: any) => {
if (ele.id != null && ele.name != null) {
groupElements.push(
<CheckboxItem
id={ele.id}
data-testid={ele.id}
key={ele.id}
>
{ele.name}
</CheckboxItem>,
)
}
})
// Render the entire list with the internal elements
if (field['group-title'] != null && field.id !== null) {
formElements.push(
<List
renderHeader={() => field['group-title']}
data-testid={field.id}
>
{groupElements}
<WhiteSpace
className="list-whitespace"
size="lg"
/>
</List>,
)
}
}
return <> {formElements} </>
})}
</div>
)
}
+5
View File
@@ -0,0 +1,5 @@
#diagnosis-form-wrapper {
.list-whitespace {
background-color: #f5f5f9;
}
}