Skip to content

Commit

Permalink
feat(app): add gripper requirement to protocol and run requirements (#…
Browse files Browse the repository at this point in the history
…12747)

Co-authored-by: Shlok Amin <[email protected]>

closes RLAB-154
  • Loading branch information
b-cooper authored May 22, 2023
1 parent 8d0cb97 commit 9c84d5f
Show file tree
Hide file tree
Showing 31 changed files with 436 additions and 156 deletions.
Binary file added app/src/assets/images/gripper_cal_pin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/src/assets/localization/en/devices_landing.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"left_mount": "Left Mount",
"lights_off": "lights off",
"lights_on": "lights on",
"loading": "loading",
"looking_for_robots": "Looking for robots",
"make_sure_robot_is_connected": "Make sure the robot is connected to this computer",
"modules": "Modules",
Expand Down
6 changes: 5 additions & 1 deletion app/src/assets/localization/en/protocol_setup.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
"96_mount": "left + right mount",
"additional_labware": "{{count}} additional labware",
"additional_off_deck_labware": "Additional Off-Deck Labware",
"attach_gripper_failure_reason": "Attach the required gripper to continue",
"attach_gripper": "attach gripper",
"attach_pipette_calibration": "Attach pipette to see calibration information",
"attach_pipette_cta": "Attach Pipette",
"attach_pipette_failure_reason": "Attach the required pipette(s) to continue",
Expand All @@ -11,6 +13,7 @@
"calibrate_deck_to_proceed_to_pipette_calibration": "Calibrate your deck in order to proceed to pipette calibration",
"calibrate_deck_to_proceed_to_tip_length_calibration": "Calibrate your deck in order to proceed to tip length calibration",
"calibrate_now_cta": "Calibrate Now",
"calibrate_gripper_failure_reason": "Calibrate the required gripper to continue",
"calibrate_pipette_failure_reason": "Calibrate the required pipette(s) to continue",
"calibrate_tiprack_failure_reason": "Calibrate the required tip lengths to continue",
"calibrate": "calibrate",
Expand All @@ -30,6 +33,7 @@
"deck_calibration_title": "Deck Calibration",
"deck_map": "Deck Map",
"example": "Example",
"extension_mount": "extension mount",
"extra_attention_warning_title": "Secure labware and modules before proceeding to run",
"feedback_form_link": "Let us know!",
"get_labware_offset_data": "Get Labware Offset Data",
Expand Down Expand Up @@ -141,7 +145,7 @@
"recalibrating_not_available": "Recalibrating Tip Length calibrations and Labware Position Check is not available.",
"recalibrating_tip_length_not_available": "Recalibrating a tip length is not available once a run has started",
"recommended": "Recommended",
"required_pipettes_title": "Required Pipettes",
"required_instrument_calibrations": "required instrument calibrations",
"required_tip_racks_title": "Required Tip Length Calibrations",
"robot_cal_description": "Robot calibration establishes how the robot knows where it is in relation to the deck. Accurate Robot calibration is essential to run protocols successfully. Robot calibration has 3 parts: Deck calibration, Tip Length calibration and Pipette Offset calibration.",
"robot_cal_help_title": "How Robot Calibration Works",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// images by equipment load name

