Skip to content

Commit 2533b1b

Browse files
authored
refactor(app): standardize module USB port display info (#19029)
This PR introduces a new hook, `getModuleUSBPort`, to standardize the formatting of USB port information for modules, ensuring consistency in module USB port display across the codebase.
1 parent 36663c3 commit 2533b1b

File tree

23 files changed

+111
-132
lines changed

23 files changed

+111
-132
lines changed

app/src/assets/localization/en/deck_configuration.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@
1212
"magnetic_block": "Magnetic block",
1313
"waste_chute": "Waste chute",
1414
"staging_area_slot": "Staging area slot",
15-
"module_in_port": "{{moduleName}} in USB-{{usbPortNumber}}"
15+
"module_in_port": "{{moduleName}} in {{usbPortNumber}}"
1616
}

app/src/assets/localization/en/device_details.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,11 @@
194194
"tip_pickup_drop": "Tip Pickup / Drop",
195195
"to_run_protocol_go_to_protocols_page": "To run a protocol on this robot, import a protocol on the <navlink>Protocols page</navlink>",
196196
"trash": "Trash",
197+
"unknown": "Unknown",
197198
"update_now": "Update now",
198199
"updating_firmware": "Updating firmware...",
199-
"usb_port": "usb-{{port}}{{hubPort}}",
200+
"usb_port": "USB-{{port}}",
201+
"usb_port_stacker": "S-{{port}}",
200202
"usb_port_not_connected": "usb not connected",
201203
"version": "Version {{version}}",
202204
"view": "View",

