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): fix dqa ODD protocol setup deck config #14169

Merged
merged 8 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from 5 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 @@ -2,13 +2,20 @@ import * as React from 'react'
import { when, resetAllWhenMocks } from 'jest-when'

import { renderWithProviders, BaseDeck } from '@opentrons/components'
import { useUpdateDeckConfigurationMutation } from '@opentrons/react-api-client'
import {
useDeckConfigurationQuery,
useUpdateDeckConfigurationMutation,
} from '@opentrons/react-api-client'

import { i18n } from '../../../i18n'
import { useMostRecentCompletedAnalysis } from '../../LabwarePositionCheck/useMostRecentCompletedAnalysis'
import { ProtocolSetupDeckConfiguration } from '..'

import type { CompletedProtocolAnalysis } from '@opentrons/shared-data'
import type { UseQueryResult } from 'react-query'
import type {
CompletedProtocolAnalysis,
DeckConfiguration,
} from '@opentrons/shared-data'

jest.mock('@opentrons/components/src/hardware-sim/BaseDeck/index')
jest.mock('@opentrons/react-api-client')
Expand All @@ -33,6 +40,9 @@ const mockUseUpdateDeckConfigurationMutation = useUpdateDeckConfigurationMutatio
typeof useUpdateDeckConfigurationMutation
>
const mockBaseDeck = BaseDeck as jest.MockedFunction<typeof BaseDeck>
const mockUseDeckConfigurationQuery = useDeckConfigurationQuery as jest.MockedFunction<
typeof useDeckConfigurationQuery
>

