Skip to content

Commit

Permalink
Merge branch 'main' into js-332-accessibility-updates
Browse files Browse the repository at this point in the history
  • Loading branch information
jasalisbury committed Mar 8, 2021
2 parents 946bfcb + e7db658 commit 84f3d0e
Show file tree
Hide file tree
Showing 26 changed files with 1,015 additions and 143 deletions.
3 changes: 2 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
"simplebar-react": "^2.3.0",
"url-join": "^4.0.1",
"use-deep-compare-effect": "^1.6.1",
"uswds": "^2.9.0"
"uswds": "^2.9.0",
"uuid": "^8.3.2"
},
"engines": {
"node": "14.16.0"
Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/ContextMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ function ContextMenu({
aria-haspopup
onClick={() => updateShown((previous) => !previous)}
aria-label={label}
type="button"
>
<FontAwesomeIcon color="black" icon={faEllipsisH} />
</Button>
Expand Down
15 changes: 9 additions & 6 deletions frontend/src/components/FormItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ import './FormItem.css';
const labelPropTypes = {
label: PropTypes.node.isRequired,
children: PropTypes.node.isRequired,
className: PropTypes.string.isRequired,
};

function FieldSetWrapper({ label, children }) {
function FieldSetWrapper({ label, children, className }) {
return (
<Fieldset unstyled>
<Fieldset unstyled className={className}>
<legend>{label}</legend>
{children}
</Fieldset>
Expand All @@ -24,9 +25,9 @@ function FieldSetWrapper({ label, children }) {

FieldSetWrapper.propTypes = labelPropTypes;

function LabelWrapper({ label, children }) {
function LabelWrapper({ label, children, className }) {
return (
<Label>
<Label className={className}>
{label}
{children}
</Label>
Expand All @@ -36,7 +37,7 @@ function LabelWrapper({ label, children }) {
LabelWrapper.propTypes = labelPropTypes;

function FormItem({
label, children, required, name, fieldSetWrapper,
label, children, required, name, fieldSetWrapper, className,
}) {
const { formState: { errors } } = useFormContext();
const fieldErrors = errors[name];
Expand All @@ -51,7 +52,7 @@ function FormItem({

return (
<FormGroup error={fieldErrors}>
<LabelType label={labelWithRequiredTag}>
<LabelType label={labelWithRequiredTag} className={className}>
<ReactHookFormError
errors={errors}
name={name}
Expand All @@ -69,11 +70,13 @@ FormItem.propTypes = {
name: PropTypes.string.isRequired,
fieldSetWrapper: PropTypes.bool,
required: PropTypes.bool,
className: PropTypes.string,
};

FormItem.defaultProps = {
required: true,
fieldSetWrapper: false,
className: '',
};

export default FormItem;
23 changes: 20 additions & 3 deletions frontend/src/components/MultiSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ function MultiSelect({
labelProperty,
valueProperty,
simple,
rules,
multiSelectOptions,
onItemSelected,
components: componentReplacements,
}) {
/*
Expand All @@ -95,7 +97,11 @@ function MultiSelect({
value: v, label: v,
}));
}
return value.map((item) => ({ label: item[labelProperty], value: item[valueProperty] }));
return value.map((item) => ({
...item,
label: item[labelProperty],
value: item[valueProperty],
}));
};

/*
Expand All @@ -109,7 +115,11 @@ function MultiSelect({
controllerOnChange(event.map((v) => v.value));
} else {
controllerOnChange(
event.map((item) => ({ [labelProperty]: item.label, [valueProperty]: item.value })),
event.map((item) => ({
...item,
[labelProperty]: item.label,
[valueProperty]: item.value,
})),
);
}
};
Expand All @@ -124,7 +134,9 @@ function MultiSelect({
id={name}
value={values}
onChange={(event) => {
if (event) {
if (onItemSelected) {
onItemSelected(event);
} else if (event) {
onChange(event, controllerOnChange);
} else {
controllerOnChange([]);
Expand Down Expand Up @@ -152,6 +164,7 @@ function MultiSelect({
}
return true;
},
...rules,
}}
name={name}
/>
Expand Down Expand Up @@ -183,13 +196,15 @@ MultiSelect.propTypes = {
// eslint-disable-next-line react/forbid-prop-types
control: PropTypes.object.isRequired,
components: PropTypes.shape({}),
onItemSelected: PropTypes.func,
multiSelectOptions: PropTypes.shape({
isClearable: PropTypes.bool,
closeMenuOnSelect: PropTypes.bool,
controlShouldRenderValue: PropTypes.bool,
hideSelectedOptions: PropTypes.bool,
}),
disabled: PropTypes.bool,
rules: PropTypes.shape({}),
required: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
};

Expand All @@ -201,6 +216,8 @@ MultiSelect.defaultProps = {
valueProperty: 'value',
multiSelectOptions: {},
components: {},
rules: {},
onItemSelected: null,
};

export default MultiSelect;
23 changes: 15 additions & 8 deletions frontend/src/components/Navigator/components/NavigatorHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,23 @@
USWDS step indicator header, grabbed from https://designsystem.digital.gov/components/step-indicator/
The uswds react library we use doesn't have this component yet.
*/
import React from 'react';
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';

const NavigatorHeader = ({ label }) => (
<div className="usa-step-indicator__header">
<h2 className="usa-step-indicator__heading">
<span className="usa-step-indicator__heading-text">{label}</span>
</h2>
</div>
);
const NavigatorHeader = ({ label }) => {
useEffect(() => {
document.getElementsByClassName('usa-step-indicator__heading-text')[0].focus();
}, []);

return (
<div className="usa-step-indicator__header">
<h2 className="usa-step-indicator__heading">
{/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */}
<span tabIndex="0" className="usa-step-indicator__heading-text">{label}</span>
</h2>
</div>
);
};

NavigatorHeader.propTypes = {
label: PropTypes.string.isRequired,
Expand Down
19 changes: 14 additions & 5 deletions frontend/src/components/Navigator/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,16 @@ function Navigator({
return pageState;
}

const currentPageState = pageState[page.position];
const isComplete = page.isPageComplete ? page.isPageComplete(getValues()) : isValid;

const newPageState = { ...pageState };
if (isValid) {
if (isComplete) {
newPageState[page.position] = COMPLETE;
} else if (currentPageState === COMPLETE) {
newPageState[page.position] = IN_PROGRESS;
} else {
newPageState[page.position] = isDirty ? IN_PROGRESS : pageState[page.position];
newPageState[page.position] = isDirty ? IN_PROGRESS : currentPageState;
}
return newPageState;
};
Expand All @@ -99,9 +104,10 @@ function Navigator({
};

const onUpdatePage = async (index) => {
const newIndex = index === page.position ? null : index;
await onSaveForm();
updatePage(newIndex);
if (index !== page.position) {
updatePage(index);
}
};

const onContinue = () => {
Expand Down Expand Up @@ -137,7 +143,9 @@ function Navigator({
const state = p.review ? formData.status : stateOfPage;
return {
label: p.label,
onNavigation: () => onUpdatePage(p.position),
onNavigation: () => {
onUpdatePage(p.position);
},
state,
current,
review: p.review,
Expand Down Expand Up @@ -175,6 +183,7 @@ function Navigator({
&& (
<Container skipTopPadding>
<NavigatorHeader
key={page.label}
label={page.label}
/>
{hasErrors
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import fetchMock from 'fetch-mock';
import React from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import join from 'url-join';
import { Router } from 'react-router-dom';
import { createMemoryHistory } from 'history';

import goalsObjectives from '../goalsObjectives';

Expand Down Expand Up @@ -40,6 +42,21 @@ const renderGoals = (grantIds, activityRecipientType, initialData, goals = []) =
);
};

// eslint-disable-next-line react/prop-types
const RenderReview = ({ goals }) => {
const history = createMemoryHistory();
const hookForm = useForm({
defaultValues: { goals },
});
return (
<Router history={history}>
<FormProvider {...hookForm}>
{goalsObjectives.reviewSection()}
</FormProvider>
</Router>
);
};

describe('goals objectives', () => {
afterEach(() => fetchMock.restore());
describe('when activity recipient type is "grantee"', () => {
Expand All @@ -63,4 +80,25 @@ describe('goals objectives', () => {
expect(screen.queryByText('Goals and objectives')).toBeNull();
});
});

describe('review page', () => {
it('displays goals with no objectives', async () => {
render(<RenderReview goals={[{ id: 1, name: 'goal' }]} />);
const goal = await screen.findByText('goal');
expect(goal).toBeVisible();
});

it('displays goals with objectives', async () => {
render(<RenderReview goals={[{
id: 1,
name: 'goal',
objectives: [{
id: 1, title: 'title', ttaProvided: 'ttaProvided', status: 'Not Started',
}],
}]}
/>);
const objective = await screen.findByText('title');
expect(objective).toBeVisible();
});
});
});
5 changes: 1 addition & 4 deletions frontend/src/pages/ActivityReport/Pages/components/Goal.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,5 @@

.smart-hub--goal-content {
margin-left: 1rem;
}

.usa-form .smart-hub--button {
margin-top: 0;
width: 100%;
}

0 comments on commit 84f3d0e

Please sign in to comment.