forked from HHS/Head-Start-TTADP
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Various frontend changes to better match design
* Add resource selector * Virtual delivery method field added * Fix styling (margins colors etc) * Copy updates
- Loading branch information
1 parent
90a7211
commit 0603eb0
Showing
15 changed files
with
332 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
frontend/src/pages/ActivityReport/Pages/components/ResourceSelector.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
63 changes: 63 additions & 0 deletions
63
frontend/src/pages/ActivityReport/Pages/components/__tests__/ResourceSelector.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.