Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duration fix, Filter grantees to region and Small screen fixes #331

Merged
merged 33 commits into from
Mar 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
be553c4
Allow to filter grants/grantees based on region
Feb 18, 2021
4177286
Refactor to query for an exact region instead of multiple regions
Feb 19, 2021
20d1915
eslint fixes
Feb 19, 2021
5d5f6de
Merge branch 'main' into 154-pre-filter-grants-and-grantess
Feb 22, 2021
f877166
Add way of finding out region to use when no region is passed
Feb 22, 2021
18e53de
Fix variable name typo
Feb 22, 2021
cf5a2ac
Merge branch 'main' into 154-pre-filter-grants-and-grantess
gopar Feb 22, 2021
155d570
Stack label/values for reviewItems, and adjust font size/weight on la…
dcloud Feb 23, 2021
0e80f56
Adjust layout of Navigator, Navigator's SideNav for <1024 width screens
dcloud Feb 23, 2021
8000dfd
Merge branch 'main' into dcloud/ar-review-small-screen-adjustments
dcloud Feb 24, 2021
8b950e8
Duration supports half hours
jasalisbury Feb 24, 2021
6849479
Fix broken paths in openapi schema
dcloud Feb 25, 2021
e5227a4
Merge branch 'main' into dcloud/fix-api-docs-typos
dcloud Feb 25, 2021
027e17e
Merge branch 'main' into dcloud/ar-review-small-screen-adjustments
dcloud Feb 25, 2021
d059025
Merge branch 'main' into dcloud/fix-api-docs-typos
dcloud Feb 25, 2021
dde12f8
Merge branch 'main' into 154-pre-filter-grants-and-grantess
Feb 25, 2021
673bcbc
Updat test
Feb 25, 2021
a476d3f
Update Mock in test
Feb 25, 2021
f18d01e
Add missing tests
Feb 25, 2021
2d2e3d7
Merge pull request #197 from adhocteam/dcloud/fix-api-docs-typos
dcloud Feb 26, 2021
bfa1b12
Merge branch 'main' into dcloud/ar-review-small-screen-adjustments
dcloud Feb 26, 2021
fd3d7f2
Merge pull request #193 from adhocteam/dcloud/ar-review-small-screen-…
dcloud Feb 26, 2021
46d47e1
Add review from feedback
Feb 26, 2021
6e189dd
Lint fix
Feb 26, 2021
3fde7c5
Updates from review
Feb 26, 2021
d5feb84
Merge branch 'main' into 154-pre-filter-grants-and-grantess
Feb 26, 2021
2d7201e
Remove unused file
Feb 26, 2021
f5f0cc8
Merge branch 'main' into js-307-duration-supports-half-hours
jasalisbury Feb 26, 2021
7282fd5
Make Region non-required
Mar 1, 2021
f053341
Switch to deep compare useEffect
Mar 1, 2021
46864db
Merge pull request #184 from adhocteam/154-pre-filter-grants-and-gran…
gopar Mar 1, 2021
27d3ced
Merge branch 'main' into js-307-duration-supports-half-hours
gopar Mar 1, 2021
11f5258
Merge pull request #194 from adhocteam/js-307-duration-supports-half-…
jasalisbury Mar 1, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/openapi/index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,10 @@ components:
type: string
specialistNextSteps:
description: List of notes/next steps that a specialists enters
$ref: '#/components/schema/nextStepNotes'
$ref: '#/components/schemas/nextStepNotes'
granteeNextSteps:
description: List of notes/next steps that are assigned to the grantee
$ref: '#/components/schema/nextStepNotes'
$ref: '#/components/schemas/nextStepNotes'
shortActivityReport:
type: object
description: >
Expand Down
99 changes: 97 additions & 2 deletions frontend/src/__tests__/permissions.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import isAdmin, { hasReadWrite } from '../permissions';
import { SCOPE_IDS } from '../Constants';
import isAdmin, { hasReadWrite, allRegionsUserHasPermissionTo, getRegionWithReadWrite } from '../permissions';