export const equipmentImages = {
// TODO(BC, 12/06/22): update cal pin image
calibration_pin: require('../../assets/images/change-pip/calibration_probe.png'),
calibration_pin: require('../../assets/images/gripper_cal_pin.png'),
calibration_probe: require('../../assets/images/change-pip/calibration_probe.png'),
t10_torx_screwdriver: require('../../assets/images/t10_torx_screwdriver.png'),
// TODO(jr, 11/17/22): update screwdriver and pipette images
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export function AvailableRobotOption(
)

const { data: runsData } = useAllRunsQuery(
{},
{ pageLength: 0 },
{
onSuccess: data => {
if (data?.links?.current != null)
Expand Down
100 changes: 100 additions & 0 deletions app/src/organisms/Devices/ProtocolRun/SetupGripperCalibrationItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import {
Flex,
ALIGN_CENTER,
DIRECTION_ROW,
SPACING,
JUSTIFY_FLEX_END,
WRAP,
} from '@opentrons/components'
import { GripperModel, getGripperDisplayName } from '@opentrons/shared-data'
import { TertiaryButton } from '../../../atoms/buttons'
import { SetupCalibrationItem } from './SetupCalibrationItem'
import { GripperWizardFlows } from '../../GripperWizardFlows'

import type { GripperData } from '@opentrons/api-client'
import type { GripperWizardFlowType } from '../../GripperWizardFlows/types'
import { GRIPPER_FLOW_TYPES } from '../../GripperWizardFlows/constants'

interface SetupGripperCalibrationItemProps {
gripperData: GripperData | null
runId: string
}

export function SetupGripperCalibrationItem({
gripperData,
runId,
}: SetupGripperCalibrationItemProps): JSX.Element | null {
const { t } = useTranslation('protocol_setup')
const [
openWizardFlowType,
setOpenWizardFlowType,
] = React.useState<GripperWizardFlowType | null>(null)

const gripperCalLastModified =
gripperData != null
? gripperData.data.calibratedOffset?.last_modified ?? null
: null

let button: JSX.Element | undefined

if (gripperData == null) {
button = (
<Flex flexDirection={DIRECTION_ROW} alignItems={ALIGN_CENTER}>
<TertiaryButton
onClick={() => {
setOpenWizardFlowType(GRIPPER_FLOW_TYPES.ATTACH)
}}
>
{t('attach_gripper')}
</TertiaryButton>
</Flex>
)
} else if (gripperCalLastModified == null) {
button = (
<Flex
alignItems={ALIGN_CENTER}
marginLeft={SPACING.spacing16}
flexWrap={WRAP}
justifyContent={JUSTIFY_FLEX_END}
gridGap={SPACING.spacing8}
>
<TertiaryButton
onClick={() => {
setOpenWizardFlowType(GRIPPER_FLOW_TYPES.RECALIBRATE)
}}
>
{t('calibrate_now_cta')}
</TertiaryButton>
</Flex>
)
}

return (
<>
<SetupCalibrationItem
button={button}
calibratedDate={
gripperData != null
? gripperData.data.calibratedOffset?.last_modified ?? null
: null
}
label={t('extension_mount')}
title={
gripperData != null
? getGripperDisplayName(gripperData.instrumentModel as GripperModel)
: ''
}
runId={runId}
/>
{openWizardFlowType != null ? (
<GripperWizardFlows
flowType={openWizardFlowType}
attachedGripper={gripperData}
closeFlow={() => setOpenWizardFlowType(null)}
/>
) : null}
</>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import * as React from 'react'
import { useTranslation } from 'react-i18next'

import {
Flex,
DIRECTION_COLUMN,
COLORS,
SPACING,
TYPOGRAPHY,
} from '@opentrons/components'

import { StyledText } from '../../../atoms/text'
import * as PipetteConstants from '../../../redux/pipettes/constants'
import { useRunPipetteInfoByMount, useStoredProtocolAnalysis } from '../hooks'
import { SetupPipetteCalibrationItem } from './SetupPipetteCalibrationItem'
import { SetupGripperCalibrationItem } from './SetupGripperCalibrationItem'
import { useMostRecentCompletedAnalysis } from '../../LabwarePositionCheck/useMostRecentCompletedAnalysis'
import { useInstrumentsQuery } from '@opentrons/react-api-client'
import { isGripperInCommands } from '../../../resources/protocols/utils'

import type { GripperData } from '@opentrons/api-client'
import { i18n } from '../../../i18n'

interface SetupInstrumentCalibrationProps {
robotName: string
runId: string
}

export function SetupInstrumentCalibration({
robotName,
runId,
}: SetupInstrumentCalibrationProps): JSX.Element {
const { t } = useTranslation('protocol_setup')
const runPipetteInfoByMount = useRunPipetteInfoByMount(runId)

const { data: instrumentsQueryData } = useInstrumentsQuery()
const mostRecentAnalysis = useMostRecentCompletedAnalysis(runId)
const storedProtocolAnalysis = useStoredProtocolAnalysis(runId)
const usesGripper = isGripperInCommands(
mostRecentAnalysis?.commands ?? storedProtocolAnalysis?.commands ?? []
)
const attachedGripperMatch = usesGripper
? (instrumentsQueryData?.data ?? []).find(
(i): i is GripperData => i.instrumentType === 'gripper'
) ?? null
: null
return (
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing8}>
<StyledText
color={COLORS.black}
css={TYPOGRAPHY.pSemiBold}
id="PipetteCalibration_requiredPipettesTitle"
>
{i18n.format(t('required_instrument_calibrations'), 'titleCase')}
</StyledText>
{PipetteConstants.PIPETTE_MOUNTS.map((mount, index) => {
const pipetteInfo = runPipetteInfoByMount[mount]
return pipetteInfo != null ? (
<SetupPipetteCalibrationItem
key={index}
pipetteInfo={pipetteInfo}
mount={mount}
robotName={robotName}
runId={runId}
/>
) : null
})}
{usesGripper ? (
<SetupGripperCalibrationItem
gripperData={attachedGripperMatch}
runId={runId}
/>
) : null}
</Flex>
)
}
53 changes: 0 additions & 53 deletions app/src/organisms/Devices/ProtocolRun/SetupPipetteCalibration.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@ import type { PipetteInfo } from '../hooks'

const inexactPipetteSupportArticle =
'https://support.opentrons.com/s/article/GEN2-pipette-compatibility'
interface SetupPipetteCalibrationItemProps {
interface SetupInstrumentCalibrationItemProps {
pipetteInfo: PipetteInfo
index: number
mount: Mount
robotName: string
runId: string
Expand All @@ -53,7 +52,7 @@ export function SetupPipetteCalibrationItem({
mount,
robotName,
runId,
}: SetupPipetteCalibrationItemProps): JSX.Element | null {
}: SetupInstrumentCalibrationItemProps): JSX.Element | null {
const { t } = useTranslation(['protocol_setup', 'devices_landing'])
const deviceDetailsUrl = `/devices/${robotName}`
const [showFlexPipetteFlow, setShowFlexPipetteFlow] = React.useState<boolean>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
} from '../../../redux/analytics'
import { useIsOT3, useRunHasStarted } from '../hooks'
import { SetupDeckCalibration } from './SetupDeckCalibration'
import { SetupPipetteCalibration } from './SetupPipetteCalibration'
import { SetupInstrumentCalibration } from './SetupInstrumentCalibration'
import { SetupTipLengthCalibration } from './SetupTipLengthCalibration'

import type { ProtocolCalibrationStatus } from '../../../redux/calibration/types'
Expand Down Expand Up @@ -68,7 +68,7 @@ export function SetupRobotCalibration({
{!isOT3 ? (
<SetupDeckCalibration robotName={robotName} runId={runId} />
) : null}
<SetupPipetteCalibration robotName={robotName} runId={runId} />
<SetupInstrumentCalibration robotName={robotName} runId={runId} />
{!isOT3 ? (
<SetupTipLengthCalibration robotName={robotName} runId={runId} />
) : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import { i18n } from '../../../../i18n'
import { mockTipRackDefinition } from '../../../../redux/custom-labware/__fixtures__'
import { useRunPipetteInfoByMount } from '../../hooks'
import { SetupPipetteCalibrationItem } from '../SetupPipetteCalibrationItem'
import { SetupPipetteCalibration } from '../SetupPipetteCalibration'

import { SetupInstrumentCalibration } from '../SetupInstrumentCalibration'
import type { PipetteInfo } from '../../hooks'

jest.mock('../../hooks')
Expand Down Expand Up @@ -41,7 +40,7 @@ const PIPETTE_INFO = {

const render = () => {
return renderWithProviders(
<SetupPipetteCalibration robotName={ROBOT_NAME} runId={RUN_ID} />,
<SetupInstrumentCalibration robotName={ROBOT_NAME} runId={RUN_ID} />,
{
i18nInstance: i18n,
}
Expand All @@ -64,7 +63,7 @@ describe('SetupPipetteCalibration', () => {

it('renders required pipettes title', () => {
const { getByText } = render()
getByText('Required Pipettes')
getByText('Required Instrument Calibrations')
})
it('renders one SetupPipetteCalibrationItem when protocol run requires one pipette', () => {
const { getAllByText } = render()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ const RUN_ID = '1'
describe('SetupPipetteCalibrationItem', () => {
const render = ({
pipetteInfo = mockPipetteInfo,
index = 1,
mount = 'left',
robotName = ROBOT_NAME,
runId = RUN_ID,
Expand All @@ -47,7 +46,6 @@ describe('SetupPipetteCalibrationItem', () => {
<SetupPipetteCalibrationItem
{...{
pipetteInfo,
index,
mount,
robotName,
runId,
Expand Down
Loading

0 comments on commit 9c84d5f

Please sign in to comment.