Skip to content

Commit

Permalink
Merge pull request #616 from HHS/TTAHUB-430/add-approved-and-created-…
Browse files Browse the repository at this point in the history
…date-to-ar

[TTAHUB-430] add approved and created date to activity report tables
  • Loading branch information
thewatermethod authored Nov 12, 2021
2 parents 182f83d + 9ba70c6 commit f170803
Show file tree
Hide file tree
Showing 25 changed files with 171 additions and 95 deletions.
1 change: 1 addition & 0 deletions frontend/src/Constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,5 @@ export const ESCAPE_KEY_CODE = 27;
export const ESCAPE_KEY_CODES = ['Escape', 'Esc'];

export const DATE_FMT = 'YYYY/MM/DD';
export const DATE_DISPLAY_FORMAT = 'MM/DD/YYYY';
export const EARLIEST_INC_FILTER_DATE = moment('2020-08-31');
35 changes: 20 additions & 15 deletions frontend/src/components/ActivityReportsTable/ReportRow.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from 'react';
import PropTypes from 'prop-types';
import {
Tag, Checkbox,
} from '@trussworks/react-uswds';
import { Checkbox } from '@trussworks/react-uswds';
import { Link, useHistory } from 'react-router-dom';

import moment from 'moment';
import ContextMenu from '../ContextMenu';
import { getReportsDownloadURL } from '../../fetchers/helpers';
import TooltipWithCollection from '../TooltipWithCollection';
import Tooltip from '../Tooltip';
import { DATE_DISPLAY_FORMAT } from '../../Constants';

function ReportRow({
report, openMenuUp, handleReportSelect, isChecked,
Expand All @@ -22,6 +22,8 @@ function ReportRow({
collaborators,
lastSaved,
calculatedStatus,
approvedAt,
createdAt,
legacyId,
} = report;

Expand Down Expand Up @@ -85,24 +87,21 @@ function ReportRow({
</td>
<td>{startDate}</td>
<td>
<span className="smart-hub--ellipsis" title={authorName}>
{authorName}
</span>
<Tooltip
displayText={authorName}
tooltipText={authorName}
buttonLabel="click to reveal author name"
/>
</td>
<td>{moment(createdAt).format(DATE_DISPLAY_FORMAT)}</td>
<td>
<TooltipWithCollection collection={topics} collectionTitle={`topics for ${displayId}`} />
</td>
<td>
<TooltipWithCollection collection={collaboratorNames} collectionTitle={`collaborators for ${displayId}`} />
</td>
<td>{lastSaved}</td>
<td>
<Tag
className={`smart-hub--table-tag-status smart-hub--status-${calculatedStatus}`}
>
{calculatedStatus === 'needs_action' ? 'Needs action' : calculatedStatus}
</Tag>
</td>
<td>{approvedAt && moment(approvedAt).format(DATE_DISPLAY_FORMAT)}</td>
<td>
<ContextMenu label={contextMenuLabel} menuItems={menuItems} up={openMenuUp} />
</td>
Expand All @@ -122,14 +121,20 @@ export const reportPropTypes = {
}),
}),
})).isRequired,
approvedAt: PropTypes.string,
createdAt: PropTypes.string,
startDate: PropTypes.string.isRequired,
author: PropTypes.shape({
fullName: PropTypes.string,
homeRegionId: PropTypes.number,
name: PropTypes.string,
}).isRequired,
topics: PropTypes.arrayOf(PropTypes.string).isRequired,
collaborators: PropTypes.arrayOf(PropTypes.string).isRequired,
collaborators: PropTypes.arrayOf(
PropTypes.shape({
fullName: PropTypes.string,
}),
).isRequired,
lastSaved: PropTypes.string.isRequired,
calculatedStatus: PropTypes.string.isRequired,
legacyId: PropTypes.string,
Expand Down
41 changes: 9 additions & 32 deletions frontend/src/components/ActivityReportsTable/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -317,28 +317,6 @@ describe('Table sorting', () => {
await screen.findByText('Activity Reports');
});

