Skip to content

Commit

Permalink
Merge pull request #151 from adhocteam/js-225-author-resubmits-report
Browse files Browse the repository at this point in the history
Authors can resubmit a report for approval
  • Loading branch information
jasalisbury committed Feb 12, 2021
2 parents 70644cc + 33863df commit 79a4808
Show file tree
Hide file tree
Showing 33 changed files with 681 additions and 109 deletions.
8 changes: 7 additions & 1 deletion docs/openapi/index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ components:
description: Topics covered during the TTA
items:
type: string
approvingManager:
$ref: '#/components/schemas/user'
pageState:
type: object
enum: ['Not Started', 'In progress', 'Completed']
Expand All @@ -100,7 +102,11 @@ components:
type: string
status:
type: string
enum: ['draft', 'submitted']
enum:
- draft
- submitted
- approved
- needs_action
description: The current state of the report
ttaType:
type: array
Expand Down
8 changes: 4 additions & 4 deletions docs/openapi/paths/activity-reports/review.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ put:
type: string
description: The status of the report after review
enum:
- Approved
- Needs Action
- approved
- needs_action
managerNotes:
type: string
description: Any notes the manager needs to relay to the author/collaborators of the report
Expand All @@ -40,7 +40,7 @@ put:
status:
type: string
enum:
- Approved
- Needs Action
- approved
- needs_action
managerNotes:
type: string
12 changes: 12 additions & 0 deletions frontend/src/Constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,15 @@ export const REGIONS = [
];

export const DECIMAL_BASE = 10;

export const managerReportStatuses = [
'needs_action',
'approved',
];