describe('permissions', () => {
describe('isAdmin', () => {
it('returns true if the user is an admin', () => {
const user = {
permissions: [
{
scopeId: 2,
scopeId: SCOPE_IDS.ADMIN,
},
],
};
Expand All @@ -21,6 +22,51 @@ describe('permissions', () => {
});
});

describe('allRegionsUserHasPermissionTo', () => {
it('returns an array with all the correct regions', () => {
const user = {
permissions: [
{
scopeId: SCOPE_IDS.ADMIN,
regionId: 14,
},
{
scopeId: SCOPE_IDS.SITE_ACCESS,
regionId: 14,
},
{
scopeId: SCOPE_IDS.SITE_ACCESS,
regionId: 1,
},
{
scopeId: SCOPE_IDS.APPROVE_ACTIVITY_REPORTS,
regionId: 1,
},
{
scopeId: SCOPE_IDS.READ_WRITE_ACTIVITY_REPORTS,
regionId: 3,
},
{
scopeId: SCOPE_IDS.READ_ACTIVITY_REPORTS,
regionId: 4,
},
{
scopeId: SCOPE_IDS.APPROVE_ACTIVITY_REPORTS,
regionId: 4,
},
],
};
const regions = allRegionsUserHasPermissionTo(user);
expect(regions).toEqual(expect.arrayContaining([14, 3, 4]));
});

it('returns empty array when user has no permissions', () => {
const user = {};
const regions = allRegionsUserHasPermissionTo(user);
expect(regions).toEqual([]);
});
});

describe('hasReadWrite', () => {
it('returns true if the user has read/write to a region', () => {
const user = {
Expand All @@ -46,4 +92,53 @@ describe('permissions', () => {
expect(hasReadWrite(user)).toBeFalsy();
});
});

describe('getRegionWithReadWrite', () => {
it('returns region where user has permission', () => {
const user = {
permissions: [
{
regionId: 4,
scopeId: SCOPE_IDS.READ_ACTIVITY_REPORTS,
},
{
regionId: 1,
scopeId: SCOPE_IDS.ADMIN,
},
{
regionId: 2,
scopeId: SCOPE_IDS.READ_WRITE_ACTIVITY_REPORTS,
},
],
};

const region = getRegionWithReadWrite(user);
expect(region).toBe(2);
});

it('returns no region', () => {
const user = {
permissions: [
{
regionId: 4,
scopeId: SCOPE_IDS.READ_ACTIVITY_REPORTS,
},
{
regionId: 1,
scopeId: SCOPE_IDS.ADMIN,
},
],
};

const region = getRegionWithReadWrite(user);
expect(region).toBe(-1);
});

it('returns region because user object has no permissions', () => {
const user = {};

const region = getRegionWithReadWrite(user);
expect(region).toBe(-1);
});
});
});
2 changes: 1 addition & 1 deletion frontend/src/components/Navigator/components/SideNav.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const tagClass = (state) => {
function SideNav({
pages, skipTo, skipToMessage, lastSaveTime, errorMessage,
}) {
const isMobile = useMediaQuery({ maxWidth: 640 });
const isMobile = useMediaQuery({ maxWidth: 1023 });
const navItems = () => pages.map((page) => (
<li key={page.label} className="smart-hub--navigator-item">
<Button
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/Navigator/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ function Navigator({

return (
<Grid row gap>
<Grid className="smart-hub-sidenav-wrapper no-print" col={12} tablet={{ col: 6 }} desktop={{ col: 4 }}>
<Grid className="smart-hub-sidenav-wrapper no-print" col={12} desktop={{ col: 4 }}>
<SideNav
skipTo="navigator-form"
skipToMessage="Skip to report content"
Expand All @@ -139,7 +139,7 @@ function Navigator({
errorMessage={errorMessage}
/>
</Grid>
<Grid className="smart-hub-navigator-wrapper" col={12} tablet={{ col: 6 }} desktop={{ col: 8 }}>
<Grid className="smart-hub-navigator-wrapper" col={12} desktop={{ col: 8 }}>
<FormProvider {...hookForm}>
<div id="navigator-form">
{page.review
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/fetchers/activityReports.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ export const getReportAlerts = async () => {
return reports.json();
};

export const getRecipients = async () => {
const recipients = await get(join(activityReportUrl, 'activity-recipients'));
export const getRecipients = async (region) => {
const recipients = await get(join(activityReportUrl, 'activity-recipients', `?region=${region}`));
return recipients.json();
};

Expand Down
13 changes: 0 additions & 13 deletions frontend/src/hooks.js

This file was deleted.

30 changes: 15 additions & 15 deletions frontend/src/pages/ActivityReport/Pages/Review/reviewItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
of the activity report, they contain items.
3. Items: these are the individual form fields for the activity report
*/
import { Grid } from '@trussworks/react-uswds';
import PropTypes from 'prop-types';
import { HashLink } from 'react-router-hash-link';
import _ from 'lodash';
Expand Down Expand Up @@ -41,26 +40,27 @@ const Section = ({
const isEmpty = !items.some(({ value }) => value && value.length);
const classes = [
'smart-hub-review-section',
'margin-top-2 desktop:margin-top-0',
isEmpty ? 'smart-hub-review-section--empty no-print' : '',
'margin-bottom-3',
].filter((x) => x).join(' ');

return (
<div className={classes}>
<Grid row className="border-bottom padding-bottom-1 margin-bottom-105">
<Grid col={6}>
<div className="grid-row border-bottom padding-bottom-1 margin-bottom-105">
<div className="grid-col-12 desktop:grid-col-6">
<b className="margin-y-1">{title}</b>
</Grid>
<Grid col={6} className="flex-align-end display-flex flex-column flex-justify-center">
</div>
<div className="grid-col-12 desktop:grid-col-6 display-flex flex-align-end flex-column flex-justify-center">
<HashLink
aria-label={`Edit form section "${title}"`}
to={`${basePath}#${anchor}`}
className="smart-hub-edit-link pull-right no-print"
>
Edit
</HashLink>
</Grid>
</Grid>
</div>
</div>
{items.map(({ label, value, path }) => (
<Item key={label} label={label} value={value} path={path} />
))}
Expand All @@ -85,18 +85,18 @@ const Item = ({ label, value, path }) => {
const classes = ['margin-top-1', emptySelector].filter((x) => x !== '').join(' ');

return (
<Grid row className={classes}>
<Grid col={6}>
<div className={`grid-row ${classes} margin-bottom-3 desktop:margin-bottom-0`}>
<div className="grid-col-12 desktop:grid-col-6 font-sans-2xs desktop:font-sans-sm text-bold desktop:text-normal">
{label}
</Grid>
<Grid col={6}>
</div>
<div className="grid-col-12 desktop:grid-col-6">
{values.map((v, index) => (
<Grid aria-label={`${label} ${index + 1}`} key={`${label}${v}`} col={12} className="flex-align-end display-flex flex-column flex-justify-center">
<div aria-label={`${label} ${index + 1}`} key={`${label}${v}`} col={12} className="desktop:flex-align-end display-flex flex-column flex-justify-center">
{Number.isNaN(v) ? '' : v}
</Grid>
</div>
))}
</Grid>
</Grid>
</div>
</div>
);
};

Expand Down
1 change: 1 addition & 0 deletions frontend/src/pages/ActivityReport/Pages/activitySummary.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ const ActivitySummary = ({
name="duration"
type="number"
min={0}
step={0.5}
inputRef={
register({
required: 'Please enter the duration of the activity',
Expand Down
18 changes: 17 additions & 1 deletion frontend/src/pages/ActivityReport/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@ import userEvent from '@testing-library/user-event';

import { withText } from '../../../testHelpers';
import ActivityReport from '../index';
// import { getRegionWithReadWrite } from '../../../permissions';

jest.mock('../../../permissions', () => ({
getRegionWithReadWrite: jest.fn(() => 1),
}));

const formData = () => ({
regionId: 1,
deliveryMethod: 'in-person',
ttaType: ['training'],
duration: '1',
Expand Down Expand Up @@ -62,7 +68,7 @@ describe('ActivityReport', () => {
afterEach(() => fetchMock.restore());

beforeEach(() => {
fetchMock.get('/api/activity-reports/activity-recipients', recipients);
fetchMock.get('/api/activity-reports/activity-recipients?region=1', recipients);
fetchMock.get('/api/users/collaborators?region=1', []);
fetchMock.get('/api/activity-reports/approvers?region=1', []);
});
Expand All @@ -74,9 +80,18 @@ describe('ActivityReport', () => {
expect(alert).toHaveTextContent('Unable to load activity report');
});

it('handles when region is invalid', async () => {
fetchMock.get('/api/activity-reports/-1', () => { throw new Error('unable to download report'); });

renderActivityReport('-1');
const alert = await screen.findByTestId('alert');
expect(alert).toHaveTextContent('Unable to load activity report');
});

describe('last saved time', () => {
it('is shown if history.state.showLastUpdatedTime is true', async () => {
const data = formData();

fetchMock.get('/api/activity-reports/1', data);
renderActivityReport('1', 'activity-summary', true);
await screen.findByRole('group', { name: 'Who was the activity for?' }, { timeout: 4000 });
Expand All @@ -85,6 +100,7 @@ describe('ActivityReport', () => {

it('is not shown if history.state.showLastUpdatedTime is null', async () => {
const data = formData();

fetchMock.get('/api/activity-reports/1', data);
renderActivityReport('1', 'activity-summary');
await screen.findByRole('group', { name: 'Who was the activity for?' });
Expand Down
Loading