it('clicking status column header will sort by status', async () => {
const statusColumnHeader = await screen.findByText(/status/i);
fetchMock.reset();
fetchMock.get(
'/api/activity-reports?sortBy=calculatedStatus&sortDir=asc&offset=0&limit=10&region.in[]=1',
{ count: 2, rows: activityReportsSorted },
);

fireEvent.click(statusColumnHeader);
await waitFor(() => expect(screen.getAllByRole('cell')[7]).toHaveTextContent(/needs action/i));
await waitFor(() => expect(screen.getAllByRole('cell')[16]).toHaveTextContent(/draft/i));

fetchMock.get(
'/api/activity-reports?sortBy=calculatedStatus&sortDir=desc&offset=0&limit=10&region.in[]=1',
{ count: 2, rows: activityReports },
);

fireEvent.click(statusColumnHeader);
await waitFor(() => expect(screen.getAllByRole('cell')[7]).toHaveTextContent(/draft/i));
await waitFor(() => expect(screen.getAllByRole('cell')[16]).toHaveTextContent(/needs action/i));
});

it('clicking Last saved column header will sort by updatedAt', async () => {
const columnHeader = await screen.findByText(/last saved/i);

Expand All @@ -348,8 +326,8 @@ describe('Table sorting', () => {
);

fireEvent.click(columnHeader);
await waitFor(() => expect(screen.getAllByRole('cell')[6]).toHaveTextContent(/02\/04\/2021/i));
await waitFor(() => expect(screen.getAllByRole('cell')[15]).toHaveTextContent(/02\/05\/2021/i));
await waitFor(() => expect(screen.getAllByRole('cell')[7]).toHaveTextContent(/02\/04\/2021/i));
await waitFor(() => expect(screen.getAllByRole('cell')[17]).toHaveTextContent(/02\/05\/2021/i));
});

it('clicking Collaborators column header will sort by collaborators', async () => {
Expand All @@ -361,8 +339,8 @@ describe('Table sorting', () => {
);

await act(async () => fireEvent.click(columnHeader));
await waitFor(() => expect(screen.getAllByRole('cell')[5]).toHaveTextContent('Cucumber User, GS Hermione Granger, SS'));
await waitFor(() => expect(screen.getAllByRole('cell')[14]).toHaveTextContent('Orange, GS Hermione Granger, SS'));
await waitFor(() => expect(screen.getAllByRole('cell')[6]).toHaveTextContent('Cucumber User, GS Hermione Granger, SS'));
await waitFor(() => expect(screen.getAllByRole('cell')[16]).toHaveTextContent('Orange, GS Hermione Granger, SS'));
});

it('clicking Topics column header will sort by topics', async () => {
Expand All @@ -374,8 +352,7 @@ describe('Table sorting', () => {
);

await act(async () => fireEvent.click(columnHeader));
await waitFor(() => expect(screen.getAllByRole('cell')[4]).toHaveTextContent(''));
await waitFor(() => expect(screen.getAllByRole('cell')[13]).toHaveTextContent(/Behavioral \/ Mental Health CLASS: Instructional Support click to visually reveal the topics for R14-AR-1$/i));
await waitFor(() => expect(screen.getAllByRole('cell')[15]).toHaveTextContent(/Behavioral \/ Mental Health CLASS: Instructional Support click to visually reveal the topics for R14-AR-1$/i));
});

it('clicking Creator column header will sort by author', async () => {
Expand All @@ -388,7 +365,7 @@ describe('Table sorting', () => {

fireEvent.click(columnHeader);
await waitFor(() => expect(screen.getAllByRole('cell')[3]).toHaveTextContent('Kiwi, GS'));
await waitFor(() => expect(screen.getAllByRole('cell')[12]).toHaveTextContent('Kiwi, TTAC'));
await waitFor(() => expect(screen.getAllByRole('cell')[13]).toHaveTextContent('Kiwi, TTAC'));
});

it('clicking Start date column header will sort by start date', async () => {
Expand All @@ -401,7 +378,7 @@ describe('Table sorting', () => {

fireEvent.click(columnHeader);
await waitFor(() => expect(screen.getAllByRole('cell')[2]).toHaveTextContent('02/01/2021'));
await waitFor(() => expect(screen.getAllByRole('cell')[11]).toHaveTextContent('02/08/2021'));
await waitFor(() => expect(screen.getAllByRole('cell')[12]).toHaveTextContent('02/08/2021'));
});

it('clicking Grantee column header will sort by grantee', async () => {
Expand Down Expand Up @@ -462,8 +439,8 @@ describe('Table sorting', () => {
);

fireEvent.click(pageOne);
await waitFor(() => expect(screen.getAllByRole('cell')[6]).toHaveTextContent(/02\/05\/2021/i));
await waitFor(() => expect(screen.getAllByRole('cell')[15]).toHaveTextContent(/02\/04\/2021/i));
await waitFor(() => expect(screen.getAllByRole('cell')[7]).toHaveTextContent(/02\/05\/2021/i));
await waitFor(() => expect(screen.getAllByRole('cell')[17]).toHaveTextContent(/02\/04\/2021/i));
});

it('clicking on the second page updates to, from and total', async () => {
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/components/ActivityReportsTable/index.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.usa-table-container--scrollable {
.usa-table-container--scrollable,
.usa-checkbox__label {
margin-top: 0px;
}

3 changes: 2 additions & 1 deletion frontend/src/components/ActivityReportsTable/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,10 +299,11 @@ function ActivityReportsTable({
{renderColumnHeader('Grantee', 'activityRecipients')}
{renderColumnHeader('Start date', 'startDate')}
{renderColumnHeader('Creator', 'author')}
{renderColumnHeader('Created date', 'createdAt')}
{renderColumnHeader('Topic(s)', 'topics')}
{renderColumnHeader('Collaborator(s)', 'collaborators')}
{renderColumnHeader('Last saved', 'updatedAt')}
{renderColumnHeader('Status', 'calculatedStatus')}
{renderColumnHeader('Approved date', 'approvedAt')}
<th scope="col" aria-label="context menu" />
</tr>
</thead>
Expand Down
16 changes: 7 additions & 9 deletions frontend/src/components/DatePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,9 @@ import { SingleDatePicker } from 'react-dates';
import { OPEN_UP, OPEN_DOWN } from 'react-dates/constants';
import { Controller } from 'react-hook-form/dist/index.ie11';
import moment from 'moment';

import { DATE_DISPLAY_FORMAT } from '../Constants';
import './DatePicker.css';

const dateFmt = 'MM/DD/YYYY';

const DateInput = ({
control, minDate, name, disabled, maxDate, openUp, required, ariaName, maxDateInclusive,
}) => {
Expand All @@ -29,17 +27,17 @@ const DateInput = ({
const openDirection = openUp ? OPEN_UP : OPEN_DOWN;

const isOutsideRange = (date) => {
const isBefore = minDate && date.isBefore(moment(minDate, dateFmt));
const isBefore = minDate && date.isBefore(moment(minDate, DATE_DISPLAY_FORMAT));

// If max date is inclusive (maxDateInclusive == true)
// allow the user to pick a start date that is the same as the maxDate
// otherwise, only the day before is allowed
let isAfter = false;
if (maxDateInclusive) {
const newDate = moment(maxDate, dateFmt).add(1, 'days');
isAfter = maxDate && date.isAfter(newDate, dateFmt);
const newDate = moment(maxDate, DATE_DISPLAY_FORMAT).add(1, 'days');
isAfter = maxDate && date.isAfter(newDate, DATE_DISPLAY_FORMAT);
} else {
isAfter = maxDate && date.isAfter(moment(maxDate, dateFmt));
isAfter = maxDate && date.isAfter(moment(maxDate, DATE_DISPLAY_FORMAT));
}

return isBefore || isAfter;
Expand All @@ -52,7 +50,7 @@ const DateInput = ({
<div className="usa-hint font-body-2xs" id={hintId}>mm/dd/yyyy</div>
<Controller
render={({ onChange, value, ref }) => {
const date = value ? moment(value, dateFmt) : null;
const date = value ? moment(value, DATE_DISPLAY_FORMAT) : null;
return (
<div className="display-flex smart-hub--date-picker-input">
<SingleDatePicker
Expand All @@ -69,7 +67,7 @@ const DateInput = ({
disabled={disabled}
hideKeyboardShortcutsPanel
onDateChange={(d) => {
const newDate = d ? d.format(dateFmt) : d;
const newDate = d ? d.format(DATE_DISPLAY_FORMAT) : d;
onChange(newDate);
const input = document.getElementById(name);
if (input) input.focus();
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/Tooltip.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
display: inline-block;
overflow-x: hidden;
overflow-y: visible;
width: 173.5px;
max-width: 175px;
text-overflow: ellipsis;
vertical-align: middle;
}
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/components/TooltipWithCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ export default function TooltipWithCollection({ collection, collectionTitle }) {

if (collection.length === 1) {
return (
<span className="smarthub-ellipsis">{tooltip}</span>
<Tooltip
displayText={tooltip}
tooltipText={tooltip}
buttonLabel={`click to visually reveal the ${collectionTitle}`}
/>
);
}

Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/__tests__/TooltipWithCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ describe('TooltipWithCollection', () => {

it('renders a single span when passed a one item array', async () => {
renderTooltip(['Jimbo']);
const jimbo = screen.getByText('Jimbo');
const jimbo = screen.getAllByText('Jimbo')[1];
expect(jimbo).toBeVisible();
expect(jimbo.parentElement).toHaveClass('smarthub-ellipsis');
expect(jimbo.parentElement.parentElement).toHaveClass('smart-hub--ellipsis');
});
});
5 changes: 3 additions & 2 deletions frontend/src/pages/ApprovedActivityReport/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import ViewTable from './components/ViewTable';
import { getReport, unlockReport } from '../../fetchers/activityReports';
import { allRegionsUserHasPermissionTo, canUnlockReports } from '../../permissions';
import Modal from '../../components/Modal';
import { DATE_DISPLAY_FORMAT } from '../../Constants';

/**
*
Expand Down Expand Up @@ -194,8 +195,8 @@ export default function ApprovedActivityReport({ match, user }) {
setParticipantCount(newCount);
setReasons(formatSimpleArray(report.reason));
setProgramType(formatSimpleArray(report.programTypes));
setStartDate(moment(report.startDate, 'MM/DD/YYYY').format('MMMM D, YYYY'));
setEndDate(moment(report.endDate, 'MM/DD/YYYY').format('MMMM D, YYYY'));
setStartDate(moment(report.startDate, DATE_DISPLAY_FORMAT).format('MMMM D, YYYY'));
setEndDate(moment(report.endDate, DATE_DISPLAY_FORMAT).format('MMMM D, YYYY'));
setDuration(`${report.duration} hours`);
setMethod(formatMethod(report.ttaType, report.virtualDeliveryType));
setRequester(formatRequester(report.requester));
Expand Down
19 changes: 15 additions & 4 deletions frontend/src/pages/Landing/MyAlerts.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
Tag, Table, useModal, connectModal,
} from '@trussworks/react-uswds';
import { Link, useHistory } from 'react-router-dom';

import moment from 'moment';
import DeleteReportModal from '../../components/DeleteReportModal';
import Container from '../../components/Container';
import ContextMenu from '../../components/ContextMenu';
Expand Down Expand Up @@ -44,6 +44,7 @@ function ReportsRow({ reports, removeAlert, message }) {
calculatedStatus,
pendingApprovals,
approvers,
createdAt,
} = report;

const justSubmitted = message && message.reportId === id;
Expand Down Expand Up @@ -92,9 +93,18 @@ function ReportsRow({ reports, removeAlert, message }) {
</td>
<td>{startDate}</td>
<td>
<span className="smart-hub--ellipsis" title={author ? author.fullName : ''}>
{author ? author.fullName : ''}
</span>
{ author
? (
<Tooltip
displayText={author.fullName}
tooltipText={author.fullName}
buttonLabel={`click to reveal: ${author.fullName} `}
screenReadDisplayText={false}
/>
) : <span /> }
</td>
<td>
{moment(createdAt).format('MM/DD/YYYY')}
</td>
<td>
<TooltipWithCollection collection={collaboratorNames} collectionTitle={`collaborators for ${displayId}`} />
Expand Down Expand Up @@ -311,6 +321,7 @@ function MyAlerts(props) {
{renderColumnHeader('Grantee', 'activityRecipients')}
{renderColumnHeader('Start date', 'startDate')}
{renderColumnHeader('Creator', 'author')}
{renderColumnHeader('Created date', 'createdAt')}
{renderColumnHeader('Collaborator(s)', 'collaborators')}
{renderColumnHeader('Approvers(s)', 'approvals', true)}
{renderColumnHeader('Status', 'calculatedStatus')}
Expand Down
Loading

0 comments on commit f170803

Please sign in to comment.