Skip to content

Commit

Permalink
feat(app): status bar Update animation during update installation (#1…
Browse files Browse the repository at this point in the history
…3519)

* When the RobotUpdateProgressModal is first rendered, send a command to the robot to start the Updating animation (pulsing white) on the status bar
* When there is an error during an update, send a command to the robot to display the Idle animation (solid white) on the status bar
  • Loading branch information
fsinapi authored Sep 12, 2023
1 parent 2629597 commit 91002f0
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
SPACING,
BORDERS,
} from '@opentrons/components'
import { useCreateLiveCommandMutation } from '@opentrons/react-api-client'

import { StyledText } from '../../../../atoms/text'
import { LegacyModal } from '../../../../molecules/LegacyModal'
Expand All @@ -26,6 +27,7 @@ import {
} from '../../../../redux/robot-update'
import successIcon from '../../../../assets/images/icon_success.png'

import type { SetStatusBarCreateCommand } from '@opentrons/shared-data/protocol/types/schemaV7/command/incidental'
import type { Dispatch } from '../../../../redux/types'
import type { UpdateStep } from '.'
import type { RobotUpdateAction } from '../../../../redux/robot-update/types'
Expand Down Expand Up @@ -76,6 +78,26 @@ function RobotUpdateProgressFooter({
dispatch(startRobotUpdate(robotName))
}, [robotName])

const { createLiveCommand } = useCreateLiveCommandMutation()
const idleCommand: SetStatusBarCreateCommand = {
commandType: 'setStatusBar',
params: { animation: 'idle' },
}

// Called if the update fails
const startIdleAnimationIfFailed = (): void => {
if (errorMessage) {
createLiveCommand({
command: idleCommand,
waitUntilComplete: false,
}).catch((e: Error) =>
console.warn(`cannot run status bar animation: ${e.message}`)
)
}
}

React.useEffect(startIdleAnimationIfFailed, [])

return (
<Flex alignItems={ALIGN_CENTER} justifyContent={JUSTIFY_FLEX_END}>
{errorMessage && (
Expand Down Expand Up @@ -124,13 +146,32 @@ export function RobotUpdateProgressModal({
return dispatch(clearRobotUpdateSession())
}

const { createLiveCommand } = useCreateLiveCommandMutation()
const updatingCommand: SetStatusBarCreateCommand = {
commandType: 'setStatusBar',
params: { animation: 'updating' },
}

// Called when the first step of the update begins
const startUpdatingAnimation = (): void => {
createLiveCommand({
command: updatingCommand,
waitUntilComplete: false,
}).catch((e: Error) =>
console.warn(`cannot run status bar animation: ${e.message}`)
)
}

let modalBodyText = t('downloading_update')
if (updateStep === 'install') {
modalBodyText = t('installing_update')
} else if (updateStep === 'restart') {
modalBodyText = t('restarting_robot')
}

// Make sure to start the animation when this modal first pops up
React.useEffect(startUpdatingAnimation, [])

// Account for update methods that do not require download & decreasing percent oddities.
React.useEffect(() => {
const explicitStepProgress = stepProgress || 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,19 @@ import * as React from 'react'
import { i18n } from '../../../../../i18n'
import { fireEvent } from '@testing-library/react'
import { renderWithProviders } from '@opentrons/components'
import { useCreateLiveCommandMutation } from '@opentrons/react-api-client'

import type { SetStatusBarCreateCommand } from '@opentrons/shared-data/protocol/types/schemaV7/command/incidental'

import { RobotUpdateProgressModal } from '../RobotUpdateProgressModal'

jest.mock('@opentrons/react-api-client')
jest.mock('@opentrons/shared-data/protocol/types/schemaV7/command/incidental')

const mockUseCreateLiveCommandMutation = useCreateLiveCommandMutation as jest.MockedFunction<
typeof useCreateLiveCommandMutation
>

const render = (
props: React.ComponentProps<typeof RobotUpdateProgressModal>
) => {
Expand All @@ -15,15 +25,21 @@ const render = (

describe('DownloadUpdateModal', () => {
let props: React.ComponentProps<typeof RobotUpdateProgressModal>
let mockCreateLiveCommand = jest.fn()

beforeEach(() => {
mockCreateLiveCommand = jest.fn()
mockCreateLiveCommand.mockResolvedValue(null)
props = {
robotName: 'testRobot',
updateStep: 'download',
error: null,
stepProgress: 50,
closeUpdateBuildroot: jest.fn(),
}
mockUseCreateLiveCommandMutation.mockReturnValue({
createLiveCommand: mockCreateLiveCommand,
} as any)
})

afterEach(() => {
Expand All @@ -36,6 +52,20 @@ describe('DownloadUpdateModal', () => {
expect(getByText('Updating testRobot')).toBeInTheDocument()
})

it('activates the Update animation when first rendered', () => {
render(props)
const updatingCommand: SetStatusBarCreateCommand = {
commandType: 'setStatusBar',
params: { animation: 'updating' },
}

expect(mockUseCreateLiveCommandMutation).toBeCalledWith()
expect(mockCreateLiveCommand).toBeCalledWith({
command: updatingCommand,
waitUntilComplete: false,
})
})

it('renders the correct text when downloading the robot update with no close button', () => {
const [{ queryByRole, getByText }] = render(props)

Expand Down Expand Up @@ -89,11 +119,16 @@ describe('DownloadUpdateModal', () => {

expect(getByText('Robot software successfully updated')).toBeInTheDocument()
expect(exitButton).toBeInTheDocument()
expect(mockCreateLiveCommand).toBeCalledTimes(1)
fireEvent.click(exitButton)
expect(props.closeUpdateBuildroot).toHaveBeenCalled()
})

it('renders an error modal and exit button if an error occurs', () => {
const idleCommand: SetStatusBarCreateCommand = {
commandType: 'setStatusBar',
params: { animation: 'idle' },
}
props = {
...props,
error: 'test error',
Expand All @@ -106,5 +141,12 @@ describe('DownloadUpdateModal', () => {
fireEvent.click(exitButton)
expect(getByText('Try again')).toBeInTheDocument()
expect(props.closeUpdateBuildroot).toHaveBeenCalled()

expect(mockUseCreateLiveCommandMutation).toBeCalledWith()
expect(mockCreateLiveCommand).toBeCalledTimes(2)
expect(mockCreateLiveCommand).toBeCalledWith({
command: idleCommand,
waitUntilComplete: false,
})
})
})

0 comments on commit 91002f0

Please sign in to comment.