Update save/cancel button UX

refs MAT-181
flag=rce_buttons_and_icons

Test Plan
- Create a new Button & Icon
> Verify the create button tray has
  functioning "save" and "cancel" buttons
- Edit the button
> Verify a new checkbox is at the bottom of the
  tray reading "Apply changes to all instances of
  this Button and Icon in the Course."
- Check the box and click "save"
> Verify all instances of that button/icon in the
  course are updated
- Edit the button again. This time, don't check the
  box before clicking "Save"
- Verify only that instanec of the button/icon is
  updated

Change-Id: I30a1779d711d5409a9745860c0c5b907ff10635f
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/273446
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
QA-Review: Juan Chavez <juan.chavez@instructure.com>
Product-Review: David Lyons <lyons@instructure.com>
Reviewed-by: Juan Chavez <juan.chavez@instructure.com>
This commit is contained in:
Weston Dransfield 2021-09-13 12:09:54 -06:00
parent 8eba7b9993
commit 48e44d079a
2 changed files with 65 additions and 47 deletions

View File

@ -16,54 +16,63 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React from 'react'
import React, {useState} from 'react'
import {Button} from '@instructure/ui-buttons'
import {Checkbox} from '@instructure/ui-checkbox'
import {Flex} from '@instructure/ui-flex'
import {View} from '@instructure/ui-view'
import {Tooltip} from '@instructure/ui-tooltip'
import formatMessage from '../../../../../format-message'
export const Footer = ({disabled, onCancel, onSubmit, onReplace, editing}) => (
<View as="footer" padding="0 small">
<Flex>
<Flex.Item shouldGrow shouldShrink>
<Button disabled={disabled} onClick={onCancel}>
{formatMessage('Cancel')}
</Button>
</Flex.Item>
<Flex.Item>
{editing ? (
<>
<Tooltip
renderTip={formatMessage(
'Apply changes to all instances of this image in the course'
)}
on={['hover', 'focus']}
>
<Button disabled={disabled} color="primary" onClick={onReplace}>
{formatMessage('Save and Replace All')}
</Button>
</Tooltip>
export const Footer = ({disabled, onCancel, onSubmit, onReplace, editing}) => {
const [replaceAll, setReplaceAll] = useState(false)
<Tooltip
renderTip={formatMessage(
'Save as a new image'
)}
on={['hover', 'focus']}
>
<Button disabled={disabled} color="primary" onClick={onSubmit} margin="0 0 0 x-small">
return (
<View as="footer">
{editing && (
<View as="div" padding="medium">
<Checkbox
label={formatMessage(
'Apply changes to all instances of this Button and Icon in the Course'
)}
data-testid='cb-replace-all'
checked={replaceAll}
onChange={() => {
setReplaceAll(prev => !prev)
}}
/>
</View>
)}
<View
as="div"
background="secondary"
borderWidth="small none none none"
padding="small small x-small none"
>
<Flex>
<Flex.Item shouldGrow shouldShrink></Flex.Item>
<Flex.Item>
<Button disabled={disabled} onClick={onCancel}>
{formatMessage('Cancel')}
</Button>
{editing ? (
<Button
disabled={disabled}
color="primary"
onClick={replaceAll ? onReplace : onSubmit}
margin="0 0 0 x-small"
>
{formatMessage('Save')}
</Button>
</Tooltip>
</>
) : (
<Button disabled={disabled} color="primary" onClick={onSubmit}>
{formatMessage('Apply')}
</Button>
)}
</Flex.Item>
</Flex>
</View>
)
) : (
<Button disabled={disabled} margin="0 0 0 x-small" color="primary" onClick={onSubmit}>
{formatMessage('Apply')}
</Button>
)}
</Flex.Item>
</Flex>
</View>
</View>
)
}

View File

@ -62,19 +62,28 @@ describe('<Footer />', () => {
const subject = (overrides = {}) => render(<Footer {...defaults} {...overrides} />)
it('renders the "Save & Replace All" button', async () => {
const {findByText} = subject()
expect(await findByText('Save and Replace All')).toBeInTheDocument()
it('renders the "apply to all" checkbox', async () => {
const {findByTestId} = subject()
expect(await findByTestId('cb-replace-all')).toBeInTheDocument()
})
it('renders the "Save" button', async () => {
it('renders the "save" button', async () => {
const {findByText} = subject()
expect(await findByText('Save')).toBeInTheDocument()
})
it('does not render the "apply" button', async () => {
const {queryByText} = subject()
expect(await queryByText('Apply')).not.toBeInTheDocument()
})
it('calls "onReplace" when "Save & Replace All" is pressed', async () => {
const {findByText} = subject()
userEvent.click(await findByText('Save and Replace All'))
const {findByText, findByLabelText} = subject()
const checkbox = await findByLabelText('Apply changes to all instances of this Button and Icon in the Course')
userEvent.click(checkbox)
userEvent.click(await findByText('Save'))
expect(defaults.onReplace).toHaveBeenCalled()
})