diff --git a/app/src/assets/localization/en/protocol_command_text.json b/app/src/assets/localization/en/protocol_command_text.json index daeafa3f647..a5dbeb0d82c 100644 --- a/app/src/assets/localization/en/protocol_command_text.json +++ b/app/src/assets/localization/en/protocol_command_text.json @@ -36,7 +36,7 @@ "move_to_coordinates": "Moving to (X: {{x}}, Y: {{y}}, Z: {{z}})", "move_to_slot": "Moving to Slot {{slot_name}}", "move_to_well": "Moving to well {{well_name}} of {{labware}} in {{labware_location}}", - "move_to_addressable_area": "Moving to {{addressable_area}} at {{speed}} mm/s at {{height}} mm high", + "move_to_addressable_area": "Moving to {{addressable_area}}", "notes": "notes", "off_deck": "off deck", "offdeck": "offdeck", @@ -57,6 +57,7 @@ "tc_awaiting_for_duration": "Waiting for Thermocycler profile to complete", "tc_run_profile_steps": "temperature: {{celsius}}°C, seconds: {{seconds}}", "tc_starting_profile": "Thermocycler starting {{repetitions}} repetitions of cycle composed of the following steps:", + "trash_bin_in_slot": "Trash Bin in {{slot_name}}", "touch_tip": "Touching tip", "unlatching_hs_latch": "Unlatching labware on Heater-Shaker", "wait_for_duration": "Pausing for {{seconds}} seconds. {{message}}", @@ -64,5 +65,6 @@ "waiting_for_hs_to_reach": "Waiting for Heater-Shaker to reach target temperature", "waiting_for_tc_block_to_reach": "Waiting for Thermocycler block to reach target temperature and holding for specified time", "waiting_for_tc_lid_to_reach": "Waiting for Thermocycler lid to reach target temperature", - "waiting_to_reach_temp_module": "Waiting for Temperature Module to reach {{temp}}" + "waiting_to_reach_temp_module": "Waiting for Temperature Module to reach {{temp}}", + "waste_chute": "Waste Chute" } diff --git a/app/src/organisms/CommandText/__fixtures__/mockRobotSideAnalysis.json b/app/src/organisms/CommandText/__fixtures__/mockRobotSideAnalysis.json index bb4d9c6181f..b55fed3e651 100644 --- a/app/src/organisms/CommandText/__fixtures__/mockRobotSideAnalysis.json +++ b/app/src/organisms/CommandText/__fixtures__/mockRobotSideAnalysis.json @@ -6331,6 +6331,66 @@ "result": {}, "startedAt": "2023-01-31T21:53:14.615361+00:00", "completedAt": "2023-01-31T21:53:14.616757+00:00" + }, + { + "id": "aca688ed-4916-496d-aae8-ca0e6e56c47b", + "key": "e4be36b4-500c-45dd-8405-73115c80aa4c", + "commandType": "moveToAddressableArea", + "createdAt": "2023-11-29T20:31:00.780650+00:00", + "startedAt": "2023-11-29T20:31:29.248207+00:00", + "completedAt": "2023-11-29T20:31:33.972466+00:00", + "status": "succeeded", + "params": { + "forceDirect": false, + "pipetteId": "c51ddc01-2d21-4e8a-9b10-2cef033488e8", + "addressableAreaName": "1and8ChannelWasteChute", + "offset": { "x": 0, "y": 0, "z": 0 } + } + }, + { + "id": "aca688ed-4916-496d-aae8-ca0e6e56c47c", + "key": "e4be36b4-500c-45dd-8405-73115c80aa44", + "commandType": "moveToAddressableArea", + "createdAt": "2023-11-29T20:31:00.780650+00:00", + "startedAt": "2023-11-29T20:31:29.248207+00:00", + "completedAt": "2023-11-29T20:31:33.972466+00:00", + "status": "succeeded", + "params": { + "forceDirect": false, + "pipetteId": "c51ddc01-2d21-4e8a-9b10-2cef033488e8", + "addressableAreaName": "fixedTrash", + "offset": { "x": 0, "y": 0, "z": 0 } + } + }, + { + "id": "aca688ed-4916-496d-aae8-ca0e6e56c47d", + "key": "e4be36b4-500c-45dd-8405-73115c80aa4z", + "commandType": "moveToAddressableArea", + "createdAt": "2023-11-29T20:31:00.780650+00:00", + "startedAt": "2023-11-29T20:31:29.248207+00:00", + "completedAt": "2023-11-29T20:31:33.972466+00:00", + "status": "succeeded", + "params": { + "forceDirect": false, + "pipetteId": "c51ddc01-2d21-4e8a-9b10-2cef033488e8", + "addressableAreaName": "movableTrashD3", + "offset": { "x": 0, "y": 0, "z": 0 } + } + }, + { + "id": "aca688ed-4916-496d-aae8-ca0e6e56c47e", + "key": "e4be36b4-500c-45dd-8405-73115c80aa4x", + "commandType": "moveToAddressableArea", + "createdAt": "2023-11-29T20:31:00.780650+00:00", + "startedAt": "2023-11-29T20:31:29.248207+00:00", + "completedAt": "2023-11-29T20:31:33.972466+00:00", + "status": "succeeded", + "params": { + "forceDirect": false, + "pipetteId": "c51ddc01-2d21-4e8a-9b10-2cef033488e8", + "addressableAreaName": "D3", + "offset": { "x": 0, "y": 0, "z": 0 } + } } ], "errors": [], diff --git a/app/src/organisms/CommandText/__tests__/CommandText.test.tsx b/app/src/organisms/CommandText/__tests__/CommandText.test.tsx index 8a481d8b60b..54ba696ac40 100644 --- a/app/src/organisms/CommandText/__tests__/CommandText.test.tsx +++ b/app/src/organisms/CommandText/__tests__/CommandText.test.tsx @@ -7,6 +7,7 @@ import { DropTipInPlaceRunTimeCommand, FLEX_ROBOT_TYPE, MoveToAddressableAreaRunTimeCommand, + OT2_ROBOT_TYPE, PrepareToAspirateRunTimeCommand, } from '@opentrons/shared-data' import { i18n } from '../../../i18n' @@ -193,26 +194,114 @@ describe('CommandText', () => { getByText('Moving to well A1 of NEST 1 Well Reservoir 195 mL in Slot 5') } }) - it('renders correct text for moveToAddressableArea', () => { + it('renders correct text for labware involving an addressable area slot', () => { + const { getByText } = renderWithProviders( + , + { + i18nInstance: i18n, + } + )[0] + getByText( + 'Moving Opentrons 96 Tip Rack 300 µL using gripper from Slot 9 to Slot 5' + ) + }) + it('renders correct text for moveToAddressableArea for Waste Chutes', () => { const { getByText } = renderWithProviders( , + { i18nInstance: i18n } + )[0] + getByText('Moving to Waste Chute') + }) + it('renders correct text for moveToAddressableArea for Fixed Trash', () => { + const { getByText } = renderWithProviders( + , + { i18nInstance: i18n } + )[0] + getByText('Moving to Fixed Trash') + }) + it('renders correct text for moveToAddressableArea for Trash Bins', () => { + const { getByText } = renderWithProviders( + , + { i18nInstance: i18n } + )[0] + getByText('Moving to Trash Bin in D3') + }) + it('renders correct text for moveToAddressableArea for slots', () => { + const { getByText } = renderWithProviders( + , { i18nInstance: i18n } )[0] - getByText('Moving to D3 at 200 mm/s at 100 mm high') + getByText('Moving to D3') }) it('renders correct text for configureForVolume', () => { const command = { diff --git a/app/src/organisms/CommandText/index.tsx b/app/src/organisms/CommandText/index.tsx index f39b43299bd..27f92ab3cd0 100644 --- a/app/src/organisms/CommandText/index.tsx +++ b/app/src/organisms/CommandText/index.tsx @@ -4,6 +4,7 @@ import { useTranslation } from 'react-i18next' import { Flex, DIRECTION_COLUMN, SPACING } from '@opentrons/components' import { getPipetteNameSpecs, RunTimeCommand } from '@opentrons/shared-data' import { + getAddressableAreaDisplayName, getLabwareName, getLabwareDisplayLocation, getFinalLabwareLocation, @@ -235,13 +236,16 @@ export function CommandText(props: Props): JSX.Element | null { ) } case 'moveToAddressableArea': { - const { addressableAreaName, speed, minimumZHeight } = command.params + const addressableAreaDisplayName = getAddressableAreaDisplayName( + robotSideAnalysis, + command.id, + t + ) + return ( {t('move_to_addressable_area', { - addressable_area: addressableAreaName, - speed: speed, - height: minimumZHeight, + addressable_area: addressableAreaDisplayName, })} ) diff --git a/app/src/organisms/CommandText/utils/getAddressableAreaDisplayName.ts b/app/src/organisms/CommandText/utils/getAddressableAreaDisplayName.ts new file mode 100644 index 00000000000..6b8d93890f8 --- /dev/null +++ b/app/src/organisms/CommandText/utils/getAddressableAreaDisplayName.ts @@ -0,0 +1,56 @@ +import type { + CompletedProtocolAnalysis, + MoveToAddressableAreaParams, +} from '@opentrons/shared-data' +import type { TFunction } from 'react-i18next' + +export function getAddressableAreaDisplayName( + analysis: CompletedProtocolAnalysis, + commandId: string, + t: TFunction<'protocol_command_text'> +): string { + const addressableAreaCommand = (analysis?.commands ?? []).find( + command => command.id === commandId + ) + + if ( + addressableAreaCommand == null || + !('addressableAreaName' in addressableAreaCommand.params) + ) { + return '' + } + + const addressableAreaName: MoveToAddressableAreaParams['addressableAreaName'] = + addressableAreaCommand.params.addressableAreaName + + if (addressableAreaName.includes('movableTrash')) { + const slotName = getMovableTrashSlot(addressableAreaName) + return t('trash_bin_in_slot', { slot_name: slotName }) + } else if (addressableAreaName.includes('WasteChute')) { + return t('waste_chute') + } else if (addressableAreaName === 'fixedTrash') return t('fixed_trash') + else return addressableAreaName +} + +const getMovableTrashSlot = (addressableAreaName: string): string => { + switch (addressableAreaName) { + case 'movableTrashA1': + return 'A1' + case 'movableTrashA3': + return 'A3' + case 'movableTrashB1': + return 'B1' + case 'movableTrashB3': + return 'B3' + case 'movableTrashC1': + return 'C1' + case 'movableTrashC3': + return 'C3' + case 'movableTrashD1': + return 'D1' + case 'movableTrashD3': + return 'D3' + default: + return '' + } +} diff --git a/app/src/organisms/CommandText/utils/getLabwareDisplayLocation.ts b/app/src/organisms/CommandText/utils/getLabwareDisplayLocation.ts index f675851a00b..aad564a1707 100644 --- a/app/src/organisms/CommandText/utils/getLabwareDisplayLocation.ts +++ b/app/src/organisms/CommandText/utils/getLabwareDisplayLocation.ts @@ -28,6 +28,10 @@ export function getLabwareDisplayLocation( return isOnDevice ? location.slotName : t('slot', { slot_name: location.slotName }) + } else if ('addressableAreaName' in location) { + return isOnDevice + ? location.addressableAreaName + : t('slot', { slot_name: location.addressableAreaName }) } else if ('moduleId' in location) { const moduleModel = getModuleModel(robotSideAnalysis, location.moduleId) if (moduleModel == null) { diff --git a/app/src/organisms/CommandText/utils/index.ts b/app/src/organisms/CommandText/utils/index.ts index 5435a292d11..2e8b67884fd 100644 --- a/app/src/organisms/CommandText/utils/index.ts +++ b/app/src/organisms/CommandText/utils/index.ts @@ -1,3 +1,4 @@ +export * from './getAddressableAreaDisplayName' export * from './getLabwareName' export * from './getPipetteNameOnMount' export * from './getModuleModel'