export const REPORT_STATUSES = {
DRAFT: 'draft',
SUBMITTED: 'submitted',
NEEDS_ACTION: 'needs_action',
APPROVED: 'approved',
};
7 changes: 4 additions & 3 deletions frontend/src/components/Navigator/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@ describe('Navigator', () => {
const renderNavigator = (currentPage = 'first', onSubmit = () => {}, onSave = () => {}) => {
render(
<Navigator
reportId={1}
submitted={false}
initialData={initialData}
status="draft"
formData={initialData}
updateFormData={() => {}}
onReview={() => {}}
approvingManager={false}
defaultValues={{ first: '', second: '' }}
Expand All @@ -80,7 +81,7 @@ describe('Navigator', () => {
const firstInput = screen.getByTestId('first');
userEvent.click(firstInput);
const first = await screen.findByRole('button', { name: 'first page' });
await waitFor(() => expect(within(first).getByText('In progress')).toBeVisible());
await waitFor(() => expect(within(first).getByText('In Progress')).toBeVisible());
});

it('onContinue calls onSave with correct page position', async () => {
Expand Down
14 changes: 8 additions & 6 deletions frontend/src/components/Navigator/components/SideNav.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
import { startCase } from 'lodash';
import Sticky from 'react-stickynode';
import { Button, Tag, Alert } from '@trussworks/react-uswds';
import { useMediaQuery } from 'react-responsive';
import moment from 'moment';

import Container from '../../Container';
import './SideNav.css';
import { REPORT_STATUSES } from '../../../Constants';
import {
NOT_STARTED, IN_PROGRESS, COMPLETE, SUBMITTED, APPROVED, NEEDS_ACTION,
NOT_STARTED, IN_PROGRESS, COMPLETE,
} from '../constants';

const tagClass = (state) => {
Expand All @@ -24,11 +26,11 @@ const tagClass = (state) => {
return 'smart-hub--tag-in-progress';
case COMPLETE:
return 'smart-hub--tag-complete';
case SUBMITTED:
case REPORT_STATUSES.SUBMITTED:
return 'smart-hub--tag-submitted';
case APPROVED:
case REPORT_STATUSES.APPROVED:
return 'smart-hub--tag-submitted';
case NEEDS_ACTION:
case REPORT_STATUSES.NEEDS_ACTION:
return 'smart-hub--tag-needs-action';
default:
return '';
Expand All @@ -50,10 +52,10 @@ function SideNav({
>
<span className="margin-left-2">{page.label}</span>
<span className="margin-left-auto margin-right-2">
{page.state !== 'draft'
{page.state !== REPORT_STATUSES.DRAFT
&& (
<Tag className={`smart-hub--tag ${tagClass(page.state)}`}>
{page.state}
{startCase(page.state)}
</Tag>
)}
</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import {

import SideNav from '../SideNav';
import {
NOT_STARTED, IN_PROGRESS, COMPLETE, SUBMITTED,
NOT_STARTED, IN_PROGRESS, COMPLETE,
} from '../../constants';

import { REPORT_STATUSES } from '../../../../Constants';

describe('SideNav', () => {
const renderNav = (state, onNavigation = () => {}, current = false) => {
const pages = [
Expand Down Expand Up @@ -39,14 +41,14 @@ describe('SideNav', () => {
describe('displays the correct status', () => {
it('not started', () => {
renderNav(NOT_STARTED);
const notStarted = screen.getByText('Not started');
const notStarted = screen.getByText('Not Started');
expect(notStarted).toHaveClass('smart-hub--tag-not-started');
expect(notStarted).toBeVisible();
});

it('in progress', () => {
renderNav(IN_PROGRESS);
const inProgress = screen.getByText('In progress');
const inProgress = screen.getByText('In Progress');
expect(inProgress).toHaveClass('smart-hub--tag-in-progress');
expect(inProgress).toBeVisible();
});
Expand All @@ -59,7 +61,7 @@ describe('SideNav', () => {
});

it('submitted', () => {
renderNav(SUBMITTED);
renderNav(REPORT_STATUSES.SUBMITTED);
const submitted = screen.getByText('Submitted');
expect(submitted).toHaveClass('smart-hub--tag-submitted');
expect(submitted).toBeVisible();
Expand All @@ -69,13 +71,13 @@ describe('SideNav', () => {
it('clicking a nav item calls onNavigation', () => {
const onNav = jest.fn();
renderNav(NOT_STARTED, onNav);
const notStarted = screen.getByText('Not started');
const notStarted = screen.getByText('Not Started');
userEvent.click(notStarted);
expect(onNav).toHaveBeenCalled();
});

it('the currently selected page has the current class', () => {
renderNav(SUBMITTED, () => {}, true);
renderNav(REPORT_STATUSES.SUBMITTED, () => {}, true);
const submitted = screen.getByRole('button', { name: 'test' });
expect(submitted).toHaveClass('smart-hub--navigator-link-active');
});
Expand Down
3 changes: 0 additions & 3 deletions frontend/src/components/Navigator/constants.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
export const NOT_STARTED = 'Not started';
export const IN_PROGRESS = 'In progress';
export const COMPLETE = 'Complete';
export const SUBMITTED = 'Submitted';
export const APPROVED = 'Approved';
export const NEEDS_ACTION = 'Needs Action';
16 changes: 8 additions & 8 deletions frontend/src/components/Navigator/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import SideNav from './components/SideNav';
import NavigatorHeader from './components/NavigatorHeader';

function Navigator({
initialData,
formData,
updateFormData,
initialLastUpdated,
pages,
onFormSubmit,
Expand All @@ -32,10 +33,8 @@ function Navigator({
onSave,
autoSaveInterval,
approvingManager,
status,
reportId,
}) {
const [formData, updateFormData] = useState(initialData);
const [errorMessage, updateErrorMessage] = useState();
const [lastSaveTime, updateLastSaveTime] = useState(initialLastUpdated);
const { pageState } = formData;
Expand Down Expand Up @@ -105,7 +104,7 @@ function Navigator({
const navigatorPages = pages.map((p) => {
const current = p.position === page.position;
const stateOfPage = current ? IN_PROGRESS : pageState[p.position];
const state = p.review ? status : stateOfPage;
const state = p.review ? formData.status : stateOfPage;
return {
label: p.label,
onNavigation: () => onSaveForm(false, p.position),
Expand Down Expand Up @@ -136,7 +135,6 @@ function Navigator({
additionalData,
onReview,
approvingManager,
reportId,
)}
{!page.review
&& (
Expand All @@ -161,11 +159,14 @@ function Navigator({
}

Navigator.propTypes = {
initialData: PropTypes.shape({}),
formData: PropTypes.shape({
status: PropTypes.string,
pageState: PropTypes.shape({}),
}).isRequired,
updateFormData: PropTypes.func.isRequired,
initialLastUpdated: PropTypes.instanceOf(moment),
onFormSubmit: PropTypes.func.isRequired,
onSave: PropTypes.func.isRequired,
status: PropTypes.string.isRequired,
onReview: PropTypes.func.isRequired,
approvingManager: PropTypes.bool.isRequired,
pages: PropTypes.arrayOf(
Expand All @@ -184,7 +185,6 @@ Navigator.propTypes = {
};

Navigator.defaultProps = {
initialData: {},
additionalData: {},
autoSaveInterval: 1000 * 60 * 2,
initialLastUpdated: null,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react';
import PropTypes from 'prop-types';

const Approved = ({
additionalNotes,
managerNotes,
}) => (
<>
<h2>Report approved</h2>
<div className="smart-hub--creator-notes">
<p>
<span className="text-bold">Creator notes</span>
<br />
<br />
{ additionalNotes || 'No creator notes' }
</p>
</div>
<div className="smart-hub--creator-notes margin-top-2">
<p>
<span className="text-bold">Manager notes</span>
<br />
<br />
{ managerNotes || 'No manager notes' }
</p>
</div>
</>
);

Approved.propTypes = {
additionalNotes: PropTypes.string,
managerNotes: PropTypes.string,
};

Approved.defaultProps = {
additionalNotes: '',
managerNotes: '',
};

export default Approved;
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import React from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';
import {
Dropdown, Form, Label, Fieldset, Textarea, Alert, Button,
} from '@trussworks/react-uswds';

const possibleStatus = [
'Approved',
'Needs Action',
];
import { managerReportStatuses } from '../../../../../Constants';

const ApproverReviewPage = ({
const Review = ({
reviewed,
additionalNotes,
register,
Expand All @@ -27,12 +25,12 @@ const ApproverReviewPage = ({
</Alert>
)}
<h2>Review and approve report</h2>
<div className="smart-hub--creator-notes">
<div className="smart-hub--creator-notes" aria-label="additionalNotes">
<p>
<span className="text-bold">Creator notes</span>
<br />
<br />
{ additionalNotes || 'No creator notes' }
{ additionalNotes || 'No creator notes'}
</p>
</div>
<Form className="smart-hub--form-large" onSubmit={handleSubmit(onFormReview)}>
Expand All @@ -43,16 +41,16 @@ const ApproverReviewPage = ({
<Label htmlFor="status">Choose report status</Label>
<Dropdown id="status" name="status" defaultValue="" inputRef={register({ required: true })}>
<option name="default" value="" disabled hidden>- Select -</option>
{possibleStatus.map((status) => (
<option key={status} value={status}>{status}</option>
{managerReportStatuses.map((status) => (
<option key={status} value={status}>{_.startCase(status)}</option>
))}
</Dropdown>
<Button type="submit" disabled={!valid}>Submit</Button>
</Form>
</>
);

ApproverReviewPage.propTypes = {
Review.propTypes = {
reviewed: PropTypes.bool.isRequired,
additionalNotes: PropTypes.string.isRequired,
register: PropTypes.func.isRequired,
Expand All @@ -61,4 +59,4 @@ ApproverReviewPage.propTypes = {
onFormReview: PropTypes.func.isRequired,
};

export default ApproverReviewPage;
export default Review;
Loading

0 comments on commit 79a4808

Please sign in to comment.