Skip to content

Commit

Permalink
feat(app): Display bad runs on the ODD (#14736)
Browse files Browse the repository at this point in the history
When runs are bad, which means they couldn't be loaded correctly, we now
get standin records called BadRuns rather than 500 errors. We should
display that a run is bad on the ODD. For now, let's try making it red
and displaying a status text.

This is what this looks like. Thoughts?

![image](https://github.com/Opentrons/opentrons/assets/3091648/11da4921-5901-4157-86ce-5e45a79cac26)
  • Loading branch information
sfoster1 authored Mar 26, 2024
1 parent 1b28bab commit 4454df6
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 11 deletions.
1 change: 1 addition & 0 deletions app/src/assets/localization/en/device_details.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"an_error_occurred_while_updating": "An error occurred while updating your pipette's settings.",
"attach_gripper": "Attach gripper",
"attach_pipette": "Attach pipette",
"bad_run": "run could not be loaded",
"both_mounts": "Both Mounts",
"bundle_firmware_file_not_found": "Bundled fw file not found for module of type: {{module}}",
"calibrate_gripper": "Calibrate gripper",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { useTrackEvent } from '../../../redux/analytics'
import { Skeleton } from '../../../atoms/Skeleton'
import { useMissingProtocolHardware } from '../../../pages/Protocols/hooks'
import { useCloneRun } from '../../ProtocolUpload/hooks'
import { useHardwareStatusText } from './hooks'
import { useRerunnableStatusText } from './hooks'
import {
useRobotInitializationStatus,
INIT_STATUS,
Expand Down Expand Up @@ -77,8 +77,10 @@ export function ProtocolWithLastRun({
conflictedSlots,
} = useMissingProtocolHardware(protocolData.id)
const history = useHistory()
const isReadyToBeReRun = missingProtocolHardware.length === 0
const chipText = useHardwareStatusText(
const isOk = 'ok' in runData ? !(runData?.ok === false) : true
const isReadyToBeReRun = isOk && missingProtocolHardware.length === 0
const chipText = useRerunnableStatusText(
isOk,
missingProtocolHardware,
conflictedSlots
)
Expand Down Expand Up @@ -162,7 +164,13 @@ export function ProtocolWithLastRun({
flexDirection={DIRECTION_COLUMN}
padding={SPACING.spacing24}
gridGap={SPACING.spacing24}
backgroundColor={isReadyToBeReRun ? COLORS.green35 : COLORS.yellow35}
backgroundColor={
isOk
? isReadyToBeReRun
? COLORS.green35
: COLORS.yellow35
: COLORS.red35
}
width="25.8125rem"
height="24.5rem"
borderRadius={BORDERS.borderRadius16}
Expand All @@ -171,7 +179,7 @@ export function ProtocolWithLastRun({
<Flex justifyContent={JUSTIFY_SPACE_BETWEEN}>
<Chip
paddingLeft="0"
type={isReadyToBeReRun ? 'success' : 'warning'}
type={isOk ? (isReadyToBeReRun ? 'success' : 'warning') : 'error'}
background={false}
text={i18n.format(chipText, 'capitalize')}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { useMissingProtocolHardware } from '../../../../pages/Protocols/hooks'
import { useTrackProtocolRunEvent } from '../../../Devices/hooks'
import { useTrackEvent } from '../../../../redux/analytics'
import { useCloneRun } from '../../../ProtocolUpload/hooks'
import { useHardwareStatusText } from '../hooks'
import { useRerunnableStatusText } from '../hooks'
import { RecentRunProtocolCard } from '../'
import { useNotifyAllRunsQuery } from '../../../../resources/runs'
import {
Expand Down Expand Up @@ -82,6 +82,14 @@ const mockRunData = {
status: RUN_STATUS_FAILED,
} as any

const mockBadRunData = {
...mockRunData,
ok: false,
dataError: {
title: 'Bad run oh no',
},
} as any

const mockCloneRun = vi.fn()

const render = (props: React.ComponentProps<typeof RecentRunProtocolCard>) => {
Expand Down Expand Up @@ -109,7 +117,7 @@ describe('RecentRunProtocolCard', () => {
}

vi.mocked(Skeleton).mockReturnValue(<div>mock Skeleton</div>)
vi.mocked(useHardwareStatusText).mockReturnValue('Ready to run')
vi.mocked(useRerunnableStatusText).mockReturnValue('Ready to run')
vi.mocked(useTrackEvent).mockReturnValue(mockTrackEvent)
vi.mocked(useMissingProtocolHardware).mockReturnValue({
missingProtocolHardware: [],
Expand Down Expand Up @@ -157,7 +165,7 @@ describe('RecentRunProtocolCard', () => {
isLoading: false,
conflictedSlots: [],
})
vi.mocked(useHardwareStatusText).mockReturnValue('Missing 1 pipette')
vi.mocked(useRerunnableStatusText).mockReturnValue('Missing 1 pipette')
render(props)
screen.getByText('Missing 1 pipette')
})
Expand All @@ -168,7 +176,7 @@ describe('RecentRunProtocolCard', () => {
isLoading: false,
conflictedSlots: ['cutoutD3'],
})
vi.mocked(useHardwareStatusText).mockReturnValue('Location conflicts')
vi.mocked(useRerunnableStatusText).mockReturnValue('Location conflicts')
render(props)
screen.getByText('Location conflicts')
})
Expand All @@ -179,7 +187,7 @@ describe('RecentRunProtocolCard', () => {
isLoading: false,
conflictedSlots: [],
})
vi.mocked(useHardwareStatusText).mockReturnValue('Missing 1 module')
vi.mocked(useRerunnableStatusText).mockReturnValue('Missing 1 module')
render(props)
screen.getByText('Missing 1 module')
})
Expand All @@ -190,11 +198,23 @@ describe('RecentRunProtocolCard', () => {
isLoading: false,
conflictedSlots: [],
})
vi.mocked(useHardwareStatusText).mockReturnValue('Missing hardware')
vi.mocked(useRerunnableStatusText).mockReturnValue('Missing hardware')
render(props)
screen.getByText('Missing hardware')
})

it('should render bad protocol chip when the protocol is bad even if hardware matches', () => {
vi.mocked(useNotifyAllRunsQuery).mockReturnValue({
data: { data: [mockRunData] },
} as any)
const propsWithBadRun = { runData: mockBadRunData }
vi.mocked(useRerunnableStatusText).mockReturnValue(
'Run could not be loaded'
)
render(propsWithBadRun)
screen.getByText('Run could not be loaded')
})

it('when tapping a card, mock functions is called and loading state is activated', () => {
render(props)
const button = screen.getByLabelText('RecentRunProtocolCard')
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './useHardwareStatusText'
export * from './useRerunnableStatusText'
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useTranslation } from 'react-i18next'
import { useHardwareStatusText } from './useHardwareStatusText'
import type { ProtocolHardware } from '../../../../pages/Protocols/hooks'

export function useRerunnableStatusText(
runOk: boolean,
missingProtocolhardware: ProtocolHardware[],
conflictedSlots: string[]
): string {
const hardwareStatus = useHardwareStatusText(
missingProtocolhardware,
conflictedSlots
)
const { t, i18n } = useTranslation('device_details')
return runOk ? hardwareStatus : i18n.format(t('bad_run'), 'capitalize')
}

0 comments on commit 4454df6

Please sign in to comment.