Skip to content

Commit c8ded75

Browse files
ncdiehl11sfoster1
authored andcommitted
feat(app): show QT runs in RecentProtocolRuns (#20295)
With the decision to treat Quick Transfer protocols more like standard protocols, we want to show them in the desktop app's `RecentProtocolRuns` component. This also allows us to view and download any files from the run, which as of now would include photos taken during any potential error recovery. There are also a few instances in ODD where we implicitly delete QT runs. We don't want to do this!
1 parent a77aa51 commit c8ded75

File tree

5 files changed

+122
-123
lines changed

5 files changed

+122
-123
lines changed

app/src/organisms/Desktop/Devices/RecentProtocolRuns.tsx

Lines changed: 85 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,7 @@ export function RecentProtocolRuns({
4040
const currentRunId = useCurrentRunId()
4141
const { isRunTerminal } = useRunStatuses()
4242
const robotIsBusy = currentRunId != null ? !isRunTerminal : false
43-
const nonQuickTransferRuns = runs?.filter(run => {
44-
const protocol = protocols?.data?.data.find(
45-
protocol => protocol.id === run.protocolId
46-
)
47-
return protocol?.protocolKind !== 'quick-transfer'
48-
})
49-
43+
const allRunsMutable = [...(runs ?? [])]
5044
return (
5145
<Flex
5246
alignItems={ALIGN_FLEX_START}
@@ -73,84 +67,82 @@ export function RecentProtocolRuns({
7367
paddingX={SPACING.spacing16}
7468
width="100%"
7569
>
76-
{isRobotViewable &&
77-
nonQuickTransferRuns &&
78-
nonQuickTransferRuns?.length > 0 && (
79-
<>
80-
<Flex
81-
justifyContent={JUSTIFY_FLEX_START}
82-
padding={SPACING.spacing8}
83-
width="88%"
84-
marginRight="12%"
85-
gridGap={SPACING.spacing20}
86-
color={COLORS.grey60}
70+
{isRobotViewable && allRunsMutable && allRunsMutable?.length > 0 && (
71+
<>
72+
<Flex
73+
justifyContent={JUSTIFY_FLEX_START}
74+
padding={SPACING.spacing8}
75+
width="88%"
76+
marginRight="12%"
77+
gridGap={SPACING.spacing20}
78+
color={COLORS.grey60}
79+
>
80+
<LegacyStyledText
81+
as="p"
82+
width="25%"
83+
data-testid="RecentProtocolRuns_RunTitle"
8784
>
88-
<LegacyStyledText
89-
as="p"
90-
width="25%"
91-
data-testid="RecentProtocolRuns_RunTitle"
92-
>
93-
{t('run')}
94-
</LegacyStyledText>
95-
<LegacyStyledText
96-
as="p"
97-
width="27%"
98-
data-testid="RecentProtocolRuns_ProtocolTitle"
99-
>
100-
{t('protocol')}
101-
</LegacyStyledText>
102-
<LegacyStyledText
103-
as="p"
104-
width="5%"
105-
data-testid="RecentProtocolRuns_FilesTitle"
106-
>
107-
{t('files')}
108-
</LegacyStyledText>
109-
<LegacyStyledText
110-
as="p"
111-
width="14%"
112-
data-testid="RecentProtocolRuns_StatusTitle"
113-
>
114-
{t('status')}
115-
</LegacyStyledText>
116-
<LegacyStyledText
117-
as="p"
118-
width="14%"
119-
data-testid="RecentProtocolRuns_DurationTitle"
120-
>
121-
{t('run_duration')}
122-
</LegacyStyledText>
123-
</Flex>
124-
{nonQuickTransferRuns
125-
.sort(
126-
(a, b) =>
127-
new Date(b.createdAt).getTime() -
128-
new Date(a.createdAt).getTime()
129-
)
85+
{t('run')}
86+
</LegacyStyledText>
87+
<LegacyStyledText
88+
as="p"
89+
width="27%"
90+
data-testid="RecentProtocolRuns_ProtocolTitle"
91+
>
92+
{t('protocol')}
93+
</LegacyStyledText>
94+
<LegacyStyledText
95+
as="p"
96+
width="5%"
97+
data-testid="RecentProtocolRuns_FilesTitle"
98+
>
99+
{t('files')}
100+
</LegacyStyledText>
101+
<LegacyStyledText
102+
as="p"
103+
width="14%"
104+
data-testid="RecentProtocolRuns_StatusTitle"
105+
>
106+
{t('status')}
107+
</LegacyStyledText>
108+
<LegacyStyledText
109+
as="p"
110+
width="14%"
111+
data-testid="RecentProtocolRuns_DurationTitle"
112+
>
113+
{t('run_duration')}
114+
</LegacyStyledText>
115+
</Flex>
116+
{allRunsMutable
117+
.sort(
118+
(a, b) =>
119+
new Date(b.createdAt).getTime() -
120+
new Date(a.createdAt).getTime()
121+
)
130122

131-
.map((run, index) => {
132-
const protocol = protocols?.data?.data.find(
133-
protocol => protocol.id === run.protocolId
134-
)
135-
const protocolName =
136-
protocol?.metadata.protocolName ??
137-
protocol?.files[0].name ??
138-
t('shared:loading') ??
139-
''
123+
.map((run, index) => {
124+
const protocol = protocols?.data?.data.find(
125+
protocol => protocol.id === run.protocolId
126+
)
127+
const protocolName =
128+
protocol?.metadata.protocolName ??
129+
protocol?.files[0].name ??
130+
t('shared:loading') ??
131+
''
140132

141-
return (
142-
<HistoricalProtocolRun
143-
run={run}
144-
protocolName={protocolName}
145-
protocolKey={protocol?.key}
146-
robotName={robotName}
147-
robotIsBusy={robotIsBusy}
148-
key={index}
149-
/>
150-
)
151-
})}
152-
</>
153-
)}
133+
return (
134+
<HistoricalProtocolRun
135+
run={run}
136+
protocolName={protocolName}
137+
protocolKey={protocol?.key}
138+
robotName={robotName}
139+
robotIsBusy={robotIsBusy}
140+
key={index}
141+
/>
142+
)
143+
})}
144+
</>
145+
)}
154146
{!isRobotViewable && (
155147
<LegacyStyledText
156148
as="p"
@@ -163,19 +155,17 @@ export function RecentProtocolRuns({
163155
{t('offline_recent_protocol_runs')}
164156
</LegacyStyledText>
165157
)}
166-
{isRobotViewable &&
167-
(nonQuickTransferRuns == null ||
168-
nonQuickTransferRuns.length === 0) && (
169-
<LegacyStyledText
170-
as="p"
171-
alignItems={ALIGN_CENTER}
172-
display={DISPLAY_FLEX}
173-
flex="1 0"
174-
id="RecentProtocolRuns_no_runs"
175-
>
176-
{t('no_protocol_runs')}
177-
</LegacyStyledText>
178-
)}
158+
{isRobotViewable && allRunsMutable?.length === 0 && (
159+
<LegacyStyledText
160+
as="p"
161+
alignItems={ALIGN_CENTER}
162+
display={DISPLAY_FLEX}
163+
flex="1 0"
164+
id="RecentProtocolRuns_no_runs"
165+
>
166+
{t('no_protocol_runs')}
167+
</LegacyStyledText>
168+
)}
179169
</Flex>
180170
</Flex>
181171
)

app/src/organisms/Desktop/Devices/__tests__/RecentProtocolRuns.test.tsx

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { beforeEach, describe, it, vi } from 'vitest'
33

44
import '@testing-library/jest-dom/vitest'
55

6+
import { useAllProtocolsQuery } from '@opentrons/react-api-client'
7+
68
import { renderWithProviders } from '/app/__testing-utils__'
79
import { i18n } from '/app/i18n'
810
import { useIsRobotViewable } from '/app/redux-resources/robots'
@@ -13,8 +15,9 @@ import { RecentProtocolRuns } from '../RecentProtocolRuns'
1315

1416
import type { AxiosError } from 'axios'
1517
import type { UseQueryResult } from 'react-query'
16-
import type { Runs } from '@opentrons/api-client'
18+
import type { Protocols, Runs } from '@opentrons/api-client'
1719

20+
vi.mock('@opentrons/react-api-client')
1821
vi.mock('/app/redux-resources/robots')
1922
vi.mock('/app/resources/runs')
2023
vi.mock('../HistoricalProtocolRun')
@@ -76,4 +79,35 @@ describe('RecentProtocolRuns', () => {
7679
screen.getByText('Run duration')
7780
screen.getByText('mock HistoricalProtocolRun')
7881
})
82+
it('renders quick transfer runs', () => {
83+
vi.mocked(useIsRobotViewable).mockReturnValue(true)
84+
vi.mocked(useAllProtocolsQuery).mockReturnValue({
85+
data: {
86+
data: [
87+
{
88+
id: 'test_protocol_id',
89+
protocolKind: 'quick-transfer',
90+
metadata: {
91+
protocolName: 'test protocol',
92+
},
93+
},
94+
],
95+
},
96+
} as any as UseQueryResult<Protocols, AxiosError>)
97+
vi.mocked(useNotifyAllRunsQuery).mockReturnValue({
98+
data: {
99+
data: [
100+
{
101+
createdAt: '2022-05-04T18:24:40.833862+00:00',
102+
current: false,
103+
id: 'test_id',
104+
protocolId: 'test_protocol_id',
105+
status: 'succeeded',
106+
},
107+
] as any as Runs,
108+
},
109+
} as any as UseQueryResult<Runs, AxiosError>)
110+
render()
111+
screen.getByText('mock HistoricalProtocolRun')
112+
})
79113
})

app/src/organisms/ODD/RunningProtocol/ConfirmCancelRunModal/index.tsx

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { useNavigate } from 'react-router-dom'
66
import { RUN_STATUS_STOPPED } from '@opentrons/api-client'
77
import { COLORS, LegacyStyledText } from '@opentrons/components'
88
import {
9-
useDeleteRunMutation,
109
useDismissCurrentRunMutation,
1110
useStopRunMutation,
1211
} from '@opentrons/react-api-client'
@@ -40,20 +39,8 @@ export function ConfirmCancelRunModal({
4039
}: ConfirmCancelRunModalProps): JSX.Element {
4140
const { t } = useTranslation(['run_details', 'shared'])
4241
const { stopRun } = useStopRunMutation()
43-
const { deleteRun } = useDeleteRunMutation({
44-
onError: error => {
45-
setIsCanceling(false)
46-
console.error('Error deleting quick transfer run', error)
47-
},
48-
})
4942
const { dismissCurrentRun, isLoading: isDismissing } =
50-
useDismissCurrentRunMutation({
51-
onSettled: () => {
52-
if (isQuickTransfer) {
53-
deleteRun(runId)
54-
}
55-
},
56-
})
43+
useDismissCurrentRunMutation()
5744
const localRobot = useSelector(getLocalRobot)
5845
const { data, isError: isRunFetchError } = useNotifyRunQuery(runId)
5946
const runStatus = data?.data.status

app/src/pages/ODD/RobotDashboard/index.tsx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import {
1010
SPACING,
1111
TYPOGRAPHY,
1212
} from '@opentrons/components'
13-
import { useAllProtocolsQuery } from '@opentrons/react-api-client'
1413

1514
import { Navigation } from '/app/organisms/ODD/Navigation'
1615
import {
@@ -31,7 +30,6 @@ export function RobotDashboard(): JSX.Element {
3130
const { t } = useTranslation('device_details')
3231
const { data: allRunsQueryData, error: allRunsQueryError } =
3332
useNotifyAllRunsQuery()
34-
const protocols = useAllProtocolsQuery()
3533

3634
const { unfinishedUnboxingFlowRoute } = useSelector(
3735
getOnDeviceDisplaySettings
@@ -46,11 +44,6 @@ export function RobotDashboard(): JSX.Element {
4644
acc.some(collectedRun => collectedRun.protocolId === run.protocolId)
4745
) {
4846
return acc
49-
} else if (
50-
protocols?.data?.data.find(protocol => protocol.id === run.protocolId)
51-
?.protocolKind === 'quick-transfer'
52-
) {
53-
return acc
5447
} else {
5548
return [...acc, run]
5649
}

app/src/pages/ODD/RunSummary/index.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,6 @@ export function RunSummary(): JSX.Element {
126126
const localRobot = useSelector(getLocalRobot)
127127
const robotName = localRobot?.name ?? 'no name'
128128
const robotType = useRobotType(robotName)
129-
const onCloneRunSuccess = (): void => {
130-
if (isQuickTransfer) {
131-
deleteRun(runId)
132-
}
133-
}
134129

135130
const { trackProtocolRunEvent } = useTrackProtocolRunEvent(
136131
runId,
@@ -146,7 +141,7 @@ export function RunSummary(): JSX.Element {
146141
}
147142
}, [isRunCurrent, enteredER])
148143

149-
const { reset, isResetRunLoading } = useRunControls(runId, onCloneRunSuccess)
144+
const { reset, isResetRunLoading } = useRunControls(runId)
150145
const trackEvent = useTrackEvent()
151146
const { trackEventWithRobotSerial } = useTrackEventWithRobotSerial()
152147

0 commit comments

Comments
 (0)