Skip to content

feature(app): get command text for flex stacker commands #18045

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

Merged
merged 31 commits into from
Apr 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
823fbbc
WIP implement getFlexStackerCommandText
TamarZanzouri Apr 9, 2025
eacd66c
exploring
TamarZanzouri Apr 9, 2025
e3e2c23
get retieve command text
TamarZanzouri Apr 9, 2025
dd88d91
command text for store WIP
TamarZanzouri Apr 10, 2025
cc67cdf
add defualts to text. fixed logic to get labware location. lint fixes
TamarZanzouri Apr 10, 2025
7c25d82
setStoredLabware
TamarZanzouri Apr 10, 2025
b06b674
empty+fill
TamarZanzouri Apr 10, 2025
b30714f
bug fixes and started to add tests
TamarZanzouri Apr 10, 2025
22fa669
added tests
TamarZanzouri Apr 11, 2025
735849e
export and import KEYS_BY_COMMAND_TYPE
TamarZanzouri Apr 11, 2025
00d5e27
describe each and move logic to function without let
TamarZanzouri Apr 11, 2025
46b35ff
linting
TamarZanzouri Apr 11, 2025
906b7f3
Update app/src/assets/localization/en/protocol_command_text.json
TamarZanzouri Apr 11, 2025
1a6125f
Update app/src/assets/localization/en/protocol_command_text.json
TamarZanzouri Apr 11, 2025
ce40b3e
Merge branch 'edge' into EXEC-1135-support-for-stacker-commands-in-ru…
TamarZanzouri Apr 11, 2025
0d3e231
Merge branch 'edge' into EXEC-1135-support-for-stacker-commands-in-ru…
TamarZanzouri Apr 15, 2025
c4547f7
pr feedback + getLabwareDisplayLocation WIP
TamarZanzouri Apr 15, 2025
67a0a90
WIP get labware location
TamarZanzouri Apr 15, 2025
12536f3
slot only and full for stacker and text fixes
TamarZanzouri Apr 16, 2025
2d939f8
branded translations
TamarZanzouri Apr 16, 2025
4b9493d
Merge branch 'edge' into EXEC-1135-support-for-stacker-commands-in-ru…
TamarZanzouri Apr 16, 2025
9c7c4f3
get def by uri and column for full command text
TamarZanzouri Apr 16, 2025
1141e2c
fixed failing tests and detail level and moduleModel null when stACKER
TamarZanzouri Apr 16, 2025
ef17990
lint and formatting
TamarZanzouri Apr 16, 2025
07b95c7
Update components/src/organisms/CommandText/useCommandTextString/util…
TamarZanzouri Apr 16, 2025
684a1e0
removed comments and changed to robot
TamarZanzouri Apr 16, 2025
f9ba3af
suggestion fix
TamarZanzouri Apr 16, 2025
f85d914
fixed column name and small fixes
TamarZanzouri Apr 16, 2025
2a0b002
simplify getSlotColumn thanks to Sara
TamarZanzouri Apr 16, 2025
ed839ac
fixed lint
TamarZanzouri Apr 17, 2025
6a17483
lint
TamarZanzouri Apr 17, 2025
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
10 changes: 10 additions & 0 deletions app/src/assets/localization/en/anonymous.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@
"estop_pressed_description": "First, safely clear the deck of any labware or spills. Then, twist the E-stop button clockwise. Finally, have the robot move the gantry to its home position.",
"find_your_robot": "Find your robot in the Devices section of the app to install software updates.",
"firmware_update_download_logs": "Contact support for assistance.",
"flex_stacker_empty": "Manually empty all labware from robot Stacker",
"flex_stacker_empty_from_location": "Manually empty all labware from robot {{stackerColumn}}",
"flex_stacker_fill": "Fill robot Stacker",
"flex_stacker_fill_with_quantity_and_labware": "Fill robot {{stackerColumn}} with {{quantity}} {{labwareAndLidDisplayNames}}",
"flex_stacker_retrieve": "Retrieve from robot Stacker",
"flex_stacker_set_stored_labware": "Set stored labware in robot Stacker",
"flex_stacker_set_stored_labware_with_quantity_and_location": "Configure robot {{stackerColumn}} with {{quantity}} {{labwareAndLidDisplayNames}}",
"flex_stacker_store": "Store into robot Stacker",
"general_error_message": "If you keep getting this message, try restarting your app and robot. If this does not resolve the issue, contact support.",
"gripper": "Gripper",
"gripper_still_attached": "Gripper still attached",
Expand Down Expand Up @@ -55,6 +63,7 @@
"previous_releases": "View previous releases",
"receive_alert": "Receive an alert when a software update is available.",
"restore_description": "Reverting to previous software versions is not recommended, but you can access previous releases below. For best results, uninstall the existing app and remove its configuration files before installing the previous version.",
"retrieve_labware_from_stacker_to": "Retrieve {{primaryDefinitionDisplayName}} from robot Stacker to {{slotName}}",
"robot_server_version_ot3_description": "The robot software includes the robot server and the touchscreen display interface.",
"robot_software_update_required": "A robot software update is required to run protocols with this version of the app.",
"run_failed_modal_description_desktop": "Contact support for assistance.",
Expand All @@ -70,6 +79,7 @@
"show_labware_offset_snippets_description": "Only for users who need to apply labware offset data outside of the app. When enabled, code snippets for Jupyter Notebook and SSH are available during protocol setup after configuring all required offsets.",
"something_seems_wrong": "There may be a problem with your pipette. Exit setup and contact support for assistance.",
"storage_limit_reached_description": "Your robot has reached the limit of quick transfers that it can store. You must delete an existing quick transfer before creating a new one.",
"store_labware_from_slot_to_stacker": "Store {{primaryDefinitionDisplayName}} from {{slotName}} to robot Stacker",
"system_language_preferences_update_description": "Your system’s language was recently updated. Would you like to use the updated language as the default for the app?",
"these_are_advanced_settings": "<block>These are advanced settings. Please do not attempt to adjust without assistance from support. Changing these settings may affect the lifespan of your pipette.</block><block>These settings do not override any pipette settings defined in protocols.</block>",
"u2e_driver_description": "The OT-2 uses this adapter for its USB connection to the desktop app.",
Expand Down
10 changes: 10 additions & 0 deletions app/src/assets/localization/en/branded.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@
"estop_pressed_description": "First, safely clear the deck of any labware or spills. Then, twist the E-stop button clockwise. Finally, have Flex move the gantry to its home position.",
"find_your_robot": "Find your robot in the Opentrons App to install software updates.",
"firmware_update_download_logs": "Download the robot logs from the Opentrons App and send them to support@opentrons.com for assistance.",
"flex_stacker_empty": "Manually empty all labware from Flex Stacker",
"flex_stacker_empty_from_location": "Manually empty all labware from Flex {{stackerColumn}}",
"flex_stacker_fill": "Fill Flex Stacker",
"flex_stacker_fill_with_quantity_and_labware": "Fill Flex {{stackerColumn}} with {{quantity}} {{labwareAndLidDisplayNames}}",
"flex_stacker_retrieve": "Retrieve from Flex Stacker",
"flex_stacker_set_stored_labware": "Set stored labware in Flex Stacker",
"flex_stacker_set_stored_labware_with_quantity_and_location": "Configure Flex {{stackerColumn}} with {{quantity}} {{labwareAndLidDisplayNames}}",
"flex_stacker_store": "Store into Flex Stacker",
"general_error_message": "If you keep getting this message, try restarting your app and robot. If this does not resolve the issue, contact Opentrons Support.",
"gripper": "Flex Gripper",
"gripper_still_attached": "Flex Gripper still attached",
Expand Down Expand Up @@ -55,6 +63,7 @@
"previous_releases": "View previous Opentrons releases",
"receive_alert": "Receive an alert when an Opentrons software update is available.",
"restore_description": "Opentrons does not recommend reverting to previous software versions, but you can access previous releases below. For best results, uninstall the existing app and remove its configuration files before installing the previous version.",
"retrieve_labware_from_stacker_to": "Retrieve {{primaryDefinitionDisplayName}} from Flex Stacker to {{slotName}}",
"robot_server_version_ot3_description": "The Opentrons Flex software includes the robot server and the touchscreen display interface.",
"robot_software_update_required": "A robot software update is required to run protocols with this version of the Opentrons App.",
"run_failed_modal_description_desktop": "Download the run log and send it to support@opentrons.com for assistance.",
Expand All @@ -70,6 +79,7 @@
"show_labware_offset_snippets_description": "Only for users who need to apply labware offset data outside of the Opentrons App. When enabled, code snippets for Jupyter Notebook and SSH are available during protocol setup after configuring all required offsets.",
"something_seems_wrong": "There may be a problem with your pipette. Exit setup and contact Opentrons Support for assistance.",
"storage_limit_reached_description": "Your Opentrons Flex has reached the limit of quick transfers that it can store. You must delete an existing quick transfer before creating a new one.",
"store_labware_from_slot_to_stacker": "Store {{primaryDefinitionDisplayName}} from {{slotName}} to Flex Stacker",
"system_language_preferences_update_description": "Your system’s language was recently updated. Would you like to use the updated language as the default for the Opentrons App?",
"these_are_advanced_settings": "<block>These are advanced settings. Please do not attempt to adjust without assistance from Opentrons Support. Changing these settings may affect the lifespan of your pipette.</block><block>These settings do not override any pipette settings defined in protocols.</block>",
"u2e_driver_description": "The OT-2 uses this adapter for its USB connection to the Opentrons App.",
Expand Down
4 changes: 3 additions & 1 deletion app/src/assets/localization/en/protocol_command_text.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
"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}}",
"target_temperature": "target temperature",
"tc_awaiting_for_duration": "Waiting for Thermocycler profile to complete",
"tc_run_profile_steps": "Temperature: {{celsius}}°C, hold time: {{duration}}",
Expand All @@ -108,5 +109,6 @@
"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}}",
"waste_chute": "Waste Chute",
"with_reference_of": "with reference of {{wavelength}} nm"
"with_reference_of": "with reference of {{wavelength}} nm",
"with_lid_name": " with {{lidDisplayName}}"
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
params: UseCommandTextStringParams
): GetCommandTextResult {
const { command } = params
const { t } = useTranslation('protocol_command_text')
const { t } = useTranslation(['protocol_command_text', 'branded'])

Check warning on line 56 in components/src/organisms/CommandText/useCommandTextString/index.ts

View check run for this annotation

Codecov / codecov/patch

components/src/organisms/CommandText/useCommandTextString/index.ts#L56

Added line #L56 was not covered by tests

const fullParams = { ...params, t }

Expand Down Expand Up @@ -147,6 +147,18 @@
command,
}),
}
case 'flexStacker/retrieve':
case 'flexStacker/store':
case 'flexStacker/setStoredLabware':
case 'flexStacker/empty':
case 'flexStacker/fill':
return {
kind: 'generic',
commandText: utils.getFlexStackerCommandText({
...fullParams,
command,
}),
}

