Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(app): Inject labware definitions into Error Recovery #17248

Merged
merged 2 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export function RunHeaderModalContainer(
runStatus={runStatus}
runId={runId}
unvalidatedFailedCommand={recoveryModalUtils.failedCommand}
runLwDefsByUri={recoveryModalUtils.runLwDefsByUri}
protocolAnalysis={robotProtocolAnalysis}
/>
) : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export const mockRecoveryContentProps: RecoveryContentProps = {
byRunRecord: mockFailedCommand,
byAnalysis: mockFailedCommand,
},
runLwDefsByUri: {} as any,
errorKind: 'GENERAL_ERROR',
robotType: FLEX_ROBOT_TYPE,
runId: 'MOCK_RUN_ID',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ vi.mock('react-redux', async () => {
describe('useErrorRecoveryFlows', () => {
beforeEach(() => {
vi.mocked(useCurrentlyRecoveringFrom).mockReturnValue('mockCommand' as any)
vi.mocked(useRunLoadedLabwareDefinitionsByUri).mockReturnValue({})
})

it('should have initial state of isERActive as false', () => {
Expand Down Expand Up @@ -89,12 +90,32 @@ describe('useErrorRecoveryFlows', () => {
expect(result.current.failedCommand).toEqual('mockCommand')
})

it("should return the run's labware definitions", () => {
const { result } = renderHook(() =>
useErrorRecoveryFlows('MOCK_ID', RUN_STATUS_RUNNING)
)

expect(result.current.failedCommand).toEqual('mockCommand')
})

it(`should return isERActive false if the run status is ${RUN_STATUS_STOP_REQUESTED} before seeing ${RUN_STATUS_AWAITING_RECOVERY}`, () => {
const { result } = renderHook(() =>
useErrorRecoveryFlows('MOCK_ID', RUN_STATUS_STOP_REQUESTED)
)

expect(result.current.isERActive).toEqual(false)
expect(result.current.runLwDefsByUri).toEqual({})
})

it('should not return isERActive if the run labware defintions is null', () => {
vi.mocked(useRunLoadedLabwareDefinitionsByUri).mockReturnValue(null)

const { result } = renderHook(
runStatus => useErrorRecoveryFlows('MOCK_ID', runStatus),
{
initialProps: RUN_STATUS_AWAITING_RECOVERY,
}
)
expect(result.current.isERActive).toBe(false)
})

it('should set hasSeenAwaitingRecovery to true when runStatus is RUN_STATUS_AWAITING_RECOVERY', () => {
Expand Down Expand Up @@ -143,6 +164,7 @@ describe('ErrorRecoveryFlows', () => {
unvalidatedFailedCommand: mockFailedCommand,
runId: 'MOCK_RUN_ID',
protocolAnalysis: null,
runLwDefsByUri: {},
}
vi.mocked(ErrorRecoveryWizard).mockReturnValue(<div>MOCK WIZARD</div>)
vi.mocked(RecoverySplash).mockReturnValue(<div>MOCK RUN PAUSED SPLASH</div>)
Expand All @@ -167,7 +189,6 @@ describe('ErrorRecoveryFlows', () => {
intent: 'recovering',
showTakeover: false,
})
vi.mocked(useRunLoadedLabwareDefinitionsByUri).mockReturnValue({})
})

it('renders the wizard when showERWizard is true', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,17 +198,7 @@ describe('getRunCurrentModulesInfo', () => {
const result = getRunCurrentModulesInfo({
runRecord: null as any,
deckDef: mockDeckDef,
labwareDefinitionsByUri: {},
})

expect(result).toEqual([])
})

it('should return an empty array if protocolAnalysis is null', () => {
const result = getRunCurrentModulesInfo({
runRecord: mockRunRecord,
deckDef: mockDeckDef,
labwareDefinitionsByUri: null,
runLwDefsByUri: {},
})

expect(result).toEqual([])
Expand All @@ -219,7 +209,7 @@ describe('getRunCurrentModulesInfo', () => {
const result = getRunCurrentModulesInfo({
runRecord: mockRunRecord,
deckDef: mockDeckDef,
labwareDefinitionsByUri: {
runLwDefsByUri: {
'opentrons/opentrons_96_pcr_adapter/1': 'MOCK_LW_DEF',
} as any,
})
Expand All @@ -242,7 +232,7 @@ describe('getRunCurrentModulesInfo', () => {
data: { modules: [mockModule], labware: [] },
},
deckDef: mockDeckDef,
labwareDefinitionsByUri: {},
runLwDefsByUri: {},
})
expect(result).toEqual([
{
Expand All @@ -261,7 +251,7 @@ describe('getRunCurrentModulesInfo', () => {
const result = getRunCurrentModulesInfo({
runRecord: mockRunRecord,
deckDef: mockDeckDef,
labwareDefinitionsByUri: null,
runLwDefsByUri: {},
})
expect(result).toEqual([])
})
Expand All @@ -286,7 +276,7 @@ describe('getRunCurrentLabwareInfo', () => {
it('should return an empty array if runRecord is null', () => {
const result = getRunCurrentLabwareInfo({
runRecord: undefined,
labwareDefinitionsByUri: {} as any,
runLwDefsByUri: {} as any,
})

expect(result).toEqual([])
Expand All @@ -295,7 +285,7 @@ describe('getRunCurrentLabwareInfo', () => {
it('should return an empty array if protocolAnalysis is null', () => {
const result = getRunCurrentLabwareInfo({
runRecord: { data: { labware: [] } } as any,
labwareDefinitionsByUri: null,
runLwDefsByUri: {},
})

expect(result).toEqual([])
Expand All @@ -309,7 +299,7 @@ describe('getRunCurrentLabwareInfo', () => {

const result = getRunCurrentLabwareInfo({
runRecord: { data: { labware: [mockPickUpTipLwSlotName] } } as any,
labwareDefinitionsByUri: {
runLwDefsByUri: {
[mockPickUpTipLabware.definitionUri]: mockLabwareDef,
},
})
Expand Down
52 changes: 22 additions & 30 deletions app/src/organisms/ErrorRecoveryFlows/hooks/useDeckMapUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ interface UseDeckMapUtilsProps {
runId: ErrorRecoveryFlowsProps['runId']
protocolAnalysis: ErrorRecoveryFlowsProps['protocolAnalysis']
failedLabwareUtils: UseFailedLabwareUtilsResult
labwareDefinitionsByUri: ERUtilsProps['labwareDefinitionsByUri']
runLwDefsByUri: ERUtilsProps['runLwDefsByUri']
runRecord: Run | undefined
}

Expand All @@ -65,7 +65,7 @@ export function useDeckMapUtils({
runRecord,
runId,
failedLabwareUtils,
labwareDefinitionsByUri,
runLwDefsByUri,
}: UseDeckMapUtilsProps): UseDeckMapUtilsResult {
const robotType = protocolAnalysis?.robotType ?? OT2_ROBOT_TYPE
const deckConfig = getSimplestDeckConfigForProtocol(protocolAnalysis)
Expand All @@ -78,9 +78,9 @@ export function useDeckMapUtils({
getRunCurrentModulesInfo({
runRecord,
deckDef,
labwareDefinitionsByUri,
runLwDefsByUri,
}),
[runRecord, deckDef, labwareDefinitionsByUri]
[runRecord, deckDef, runLwDefsByUri]
)

const runCurrentModules = useMemo(
Expand All @@ -94,8 +94,8 @@ export function useDeckMapUtils({
)

const currentLabwareInfo = useMemo(
() => getRunCurrentLabwareInfo({ runRecord, labwareDefinitionsByUri }),
[runRecord, labwareDefinitionsByUri]
() => getRunCurrentLabwareInfo({ runRecord, runLwDefsByUri }),
[runRecord, runLwDefsByUri]
)

const { updatedModules, remainingLabware } = useMemo(
Expand All @@ -114,32 +114,24 @@ export function useDeckMapUtils({
)

const movedLabwareDef =
labwareDefinitionsByUri != null && failedLabwareUtils.failedLabware != null
? labwareDefinitionsByUri[failedLabwareUtils.failedLabware.definitionUri]
runLwDefsByUri != null && failedLabwareUtils.failedLabware != null
? runLwDefsByUri[failedLabwareUtils.failedLabware.definitionUri]
: null

const moduleRenderInfo = useMemo(
() =>
runRecord != null && labwareDefinitionsByUri != null
? getRunModuleRenderInfo(
runRecord.data,
deckDef,
labwareDefinitionsByUri
)
runRecord != null && runLwDefsByUri != null
? getRunModuleRenderInfo(runRecord.data, deckDef, runLwDefsByUri)
: [],
[deckDef, labwareDefinitionsByUri, runRecord]
[deckDef, runLwDefsByUri, runRecord]
)

const labwareRenderInfo = useMemo(
() =>
runRecord != null && labwareDefinitionsByUri != null
? getRunLabwareRenderInfo(
runRecord.data,
labwareDefinitionsByUri,
deckDef
)
runRecord != null && runLwDefsByUri != null
? getRunLabwareRenderInfo(runRecord.data, runLwDefsByUri, deckDef)
: [],
[deckDef, labwareDefinitionsByUri, runRecord]
[deckDef, runLwDefsByUri, runRecord]
)

return {
Expand Down Expand Up @@ -258,13 +250,13 @@ interface RunCurrentModuleInfo {
export const getRunCurrentModulesInfo = ({
runRecord,
deckDef,
labwareDefinitionsByUri,
runLwDefsByUri,
}: {
runRecord: UseDeckMapUtilsProps['runRecord']
deckDef: DeckDefinition
labwareDefinitionsByUri?: LabwareDefinitionsByUri | null
runLwDefsByUri: UseDeckMapUtilsProps['runLwDefsByUri']
}): RunCurrentModuleInfo[] => {
if (runRecord == null || labwareDefinitionsByUri == null) {
if (runRecord == null) {
return []
} else {
return runRecord.data.modules.reduce<RunCurrentModuleInfo[]>(
Expand All @@ -281,7 +273,7 @@ export const getRunCurrentModulesInfo = ({

const nestedLabwareDef =
nestedLabware != null
? labwareDefinitionsByUri[nestedLabware.definitionUri]
? runLwDefsByUri[nestedLabware.definitionUri]
: null

const slotPosition = getPositionFromSlotId(
Expand Down Expand Up @@ -325,12 +317,12 @@ interface RunCurrentLabwareInfo {
// Derive the labware info necessary to render labware on the deck.
export function getRunCurrentLabwareInfo({
runRecord,
labwareDefinitionsByUri,
runLwDefsByUri,
}: {
runRecord: UseDeckMapUtilsProps['runRecord']
labwareDefinitionsByUri?: LabwareDefinitionsByUri | null
runLwDefsByUri: UseDeckMapUtilsProps['runLwDefsByUri']
}): RunCurrentLabwareInfo[] {
if (runRecord == null || labwareDefinitionsByUri == null) {
if (runRecord == null) {
return []
} else {
const allLabware = runRecord.data.labware.reduce(
Expand All @@ -341,7 +333,7 @@ export function getRunCurrentLabwareInfo({
runRecord,
true
) // Exclude modules since handled separately.
const labwareDef = getLabwareDefinition(lw, labwareDefinitionsByUri)
const labwareDef = getLabwareDefinition(lw, runLwDefsByUri)

if (slotName == null || labwareLocation == null) {
return acc
Expand Down
11 changes: 3 additions & 8 deletions app/src/organisms/ErrorRecoveryFlows/hooks/useERUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,7 @@ import { useCleanupRecoveryState } from './useCleanupRecoveryState'
import { useFailedPipetteUtils } from './useFailedPipetteUtils'
import { getRunningStepCountsFrom } from '/app/resources/protocols'

import type {
LabwareDefinition2,
LabwareDefinitionsByUri,
RobotType,
} from '@opentrons/shared-data'
import type { LabwareDefinition2, RobotType } from '@opentrons/shared-data'
import type { IRecoveryMap, RouteStep, RecoveryRoute } from '../types'
import type { ErrorRecoveryFlowsProps } from '..'
import type { UseRouteUpdateActionsResult } from './useRouteUpdateActions'
Expand Down Expand Up @@ -54,7 +50,6 @@ export type ERUtilsProps = Omit<ErrorRecoveryFlowsProps, 'failedCommand'> & {
failedCommand: ReturnType<typeof useRetainedFailedCommandBySource>
isActiveUser: UseRecoveryTakeoverResult['isActiveUser']
allRunDefs: LabwareDefinition2[]
labwareDefinitionsByUri: LabwareDefinitionsByUri | null
}

export interface ERUtilsResults {
Expand Down Expand Up @@ -90,7 +85,7 @@ export function useERUtils({
isActiveUser,
allRunDefs,
unvalidatedFailedCommand,
labwareDefinitionsByUri,
runLwDefsByUri,
}: ERUtilsProps): ERUtilsResults {
const { data: attachedInstruments } = useInstrumentsQuery()
const { data: runRecord } = useNotifyRunQuery(runId)
Expand Down Expand Up @@ -185,7 +180,7 @@ export function useERUtils({
runRecord,
protocolAnalysis,
failedLabwareUtils,
labwareDefinitionsByUri,
runLwDefsByUri,
})

const recoveryActionMutationUtils = useRecoveryActionMutation(
Expand Down
Loading
Loading