app/src/assets/localization/en/module_wizard_flows.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@
3838
"install_update": "Install update",
3939
"location_occupied": "A {{fixture}} is currently specified here on the deck configuration",
4040
"module_added": "New module detected. Setup the module for use.",
41-
"module_attached_to_port": "New {{module}} attached to USB-{{port}}!",
41+
"module_attached_to_port": "New {{module}} attached to {{port}}!",
4242
"module_attached_multiple": "Multiple new modules detected. Which module do you want to setup?",
43-
"module_attached_select": "{{module}} in USB-{{port}}",
43+
"module_attached_select": "{{module}} in {{port}}",
4444
"module_start_setup": "Start setup",
4545
"module_added_link": "Launch Setup",
4646
"module_calibrating": "Stand back, {{moduleName}} is calibrating",
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './useModuleUSBPort'
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { useTranslation } from 'react-i18next'
2+
3+
import { FLEX_STACKER_MODULE_TYPE } from '@opentrons/shared-data'
4+
5+
import type { AttachedModule } from '/app/redux/modules/types'
6+
7+
export interface UseModuleUSBPortResult {
8+
parseModuleUSBPort: (module: AttachedModule | null) => string
9+
}
10+
11+
export function useModuleUSBPort(): UseModuleUSBPortResult {
12+
const { t } = useTranslation('device_details')
13+
14+
const parseModuleUSBPort = (module: AttachedModule | null): string => {
15+
if (module?.usbPort == null) {
16+
return t('usb_port_not_connected')
17+
}
18+
19+
const { port, hubPort } = module.usbPort
20+
if (module.moduleType === FLEX_STACKER_MODULE_TYPE) {
21+
if (hubPort != null) {
22+
return t('usb_port_stacker', { port: hubPort })
23+
} else {
24+
console.error(`Flex Stacker ${module.serialNumber} has no USB hubPort`)
25+
return t('usb_port_stacker', { port: t('unknown') })
26+
}
27+
}
28+
29+
return t('usb_port', {
30+
port: port + (hubPort != null ? '.' + hubPort : ''),
31+
})
32+
}
33+
34+
return { parseModuleUSBPort }
35+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './utils'
2+
export * from './hooks'

app/src/molecules/ModuleInfo/ModuleInfo.tsx

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,11 @@ import {
2424
import { useRunHasStarted } from '/app/resources/runs'
2525

2626
import type { ModuleModel } from '@opentrons/shared-data'
27-
import type { PhysicalPort } from '/app/redux/modules/api-types'
2827

2928
export interface ModuleInfoProps {
3029
moduleModel: ModuleModel
3130
isAttached: boolean
32-
physicalPort: PhysicalPort | null
31+
physicalPort?: string | null
3332
runId?: string
3433
}
3534

@@ -49,14 +48,8 @@ export const ModuleInfo = (props: ModuleInfoProps): JSX.Element => {
4948
if (moduleModel === MAGNETIC_BLOCK_V1) {
5049
connectionStatus = t('no_usb_required')
5150
}
52-
if (physicalPort === null && isAttached) {
53-
connectionStatus = t('usb_connected_no_port_info')
54-
} else if (physicalPort != null && isAttached) {
55-
const portDisplay =
56-
physicalPort?.hubPort != null
57-
? `${physicalPort.port}.${physicalPort.hubPort}`
58-
: physicalPort?.port
59-
connectionStatus = t('usb_port_connected', { port: portDisplay })
51+
if (isAttached) {
52+
connectionStatus = physicalPort ?? t('usb_connected_no_port_info')
6053
}
6154

6255
return (

app/src/molecules/ModuleInfo/__tests__/ModuleInfo.test.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,18 @@ describe('ModuleInfo', () => {
5656
it('should show module connected and USB number', () => {
5757
props = {
5858
...props,
59-
physicalPort: { port: 1, hub: false, portGroup: 'unknown', path: '' },
59+
physicalPort: 'USB-1',
6060
isAttached: true,
6161
}
6262
render(props)
6363
screen.getByText('Connected')
64-
screen.getByText('USB Port 1')
64+
screen.getByText('USB-1')
6565
})
6666

6767
it('should not show module connected when run has started', () => {
6868
props = {
6969
...props,
70-
physicalPort: { port: 1, hub: false, portGroup: 'unknown', path: '' },
70+
physicalPort: 'USB-1',
7171
isAttached: true,
7272
runId: MOCK_RUN_ID,
7373
}

app/src/organisms/Desktop/Devices/ProtocolRun/ProtocolRunHeader/RunHeaderModalContainer/modals/HeaterShakerIsRunningModal/HeaterShakerModuleCard.tsx

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { useTranslation } from 'react-i18next'
2-
31
import {
42
ALIGN_FLEX_START,
53
COLORS,
@@ -15,6 +13,7 @@ import {
1513
import { getModuleDisplayName } from '@opentrons/shared-data'
1614

1715
import heaterShakerModule from '/app/assets/images/heater_shaker_module_transparent.png'
16+
import { useModuleUSBPort } from '/app/local-resources/modules'
1817
import { HeaterShakerModuleData } from '/app/organisms/ModuleCard/HeaterShakerModuleData'
1918

2019
import type { HeaterShakerModule } from '/app/redux/modules/types'
@@ -27,7 +26,7 @@ export const HeaterShakerModuleCard = (
2726
props: HeaterShakerModuleCardProps
2827
): JSX.Element | null => {
2928
const { module } = props
30-
const { t } = useTranslation('device_details')
29+
const { parseModuleUSBPort } = useModuleUSBPort()
3130

3231
return (
3332
<Flex
@@ -51,11 +50,7 @@ export const HeaterShakerModuleCard = (
5150
fontSize={TYPOGRAPHY.fontSizeCaption}
5251
paddingBottom={SPACING.spacing4}
5352
>
54-
{module?.usbPort !== null
55-
? t('usb_port', {
56-
port: module?.usbPort?.port,
57-
})
58-
: t('usb_port_not_connected')}
53+
{parseModuleUSBPort(module)}
5954
</LegacyStyledText>
6055
<Flex paddingBottom={SPACING.spacing4}>
6156
<Icon

app/src/organisms/Desktop/Devices/ProtocolRun/ProtocolRunHeader/RunHeaderModalContainer/modals/HeaterShakerIsRunningModal/__tests__/HeaterShakerModuleCard.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ describe('HeaterShakerModuleCard', () => {
3131

3232
it('renders the correct info', () => {
3333
render(props)
34-
screen.getByText('usb-1')
34+
screen.getByText('USB-1')
3535
screen.getByText('Heater-Shaker Module GEN1')
3636
screen.getByText('mock heater shaker module data')
3737
screen.getByAltText('Heater-Shaker')

0 commit comments

Comments
 (0)