Skip to content

Commit

Permalink
Various frontend changes to better match design
Browse files Browse the repository at this point in the history
 * Add resource selector
 * Virtual delivery method field added
 * Fix styling (margins colors etc)
 * Copy updates
  • Loading branch information
jasalisbury committed Mar 2, 2021
1 parent 90a7211 commit 0603eb0
Show file tree
Hide file tree
Showing 15 changed files with 332 additions and 55 deletions.
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"@babel/runtime": "^7.12.1",
"@fortawesome/fontawesome-free": "^5.15.1",
"@fortawesome/fontawesome-svg-core": "^1.2.32",
"@fortawesome/free-regular-svg-icons": "^5.15.2",
"@fortawesome/free-solid-svg-icons": "^5.15.1",
"@fortawesome/react-fontawesome": "^0.1.11",
"@hookform/error-message": "^0.0.5",
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ body {
background-color: #f8f8f8;
}

.text-ink {
color: #21272D
}

.smart-hub-bg-blue-primary {
background-color: #0166ab;
}
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/FileUploader.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ function Dropzone(props) {
{...getRootProps()}
>
<input {...getInputProps()} />
<button type="button" className="usa-button">
Browse files
<button type="button" className="usa-button usa-button--outline">
Upload Resources
</button>
{errorMessage
&& (
Expand Down
51 changes: 40 additions & 11 deletions frontend/src/pages/ActivityReport/Pages/activitySummary.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const ActivitySummary = ({
const activityRecipientType = watch('activityRecipientType');
const startDate = watch('startDate');
const endDate = watch('endDate');
const isVirtual = watch('deliveryMethod') === 'virtual';
const { nonGrantees: rawNonGrantees, grants: rawGrants } = recipients;

const grants = rawGrants.map((grantee) => ({
Expand Down Expand Up @@ -88,7 +89,7 @@ const ActivitySummary = ({
</Helmet>
<Fieldset className="smart-hub--report-legend smart-hub--form-section" legend="Who was the activity for?">
<div id="activity-for" />
<div className="smart-hub--form-section">
<div className="smart-hub--form-group">
<FormItem
label="Was this activity for a grantee or non-grantee?"
name="activityRecipientType"
Expand All @@ -112,7 +113,7 @@ const ActivitySummary = ({
/>
</FormItem>
</div>
<div className="smart-hub--form-section">
<div className="smart-hub--form-group">
<FormItem
label={recipientLabel}
name="activityRecipients"
Expand All @@ -129,7 +130,7 @@ const ActivitySummary = ({
/>
</FormItem>
</div>
<div className="smart-hub--form-section">
<div className="smart-hub--form-group">
<FormItem
label="Collaborating Specialists"
name="collaborators"
Expand All @@ -148,7 +149,7 @@ const ActivitySummary = ({
</div>
{granteeSelected
&& (
<div className="smart-hub--form-section">
<div className="smart-hub--form-group">
<FormItem
label="Program type(s)"
name="programTypes"
Expand All @@ -163,7 +164,7 @@ const ActivitySummary = ({
</FormItem>
</div>
)}
<div className="smart-hub--form-section">
<div className="smart-hub--form-group">
<FormItem
label="Target Populations addressed. You may choose more than one."
name="targetPopulations"
Expand All @@ -180,7 +181,7 @@ const ActivitySummary = ({
</Fieldset>
<Fieldset className="smart-hub--report-legend smart-hub--form-section" legend="Reason for Activity">
<div id="reasons" />
<div className="smart-hub--form-section">
<div className="smart-hub--form-group">
<FormItem
label="Who requested this activity? Use &quot;Regional Office&quot; for TTA not requested by grantee."
name="requester"
Expand All @@ -204,7 +205,7 @@ const ActivitySummary = ({
/>
</FormItem>
</div>
<div className="smart-hub--form-section">
<div className="smart-hub--form-group">
<FormItem
label="Reason(s). You may choose more than one."
name="reason"
Expand Down Expand Up @@ -250,7 +251,7 @@ const ActivitySummary = ({
</Grid>
<Grid col={5}>
<FormItem
label="Duration"
label="Duration (round to the nearest half hour)"
name="duration"
>
<TextInput
Expand All @@ -274,7 +275,7 @@ const ActivitySummary = ({
</Fieldset>
<Fieldset className="smart-hub--report-legend smart-hub--form-section" legend="Training or Technical Assistance">
<div id="tta" />
<div className="smart-hub--form-section">
<div className="smart-hub--form-group">
<FormItem
label="What TTA was provided"
name="ttaType"
Expand All @@ -284,7 +285,7 @@ const ActivitySummary = ({
{renderCheckbox('ttaType', 'technical-assistance', 'Technical Assistance', 'Please specify the type of TTA provided')}
</FormItem>
</div>
<div className="smart-hub--form-section">
<div className="smart-hub--form-group">
<FormItem
label="How was the activity conducted?"
name="deliveryMethod"
Expand All @@ -307,11 +308,39 @@ const ActivitySummary = ({
inputRef={register({ required: 'Please specify how the activity was conducted' })}
/>
</FormItem>
<div aria-live="polite">
{isVirtual && (
<div className="smart-hub--form-group smart-hub--virtual-delivery-group">
<FormItem
label="Please specify how the virtual event was conducted."
name="virtualDeliveryType"
fieldSetWrapper
>
<Radio
id="virtual-deliver-method-video"
name="virtualDeliveryType"
label="Video"
value="video"
className="smart-hub--report-checkbox"
inputRef={register({ required: 'Please specify how the virtual event was conducted' })}
/>
<Radio
id="virtual-deliver-method-telephone"
name="virtualDeliveryType"
label="Telephone"
value="telephone"
className="smart-hub--report-checkbox"
inputRef={register({ required: 'Please specify how the virtual event was conducted' })}
/>
</FormItem>
</div>
)}
</div>
</div>
</Fieldset>
<Fieldset className="smart-hub--report-legend smart-hub--form-section" legend="Participants">
<div id="other-participants" />
<div className="smart-hub--form-section">
<div className="smart-hub--form-group">
<FormItem
label={participantsLabel}
name="participants"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React from 'react';
import PropTypes from 'prop-types';

import { useFormContext, useFieldArray } from 'react-hook-form';

import { Button, TextInput } from '@trussworks/react-uswds';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faPlus, faTrash } from '@fortawesome/free-solid-svg-icons';
import { faCircle } from '@fortawesome/free-regular-svg-icons';

const ResourceSelector = ({ name, ariaName }) => {
const { register, control, getValues } = useFormContext();

const { fields, append, remove } = useFieldArray({
control,
name,
});

const canDelete = fields.length > 1;

return (
<>
{fields.map((item, index) => (
<div key={item.id} className="display-flex flex-align-center">
<TextInput
name={`${name}[${index}].value`}
type="text"
defaultValue={item.value}
inputRef={register()}
/>
{canDelete && (
<Button onClick={() => remove(index)} aria-label={`remove ${ariaName} ${index + 1}`} className="smart-hub--remove-resource" unstyled type="button">
<FontAwesomeIcon color="black" icon={faTrash} />
</Button>
)}
</div>
))}
<Button
unstyled
type="button"
onClick={() => {
const allValues = getValues();
const fieldArray = allValues[name] || [];
const canAdd = fieldArray.every((field) => field.value !== '');
if (canAdd) {
append({ value: '' });
}
}}
>
<span className="fa-layers fa-fw">
<FontAwesomeIcon color="#0166ab" size="lg" icon={faCircle} />
<FontAwesomeIcon color="#0166ab" size="xs" icon={faPlus} />
</span>
<span className="margin-left-1">
Add New Resource
</span>
</Button>
</>
);
};

ResourceSelector.propTypes = {
name: PropTypes.string.isRequired,
ariaName: PropTypes.string.isRequired,
};

export default ResourceSelector;
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/* eslint-disable react/jsx-props-no-spreading */
import '@testing-library/jest-dom';
import userEvent from '@testing-library/user-event';
import { render, screen, waitFor } from '@testing-library/react';
import React from 'react';
import { FormProvider, useForm } from 'react-hook-form';

import ResourceSelector from '../ResourceSelector';

// eslint-disable-next-line react/prop-types
const RenderResourceSelector = ({ data }) => {
const hookForm = useForm({
defaultValues: {
name: data,
},
});
return (
<FormProvider {...hookForm}>
<ResourceSelector
name="name"
ariaName="name"
/>
</FormProvider>
);
};

describe('ResourceSelector', () => {
it('can have a resource added', async () => {
render(<RenderResourceSelector data={[{ value: 'test' }]} />);
const addResource = await screen.findByRole('button', { name: 'Add New Resource' });
userEvent.click(addResource);
const text = await screen.findAllByRole('textbox');
expect(text.length).toBe(2);
});

it('prevents adding of additional resources if one resource is empty', async () => {
render(<RenderResourceSelector data={[{ value: '' }]} />);
const addResource = await screen.findByRole('button');
userEvent.click(addResource);
const text = await screen.findAllByRole('textbox');
expect(text.length).toBe(1);
});

describe('with a single entry', () => {
it('hides the delete button', async () => {
render(<RenderResourceSelector data={[{ value: 'test' }]} />);
const remove = screen.queryByRole('button', { name: 'remove name 1' });
await waitFor(() => expect(remove).toBeNull());
});
});

describe('with multiple entries', () => {
it('allows removal of an item', async () => {
render(<RenderResourceSelector data={[{ value: 'first' }, { value: 'second' }]} />)
const text = await screen.findAllByRole('textbox');
expect(text.length).toBe(2);
const remove = screen.queryByRole('button', { name: 'remove name 1' });
userEvent.click(remove);
const newText = await screen.findAllByRole('textbox');
expect(newText.length).toBe(1);
});
});
});

0 comments on commit 0603eb0

Please sign in to comment.