-
Notifications
You must be signed in to change notification settings - Fork 128
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds initial mhv-supply-reordering application (#33224)
* Adds initial mhv-supply-reorder form app * Adds mocks * Adds alerts * Moves breadcrumbs to IntroductionPage * Sets useTopBackLink: true in formConfig (large continue button) * Show subtitle on IntroductionPage, only * Sets 'Finish this order later' content for save link * Removes margin from paragraph in informative va-alert * Sets Select supplies as first page * Sets supply count, 'No supplies selected/found' text * Adds formatDate helper * Adds checkboxes for selecting supplies * Adds product description * Updates readme * No e2e specs, yet * Adds unit specs
- Loading branch information
Showing
57 changed files
with
2,318 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
# mhv-supply-reordering | ||
|
||
## Background Info | ||
|
||
About: This app provides an interface to re-order Hearing Aid and Sleep Apnea accessories | ||
Slack Channel: [#va-cto-supply-reordering](https://dsva.slack.com/archives/C05DFSM57FW/p1689711688225089) | ||
|
||
## App | ||
|
||
Form app generated with `yarn new:app`. Changes to the following files were reverted, since `VA_FORM_IDS.FORM_VA_2346A` already exists. | ||
|
||
- `src/platform/forms/constants.js` | ||
- `src/platform/forms/tests/forms.unit.spec.js` | ||
|
||
## Quick start to get running locally | ||
|
||
Before you get started check [this page](https://depo-platform-documentation.scrollhelp.site/developer-docs/setting-up-your-local-frontend-environment) first to make sure you are setup to use the correct version of Node and Yarn. | ||
|
||
- clone vets-website repo `git clone [email protected]:department-of-veterans-affairs/vets-website.git` | ||
- run `yarn install` | ||
- turn on local mocks `yarn mock-api --responses src/applications/mhv-supply-reordering/mocks/index.js` | ||
- start app `yarn watch --env entry=mhv-supply-reordering` | ||
- Run this in your browser console to simulate being logged in `localStorage.setItem('hasSession', true);` | ||
- visit the app: `http://localhost:3001/my-health/order-supplies` | ||
|
||
Note: The application fetches supply data from `/v0/in_progress_forms/mdot`. This endpoint is mocked in the local development environment. | ||
|
||
## Running tests | ||
|
||
Unit tests can be run using this command: `yarn test:unit --app-folder mhv-supply-reordering`. To get detailed errors, run this command with `--log-level=error`. To get coverage reports run this command `yarn test:unit --app-folder mhv-supply-reordering --coverage --coverage-html`. View the report at `/coverage/index.html` | ||
|
||
Cypress tests can be run with the GUI using this command: `yarn cy:open`. From there you can filter by `mhv-supply-reordering` to run end to end tests for this app. | ||
|
||
Run Cypress from command line: | ||
|
||
- Run all `yarn cy:run --spec "src/applications/mhv-supply-reordering/**/**/*"` | ||
- Specify browser `-b electron` | ||
|
||
## VA Forms - Web Component Fields and Patterns | ||
|
||
[[docs](https://depo-platform-documentation.scrollhelp.site/developer-docs/va-forms-library-web-component-fields-and-patterns)] | ||
|
||
[[examples](https://staging.va.gov/mock-form-patterns/introduction)] | ||
|
||
A web-component-field is a design system web component for use in forms. These can be found at `src/platform/forms-system/src/js/web-component-fields`. | ||
|
||
A web-component-pattern is a group of web-component-fields that can span one or more pages (e.g. - a multi-page form). These can be found at `src/platform/forms-system/src/js/web-component-patterns`. | ||
|
||
## Form Flow | ||
|
||
- IntroductionPage | ||
- ChooseSupplies | ||
- ContactInformation (optionally: EditEmail, EditAddress) | ||
- ReviewPage | ||
- ConfirmationPage | ||
|
||
## API Responses | ||
|
||
[[mocker-api](https://github.com/jaywcjlove/mocker-api/tree/v2.9.0?tab=readme-ov-file#usage)] | ||
|
||
[[vets-api OpenAPI documentation](https://department-of-veterans-affairs.github.io/va-digital-services-platform-docs/api-reference/#/in_progress_forms)] | ||
|
||
`GET /v0/in_progress_forms/MDOT` returns the following... (note the lack of a `data` property) | ||
|
||
```json | ||
{ | ||
"formData": { | ||
"fullName": {}, | ||
"permanentAddress": {}, | ||
"temporaryAddress": {}, | ||
"ssnLastFour": "", | ||
"gender": "", | ||
"vetEmail": "", | ||
"dateOfBirth": "", | ||
"eligibility": {}, | ||
"supplies": [] | ||
}, | ||
"metadata": { | ||
"version": 0, | ||
"prefill": true, | ||
"returnUrl": "" | ||
} | ||
} | ||
``` | ||
|
||
When requesting `GET /v0/in_progress_forms/MDOT`, the MDOT client in vets-api will make a request to the system of record for veteran details and supplies available to the veteran. See `V0::InProgressFormsController.camelized_prefill_for_user` and `FormProfiles::MDOT#prefill`. On the front-end, test against the possible responses for `MDOT::Client.new(user).get_supplies` which are mapped to `mdot.exceptions` values in `vets-api/config/locales/exceptions.en.yml` and then passed along in the response. Also, see `vets-api/spec/support/vcr_cassettes/mdot/get_supplies*.yml`. | ||
|
||
## Dynamic Form Fields | ||
|
||
[[using update and replace schema funcs](https://depo-platform-documentation.scrollhelp.site/developer-docs/va-forms-library-how-to-use-updateschema-and-repla)] | ||
|
||
see `src/applications/disability-benefits/all-claims/pages/toxicExposure/toxicExposureConditions.js` for an example. | ||
|
||
## Device Types, Device Names | ||
|
||
How do we access other device types? (e.g. - assistive devices, nebulizers). Are these included in the request for supplies? | ||
|
||
The `productGroup` property of a supply can be one of the following values: `['accessories', 'batteries', 'apnea']`. `'assistive devices'` will be added to this list in the near future. | ||
|
||
The `deviceName` property of a supply indicates the associated device for the supply. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { | ||
GET_MDOT_IN_PROGRESS_FORM_STARTED, | ||
GET_MDOT_IN_PROGRESS_FORM_SUCCEEDED, | ||
GET_MDOT_IN_PROGRESS_FORM_FAILED, | ||
getMdotInProgressForm, | ||
} from './mdotInProgressForm'; | ||
|
||
export { | ||
GET_MDOT_IN_PROGRESS_FORM_STARTED, | ||
GET_MDOT_IN_PROGRESS_FORM_SUCCEEDED, | ||
GET_MDOT_IN_PROGRESS_FORM_FAILED, | ||
getMdotInProgressForm, | ||
}; |
35 changes: 35 additions & 0 deletions
35
src/applications/mhv-supply-reordering/actions/mdotInProgressForm.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { apiRequest } from 'platform/utilities/api'; | ||
|
||
export const GET_MDOT_IN_PROGRESS_FORM_STARTED = | ||
'GET_MDOT_IN_PROGRESS_FORM_STARTED'; | ||
export const GET_MDOT_IN_PROGRESS_FORM_SUCCEEDED = | ||
'GET_MDOT_IN_PROGRESS_FORM_SUCCEEDED'; | ||
export const GET_MDOT_IN_PROGRESS_FORM_FAILED = | ||
'GET_MDOT_IN_PROGRESS_FORM_FAILED'; | ||
|
||
const getMdotInProgressFormStarted = () => ({ | ||
type: GET_MDOT_IN_PROGRESS_FORM_STARTED, | ||
}); | ||
|
||
const getMdotInProgressFormSucceeded = payload => ({ | ||
type: GET_MDOT_IN_PROGRESS_FORM_SUCCEEDED, | ||
payload, | ||
}); | ||
|
||
const getMdotInProgressFormFailed = payload => ({ | ||
type: GET_MDOT_IN_PROGRESS_FORM_FAILED, | ||
payload, | ||
}); | ||
|
||
const MDOT_IN_PROGRESS_FORM_PATH = '/in_progress_forms/MDOT'; | ||
|
||
export const getMdotInProgressForm = () => async dispatch => { | ||
await dispatch(getMdotInProgressFormStarted()); | ||
return apiRequest(MDOT_IN_PROGRESS_FORM_PATH) | ||
.then(payload => { | ||
return dispatch(getMdotInProgressFormSucceeded(payload)); | ||
}) | ||
.catch(err => { | ||
return dispatch(getMdotInProgressFormFailed(err)); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import '@department-of-veterans-affairs/platform-polyfills'; | ||
import './sass/mhv-supply-reordering.scss'; | ||
|
||
import { startAppFromIndex } from '@department-of-veterans-affairs/platform-startup/exports'; | ||
|
||
import routes from './routes'; | ||
import reducer from './reducers'; | ||
import manifest from './manifest.json'; | ||
|
||
startAppFromIndex({ | ||
entryName: manifest.entryName, | ||
url: manifest.rootUrl, | ||
reducer, | ||
routes, | ||
}); |
22 changes: 22 additions & 0 deletions
22
src/applications/mhv-supply-reordering/components/Breadcrumbs.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import React from 'react'; | ||
import { VaBreadcrumbs } from '@department-of-veterans-affairs/component-library/dist/react-bindings'; | ||
import manifest from '../manifest.json'; | ||
|
||
const breadcrumbList = [ | ||
{ | ||
href: '/', | ||
label: 'VA.gov Home', | ||
}, | ||
{ | ||
href: '/my-health', | ||
label: 'Health care', | ||
}, | ||
{ | ||
href: manifest.rootUrl, | ||
label: manifest.appName, | ||
}, | ||
]; | ||
|
||
const Breadcrumbs = () => <VaBreadcrumbs breadcrumbList={breadcrumbList} />; | ||
|
||
export default Breadcrumbs; |
6 changes: 6 additions & 0 deletions
6
src/applications/mhv-supply-reordering/components/DlcEmailLink.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import React from 'react'; | ||
import { DLC_EMAIL } from '../constants'; | ||
|
||
const DlcEmailLink = () => <a href={`mailto:${DLC_EMAIL}`}>{DLC_EMAIL}</a>; | ||
|
||
export default DlcEmailLink; |
12 changes: 12 additions & 0 deletions
12
src/applications/mhv-supply-reordering/components/DlcTelephoneLink.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import React from 'react'; | ||
import { CONTACTS } from '@department-of-veterans-affairs/component-library/contacts'; | ||
import { DLC_TELEPHONE } from '../constants'; | ||
|
||
const DlcTelephoneLink = () => ( | ||
<> | ||
<va-telephone contact={DLC_TELEPHONE} /> ( | ||
<va-telephone contact={CONTACTS['711']} tty />) | ||
</> | ||
); | ||
|
||
export default DlcTelephoneLink; |
154 changes: 154 additions & 0 deletions
154
src/applications/mhv-supply-reordering/components/EditAddress.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
import React, { useState } from 'react'; | ||
import { | ||
VaCheckbox, | ||
VaSelect, | ||
VaTextInput, | ||
VaButton, | ||
} from '@department-of-veterans-affairs/component-library/dist/react-bindings'; | ||
import constants from 'vets-json-schema/dist/constants.json'; | ||
import UnsavedFieldNote from './UnsavedFieldNote'; | ||
|
||
const COUNTRY_VALUES = constants.countries.map(country => country.value); | ||
const COUNTRY_NAMES = constants.countries.map(country => country.label); | ||
|
||
const MILITARY_STATE_VALUES = constants.militaryStates.map( | ||
state => state.value, | ||
); | ||
|
||
// filtered States that include US territories | ||
const filteredStates = constants.states.USA.filter( | ||
state => !MILITARY_STATE_VALUES.includes(state.value), | ||
); | ||
|
||
const STATE_VALUES = filteredStates.map(state => state.value); | ||
const STATE_NAMES = filteredStates.map(state => state.label); | ||
|
||
const EditAddress = ({ data, goToPath, setFormData }) => { | ||
const [address, setAddress] = useState(data.permanentAddress || {}); | ||
|
||
const handleSubmit = event => { | ||
event.preventDefault(); | ||
setFormData({ ...data, permanentAddress: address }); | ||
goToPath('/contact-information'); | ||
}; | ||
|
||
const handleInputChange = event => { | ||
const { name, value } = event.target; | ||
setAddress(prevAddress => ({ ...prevAddress, [name]: value })); | ||
}; | ||
|
||
return ( | ||
<div> | ||
<h2>Order medical supplies</h2> | ||
<h3>Contact information</h3> | ||
<UnsavedFieldNote fieldName="mailing address" /> | ||
<form onSubmit={handleSubmit}> | ||
<VaCheckbox | ||
label="I live on a U.S. military base outside of the United States." | ||
onVaChange={e => | ||
setAddress(prevAddress => ({ | ||
...prevAddress, | ||
isMilitary: e.detail.checked, | ||
})) | ||
} | ||
checked={address.isMilitary} | ||
/> | ||
|
||
<VaSelect | ||
label="Country (Required)" | ||
name="country" | ||
value={address.country} | ||
onVaSelect={e => | ||
handleInputChange({ | ||
target: { name: 'country', value: e.detail.value }, | ||
}) | ||
} | ||
required | ||
> | ||
{COUNTRY_VALUES.map((value, index) => ( | ||
<option key={value} value={value}> | ||
{COUNTRY_NAMES[index]} | ||
</option> | ||
))} | ||
</VaSelect> | ||
|
||
<VaTextInput | ||
label="Street address (Required)" | ||
name="street" | ||
value={address.street} | ||
onVaInput={e => | ||
handleInputChange({ | ||
target: { name: 'street', value: e.target.value }, | ||
}) | ||
} | ||
required | ||
/> | ||
|
||
<VaTextInput | ||
label="Street address line 2" | ||
name="street2" | ||
value={address.street2} | ||
onVaInput={e => | ||
handleInputChange({ | ||
target: { name: 'street2', value: e.target.value }, | ||
}) | ||
} | ||
/> | ||
|
||
<VaTextInput | ||
label="City (Required)" | ||
name="city" | ||
value={address.city} | ||
onVaInput={e => | ||
handleInputChange({ | ||
target: { name: 'city', value: e.target.value }, | ||
}) | ||
} | ||
required | ||
/> | ||
|
||
<VaSelect | ||
label="State (Required)" | ||
name="state" | ||
value={address.state} | ||
onVaSelect={e => | ||
handleInputChange({ | ||
target: { name: 'state', value: e.detail.value }, | ||
}) | ||
} | ||
required | ||
> | ||
{STATE_VALUES.map((value, index) => ( | ||
<option key={value} value={value}> | ||
{STATE_NAMES[index]} | ||
</option> | ||
))} | ||
</VaSelect> | ||
|
||
<VaTextInput | ||
label="Postal code (Required)" | ||
name="postalCode" | ||
value={address.postalCode} | ||
onVaInput={e => | ||
handleInputChange({ | ||
target: { name: 'postalCode', value: e.target.value }, | ||
}) | ||
} | ||
required | ||
/> | ||
|
||
<div> | ||
<VaButton text="Update" onClick={handleSubmit} uswds /> | ||
<VaButton | ||
text="Cancel" | ||
secondary | ||
onClick={() => goToPath('/contact-information')} | ||
uswds | ||
/> | ||
</div> | ||
</form> | ||
</div> | ||
); | ||
}; | ||
|
||
export default EditAddress; |
Oops, something went wrong.