Skip to content

Commit

Permalink
feat(app): add rename function for clear all data
Browse files Browse the repository at this point in the history
call updateName function when clear all data to allow users to use the same name in the unboxing
flow.

close RAUT-708
  • Loading branch information
koji committed Sep 11, 2023
1 parent 124f184 commit 2476588
Show file tree
Hide file tree
Showing 6 changed files with 317 additions and 94 deletions.
107 changes: 54 additions & 53 deletions app/src/assets/localization/en/device_settings.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react'
import { useSelector } from 'react-redux'
import { useDispatch, useSelector } from 'react-redux'
import { useTranslation } from 'react-i18next'
import last from 'lodash/last'
import { useHistory } from 'react-router-dom'
Expand All @@ -15,6 +15,8 @@ import {
ALIGN_CENTER,
PrimaryButton,
} from '@opentrons/components'
import { useUpdateRobotNameMutation } from '@opentrons/react-api-client'

import { StyledText } from '../../../../../atoms/text'
import { LegacyModal } from '../../../../../molecules/LegacyModal'
import {
Expand All @@ -27,9 +29,14 @@ import {
getResetConfigOptions,
resetConfig,
} from '../../../../../redux/robot-admin'
import { useIsOT3 } from '../../../hooks'
import {
getRobotSerialNumber,
removeRobot,
} from '../../../../../redux/discovery'
import { useIsOT3, useRobot } from '../../../hooks'

import type { State } from '../../../../../redux/types'
import type { UpdatedRobotName } from '@opentrons/api-client'
import type { Dispatch, State } from '../../../../../redux/types'
import type { ResetConfigRequest } from '../../../../../redux/robot-admin/types'

interface DeviceResetModalProps {
Expand All @@ -54,9 +61,28 @@ export function DeviceResetModal({
return lastId != null ? getRequestById(state, lastId) : null
})?.status

const [tempRobotName, setTempRobotName] = React.useState<string>(robotName)

const serverResetOptions = useSelector((state: State) =>
getResetConfigOptions(state, robotName)
)
const dispatch = useDispatch<Dispatch>()
const robot = useRobot(robotName)
const serialNumber =
robot?.status != null ? getRobotSerialNumber(robot) : null

const { updateRobotName } = useUpdateRobotNameMutation({
onSuccess: (data: UpdatedRobotName) => {
if (serialNumber != null) {
setTempRobotName(serialNumber)
}
data.name != null && history.push(`/devices`)
dispatch(removeRobot(robotName))
},
onError: (error: Error) => {
console.error('error', error.message)
},
})

const triggerReset = (): void => {
if (resetOptions != null) {
Expand All @@ -72,10 +98,14 @@ export function DeviceResetModal({
serverResetOptions.filter(o => o.id !== 'onDeviceDisplay').length

if (isEveryOptionSelected) {
if (serialNumber != null) {
updateRobotName(serialNumber)
}
resetOptions = {
...resetOptions,
onDeviceDisplay: true,
}
dispatchRequest(resetConfig(tempRobotName, resetOptions))
}
}
dispatchRequest(resetConfig(robotName, resetOptions))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,102 @@
import * as React from 'react'
import { MemoryRouter } from 'react-router-dom'
import { fireEvent } from '@testing-library/react'
import { when, resetAllWhenMocks } from 'jest-when'

import { renderWithProviders } from '@opentrons/components'
import { useUpdateRobotNameMutation } from '@opentrons/react-api-client'

import { i18n } from '../../../../../../i18n'
import { resetConfig } from '../../../../../../redux/robot-admin'
import {
resetConfig,
getResetConfigOptions,
} from '../../../../../../redux/robot-admin'
import { useDispatchApiRequest } from '../../../../../../redux/robot-api'
import { getRobotSerialNumber } from '../../../../../../redux/discovery'
import { useIsOT3, useRobot } from '../../../../hooks'
import { mockConnectableRobot } from '../../../../../../redux/discovery/__fixtures__'
import { DeviceResetModal } from '../DeviceResetModal'

import type { State } from '../../../../../../redux/types'
import type { DispatchApiRequestType } from '../../../../../../redux/robot-api'

jest.mock('@opentrons/react-api-client')
jest.mock('../../../../hooks')
jest.mock('../../../../../../redux/robot-admin')
jest.mock('../../../../../../redux/robot-api')
jest.mock('../../../../../../redux/discovery')
jest.mock('../../../../hooks')

const mockResetConfig = resetConfig as jest.MockedFunction<typeof resetConfig>
const mockUseDispatchApiRequest = useDispatchApiRequest as jest.MockedFunction<
typeof useDispatchApiRequest
>
const mockUseUpdateRobotNameMutation = useUpdateRobotNameMutation as jest.MockedFunction<
typeof useUpdateRobotNameMutation
>
const mockGetRobotSerialNumber = getRobotSerialNumber as jest.MockedFunction<
typeof getRobotSerialNumber
>
const mockUseIsOT3 = useIsOT3 as jest.MockedFunction<typeof useIsOT3>
const mockGetResetConfigOptions = getResetConfigOptions as jest.MockedFunction<
typeof getResetConfigOptions
>
const mockUseRobot = useRobot as jest.MockedFunction<typeof useRobot>

const mockResetOptions = {}
const mockCloseModal = jest.fn()
const mockUpdateName = jest.fn()
const ROBOT_NAME = 'otie'
const SERIAL_NUMBER = 'mockSerialNumber'
const mockOT2ResetOptions = [
{
id: 'bootScripts',
name: 'BootScript Foo',
description: 'BootScript foo description',
},
{
id: 'deckCalibration',
name: 'deck Calibration Bar',
description: 'deck Calibration bar description',
},
{
id: 'pipetteOffsetCalibrations',
name: 'pipette calibration FooBar',
description: 'pipette calibration fooBar description',
},
{
id: 'runsHistory',
name: 'RunsHistory FooBar',
description: 'runsHistory fooBar description',
},
{
id: 'tipLengthCalibrations',
name: 'tip length FooBar',
description: 'tip length fooBar description',
},
]
const mockFlexResetOptions = [
{
id: 'bootScripts',
name: 'BootScript Foo',
description: 'BootScript foo description',
},
{
id: 'pipetteOffsetCalibrations',
name: 'pipette calibration FooBar',
description: 'pipette calibration fooBar description',
},
{
id: 'gripperOffsetCalibrations',
name: 'gripper calibration FooBar',
description: 'gripper calibration fooBar description',
},
{
id: 'runsHistory',
name: 'RunsHistory FooBar',
description: 'runsHistory fooBar description',
},
]

const render = (props: React.ComponentProps<typeof DeviceResetModal>) => {
return renderWithProviders(
<MemoryRouter>
Expand All @@ -35,10 +111,22 @@ describe('RobotSettings DeviceResetModal', () => {
beforeEach(() => {
dispatchApiRequest = jest.fn()
mockUseDispatchApiRequest.mockReturnValue([dispatchApiRequest, []])
mockUseUpdateRobotNameMutation.mockReturnValue({
updateRobotName: mockUpdateName,
} as any)

when(mockGetRobotSerialNumber)
.calledWith(mockConnectableRobot)
.mockReturnValue(SERIAL_NUMBER)
when(mockUseIsOT3).calledWith('otie').mockReturnValue(false)
when(mockGetResetConfigOptions)
.calledWith({} as State, ROBOT_NAME)
.mockReturnValue(mockOT2ResetOptions)
})

afterEach(() => {
jest.resetAllMocks()
resetAllWhenMocks()
})

it('should render title, description, and buttons', () => {
Expand All @@ -54,7 +142,7 @@ describe('RobotSettings DeviceResetModal', () => {
getByRole('button', { name: 'Yes, clear data and restart robot' })
})

it('should close the modal when the user clicks the Yes button', () => {
it('should close the modal when the user clicks the Yes button - OT-2', () => {
const clearMockResetOptions = {
bootScript: true,
deckCalibration: true,
Expand All @@ -68,12 +156,41 @@ describe('RobotSettings DeviceResetModal', () => {
const clearDataAndRestartRobotButton = getByRole('button', {
name: 'Yes, clear data and restart robot',
})
fireEvent.click(clearDataAndRestartRobotButton)
clearDataAndRestartRobotButton.click()
expect(dispatchApiRequest).toBeCalledWith(
mockResetConfig(ROBOT_NAME, clearMockResetOptions)
)
})

it('should close the modal when the user clicks the Yes button - Flex', () => {
when(mockUseIsOT3).calledWith('flex').mockReturnValue(true)
when(mockGetResetConfigOptions)
.calledWith({} as State, 'flex')
.mockReturnValue(mockFlexResetOptions)
const clearMockResetOptions = {
bootScripts: true,
gripperOffsetCalibrations: true,
pipetteOffsetCalibrations: true,
runsHistory: true,
}
mockUseRobot.mockReturnValue(mockConnectableRobot)
mockGetRobotSerialNumber.mockReturnValue(SERIAL_NUMBER)
const [{ getByRole }] = render({
closeModal: mockCloseModal,
isRobotReachable: true,
robotName: 'flex',
resetOptions: clearMockResetOptions,
})
const clearDataAndRestartRobotButton = getByRole('button', {
name: 'Yes, clear data and restart robot',
})
clearDataAndRestartRobotButton.click()
expect(mockUpdateName).toHaveBeenCalledWith(SERIAL_NUMBER)
expect(dispatchApiRequest).toBeCalledWith(
mockResetConfig(SERIAL_NUMBER, clearMockResetOptions)
)
})

it('should close the modal when clicking the Cancel button', () => {
const [{ getByRole }] = render({
closeModal: mockCloseModal,
Expand All @@ -82,7 +199,7 @@ describe('RobotSettings DeviceResetModal', () => {
resetOptions: mockResetOptions,
})
const cancelButton = getByRole('button', { name: 'cancel' })
fireEvent.click(cancelButton)
cancelButton.click()
expect(mockCloseModal).toHaveBeenCalled()
})

Expand All @@ -96,7 +213,7 @@ describe('RobotSettings DeviceResetModal', () => {
const closeIconButton = getByTestId(
'ModalHeader_icon_close_Reset to factory settings?'
)
fireEvent.click(closeIconButton)
closeIconButton.click()
expect(mockCloseModal).toHaveBeenCalled()
})

Expand Down Expand Up @@ -124,7 +241,7 @@ describe('RobotSettings DeviceResetModal', () => {
})

const closeButton = getByRole('button', { name: 'close' })
fireEvent.click(closeButton)
closeButton.click()
expect(mockCloseModal).toHaveBeenCalled()
})

Expand All @@ -138,7 +255,7 @@ describe('RobotSettings DeviceResetModal', () => {
const closeIconButton = getByTestId(
'ModalHeader_icon_close_Connection to robot lost'
)
fireEvent.click(closeIconButton)
closeIconButton.click()
expect(mockCloseModal).toHaveBeenCalled()
})
})
3 changes: 0 additions & 3 deletions app/src/organisms/RobotSettingsCalibration/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,6 @@ export function RobotSettingsCalibration({
: null
)

console.log('pipetteOffsetCalibrations', pipetteOffsetCalibrations)
// console.log('attachedInstruments', attachedInstruments)

const createStatus = createRequest?.status

const isJogging =
Expand Down
29 changes: 28 additions & 1 deletion app/src/organisms/RobotSettingsDashboard/DeviceReset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
useConditionalConfirm,
DIRECTION_ROW,
} from '@opentrons/components'
import { useUpdateRobotNameMutation } from '@opentrons/react-api-client'

import { StyledText } from '../../atoms/text'
import { MediumButton, SmallButton } from '../../atoms/buttons'
Expand All @@ -24,7 +25,13 @@ import {
resetConfig,
} from '../../redux/robot-admin'
import { useDispatchApiRequest } from '../../redux/robot-api'
import {
getRobotSerialNumber,
removeRobot,
getLocalRobot,
} from '../../redux/discovery'

import type { UpdatedRobotName } from '@opentrons/api-client'
import type { Dispatch, State } from '../../redux/types'
import type { ResetConfigRequest } from '../../redux/robot-admin/types'
import type { SetSettingOption } from '../../pages/OnDeviceDisplay/RobotSettingsDashboard'
Expand Down Expand Up @@ -79,19 +86,39 @@ export function DeviceReset({
(a, b) =>
targetOptionsOrder.indexOf(a.id) - targetOptionsOrder.indexOf(b.id)
)
const [tempRobotName, setTempRobotName] = React.useState<string>(robotName)
const dispatch = useDispatch<Dispatch>()
const localRobot = useSelector(getLocalRobot)
const serialNumber =
localRobot?.status != null ? getRobotSerialNumber(localRobot) : null

const { updateRobotName } = useUpdateRobotNameMutation({
onSuccess: (data: UpdatedRobotName) => {
if (serialNumber != null) {
setTempRobotName(serialNumber)
}
dispatch(removeRobot(robotName))
},
onError: (error: Error) => {
console.error('error', error.message)
},
})

const handleClick = (): void => {
if (resetOptions != null) {
// remove clearAllStoredData since its not a setting on the backend
const { clearAllStoredData, ...serverResetOptions } = resetOptions
if (Boolean(clearAllStoredData)) {
if (serialNumber != null) {
updateRobotName(serialNumber)
}
dispatchRequest(
resetConfig(robotName, {
resetConfig(tempRobotName, {
...serverResetOptions,
onDeviceDisplay: true,
})
)
dispatchRequest(resetConfig(tempRobotName, serverResetOptions))
} else {
dispatchRequest(resetConfig(robotName, serverResetOptions))
}
Expand Down
Loading

0 comments on commit 2476588

Please sign in to comment.