const render = (
props: React.ComponentProps<typeof ProtocolSetupDeckConfiguration>
Expand All @@ -59,6 +69,9 @@ describe('ProtocolSetupDeckConfiguration', () => {
mockUseUpdateDeckConfigurationMutation.mockReturnValue({
updateDeckConfiguration: mockUpdateDeckConfiguration,
} as any)
mockUseDeckConfigurationQuery.mockReturnValue(({
data: [],
} as unknown) as UseQueryResult<DeckConfiguration>)
})

afterEach(() => {
Expand Down
23 changes: 19 additions & 4 deletions app/src/organisms/ProtocolSetupDeckConfiguration/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import {
FLEX_ROBOT_TYPE,
getSimplestDeckConfigForProtocol,
} from '@opentrons/shared-data'
import { useUpdateDeckConfigurationMutation } from '@opentrons/react-api-client'
import {
useDeckConfigurationQuery,
useUpdateDeckConfigurationMutation,
} from '@opentrons/react-api-client'

import { ChildNavigation } from '../ChildNavigation'
import { AddFixtureModal } from '../DeviceDetailsDeckConfiguration/AddFixtureModal'
Expand Down Expand Up @@ -52,15 +55,26 @@ export function ProtocolSetupDeckConfiguration({
] = React.useState<boolean>(false)

const mostRecentAnalysis = useMostRecentCompletedAnalysis(runId)
const { data: deckConfig = [] } = useDeckConfigurationQuery()

const simplestDeckConfig = getSimplestDeckConfigForProtocol(
mostRecentAnalysis
).map(({ cutoutId, cutoutFixtureId }) => ({ cutoutId, cutoutFixtureId }))

const targetDeckConfig = simplestDeckConfig.find(
deck => deck.cutoutId === cutoutId
)

const mergedDeckConfig = deckConfig.map(config =>
targetDeckConfig != null && config.cutoutId === targetDeckConfig.cutoutId
? targetDeckConfig
: config
)

const [
currentDeckConfig,
setCurrentDeckConfig,
] = React.useState<DeckConfiguration>(simplestDeckConfig)
] = React.useState<DeckConfiguration>(mergedDeckConfig)

const { updateDeckConfiguration } = useUpdateDeckConfigurationMutation()
const handleClickConfirm = (): void => {
Expand Down Expand Up @@ -94,13 +108,14 @@ export function ProtocolSetupDeckConfiguration({
onClickButton={handleClickConfirm}
/>
<Flex
koji marked this conversation as resolved.
Show resolved Hide resolved
marginTop="7.75rem"
marginTop="4rem"
paddingX={SPACING.spacing40}
justifyContent={JUSTIFY_CENTER}
>
<BaseDeck
deckConfig={simplestDeckConfig}
deckConfig={currentDeckConfig}
robotType={FLEX_ROBOT_TYPE}
height="455px"
/>
</Flex>
</Flex>
Expand Down
44 changes: 37 additions & 7 deletions app/src/pages/OnDeviceDisplay/ProtocolSetup/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
getDeckDefFromRobotType,
getModuleDisplayName,
getFixtureDisplayName,
SINGLE_SLOT_FIXTURES,
} from '@opentrons/shared-data'

import { StyledText } from '../../../atoms/text'
Expand Down Expand Up @@ -80,6 +81,8 @@
import { ConfirmAttachedModal } from './ConfirmAttachedModal'
import { getLatestCurrentOffsets } from '../../../organisms/Devices/ProtocolRun/SetupLabwarePositionCheck/utils'
import { CloseButton, PlayButton } from './Buttons'
import { useDeckConfigurationCompatibility } from '../../../resources/deck_configuration/hooks'
import { getRequiredDeckConfig } from '../../../resources/deck_configuration/utils'

import type { CutoutFixtureId, CutoutId } from '@opentrons/shared-data'
import type { OnDeviceRouteParams } from '../../../App/types'
Expand Down Expand Up @@ -302,6 +305,14 @@
setShowConfirmCancelModal,
] = React.useState<boolean>(false)

const deckConfigCompatibility = useDeckConfigurationCompatibility(
robotType,
mostRecentAnalysis
)
const requiredDeckConfigCompatibility = getRequiredDeckConfig(
deckConfigCompatibility
)

// True if any server request is still pending.
const isLoading =
mostRecentAnalysis == null ||
Expand All @@ -314,24 +325,43 @@
(getProtocolUsesGripper(mostRecentAnalysis) ? 1 : 0)
: 0

const missingProtocolHardware = useMissingProtocolHardwareFromAnalysis(
const { missingProtocolHardware } = useMissingProtocolHardwareFromAnalysis(
robotType,
mostRecentAnalysis
)
const isLocationConflict = missingProtocolHardware.conflictedSlots.length > 0

const missingPipettes = missingProtocolHardware.missingProtocolHardware.filter(
const locationConflictSlots = requiredDeckConfigCompatibility.map(
fixtureCompatibility => {
const {
compatibleCutoutFixtureIds,
cutoutFixtureId,
} = fixtureCompatibility

Check warning on line 338 in app/src/pages/OnDeviceDisplay/ProtocolSetup/index.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/pages/OnDeviceDisplay/ProtocolSetup/index.tsx#L338

Added line #L338 was not covered by tests
const isCurrentFixtureCompatible =
cutoutFixtureId != null &&
compatibleCutoutFixtureIds.includes(cutoutFixtureId)
return (

Check warning on line 342 in app/src/pages/OnDeviceDisplay/ProtocolSetup/index.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/pages/OnDeviceDisplay/ProtocolSetup/index.tsx#L342

Added line #L342 was not covered by tests
!isCurrentFixtureCompatible &&
cutoutFixtureId != null &&
!SINGLE_SLOT_FIXTURES.includes(cutoutFixtureId)
)
}
)
const isLocationConflict = locationConflictSlots.some(
conflictSlot => conflictSlot

Check warning on line 350 in app/src/pages/OnDeviceDisplay/ProtocolSetup/index.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/pages/OnDeviceDisplay/ProtocolSetup/index.tsx#L350

Added line #L350 was not covered by tests
)

const missingPipettes = missingProtocolHardware.filter(
hardware => hardware.hardwareType === 'pipette'
)

const missingGripper = missingProtocolHardware.missingProtocolHardware.filter(
const missingGripper = missingProtocolHardware.filter(
hardware => hardware.hardwareType === 'gripper'
)

const missingModules = missingProtocolHardware.missingProtocolHardware.filter(
const missingModules = missingProtocolHardware.filter(
hardware => hardware.hardwareType === 'module'
)
const missingFixtures = missingProtocolHardware.missingProtocolHardware.filter(
const missingFixtures = missingProtocolHardware.filter(
koji marked this conversation as resolved.
Show resolved Hide resolved
(hardware): hardware is ProtocolFixture =>
hardware.hardwareType === 'fixture'
)
Expand Down Expand Up @@ -748,7 +778,7 @@
padding={
setupScreen === 'prepare to run'
? `0 ${SPACING.spacing32} ${SPACING.spacing40}`
: `${SPACING.spacing32} ${SPACING.spacing40}`
: `${SPACING.spacing32} ${SPACING.spacing40} ${SPACING.spacing40}`
}
>
{setupComponentByScreen[setupScreen]}
Expand Down
3 changes: 3 additions & 0 deletions components/src/hardware-sim/BaseDeck/BaseDeck.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ interface BaseDeckProps {
animatedSVG?: boolean
/** extra props to pass to svg tag */
svgProps?: React.ComponentProps<typeof Svg>
height?: string
}

export function BaseDeck(props: BaseDeckProps): JSX.Element {
Expand All @@ -94,6 +95,7 @@ export function BaseDeck(props: BaseDeckProps): JSX.Element {
showSlotLabels = true,
animatedSVG = false,
svgProps = {},
height = '100%',
} = props
const deckDef = getDeckDefFromRobotType(robotType)

Expand Down Expand Up @@ -126,6 +128,7 @@ export function BaseDeck(props: BaseDeckProps): JSX.Element {
viewBox={`${deckDef.cornerOffsetFromOrigin[0]} ${deckDef.cornerOffsetFromOrigin[1]} ${deckDef.dimensions[0]} ${deckDef.dimensions[1]}`}
animated={animatedSVG}
{...svgProps}
height={height}
>
{robotType === OT2_ROBOT_TYPE ? (
<DeckFromLayers
Expand Down
Loading