@@ -105,10 +101,8 @@ export function SlotDetails(props: SlotDetailsProps): JSX.Element {
Slot
@@ -140,8 +134,8 @@ export function SlotDetails(props: SlotDetailsProps): JSX.Element {
) : null}
{moduleOnSlot == null &&
- topMostLabwareOnSlot == null &&
- !isTrashOnSlot ? (
+ topMostLabwareOnSlot == null &&
+ !isTrashOnSlot ? (
) : null}
From 97eb1c98dca4afcff394a1c817f667e2ac7749f6 Mon Sep 17 00:00:00 2001
From: Alise Au <20424172+ahiuchingau@users.noreply.github.com>
Date: Wed, 30 Jul 2025 16:36:03 -0400
Subject: [PATCH 04/14] edit Hardware location items in ODD
---
app/src/pages/ODD/ProtocolDetails/Hardware.tsx | 15 ++++++++-------
.../pages/ODD/QuickTransferDetails/Hardware.tsx | 9 ++++++++-
2 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/app/src/pages/ODD/ProtocolDetails/Hardware.tsx b/app/src/pages/ODD/ProtocolDetails/Hardware.tsx
index e8782a04719..cc2b8fc582a 100644
--- a/app/src/pages/ODD/ProtocolDetails/Hardware.tsx
+++ b/app/src/pages/ODD/ProtocolDetails/Hardware.tsx
@@ -18,11 +18,10 @@ import {
getFixtureDisplayName,
getModuleDisplayName,
getModuleType,
+ getModuleDeckLabel,
GRIPPER_V1_2,
MAGNETIC_BLOCK_FIXTURES,
MAGNETIC_BLOCK_TYPE,
- TC_MODULE_LOCATION_OT3,
- THERMOCYCLER_MODULE_TYPE,
} from '@opentrons/shared-data'
import {
@@ -122,11 +121,13 @@ function HardwareItem({
)
if (hardware.hardwareType === 'module') {
- const slot =
- getModuleType(hardware.moduleModel) === THERMOCYCLER_MODULE_TYPE
- ? TC_MODULE_LOCATION_OT3
- : hardware.slot
- location =
+ location = (
+
+ )
} else if (hardware.hardwareType === 'fixture') {
location = (
)
if (hardware.hardwareType === 'module') {
- location =
+ location = (
+
+ )
} else if (hardware.hardwareType === 'fixture') {
location = (
Date: Thu, 31 Jul 2025 18:15:45 -0400
Subject: [PATCH 05/14] update tests for current implementation
---
.../getLabwareDisplayLocation.test.tsx | 469 ++++++++++++++----
1 file changed, 367 insertions(+), 102 deletions(-)
diff --git a/components/src/organisms/CommandText/useCommandTextString/utils/__tests__/getLabwareDisplayLocation.test.tsx b/components/src/organisms/CommandText/useCommandTextString/utils/__tests__/getLabwareDisplayLocation.test.tsx
index d793f1fc26c..e2ae823af80 100644
--- a/components/src/organisms/CommandText/useCommandTextString/utils/__tests__/getLabwareDisplayLocation.test.tsx
+++ b/components/src/organisms/CommandText/useCommandTextString/utils/__tests__/getLabwareDisplayLocation.test.tsx
@@ -18,7 +18,7 @@ import { getModuleDisplayLocation } from '../getModuleDisplayLocation'
import { getModuleModel } from '../getModuleModel'
import type { ComponentProps } from 'react'
-import type { LabwareLocation } from '@opentrons/shared-data'
+import type { LabwareLocation, LabwareLocationSequence } from '@opentrons/shared-data'
vi.mock('../getModuleModel')
vi.mock('../getModuleDisplayLocation')
@@ -38,7 +38,7 @@ const TestWrapper = ({
location,
params,
}: {
- location: LabwareLocation | null
+ location: LabwareLocation | LabwareLocationSequence | null
params: any
}) => {
const { t } = useTranslation('protocol_command_text')
@@ -59,128 +59,393 @@ describe('getLabwareDisplayLocation with translations', () => {
robotType: FLEX_ROBOT_TYPE,
allRunDefs: [],
}
+ const detailLevels = ['full', 'slot-only']
- it('should return an empty string for null location', () => {
- render({ location: null, params: defaultParams })
- expect(screen.queryByText(/.+/)).toBeNull()
- })
+ describe('for LabwareLocation type', () => {
+ it('should return an empty string for null location', () => {
+ render({
+ location: null,
+ params: defaultParams
+ })
+ expect(screen.queryByText(/.+/)).toBeNull()
+ })
- it('should return "off deck" for offDeck location', () => {
- render({ location: 'offDeck', params: defaultParams })
+ it('should return "off deck" for offDeck location', () => {
+ render({
+ location: 'offDeck',
+ params: defaultParams
+ })
+ screen.getByText('off deck')
+ })
- screen.getByText('off deck')
- })
+ it('should return a slot name for slot location', () => {
+ render({
+ location: { slotName: 'A1' },
+ params: defaultParams
+ })
+ screen.getByText('Slot A1')
+ })
- it('should return a slot name for slot location', () => {
- render({ location: { slotName: 'A1' }, params: defaultParams })
+ it('should return an addressable area name for an addressable area location', () => {
+ render({
+ location: { addressableAreaName: 'B2' },
+ params: defaultParams
+ })
+ screen.getByText('Slot B2')
+ })
- screen.getByText('Slot A1')
- })
+ it('should special case the slotName if it contains "waste chute"', () => {
+ render({
+ location: { slotName: 'gripperWasteChute' },
+ params: defaultParams,
+ })
+ screen.getByText('Waste Chute')
+ })
- it('should return an addressable area name for an addressable area location', () => {
- render({ location: { addressableAreaName: 'B2' }, params: defaultParams })
+ it('should special case the slotName if it contains "trash bin"', () => {
+ render({
+ location: { slotName: 'trashBin' },
+ params: defaultParams,
+ })
+ screen.getByText('Trash Bin')
+ })
- screen.getByText('Slot B2')
- })
+ describe('module location', () => {
+ detailLevels.forEach(detailLevel => {
+ it(`should return a module location for a module location with detailLevel "${detailLevel}"`, () => {
+ const mockModuleModel = 'temperatureModuleV2'
+ vi.mocked(getModuleModel).mockReturnValue(mockModuleModel)
+ vi.mocked(getModuleDisplayLocation).mockReturnValue('3')
+ vi.mocked(getModuleDisplayName).mockReturnValue('Temperature Module')
+ vi.mocked(getModuleType).mockReturnValue('temperatureModuleType')
+ vi.mocked(getOccludedSlotCountForModule).mockReturnValue(1)
- it('should return a module location for a module location', () => {
- const mockModuleModel = 'temperatureModuleV2'
- vi.mocked(getModuleModel).mockReturnValue(mockModuleModel)
- vi.mocked(getModuleDisplayLocation).mockReturnValue('3')
- vi.mocked(getModuleDisplayName).mockReturnValue('Temperature Module')
- vi.mocked(getModuleType).mockReturnValue('temperatureModuleType')
- vi.mocked(getOccludedSlotCountForModule).mockReturnValue(1)
+ render({
+ location: { moduleId: 'temp123' },
+ params: { ...defaultParams, detailLevel }
+ })
- render({ location: { moduleId: 'temp123' }, params: defaultParams })
+ if (detailLevel === 'full') {
+ screen.getByText('Temperature Module in Slot 3')
+ } else {
+ screen.getByText('Slot 3')
+ }
+ })
+ })
+ })
- screen.getByText('Temperature Module in Slot 3')
- })
+ describe('adapter location', () => {
+ detailLevels.forEach(detailLevel => {
+ it(`should return an adapter location for an adapter location with detailLevel "${detailLevel}"`, () => {
+ const mockLoadedLabwares = [
+ {
+ id: 'adapter123',
+ definitionUri: 'adapter-uri',
+ location: { slotName: 'D1' },
+ },
+ ]
+ const mockAllRunDefs = [
+ { uri: 'adapter-uri', metadata: { displayName: 'Mock Adapter' } },
+ ]
+ vi.mocked(getLabwareDefURI).mockReturnValue('adapter-uri')
+ vi.mocked(getLabwareDisplayName).mockReturnValue('Mock Adapter')
+
+ render({
+ location: { labwareId: 'adapter123' },
+ params: {
+ ...defaultParams,
+ loadedLabwares: mockLoadedLabwares,
+ allRunDefs: mockAllRunDefs,
+ detailLevel,
+ },
+ })
- it('should return an adapter location for an adapter location', () => {
- const mockLoadedLabwares = [
- {
- id: 'adapter123',
- definitionUri: 'adapter-uri',
- location: { slotName: 'D1' },
- },
- ]
- const mockAllRunDefs = [
- { uri: 'adapter-uri', metadata: { displayName: 'Mock Adapter' } },
- ]
- vi.mocked(getLabwareDefURI).mockReturnValue('adapter-uri')
- vi.mocked(getLabwareDisplayName).mockReturnValue('Mock Adapter')
-
- render({
- location: { labwareId: 'adapter123' },
- params: {
- ...defaultParams,
- loadedLabwares: mockLoadedLabwares,
- allRunDefs: mockAllRunDefs,
- detailLevel: 'full',
- },
+ if (detailLevel === 'full') {
+ screen.getByText('Mock Adapter in Slot D1')
+ } else {
+ screen.getByText('Slot D1')
+ }
+ })
+ })
})
- screen.getByText('Mock Adapter in Slot D1')
- })
+ describe('adapter on module location', () => {
+ detailLevels.forEach(detailLevel => {
+ it(`should handle an adapter on module location with detailLevel "${detailLevel}"`, () => {
+ const mockLoadedLabwares = [
+ {
+ id: 'adapter123',
+ definitionUri: 'adapter-uri',
+ location: { moduleId: 'temp123' },
+ },
+ ]
+ const mockLoadedModules = [{ id: 'temp123', model: 'temperatureModuleV2' }]
+ const mockAllRunDefs = [
+ { uri: 'adapter-uri', metadata: { displayName: 'Mock Adapter' } },
+ ]
- it('should return a slot-only location when detailLevel is "slot-only"', () => {
- render({
- location: { slotName: 'C1' },
- params: { ...defaultParams, detailLevel: 'slot-only' },
- })
+ vi.mocked(getLabwareDefURI).mockReturnValue('adapter-uri')
+ vi.mocked(getModuleModel).mockReturnValue('temperatureModuleV2')
+ vi.mocked(getLabwareDisplayName).mockReturnValue('Mock Adapter')
+ vi.mocked(getModuleDisplayLocation).mockReturnValue('2')
+ vi.mocked(getModuleDisplayName).mockReturnValue('Temperature Module')
+ vi.mocked(getModuleType).mockReturnValue('temperatureModuleType')
+ vi.mocked(getOccludedSlotCountForModule).mockReturnValue(1)
- screen.getByText('Slot C1')
- })
+ render({
+ location: { labwareId: 'adapter123' },
+ params: {
+ ...defaultParams,
+ loadedLabwares: mockLoadedLabwares,
+ loadedModules: mockLoadedModules,
+ allRunDefs: mockAllRunDefs,
+ detailLevel,
+ },
+ })
- it('should special case the slotName if it contains "waste chute"', () => {
- render({
- location: { slotName: 'gripperWasteChute' },
- params: { ...defaultParams, detailLevel: 'slot-only' },
+ if (detailLevel === 'full') {
+ screen.getByText('Mock Adapter on Temperature Module in Slot 2')
+ } else {
+ screen.getByText('Slot 2')
+ }
+ })
+ })
})
-
- screen.getByText('Waste Chute')
})
- it('should special case the slotName if it contains "trash bin"', () => {
- render({
- location: { slotName: 'trashBin' },
- params: { ...defaultParams, detailLevel: 'slot-only' },
- })
+ describe('for LabwareLocationSequence type', () => {
+ describe('single sequence component tests', () => {
+ it('should handle onAddressableArea sequence', () => {
+ const locationSequence: LabwareLocationSequence = [
+ { kind: 'onAddressableArea', addressableAreaName: 'A1' },
+ { kind: 'onCutoutFixture', cutoutId: 'cutoutA1', possibleCutoutFixtureIds: ['singleLeftSlot'] }
+ ]
+ render({
+ location: locationSequence,
+ params: defaultParams
+ })
+ screen.getByText('Slot A1')
+ })
- screen.getByText('Trash Bin')
- })
+ it('should handle notOnDeck sequence', () => {
+ const locationSequence: LabwareLocationSequence = [
+ { kind: 'notOnDeck', logicalLocationName: 'offDeck' }
+ ]
+ render({
+ location: locationSequence,
+ params: defaultParams
+ })
+ screen.getByText('off deck')
+ })
+
+ describe('labware on a module', () => {
+ detailLevels.forEach(detailLevel => {
+ it(`should handle onModule sequence with detailLevel "${detailLevel}"`, () => {
+ const locationSequence: LabwareLocationSequence = [
+ { kind: 'onAddressableArea', addressableAreaName: 'thermocyclerModuleV2' },
+ { kind: 'onModule', moduleId: 'mockModuleId' },
+ {
+ kind: 'onCutoutFixture',
+ cutoutId: 'cutoutId',
+ possibleCutoutFixtureIds: ['thermocyclerModuleV2Front']
+ },
+ ]
+
+ vi.mocked(getModuleModel).mockReturnValue('thermocyclerModuleV2')
+ vi.mocked(getModuleDisplayLocation).mockReturnValue('B1')
+ vi.mocked(getModuleDisplayName).mockReturnValue('Thermocycler Module')
+ vi.mocked(getModuleType).mockReturnValue('thermocyclerModuleType')
- it('should handle an adapter on module location when the detail level is full', () => {
- const mockLoadedLabwares = [
- {
- id: 'adapter123',
- definitionUri: 'adapter-uri',
- location: { moduleId: 'temp123' },
- },
- ]
- const mockLoadedModules = [{ id: 'temp123', model: 'temperatureModuleV2' }]
- const mockAllRunDefs = [
- { uri: 'adapter-uri', metadata: { displayName: 'Mock Adapter' } },
- ]
-
- vi.mocked(getLabwareDefURI).mockReturnValue('adapter-uri')
- vi.mocked(getLabwareDisplayName).mockReturnValue('Mock Adapter')
- vi.mocked(getModuleDisplayLocation).mockReturnValue('2')
- vi.mocked(getModuleDisplayName).mockReturnValue('Temperature Module')
- vi.mocked(getModuleType).mockReturnValue('temperatureModuleType')
- vi.mocked(getOccludedSlotCountForModule).mockReturnValue(1)
-
- render({
- location: { labwareId: 'adapter123' },
- params: {
- ...defaultParams,
- loadedLabwares: mockLoadedLabwares,
- loadedModules: mockLoadedModules,
- allRunDefs: mockAllRunDefs,
- detailLevel: 'full',
- },
+ render({
+ location: locationSequence,
+ params: { ...defaultParams, detailLevel }
+ })
+
+ if (detailLevel === 'full') {
+ screen.getByText('Thermocycler Module in Slot A1+B1')
+ } else {
+ screen.getByText('Slot A1+B1')
+ }
+ })
+ })
+ })
+
+ describe('labware on another labware', () => {
+ detailLevels.forEach(detailLevel => {
+ it(`should handle onLabware sequence with detailLevel "${detailLevel}"`, () => {
+ const locationSequence: LabwareLocationSequence = [
+ { kind: 'onLabware', labwareId: 'labwareABC', lidId: null },
+ { kind: 'onAddressableArea', addressableAreaName: 'A3' },
+ { kind: 'onCutoutFixture', cutoutId: 'cutoutA3', possibleCutoutFixtureIds: ['flexStackerModuleV1', 'singleRightSlot'] }
+ ]
+ const mockLoadedLabwares = [
+ {
+ id: 'labwareABC',
+ definitionUri: 'labware-uri',
+ location: { slotName: 'A3' },
+ },
+ ]
+ const mockAllRunDefs = [
+ { uri: 'labware-uri', metadata: { displayName: 'Mock Labware' } },
+ ]
+
+ vi.mocked(getLabwareDefURI).mockReturnValue('labware-uri')
+ vi.mocked(getLabwareDisplayName).mockReturnValue('Mock Labware')
+
+ render({
+ location: locationSequence,
+ params: {
+ ...defaultParams,
+ detailLevel,
+ loadedLabwares: mockLoadedLabwares,
+ allRunDefs: mockAllRunDefs
+ }
+ })
+
+ if (detailLevel === 'full') {
+ screen.getByText('Mock Labware in Slot A3')
+ } else {
+ screen.getByText('Slot A3')
+ }
+ })
+ })
+ })
})
- screen.getByText('Mock Adapter on Temperature Module in Slot 2')
+ describe('complex sequence component tests', () => {
+ describe('labware on module sequence', () => {
+ detailLevels.forEach(detailLevel => {
+ it(`should handle labware on module sequence with detailLevel "${detailLevel}"`, () => {
+ const locationSequence: LabwareLocationSequence = [
+ { kind: 'onLabware', labwareId: 'adapter1234', lidId: null },
+ { addressableAreaName: 'temperatureModuleV2C1', kind: 'onAddressableArea' },
+ { kind: 'onModule', moduleId: 'temp123' },
+ { cutoutId: 'cutoutC1', kind: 'onCutoutFixture', possibleCutoutFixtureIds: ['temperatureModuleV2'] }
+ ]
+
+ const mockLoadedLabwares = [
+ {
+ id: 'adapter1234',
+ definitionUri: 'adapter-uri',
+ location: { moduleId: 'temp123' },
+ },
+ ]
+ const mockLoadedModules = [
+ { id: 'temp123', model: 'temperatureModuleV2' }
+ ]
+ const mockAllRunDefs = [
+ { uri: 'adapter-uri', metadata: { displayName: 'Mock Adapter' } },
+ ]
+
+ vi.mocked(getLabwareDefURI).mockReturnValue('adapter-uri')
+ vi.mocked(getLabwareDisplayName).mockReturnValue('Mock Adapter')
+ vi.mocked(getModuleModel).mockReturnValue('temperatureModuleV2')
+ vi.mocked(getModuleDisplayLocation).mockReturnValue('C1')
+ vi.mocked(getModuleDisplayName).mockReturnValue('Temperature Module')
+ vi.mocked(getModuleType).mockReturnValue('temperatureModuleType')
+ vi.mocked(getOccludedSlotCountForModule).mockReturnValue(1)
+
+ render({
+ location: locationSequence,
+ params: {
+ ...defaultParams,
+ detailLevel,
+ loadedLabwares: mockLoadedLabwares,
+ loadedModules: mockLoadedModules,
+ allRunDefs: mockAllRunDefs
+ }
+ })
+
+ if (detailLevel === 'full') {
+ screen.getByText('Mock Adapter on Temperature Module in Slot C1')
+ } else {
+ screen.getByText('Slot C1')
+ }
+ })
+ })
+ })
+
+ it('should only display the top labware in multiple labware stacking sequence', () => {
+ const locationSequence: LabwareLocationSequence = [
+ { kind: 'onLabware', labwareId: 'topLabware', lidId: null },
+ { kind: 'onLabware', labwareId: 'adapter123', lidId: null },
+ { kind: 'onAddressableArea', addressableAreaName: 'A3' },
+ { kind: 'onCutoutFixture', cutoutId: 'cutoutA3', possibleCutoutFixtureIds: ['flexStackerModuleV1', 'singleRightSlot'] }
+ ]
+
+ const mockLoadedLabwares = [
+ {
+ id: 'topLabware',
+ definitionUri: 'top-labware-uri',
+ location: { labwareId: 'adapter123' },
+ },
+ {
+ id: 'adapter123',
+ definitionUri: 'adapter-uri',
+ location: { slotName: 'A3' },
+ },
+ ]
+ const mockAllRunDefs = [
+ { uri: 'top-labware-uri', metadata: { displayName: 'Top Labware' } },
+ { uri: 'adapter-uri', metadata: { displayName: 'Mock Adapter' } },
+ ]
+
+ vi.mocked(getLabwareDefURI)
+ .mockReturnValueOnce('top-labware-uri')
+ .mockReturnValueOnce('adapter-uri')
+ vi.mocked(getLabwareDisplayName)
+ .mockReturnValueOnce('Top Labware')
+ .mockReturnValueOnce('Mock Adapter')
+
+ render({
+ location: locationSequence,
+ params: {
+ ...defaultParams,
+ detailLevel: 'full',
+ loadedLabwares: mockLoadedLabwares,
+ allRunDefs: mockAllRunDefs
+ }
+ })
+
+ screen.getByText('Top Labware in Slot A3')
+ })
+
+ it('should handle waste chute sequence', () => {
+ const locationSequence: LabwareLocationSequence = [
+ {
+ addressableAreaName: 'gripperWasteChute',
+ kind: 'onAddressableArea'
+ },
+ {
+ cutoutId: 'cutoutD3',
+ kind: 'onCutoutFixture',
+ possibleCutoutFixtureIds: [
+ 'stagingAreaSlotWithWasteChuteRightAdapterNoCover'
+ ]
+ }
+ ]
+
+ render({
+ location: locationSequence,
+ params: defaultParams
+ })
+
+ screen.getByText('Waste Chute')
+ })
+
+ it('should handle trash bin sequence', () => {
+ const locationSequence: LabwareLocationSequence = [
+ { kind: 'onAddressableArea', addressableAreaName: 'movableTrashA3' },
+ { kind: 'onCutoutFixture', cutoutId: 'cutoutA3', possibleCutoutFixtureIds: ['movableTrashA3'] }
+ ]
+
+ render({
+ location: locationSequence,
+ params: defaultParams
+ })
+ screen.getByText('Trash Bin')
+ })
+ })
})
})
+
From b42f2753b7afbc25f70215772a9472be54113db5 Mon Sep 17 00:00:00 2001
From: Alise Au <20424172+ahiuchingau@users.noreply.github.com>
Date: Thu, 31 Jul 2025 19:26:15 -0400
Subject: [PATCH 06/14] add in hopper location for getLabwareDisplayLocation
---
.../en/protocol_command_text.json | 1 +
.../getLabwareDisplayLocation.test.tsx | 45 +++++++++++-
.../utils/getLabwareDisplayLocation.tsx | 71 ++++++++-----------
.../utils/getLabwareLocation.tsx | 9 +++
4 files changed, 82 insertions(+), 44 deletions(-)
diff --git a/components/src/assets/localization/en/protocol_command_text.json b/components/src/assets/localization/en/protocol_command_text.json
index e793395f289..8af72b98f0c 100644
--- a/components/src/assets/localization/en/protocol_command_text.json
+++ b/components/src/assets/localization/en/protocol_command_text.json
@@ -93,6 +93,7 @@
"single": "single",
"single_nozzle_layout": "single nozzle layout",
"slot": "Slot {{slot_name}}",
+ "stacker_hopper_display": "Stacker {{row}}",
"target_temperature": "target temperature",
"tc_awaiting_for_duration": "Waiting for Thermocycler profile to complete",
"tc_run_profile_steps": "Temperature: {{celsius}}°C, hold time: {{duration}}",
diff --git a/components/src/organisms/CommandText/useCommandTextString/utils/__tests__/getLabwareDisplayLocation.test.tsx b/components/src/organisms/CommandText/useCommandTextString/utils/__tests__/getLabwareDisplayLocation.test.tsx
index e2ae823af80..c330f50a102 100644
--- a/components/src/organisms/CommandText/useCommandTextString/utils/__tests__/getLabwareDisplayLocation.test.tsx
+++ b/components/src/organisms/CommandText/useCommandTextString/utils/__tests__/getLabwareDisplayLocation.test.tsx
@@ -268,6 +268,50 @@ describe('getLabwareDisplayLocation with translations', () => {
}
})
})
+
+ detailLevels.forEach(detailLevel => {
+ it(`should handle labware on a stacker module with detailLevel "${detailLevel}"`, () => {
+ const locationSequence: LabwareLocationSequence = [
+ { kind: 'onAddressableArea', addressableAreaName: 'flexStackerModuleV1D4' },
+ { kind: 'onModule', moduleId: 'mockModuleId' },
+ {
+ kind: 'onCutoutFixture',
+ cutoutId: 'cutoutD3',
+ possibleCutoutFixtureIds: ['flexStackerModuleV1WithWasteChuteRightAdapterNoCover']
+ }]
+ vi.mocked(getModuleModel).mockReturnValue('flexStackerModuleV1')
+ vi.mocked(getModuleDisplayLocation).mockReturnValue('D3')
+ vi.mocked(getModuleDisplayName).mockReturnValue('Flex Stacker')
+ vi.mocked(getModuleType).mockReturnValue('flexStackerModuleType')
+
+ render({
+ location: locationSequence,
+ params: { ...defaultParams, detailLevel }
+ })
+
+ screen.getByText('Slot D4')
+ })
+ })
+
+ detailLevels.forEach(detailLevel => {
+ it(`should handle labware in stacker hopper with detailLevel "${detailLevel}"`, () => {
+ const locationSequence: LabwareLocationSequence = [
+ { kind: "inStackerHopper", moduleId: "UUID" }
+ ]
+
+ vi.mocked(getModuleModel).mockReturnValue('flexStackerModuleV1')
+ vi.mocked(getModuleDisplayLocation).mockReturnValue('D3')
+ vi.mocked(getModuleDisplayName).mockReturnValue('Flex Stacker')
+ vi.mocked(getModuleType).mockReturnValue('flexStackerModuleType')
+
+ render({
+ location: locationSequence,
+ params: { ...defaultParams, detailLevel }
+ })
+
+ screen.getByText('Stacker D')
+ })
+ })
})
describe('labware on another labware', () => {
@@ -448,4 +492,3 @@ describe('getLabwareDisplayLocation with translations', () => {
})
})
})
-
diff --git a/components/src/organisms/CommandText/useCommandTextString/utils/getLabwareDisplayLocation.tsx b/components/src/organisms/CommandText/useCommandTextString/utils/getLabwareDisplayLocation.tsx
index 07102895082..bbbeca1cb0a 100644
--- a/components/src/organisms/CommandText/useCommandTextString/utils/getLabwareDisplayLocation.tsx
+++ b/components/src/organisms/CommandText/useCommandTextString/utils/getLabwareDisplayLocation.tsx
@@ -1,8 +1,9 @@
import {
- FLEX_STACKER_MODULE_V1,
+ FLEX_STACKER_MODULE_TYPE,
getModuleDisplayName,
getModuleType,
getOccludedSlotCountForModule,
+ getModuleDeckLabel,
MOVABLE_TRASH_ADDRESSABLE_AREAS,
THERMOCYCLER_MODULE_V1,
THERMOCYCLER_MODULE_V2,
@@ -51,23 +52,18 @@ export function getLabwareDisplayLocation(
const { t, isOnDevice = false, location } = params
const locationResult = Array.isArray(location)
? getLabwareLocationFromSequence({
- ...params,
- locationSequence: location,
- })
+ ...params,
+ locationSequence: location,
+ })
: getLabwareLocation({
- ...params,
- location: location ?? null,
- })
+ ...params,
+ location: location ?? null,
+ })
if (locationResult == null) {
return ''
}
- const { slotName: initialSlotName, moduleModel, adapterName } = locationResult
- const slotName =
- moduleModel === THERMOCYCLER_MODULE_V1 ||
- moduleModel === THERMOCYCLER_MODULE_V2
- ? 'A1+B1'
- : initialSlotName
+ const { slotName, moduleModel, adapterName } = locationResult
if (slotName === 'offDeck' || slotName === 'systemLocation') {
return t('off_deck')
@@ -83,37 +79,26 @@ export function getLabwareDisplayLocation(
}
// Module location without adapter
else if (moduleModel != null && adapterName == null) {
+ const moduleSlot = getModuleDeckLabel(getModuleType(moduleModel), slotName)
+ if (getModuleType(moduleModel) === FLEX_STACKER_MODULE_TYPE) {
+ // in hopper location always return Stacker {{row}}
+ return t('stacker_hopper_display', {
+ row: getSlotRow(moduleSlot as string),
+ })
+ }
if (params.detailLevel === 'slot-only') {
- switch (moduleModel) {
- case THERMOCYCLER_MODULE_V1:
- case THERMOCYCLER_MODULE_V2:
- return t('slot', { slot_name: 'A1+B1' })
- case FLEX_STACKER_MODULE_V1:
- return t('stacker_display_name', {
- stacker_slot: getSlotColumn(slotName),
- })
- default:
- return t('slot', { slot_name: slotName })
- }
- } else {
- switch (moduleModel) {
- case FLEX_STACKER_MODULE_V1:
- return t('stacker_column_display_name', {
- stacker_slot: getSlotColumn(slotName),
- })
- default:
- return isOnDevice
- ? `${getModuleDisplayName(moduleModel)}, ${slotName}`
- : t('module_in_slot', {
- count: getOccludedSlotCountForModule(
- getModuleType(moduleModel),
- params.robotType
- ),
- module: getModuleDisplayName(moduleModel),
- slot_name: slotName,
- })
- }
+ return t('slot', { slot_name: moduleSlot })
}
+ return isOnDevice
+ ? `${getModuleDisplayName(moduleModel)}, ${moduleSlot}`
+ : t('module_in_slot', {
+ count: getOccludedSlotCountForModule(
+ getModuleType(moduleModel),
+ params.robotType
+ ),
+ module: getModuleDisplayName(moduleModel),
+ slot_name: moduleSlot,
+ })
}
// Adapter locations
else if (adapterName != null) {
@@ -138,7 +123,7 @@ export function getLabwareDisplayLocation(
}
}
-function getSlotColumn(slotName: string): string {
+function getSlotRow(slotName: string): string {
return slotName.charAt(0)
}
diff --git a/components/src/organisms/CommandText/useCommandTextString/utils/getLabwareLocation.tsx b/components/src/organisms/CommandText/useCommandTextString/utils/getLabwareLocation.tsx
index de72d1b39b2..48dccd16b5b 100644
--- a/components/src/organisms/CommandText/useCommandTextString/utils/getLabwareLocation.tsx
+++ b/components/src/organisms/CommandText/useCommandTextString/utils/getLabwareLocation.tsx
@@ -130,6 +130,15 @@ export function getLabwareLocationFromSequence(
: moduleModel ?? undefined,
}
}
+ } else if (sequenceItem.kind === 'inStackerHopper') {
+ return {
+ ...acc,
+ slotName: getModuleDisplayLocation(
+ loadedModules,
+ sequenceItem.moduleId
+ ),
+ moduleModel: getModuleModel(loadedModules, sequenceItem.moduleId),
+ }
}
// TODO(tz, 4-16-25): add inHopperLocation when logic is merged
else if (detailLevel === 'full') {
From 5772edf982ad8a12f35bf40e2e250c7bcfed4abe Mon Sep 17 00:00:00 2001
From: Alise Au <20424172+ahiuchingau@users.noreply.github.com>
Date: Thu, 31 Jul 2025 19:39:41 -0400
Subject: [PATCH 07/14] update load module command text
---
.../utils/commandText/getLoadCommandText.ts | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/components/src/organisms/CommandText/useCommandTextString/utils/commandText/getLoadCommandText.ts b/components/src/organisms/CommandText/useCommandTextString/utils/commandText/getLoadCommandText.ts
index 93bcef5b204..24f38c9409f 100644
--- a/components/src/organisms/CommandText/useCommandTextString/utils/commandText/getLoadCommandText.ts
+++ b/components/src/organisms/CommandText/useCommandTextString/utils/commandText/getLoadCommandText.ts
@@ -4,6 +4,7 @@ import {
getAllLiquidClassDefs,
getModuleDisplayName,
getModuleType,
+ getModuleDeckLabel,
getOccludedSlotCountForModule,
getPipetteSpecsV2,
THERMOCYCLER_MODULE_V1,
@@ -42,21 +43,15 @@ export const getLoadCommandText = ({
})
}
case 'loadModule': {
+ const moduleType = getModuleType(command.params.model)
const occludedSlotCount = getOccludedSlotCountForModule(
- getModuleType(command.params.model),
+ moduleType,
robotType
)
- let slotName = command.params.location.slotName
- if (
- THERMOCYCLER_MODULE_V2 === command.params.model ||
- THERMOCYCLER_MODULE_V1 === command.params.model
- ) {
- slotName = 'A1 + B1'
- }
return t('load_module_protocol_setup', {
count: occludedSlotCount,
module: getModuleDisplayName(command.params.model),
- slot_name: slotName,
+ slot_name: getModuleDeckLabel(moduleType, command.params.location.slotName),
})
}
case 'loadLid':
From 9afa8f9bb32d0c6143a661c08dac193add39f918 Mon Sep 17 00:00:00 2001
From: Alise Au <20424172+ahiuchingau@users.noreply.github.com>
Date: Mon, 4 Aug 2025 13:21:39 -0400
Subject: [PATCH 08/14] (draft): try updating labware location for move labware
intervention
---
.../en/protocol_command_text.json | 3 +-
.../MoveLabwareInterventionContent.tsx | 29 ++++++++++++-------
.../utils/getLabwareLocation.tsx | 6 +++-
.../utils/getModuleDisplayLocation.ts | 10 ++++++-
4 files changed, 34 insertions(+), 14 deletions(-)
diff --git a/app/src/assets/localization/en/protocol_command_text.json b/app/src/assets/localization/en/protocol_command_text.json
index 0363d853d0c..b4e35e6fa18 100644
--- a/app/src/assets/localization/en/protocol_command_text.json
+++ b/app/src/assets/localization/en/protocol_command_text.json
@@ -89,8 +89,7 @@
"single": "single",
"single_nozzle_layout": "single nozzle layout",
"slot": "Slot {{slot_name}}",
- "stacker_display_name": "Stacker {{stacker_slot}}",
- "stacker_column_display_name": "Stacker in Column {{stacker_slot}}",
+ "stacker_hopper_display": "Stacker {{row}}",
"target_temperature": "target temperature",
"tc_awaiting_for_duration": "Waiting for Thermocycler profile to complete",
"tc_run_profile_steps": "Temperature: {{celsius}}°C, hold time: {{duration}}",
diff --git a/app/src/organisms/InterventionModal/MoveLabwareInterventionContent.tsx b/app/src/organisms/InterventionModal/MoveLabwareInterventionContent.tsx
index e0b0db538ea..07d0f5faed0 100644
--- a/app/src/organisms/InterventionModal/MoveLabwareInterventionContent.tsx
+++ b/app/src/organisms/InterventionModal/MoveLabwareInterventionContent.tsx
@@ -10,6 +10,7 @@ import {
DIRECTION_COLUMN,
DISPLAY_NONE,
Flex,
+ getLabwareDisplayLocation,
getLoadedLabware,
getLoadedModule,
Icon,
@@ -184,19 +185,27 @@ export function MoveLabwareInterventionContent({
-
-
diff --git a/components/src/organisms/CommandText/useCommandTextString/utils/getLabwareLocation.tsx b/components/src/organisms/CommandText/useCommandTextString/utils/getLabwareLocation.tsx
index 48dccd16b5b..ca3d93a0f52 100644
--- a/components/src/organisms/CommandText/useCommandTextString/utils/getLabwareLocation.tsx
+++ b/components/src/organisms/CommandText/useCommandTextString/utils/getLabwareLocation.tsx
@@ -1,6 +1,8 @@
import {
FLEX_STACKER_MODULE_V1,
getCutoutDisplayName,
+ getModuleType,
+ FLEX_STACKER_MODULE_TYPE,
getLabwareDefURI,
getLabwareDisplayName,
getModuleModelFromAddressableArea,
@@ -204,7 +206,9 @@ export function getLabwareLocation(
return {
slotName,
- moduleModel,
+ moduleModel: getModuleType(moduleModel) === FLEX_STACKER_MODULE_TYPE
+ ? undefined
+ : moduleModel,
}
} else if ('labwareId' in location) {
if (!Array.isArray(loadedLabwares)) {
diff --git a/components/src/organisms/CommandText/useCommandTextString/utils/getModuleDisplayLocation.ts b/components/src/organisms/CommandText/useCommandTextString/utils/getModuleDisplayLocation.ts
index 878dbbf6ab9..d9edc950c28 100644
--- a/components/src/organisms/CommandText/useCommandTextString/utils/getModuleDisplayLocation.ts
+++ b/components/src/organisms/CommandText/useCommandTextString/utils/getModuleDisplayLocation.ts
@@ -1,3 +1,4 @@
+import { FLEX_STACKER_MODULE_TYPE, getModuleType } from '@opentrons/shared-data'
import { getLoadedModule } from './getLoadedModule'
import type { LoadedModules } from './types'
@@ -7,5 +8,12 @@ export function getModuleDisplayLocation(
moduleId: string
): string {
const loadedModule = getLoadedModule(loadedModules, moduleId)
- return loadedModule != null ? loadedModule.location.slotName : ''
+ if (loadedModule == null) {
+ console.warn(`Module with ID ${moduleId} not found in loaded modules`)
+ return ''
+ }
+ const slotName = loadedModule.location.slotName
+ return getModuleType(loadedModule.model) === FLEX_STACKER_MODULE_TYPE
+ ? `${slotName[0]}4`
+ : slotName
}
From d640267f129a54f787cdc447aa282028b76015cb Mon Sep 17 00:00:00 2001
From: smb2268
Date: Tue, 5 Aug 2025 23:15:41 -0400
Subject: [PATCH 09/14] Fix locations for error recovery and intervention
modals, lint
---
.../shared/LeftColumnLabwareInfo.tsx | 8 +-
.../shared/StackerHopperLwInfo.tsx | 4 +-
.../shared/StackerShuttleLwInfo.tsx | 4 +-
.../shared/TwoColLwInfoAndDeck.tsx | 2 +-
.../MoveLabwareInterventionContent.tsx | 226 +++---------------
.../__tests__/InterventionModal.test.tsx | 3 -
.../ModuleTableItem.tsx | 1 -
.../Protocols/ProtocolPreview/SlotDetails.tsx | 9 +-
.../pages/ODD/ProtocolDetails/Hardware.tsx | 9 +-
.../ODD/QuickTransferDetails/Hardware.tsx | 9 +-
.../getLabwareDisplayLocation.test.tsx | 127 ++++++----
.../utils/commandText/getLoadCommandText.ts | 9 +-
.../utils/getLabwareDisplayLocation.tsx | 40 ++--
.../utils/getLabwareLocation.tsx | 34 +--
.../utils/getModuleDisplayLocation.ts | 1 +
15 files changed, 191 insertions(+), 295 deletions(-)
diff --git a/app/src/organisms/ErrorRecoveryFlows/shared/LeftColumnLabwareInfo.tsx b/app/src/organisms/ErrorRecoveryFlows/shared/LeftColumnLabwareInfo.tsx
index 04237d680d8..88649424917 100644
--- a/app/src/organisms/ErrorRecoveryFlows/shared/LeftColumnLabwareInfo.tsx
+++ b/app/src/organisms/ErrorRecoveryFlows/shared/LeftColumnLabwareInfo.tsx
@@ -76,7 +76,9 @@ export function LeftColumnLabwareInfo({
labwareName: failedLabwareNames.name ?? '',
labwareNickname: failedLabwareNames.nickName,
currentLocationProps: {
- deckLabel: displayNameCurrentLoc.toUpperCase(),
+ deckLabel: `STACKER ${(
+ displayNameCurrentLoc?.toUpperCase() ?? ''
+ ).charAt(0)}`,
},
}
case STACKER_STALLED_SKIP.STEPS.PLACE_LABWARE_ON_SHUTTLE:
@@ -86,7 +88,9 @@ export function LeftColumnLabwareInfo({
labwareName: failedLabwareNames.name ?? '',
labwareNickname: failedLabwareNames.nickName,
currentLocationProps: {
- deckLabel: displayNameNewLoc?.toUpperCase() ?? '',
+ deckLabel: `${(displayNameNewLoc?.toUpperCase() ?? '').charAt(
+ 0
+ )}4`,
},
}
default:
diff --git a/app/src/organisms/ErrorRecoveryFlows/shared/StackerHopperLwInfo.tsx b/app/src/organisms/ErrorRecoveryFlows/shared/StackerHopperLwInfo.tsx
index cde1d8af1ae..0227f6aae56 100644
--- a/app/src/organisms/ErrorRecoveryFlows/shared/StackerHopperLwInfo.tsx
+++ b/app/src/organisms/ErrorRecoveryFlows/shared/StackerHopperLwInfo.tsx
@@ -22,8 +22,8 @@ export function StackerHopperLwInfo(props: RecoveryContentProps): JSX.Element {
diff --git a/app/src/organisms/ErrorRecoveryFlows/shared/StackerShuttleLwInfo.tsx b/app/src/organisms/ErrorRecoveryFlows/shared/StackerShuttleLwInfo.tsx
index 3f8463b0149..dfae410a511 100644
--- a/app/src/organisms/ErrorRecoveryFlows/shared/StackerShuttleLwInfo.tsx
+++ b/app/src/organisms/ErrorRecoveryFlows/shared/StackerShuttleLwInfo.tsx
@@ -19,8 +19,8 @@ export function StackerShuttleLwInfo(props: RecoveryContentProps): JSX.Element {
diff --git a/app/src/organisms/ErrorRecoveryFlows/shared/TwoColLwInfoAndDeck.tsx b/app/src/organisms/ErrorRecoveryFlows/shared/TwoColLwInfoAndDeck.tsx
index a4989dea41c..17c6104f6ec 100644
--- a/app/src/organisms/ErrorRecoveryFlows/shared/TwoColLwInfoAndDeck.tsx
+++ b/app/src/organisms/ErrorRecoveryFlows/shared/TwoColLwInfoAndDeck.tsx
@@ -186,7 +186,7 @@ export function TwoColLwInfoAndDeck(
{...props}
title={buildTitle()}
type={buildType()}
- layout={'default'}
+ layout="default"
bannerText={buildBannerText()}
/>
{buildDeckView()}
diff --git a/app/src/organisms/InterventionModal/MoveLabwareInterventionContent.tsx b/app/src/organisms/InterventionModal/MoveLabwareInterventionContent.tsx
index 07d0f5faed0..c735523ef50 100644
--- a/app/src/organisms/InterventionModal/MoveLabwareInterventionContent.tsx
+++ b/app/src/organisms/InterventionModal/MoveLabwareInterventionContent.tsx
@@ -1,44 +1,26 @@
import { useTranslation } from 'react-i18next'
-import { css } from 'styled-components'
import {
- ALIGN_CENTER,
- BORDERS,
Box,
COLORS,
- DeckInfoLabel,
DIRECTION_COLUMN,
- DISPLAY_NONE,
Flex,
getLabwareDisplayLocation,
getLoadedLabware,
- getLoadedModule,
- Icon,
LabwareRender,
- LegacyStyledText,
MoveLabwareOnDeck,
- RESPONSIVENESS,
SPACING,
- TEXT_TRANSFORM_UPPERCASE,
- TYPOGRAPHY,
} from '@opentrons/components'
import {
getDeckDefFromRobotType,
getLoadedLabwareDefinitionsByUri,
- getModuleType,
- GRIPPER_WASTE_CHUTE_ADDRESSABLE_AREA,
- OT2_ROBOT_TYPE,
- TC_MODULE_LOCATION_OT2,
- TC_MODULE_LOCATION_OT3,
- THERMOCYCLER_MODULE_TYPE,
} from '@opentrons/shared-data'
-import { Divider } from '/app/atoms/structure'
+import { InterventionInfo } from '/app/molecules/InterventionModal/InterventionContent'
import { useNotifyDeckConfigurationQuery } from '/app/resources/deck_configuration'
import {
getLabwareNameFromRunData,
- getModuleModelFromRunData,
getRunLabwareRenderInfo,
getRunModuleRenderInfo,
} from './utils'
@@ -46,61 +28,10 @@ import {
import type { RunData } from '@opentrons/api-client'
import type {
CompletedProtocolAnalysis,
- LabwareDefinitionsByUri,
- LabwareLocation,
MoveLabwareRunTimeCommand,
RobotType,
} from '@opentrons/shared-data'
-const LABWARE_DESCRIPTION_STYLE = css`
- flex-direction: ${DIRECTION_COLUMN};
- grid-gap: ${SPACING.spacing8};
- padding: ${SPACING.spacing16};
- background-color: ${COLORS.grey20};
- border-radius: ${BORDERS.borderRadius4};
- @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
- background-color: ${COLORS.grey35};
- border-radius: ${BORDERS.borderRadius8};
- }
-`
-
-const LABWARE_NAME_TITLE_STYLE = css`
- font-weight: ${TYPOGRAPHY.fontWeightSemiBold};
- @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
- display: ${DISPLAY_NONE};
- }
-`
-
-const LABWARE_NAME_STYLE = css`
- color: ${COLORS.grey60};
- @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
- ${TYPOGRAPHY.bodyTextBold}
- color: ${COLORS.black90};
- }
-`
-
-const DIVIDER_STYLE = css`
- @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
- display: ${DISPLAY_NONE};
- }
-`
-
-const LABWARE_DIRECTION_STYLE = css`
- align-items: ${ALIGN_CENTER};
- grid-gap: ${SPACING.spacing4};
- text-transform: ${TEXT_TRANSFORM_UPPERCASE};
- @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
- grid-gap: ${SPACING.spacing8};
- }
-`
-
-const ICON_STYLE = css`
- height: 1.5rem;
- @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
- height: 2.5rem;
- }
-`
-
export interface MoveLabwareInterventionProps {
command: MoveLabwareRunTimeCommand
analysis: CompletedProtocolAnalysis | null
@@ -116,7 +47,7 @@ export function MoveLabwareInterventionContent({
robotType,
isOnDevice,
}: MoveLabwareInterventionProps): JSX.Element | null {
- const { t } = useTranslation(['protocol_setup', 'protocol_command_text'])
+ const { i18n, t } = useTranslation('protocol_command_text')
const analysisCommands = analysis?.commands ?? []
const labwareDefsByUri = getLoadedLabwareDefinitionsByUri(analysisCommands)
@@ -162,6 +93,24 @@ export function MoveLabwareInterventionContent({
? labwareDefsByUri?.[movedLabwareDefUri] ?? null
: null
if (oldLabwareLocation == null || movedLabwareDef == null) return null
+ const oldDisplayLabwareLocation = getLabwareDisplayLocation({
+ location: oldLabwareLocation,
+ loadedModules: run.modules,
+ loadedLabwares: run.labware,
+ robotType: 'OT-3 Standard',
+ detailLevel: 'slot-only',
+ includeSlotText: false,
+ t,
+ })
+ const newDisplayLabwareLocation = getLabwareDisplayLocation({
+ location: command.params.newLocation,
+ loadedModules: run.modules,
+ loadedLabwares: run.labware,
+ robotType: 'OT-3 Standard',
+ detailLevel: 'slot-only',
+ includeSlotText: false,
+ t,
+ })
return (
-
-
-
- {t('labware_name')}
-
-
- {labwareName}
-
-
-
-
-
-
-
-
-
-
+
@@ -247,92 +172,3 @@ export function MoveLabwareInterventionContent({
)
}
-
-interface LabwareDisplayLocationProps {
- protocolData: RunData
- location: LabwareLocation
- robotType: RobotType
- labwareDefsByUri: LabwareDefinitionsByUri
-}
-function LabwareDisplayLocation(
- props: LabwareDisplayLocationProps
-): JSX.Element {
- const { t } = useTranslation('protocol_command_text')
- const { protocolData, location, robotType } = props
- let displayLocation: string = ''
- if (location === 'offDeck' || location === 'systemLocation') {
- // TODO(BC, 08/28/23): remove this string cast after update i18next to >23 (see https://www.i18next.com/overview/typescript#argument-of-type-defaulttfuncreturn-is-not-assignable-to-parameter-of-type-xyz)
- displayLocation = String(t('offdeck'))
- } else if ('slotName' in location) {
- displayLocation = location.slotName
- } else if ('addressableAreaName' in location) {
- const aaLocation = location.addressableAreaName
- displayLocation =
- aaLocation === GRIPPER_WASTE_CHUTE_ADDRESSABLE_AREA
- ? t('waste_chute')
- : aaLocation
- } else if ('moduleId' in location) {
- const moduleModel = getModuleModelFromRunData(
- protocolData,
- location.moduleId
- )
- if (moduleModel == null) {
- console.warn('labware is located on an unknown module model')
- } else {
- const slotName =
- getLoadedModule(protocolData.modules, location.moduleId)?.location
- ?.slotName ?? ''
- const isModuleUnderAdapterThermocycler =
- getModuleType(moduleModel) === THERMOCYCLER_MODULE_TYPE
- if (isModuleUnderAdapterThermocycler) {
- displayLocation =
- robotType === OT2_ROBOT_TYPE
- ? TC_MODULE_LOCATION_OT2
- : TC_MODULE_LOCATION_OT3
- } else {
- displayLocation = slotName
- }
- }
- } else if ('labwareId' in location) {
- const adapter = protocolData.labware.find(
- lw => lw.id === location.labwareId
- )
- if (adapter == null) {
- console.warn('labware is located on an unknown adapter')
- } else if (
- adapter.location === 'offDeck' ||
- adapter.location === 'systemLocation'
- ) {
- displayLocation = t('off_deck')
- } else if ('slotName' in adapter.location) {
- displayLocation = adapter.location.slotName
- } else if ('addressableAreaName' in adapter.location) {
- displayLocation = adapter.location.addressableAreaName
- } else if ('moduleId' in adapter.location) {
- const moduleIdUnderAdapter = adapter.location.moduleId
- const moduleModel = protocolData.modules.find(
- module => module.id === moduleIdUnderAdapter
- )?.model
- if (moduleModel == null) {
- console.warn('labware is located on an adapter on an unknown module')
- } else {
- const slotName =
- getLoadedModule(protocolData.modules, adapter.location.moduleId)
- ?.location?.slotName ?? ''
- const isModuleUnderAdapterThermocycler =
- getModuleType(moduleModel) === THERMOCYCLER_MODULE_TYPE
- if (isModuleUnderAdapterThermocycler) {
- displayLocation =
- robotType === OT2_ROBOT_TYPE
- ? TC_MODULE_LOCATION_OT2
- : TC_MODULE_LOCATION_OT3
- } else {
- displayLocation = slotName
- }
- }
- } else {
- console.warn('display location could not be established: ', location)
- }
- }
- return
-}
diff --git a/app/src/organisms/InterventionModal/__tests__/InterventionModal.test.tsx b/app/src/organisms/InterventionModal/__tests__/InterventionModal.test.tsx
index be449057d39..a5386ea0951 100644
--- a/app/src/organisms/InterventionModal/__tests__/InterventionModal.test.tsx
+++ b/app/src/organisms/InterventionModal/__tests__/InterventionModal.test.tsx
@@ -172,7 +172,6 @@ describe('InterventionModal', () => {
}
render(props)
screen.getByText('Move labware on Otie')
- screen.getByText('Labware name')
screen.getByText('mockLabware')
screen.queryAllByText('A1')
screen.queryAllByText('D3')
@@ -211,7 +210,6 @@ describe('InterventionModal', () => {
}
render(props)
screen.getByText('Move labware on Otie')
- screen.getByText('Labware name')
screen.getByText('mockLabwareInStagingArea')
screen.queryAllByText('B4')
screen.queryAllByText('C4')
@@ -246,7 +244,6 @@ describe('InterventionModal', () => {
}
render(props)
screen.getByText('Move labware on Otie')
- screen.getByText('Labware name')
screen.getByText('mockLabware')
screen.queryAllByText('A1')
screen.queryAllByText('C1')
diff --git a/app/src/organisms/ODD/ProtocolSetup/ProtocolSetupModulesAndDeck/ModuleTableItem.tsx b/app/src/organisms/ODD/ProtocolSetup/ProtocolSetupModulesAndDeck/ModuleTableItem.tsx
index 23f07d72b1a..851b9b8ae2f 100644
--- a/app/src/organisms/ODD/ProtocolSetup/ProtocolSetupModulesAndDeck/ModuleTableItem.tsx
+++ b/app/src/organisms/ODD/ProtocolSetup/ProtocolSetupModulesAndDeck/ModuleTableItem.tsx
@@ -43,7 +43,6 @@ import type {
CutoutConfig,
CutoutFixtureId,
DeckDefinition,
- ModuleModel,
} from '@opentrons/shared-data'
import type { ModulePrepCommandsType } from '/app/local-resources/modules'
import type { ProtocolCalibrationStatus } from '/app/resources/runs'
diff --git a/app/src/pages/Desktop/Protocols/ProtocolPreview/SlotDetails.tsx b/app/src/pages/Desktop/Protocols/ProtocolPreview/SlotDetails.tsx
index 8864bf8983d..05817b42a2a 100644
--- a/app/src/pages/Desktop/Protocols/ProtocolPreview/SlotDetails.tsx
+++ b/app/src/pages/Desktop/Protocols/ProtocolPreview/SlotDetails.tsx
@@ -102,7 +102,10 @@ export function SlotDetails(props: SlotDetailsProps): JSX.Element {
@@ -134,8 +137,8 @@ export function SlotDetails(props: SlotDetailsProps): JSX.Element {
) : null}
{moduleOnSlot == null &&
- topMostLabwareOnSlot == null &&
- !isTrashOnSlot ? (
+ topMostLabwareOnSlot == null &&
+ !isTrashOnSlot ? (
) : null}
diff --git a/app/src/pages/ODD/ProtocolDetails/Hardware.tsx b/app/src/pages/ODD/ProtocolDetails/Hardware.tsx
index cc2b8fc582a..1a4df8b974a 100644
--- a/app/src/pages/ODD/ProtocolDetails/Hardware.tsx
+++ b/app/src/pages/ODD/ProtocolDetails/Hardware.tsx
@@ -16,9 +16,9 @@ import {
import {
getCutoutDisplayName,
getFixtureDisplayName,
+ getModuleDeckLabel,
getModuleDisplayName,
getModuleType,
- getModuleDeckLabel,
GRIPPER_V1_2,
MAGNETIC_BLOCK_FIXTURES,
MAGNETIC_BLOCK_TYPE,
@@ -123,9 +123,10 @@ function HardwareItem({
if (hardware.hardwareType === 'module') {
location = (