Check warning on line 161 in components/src/organisms/CommandText/useCommandTextString/index.ts

View check run for this annotation

Codecov / codecov/patch

components/src/organisms/CommandText/useCommandTextString/index.ts#L155-L161

Added lines #L155 - L161 were not covered by tests
case 'thermocycler/runProfile':
return utils.getTCRunProfileCommandText({ ...fullParams, command })

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
import { screen } from '@testing-library/react'
import { vi, describe, it, beforeEach } from 'vitest'
import { useTranslation } from 'react-i18next'

import { renderWithProviders } from '../../../../../../testing/utils'
import { i18n } from '../../../../../../i18n'
import {
getFlexStackerCommandText,
KEYS_BY_COMMAND_TYPE,
} from '../getFlexStackerCommandText'
import { getLabwareDefURI } from '@opentrons/shared-data'
import { getLabwareDisplayLocation } from '../../getLabwareDisplayLocation'

vi.mock('@opentrons/shared-data')
vi.mock('../../getLabwareDisplayLocation')

const baseCommandData = {
allRunDefs: [
{ metadata: { displayName: 'tip rack' } },
{ metadata: { displayName: 'plate' } },
],
robotType: 'OT-2',
commandTextData: {
commands: [],
labware: [],
modules: [],
pipettes: [{ id: 'pipette-1', pipetteName: 'p300_single' }],
},
} as any

