diff --git a/app/src/organisms/Devices/ProtocolRun/ProtocolRunHeader.tsx b/app/src/organisms/Devices/ProtocolRun/ProtocolRunHeader.tsx index eaf55a5035b..80d3e670e1c 100644 --- a/app/src/organisms/Devices/ProtocolRun/ProtocolRunHeader.tsx +++ b/app/src/organisms/Devices/ProtocolRun/ProtocolRunHeader.tsx @@ -21,6 +21,7 @@ import { import { useModulesQuery, useDoorQuery, + useDeleteRunMutation, useHost, useRunCommandErrors, } from '@opentrons/react-api-client' @@ -158,6 +159,7 @@ export function ProtocolRunHeader({ displayName, protocolKey, isProtocolAnalyzing, + isQuickTransfer, } = useProtocolDetailsForRun(runId) const storedProtocol = useSelector((state: State) => getStoredProtocol(state, protocolKey) @@ -168,6 +170,7 @@ export function ProtocolRunHeader({ const robotAnalyticsData = useRobotAnalyticsData(robotName) const isRobotViewable = useIsRobotViewable(robotName) const runStatus = useRunStatus(runId) + const { deleteRun } = useDeleteRunMutation() const { analysisErrors } = useProtocolAnalysisErrors(runId) const isRunCurrent = Boolean( useNotifyRunQuery(runId, { refetchInterval: CURRENT_RUN_POLL_MS })?.data @@ -251,7 +254,14 @@ export function ProtocolRunHeader({ mount: aPipetteWithTip?.mount, robotType, onSkipAndHome: () => { - closeCurrentRun() + closeCurrentRun({ + onSettled: () => { + if (isQuickTransfer) { + deleteRun(runId) + navigate(`/devices/${robotName}`) + } + }, + }) }, }) @@ -302,7 +312,14 @@ export function ProtocolRunHeader({ // Close the run if no tips are attached after running tip check at least once. // This marks the robot as "not busy" as soon as a run is cancelled if drop tip CTAs are unnecessary. if (initialPipettesWithTipsCount === 0 && !enteredER) { - closeCurrentRun() + closeCurrentRun({ + onSettled: () => { + if (isQuickTransfer) { + deleteRun(runId) + navigate(`/devices/${robotName}`) + } + }, + }) } } }, [runStatus, isRunCurrent, runId, enteredER]) @@ -351,7 +368,14 @@ export function ProtocolRunHeader({ name: ANALYTICS_PROTOCOL_RUN_ACTION.FINISH, properties: robotAnalyticsData ?? undefined, }) - closeCurrentRun() + closeCurrentRun({ + onSettled: () => { + if (isQuickTransfer) { + deleteRun(runId) + navigate(`/devices/${robotName}`) + } + }, + }) } return ( @@ -543,7 +567,14 @@ export function ProtocolRunHeader({ } else { void setTipStatusResolved(() => { toggleDTWiz() - closeCurrentRun() + closeCurrentRun({ + onSettled: () => { + if (isQuickTransfer) { + deleteRun(runId) + navigate(`/devices/${robotName}`) + } + }, + }) }, toggleDTWiz) } }} diff --git a/app/src/organisms/Devices/ProtocolRun/__tests__/ProtocolRunHeader.test.tsx b/app/src/organisms/Devices/ProtocolRun/__tests__/ProtocolRunHeader.test.tsx index 64742cd7c06..3d292fcabd9 100644 --- a/app/src/organisms/Devices/ProtocolRun/__tests__/ProtocolRunHeader.test.tsx +++ b/app/src/organisms/Devices/ProtocolRun/__tests__/ProtocolRunHeader.test.tsx @@ -20,6 +20,7 @@ import { useModulesQuery, usePipettesQuery, useDismissCurrentRunMutation, + useDeleteRunMutation, useEstopQuery, useDoorQuery, useInstrumentsQuery, @@ -187,6 +188,7 @@ const PROTOCOL_DETAILS = { protocolKey: PROTOCOL_KEY, isProtocolAnalyzing: false, robotType: 'OT-2 Standard' as const, + isQuickTransfer: false, } const RUN_COMMAND_ERRORS = { @@ -284,6 +286,9 @@ describe('ProtocolRunHeader', () => { vi.mocked(useModulesQuery).mockReturnValue({ data: { data: [] }, } as any) + vi.mocked(useDeleteRunMutation).mockReturnValue({ + deleteRun: vi.fn(), + } as any) vi.mocked(usePipettesQuery).mockReturnValue({ data: { data: { @@ -477,6 +482,7 @@ describe('ProtocolRunHeader', () => { protocolKey: null, isProtocolAnalyzing: true, robotType: 'OT-2 Standard', + isQuickTransfer: false, }) render() diff --git a/app/src/organisms/Devices/hooks/__tests__/useProtocolDetailsForRun.test.tsx b/app/src/organisms/Devices/hooks/__tests__/useProtocolDetailsForRun.test.tsx index 45c2546efd0..02e3548c915 100644 --- a/app/src/organisms/Devices/hooks/__tests__/useProtocolDetailsForRun.test.tsx +++ b/app/src/organisms/Devices/hooks/__tests__/useProtocolDetailsForRun.test.tsx @@ -58,6 +58,7 @@ describe('useProtocolDetailsForRun hook', () => { protocolKey: null, isProtocolAnalyzing: false, robotType: 'OT-3 Standard', + isQuickTransfer: false, }) }) @@ -95,6 +96,7 @@ describe('useProtocolDetailsForRun hook', () => { protocolKey: 'fakeProtocolKey', isProtocolAnalyzing: false, robotType: 'OT-2 Standard', + isQuickTransfer: false, }) }) }) diff --git a/app/src/organisms/Devices/hooks/useProtocolDetailsForRun.ts b/app/src/organisms/Devices/hooks/useProtocolDetailsForRun.ts index 57c50666488..13a00225383 100644 --- a/app/src/organisms/Devices/hooks/useProtocolDetailsForRun.ts +++ b/app/src/organisms/Devices/hooks/useProtocolDetailsForRun.ts @@ -21,6 +21,7 @@ export interface ProtocolDetails { protocolKey: string | null isProtocolAnalyzing?: boolean robotType: RobotType + isQuickTransfer: boolean } export function useProtocolDetailsForRun( @@ -67,5 +68,6 @@ export function useProtocolDetailsForRun( (mostRecentAnalysis?.status === 'completed' ? mostRecentAnalysis?.robotType ?? FLEX_ROBOT_TYPE : FLEX_ROBOT_TYPE), + isQuickTransfer: protocolRecord?.data.protocolKind === 'quick-transfer', } } diff --git a/app/src/pages/RunSummary/index.tsx b/app/src/pages/RunSummary/index.tsx index 524a90d8a43..30975ef698d 100644 --- a/app/src/pages/RunSummary/index.tsx +++ b/app/src/pages/RunSummary/index.tsx @@ -80,7 +80,13 @@ export function RunSummary(): JSX.Element { const { t } = useTranslation('run_details') const navigate = useNavigate() const host = useHost() - const { data: runRecord } = useNotifyRunQuery(runId, { staleTime: Infinity }) + const { data: runRecord } = useNotifyRunQuery(runId, { + staleTime: Infinity, + onError: () => { + // in case the run is remotely deleted by a desktop app, navigate to the dash + navigate('/') + }, + }) const isRunCurrent = Boolean( useNotifyRunQuery(runId, { refetchInterval: CURRENT_RUN_POLL_MS })?.data ?.data?.current @@ -231,14 +237,15 @@ export function RunSummary(): JSX.Element { const returnToQuickTransfer = (): void => { if (!isRunCurrent) { deleteRun(runId) + navigate('/quick-transfer') } else { closeCurrentRun({ onSuccess: () => { deleteRun(runId) + navigate('/quick-transfer') }, }) } - navigate('/quick-transfer') } // TODO(jh, 05-30-24): EXEC-487. Refactor reset() so we can redirect to the setup page, showing the shimmer skeleton instead.