function TestWrapper({ command }: { command: any }): JSX.Element {
const { t } = useTranslation(['protocol_command_text', 'branded'])
const text = getFlexStackerCommandText({
command,
...baseCommandData,
t,
})

return <div>{text}</div>
}

const render = (command: any) => {
return renderWithProviders(<TestWrapper command={command} />, {
i18nInstance: i18n,
})
}

describe('getPipettingCommandText', () => {
beforeEach(() => {
vi.mocked(getLabwareDefURI).mockReturnValue('tiprack-uri')
vi.mocked(getLabwareDisplayLocation).mockReturnValue('Slot 1')
})

it('should render retrieve command text correctly', () => {
const command = {
id: 'cmd-1',
commandType: 'flexStacker/retrieve',
params: {
moduleId: 'module-id',
},
result: {
primaryLabwareURI: 'tiprack-uri',
},
}

render(command)
screen.getByText('retrieve_labware_from_stacker_to')
})

it('should render store command text correctly', () => {
const command = {
id: 'cmd-1',
commandType: 'flexStacker/store',
params: {
moduleId: 'module-id',
},
result: {
primaryLabwareURI: 'tiprack-uri',
primaryOriginLocationSequence: [
{ kind: 'onAddressableArea', addressableAreaName: 'A1' },
],
},
}

render(command)
screen.getByText('store_labware_from_slot_to_stacker')
})

it('should render setStoredLabware command text correctly', () => {
const command = {
id: 'cmd-1',
commandType: 'flexStacker/setStoredLabware',
params: {
moduleId: 'module-id',
},
result: {
primaryLabwareURI: 'tiprack-uri',
primaryLabwareDefinition: {
metadata: {
displayName: 'dummy def',
},
},
primaryOriginLocationSequence: [
{ kind: 'onAddressableArea', addressableAreaName: 'A1' },
],
},
}

render(command)
screen.getByText(
'flex_stacker_set_stored_labware_with_quantity_and_location'
)
})

it('should render fill command text correctly', () => {
const command = {
id: 'cmd-1',
commandType: 'flexStacker/fill',
params: {
moduleId: 'module-id',
},
result: {
primaryLabwareURI: 'tiprack-uri',
primaryLabwareDefinition: {
metadata: {
displayName: 'dummy def',
},
},
primaryOriginLocationSequence: [
{ kind: 'onAddressableArea', addressableAreaName: 'A1' },
],
},
}

render(command)
screen.getByText('flex_stacker_fill_with_quantity_and_labware')
})

it('should render empty command text correctly', () => {
const command = {
id: 'cmd-1',
commandType: 'flexStacker/empty',
params: {
moduleId: 'module-id',
},
result: {
primaryLabwareURI: 'tiprack-uri',
primaryLabwareDefinition: {
metadata: {
displayName: 'dummy def',
},
},
primaryOriginLocationSequence: [
{ kind: 'onAddressableArea', addressableAreaName: 'A1' },
],
},
}
render(command)
screen.getByText('flex_stacker_empty_from_location')
})
})

describe.each(Object.entries(KEYS_BY_COMMAND_TYPE))(
'Default fallback for %s',
(commandType, expectedKey) => {
it(`should render default text for ${commandType} when result is missing`, () => {
const command = {
id: 'cmd-1',
commandType: commandType,
params: {
moduleId: 'module-id',
},
}
render(command)
screen.getByText(expectedKey)
})
}
)
Loading
Loading