From 04b6ad3f6f9b96ec7e5996fd9d3bcfbee5896d6d Mon Sep 17 00:00:00 2001 From: Jamey Huffnagle Date: Fri, 18 Oct 2024 11:10:56 -0400 Subject: [PATCH] hoist utils out of Commands --- .../local-resources/labware/hooks/index.ts | 1 + .../hooks/useLabwareDisplayLocation.ts} | 60 +++++++++++++------ app/src/local-resources/labware/types.ts | 3 + .../getLabwareDefinitionsFromCommands.ts | 4 +- .../labware}/utils/getLabwareName.ts | 31 ++++++---- .../labware/utils/getLoadedLabware.ts | 12 ++++ .../local-resources/labware/utils/index.ts | 4 ++ app/src/local-resources/modules/index.ts | 5 +- app/src/local-resources/modules/types.ts | 3 + .../__tests__/getModuleImage.test.ts | 0 .../modules/utils/getLoadedModule.ts | 12 ++++ .../modules/utils/getModuleDisplayLocation.ts | 11 ++++ .../modules/{ => utils}/getModuleImage.ts | 0 .../modules/utils/getModuleModel.ts | 12 ++++ .../{ => utils}/getModulePrepCommands.ts | 0 .../local-resources/modules/utils/index.ts | 5 ++ app/src/molecules/Command/utils/accessors.ts | 29 +-------- .../Command/utils/getModuleDisplayLocation.ts | 11 ---- .../molecules/Command/utils/getModuleModel.ts | 12 ---- 19 files changed, 131 insertions(+), 84 deletions(-) rename app/src/{molecules/Command/utils/getLabwareDisplayLocation.ts => local-resources/labware/hooks/useLabwareDisplayLocation.ts} (70%) rename app/src/{molecules/Command => local-resources/labware}/utils/getLabwareDefinitionsFromCommands.ts (94%) rename app/src/{molecules/Command => local-resources/labware}/utils/getLabwareName.ts (50%) create mode 100644 app/src/local-resources/labware/utils/getLoadedLabware.ts create mode 100644 app/src/local-resources/modules/types.ts rename app/src/local-resources/modules/{ => utils}/__tests__/getModuleImage.test.ts (100%) create mode 100644 app/src/local-resources/modules/utils/getLoadedModule.ts create mode 100644 app/src/local-resources/modules/utils/getModuleDisplayLocation.ts rename app/src/local-resources/modules/{ => utils}/getModuleImage.ts (100%) create mode 100644 app/src/local-resources/modules/utils/getModuleModel.ts rename app/src/local-resources/modules/{ => utils}/getModulePrepCommands.ts (100%) create mode 100644 app/src/local-resources/modules/utils/index.ts delete mode 100644 app/src/molecules/Command/utils/getModuleDisplayLocation.ts delete mode 100644 app/src/molecules/Command/utils/getModuleModel.ts diff --git a/app/src/local-resources/labware/hooks/index.ts b/app/src/local-resources/labware/hooks/index.ts index 86c1116e270..2a0297fad2c 100644 --- a/app/src/local-resources/labware/hooks/index.ts +++ b/app/src/local-resources/labware/hooks/index.ts @@ -1 +1,2 @@ export * from './useAllLabware' +export * from './useLabwareDisplayLocation' diff --git a/app/src/molecules/Command/utils/getLabwareDisplayLocation.ts b/app/src/local-resources/labware/hooks/useLabwareDisplayLocation.ts similarity index 70% rename from app/src/molecules/Command/utils/getLabwareDisplayLocation.ts rename to app/src/local-resources/labware/hooks/useLabwareDisplayLocation.ts index 60b03609c79..83f84fa0ef2 100644 --- a/app/src/molecules/Command/utils/getLabwareDisplayLocation.ts +++ b/app/src/local-resources/labware/hooks/useLabwareDisplayLocation.ts @@ -1,3 +1,5 @@ +import { useTranslation } from 'react-i18next' + import { getLabwareDefURI, getLabwareDisplayName, @@ -6,26 +8,38 @@ import { getOccludedSlotCountForModule, } from '@opentrons/shared-data' -import { getModuleDisplayLocation } from './getModuleDisplayLocation' -import { getModuleModel } from './getModuleModel' +import { + getModuleModel, + getModuleDisplayLocation, +} from '/app/local-resources/modules' -import type { TFunction } from 'i18next' import type { RobotType, LabwareLocation, LabwareDefinition2, } from '@opentrons/shared-data' -import type { CommandTextData } from '../types' +import type { LoadedModules } from '/app/local-resources/modules' +import type { LoadedLabwares } from '/app/local-resources/labware' -// TODO(jh, 10-14-24): Refactor this util and related copy utils out of Command. -export function getLabwareDisplayLocation( - commandTextData: Omit, - allRunDefs: LabwareDefinition2[], - location: LabwareLocation, - t: TFunction, - robotType: RobotType, +export interface UseLabwareDisplayLocationProps { + loadedModules: LoadedModules + loadedLabwares: LoadedLabwares + allRunDefs: LabwareDefinition2[] + location: LabwareLocation + robotType: RobotType isOnDevice?: boolean -): string { +} + +export function useLabwareDisplayLocation({ + loadedLabwares, + loadedModules, + allRunDefs, + location, + robotType, + isOnDevice, +}: UseLabwareDisplayLocationProps): string { + const { t } = useTranslation('protocol_command_text') + if (location === 'offDeck') { return t('off_deck') } else if ('slotName' in location) { @@ -37,13 +51,13 @@ export function getLabwareDisplayLocation( ? location.addressableAreaName : t('slot', { slot_name: location.addressableAreaName }) } else if ('moduleId' in location) { - const moduleModel = getModuleModel(commandTextData, location.moduleId) + const moduleModel = getModuleModel(loadedModules, location.moduleId) if (moduleModel == null) { console.warn('labware is located on an unknown module model') return '' } else { const slotName = getModuleDisplayLocation( - commandTextData, + loadedModules, location.moduleId ) return isOnDevice @@ -58,9 +72,11 @@ export function getLabwareDisplayLocation( }) } } else if ('labwareId' in location) { - const adapter = commandTextData.labware.find( - lw => lw.id === location.labwareId - ) + if (!Array.isArray(loadedLabwares)) { + console.warn('Cannot get display location from loaded labwares object') + return '' + } + const adapter = loadedLabwares.find(lw => lw.id === location.labwareId) const adapterDef = allRunDefs.find( def => getLabwareDefURI(def) === adapter?.definitionUri ) @@ -84,7 +100,13 @@ export function getLabwareDisplayLocation( }) } else if ('moduleId' in adapter.location) { const moduleIdUnderAdapter = adapter.location.moduleId - const moduleModel = commandTextData.modules.find( + + if (!Array.isArray(loadedModules)) { + console.warn('Cannot get display location from loaded labwares object') + return '' + } + + const moduleModel = loadedModules.find( module => module.id === moduleIdUnderAdapter )?.model if (moduleModel == null) { @@ -92,7 +114,7 @@ export function getLabwareDisplayLocation( return '' } const slotName = getModuleDisplayLocation( - commandTextData, + loadedModules, adapter.location.moduleId ) return t('adapter_in_mod_in_slot', { diff --git a/app/src/local-resources/labware/types.ts b/app/src/local-resources/labware/types.ts index 99ea299573d..da55c9d7004 100644 --- a/app/src/local-resources/labware/types.ts +++ b/app/src/local-resources/labware/types.ts @@ -3,6 +3,7 @@ import type { LabwareWellShapeProperties, LabwareWellGroupMetadata, LabwareBrand, + LoadedLabware, } from '@opentrons/shared-data' export interface LabwareDefAndDate { @@ -35,3 +36,5 @@ export interface LabwareWellGroupProperties { metadata: LabwareWellGroupMetadata brand: LabwareBrand | null } + +export type LoadedLabwares = LoadedLabware[] | Record diff --git a/app/src/molecules/Command/utils/getLabwareDefinitionsFromCommands.ts b/app/src/local-resources/labware/utils/getLabwareDefinitionsFromCommands.ts similarity index 94% rename from app/src/molecules/Command/utils/getLabwareDefinitionsFromCommands.ts rename to app/src/local-resources/labware/utils/getLabwareDefinitionsFromCommands.ts index 238302e78e5..6016b0c5dd8 100644 --- a/app/src/molecules/Command/utils/getLabwareDefinitionsFromCommands.ts +++ b/app/src/local-resources/labware/utils/getLabwareDefinitionsFromCommands.ts @@ -1,6 +1,8 @@ -import type { LabwareDefinition2, RunTimeCommand } from '@opentrons/shared-data' import { getLabwareDefURI } from '@opentrons/shared-data' +import type { LabwareDefinition2, RunTimeCommand } from '@opentrons/shared-data' + +// Note: This is an O(n) operation. export function getLabwareDefinitionsFromCommands( commands: RunTimeCommand[] ): LabwareDefinition2[] { diff --git a/app/src/molecules/Command/utils/getLabwareName.ts b/app/src/local-resources/labware/utils/getLabwareName.ts similarity index 50% rename from app/src/molecules/Command/utils/getLabwareName.ts rename to app/src/local-resources/labware/utils/getLabwareName.ts index 03c6feb1367..af51fbc5fbc 100644 --- a/app/src/molecules/Command/utils/getLabwareName.ts +++ b/app/src/local-resources/labware/utils/getLabwareName.ts @@ -1,19 +1,28 @@ -import { getLoadedLabware } from './accessors' - import { getLabwareDefURI, getLabwareDisplayName } from '@opentrons/shared-data' -import { getLabwareDefinitionsFromCommands } from './getLabwareDefinitionsFromCommands' -import type { CommandTextData } from '../types' + +import { getLoadedLabware } from './getLoadedLabware' + +import type { LabwareDefinition2 } from '@opentrons/shared-data' +import type { LoadedLabwares } from '/app/local-resources/labware' const FIXED_TRASH_DEF_URIS = [ 'opentrons/opentrons_1_trash_850ml_fixed/1', 'opentrons/opentrons_1_trash_1100ml_fixed/1', 'opentrons/opentrons_1_trash_3200ml_fixed/1', ] -export function getLabwareName( - commandTextData: CommandTextData, + +export interface GetLabwareNameParams { + allRunDefs: LabwareDefinition2[] + loadedLabwares: LoadedLabwares labwareId: string -): string { - const loadedLabware = getLoadedLabware(commandTextData, labwareId) +} + +export function getLabwareName({ + allRunDefs, + loadedLabwares, + labwareId, +}: GetLabwareNameParams): string { + const loadedLabware = getLoadedLabware(loadedLabwares, labwareId) if (loadedLabware == null) { return '' } else if (FIXED_TRASH_DEF_URIS.includes(loadedLabware.definitionUri)) { @@ -21,9 +30,9 @@ export function getLabwareName( } else if (loadedLabware.displayName != null) { return loadedLabware.displayName } else { - const labwareDef = getLabwareDefinitionsFromCommands( - commandTextData.commands - ).find(def => getLabwareDefURI(def) === loadedLabware.definitionUri) + const labwareDef = allRunDefs.find( + def => getLabwareDefURI(def) === loadedLabware.definitionUri + ) return labwareDef != null ? getLabwareDisplayName(labwareDef) : '' } } diff --git a/app/src/local-resources/labware/utils/getLoadedLabware.ts b/app/src/local-resources/labware/utils/getLoadedLabware.ts new file mode 100644 index 00000000000..efd6981837a --- /dev/null +++ b/app/src/local-resources/labware/utils/getLoadedLabware.ts @@ -0,0 +1,12 @@ +import type { LoadedLabware } from '@opentrons/shared-data' +import type { LoadedLabwares } from '/app/local-resources/labware' + +export function getLoadedLabware( + loadedLabware: LoadedLabwares, + labwareId: string +): LoadedLabware | undefined { + // NOTE: old analysis contains a object dictionary of labware entities by id, this case is supported for backwards compatibility purposes + return Array.isArray(loadedLabware) + ? loadedLabware.find(l => l.id === labwareId) + : loadedLabware[labwareId] +} diff --git a/app/src/local-resources/labware/utils/index.ts b/app/src/local-resources/labware/utils/index.ts index 310ed3f065a..4288cf992aa 100644 --- a/app/src/local-resources/labware/utils/index.ts +++ b/app/src/local-resources/labware/utils/index.ts @@ -1,2 +1,6 @@ export * from './getAllDefinitions' export * from './labwareImages' +export * from './getAllDefs' +export * from './getLabwareDefinitionsFromCommands' +export * from './getLabwareName' +export * from './getLoadedLabware' diff --git a/app/src/local-resources/modules/index.ts b/app/src/local-resources/modules/index.ts index e508be48e92..85dcaa20ea5 100644 --- a/app/src/local-resources/modules/index.ts +++ b/app/src/local-resources/modules/index.ts @@ -1,2 +1,3 @@ -export * from './getModulePrepCommands' -export * from './getModuleImage' +export * from './utils' + +export * from './types' diff --git a/app/src/local-resources/modules/types.ts b/app/src/local-resources/modules/types.ts new file mode 100644 index 00000000000..8317beac7e8 --- /dev/null +++ b/app/src/local-resources/modules/types.ts @@ -0,0 +1,3 @@ +import type { LoadedModule } from '@opentrons/shared-data' + +export type LoadedModules = LoadedModule[] | Record diff --git a/app/src/local-resources/modules/__tests__/getModuleImage.test.ts b/app/src/local-resources/modules/utils/__tests__/getModuleImage.test.ts similarity index 100% rename from app/src/local-resources/modules/__tests__/getModuleImage.test.ts rename to app/src/local-resources/modules/utils/__tests__/getModuleImage.test.ts diff --git a/app/src/local-resources/modules/utils/getLoadedModule.ts b/app/src/local-resources/modules/utils/getLoadedModule.ts new file mode 100644 index 00000000000..70047e095e6 --- /dev/null +++ b/app/src/local-resources/modules/utils/getLoadedModule.ts @@ -0,0 +1,12 @@ +import type { LoadedModule } from '@opentrons/shared-data' +import type { LoadedModules } from '/app/local-resources/modules/types' + +export function getLoadedModule( + loadedModules: LoadedModules, + moduleId: string +): LoadedModule | undefined { + // NOTE: old analysis contains a object dictionary of module entities by id, this case is supported for backwards compatibility purposes + return Array.isArray(loadedModules) + ? loadedModules.find(l => l.id === moduleId) + : loadedModules[moduleId] +} diff --git a/app/src/local-resources/modules/utils/getModuleDisplayLocation.ts b/app/src/local-resources/modules/utils/getModuleDisplayLocation.ts new file mode 100644 index 00000000000..665e31d8975 --- /dev/null +++ b/app/src/local-resources/modules/utils/getModuleDisplayLocation.ts @@ -0,0 +1,11 @@ +import { getLoadedModule } from './getLoadedModule' + +import type { LoadedModules } from '../types' + +export function getModuleDisplayLocation( + loadedModules: LoadedModules, + moduleId: string +): string { + const loadedModule = getLoadedModule(loadedModules, moduleId) + return loadedModule != null ? loadedModule.location.slotName : '' +} diff --git a/app/src/local-resources/modules/getModuleImage.ts b/app/src/local-resources/modules/utils/getModuleImage.ts similarity index 100% rename from app/src/local-resources/modules/getModuleImage.ts rename to app/src/local-resources/modules/utils/getModuleImage.ts diff --git a/app/src/local-resources/modules/utils/getModuleModel.ts b/app/src/local-resources/modules/utils/getModuleModel.ts new file mode 100644 index 00000000000..18302253499 --- /dev/null +++ b/app/src/local-resources/modules/utils/getModuleModel.ts @@ -0,0 +1,12 @@ +import { getLoadedModule } from './getLoadedModule' + +import type { ModuleModel } from '@opentrons/shared-data' +import type { LoadedModules } from '/app/local-resources/modules/types' + +export function getModuleModel( + loadedModules: LoadedModules, + moduleId: string +): ModuleModel | null { + const loadedModule = getLoadedModule(loadedModules, moduleId) + return loadedModule != null ? loadedModule.model : null +} diff --git a/app/src/local-resources/modules/getModulePrepCommands.ts b/app/src/local-resources/modules/utils/getModulePrepCommands.ts similarity index 100% rename from app/src/local-resources/modules/getModulePrepCommands.ts rename to app/src/local-resources/modules/utils/getModulePrepCommands.ts diff --git a/app/src/local-resources/modules/utils/index.ts b/app/src/local-resources/modules/utils/index.ts new file mode 100644 index 00000000000..7f3f558738d --- /dev/null +++ b/app/src/local-resources/modules/utils/index.ts @@ -0,0 +1,5 @@ +export * from './getLoadedModule' +export * from './getModuleDisplayLocation' +export * from './getModuleImage' +export * from './getModuleModel' +export * from './getModulePrepCommands' diff --git a/app/src/molecules/Command/utils/accessors.ts b/app/src/molecules/Command/utils/accessors.ts index 651fb15769e..f173e382799 100644 --- a/app/src/molecules/Command/utils/accessors.ts +++ b/app/src/molecules/Command/utils/accessors.ts @@ -1,21 +1,6 @@ -import type { RunData } from '@opentrons/api-client' -import type { - CompletedProtocolAnalysis, - LoadedLabware, - LoadedModule, - LoadedPipette, -} from '@opentrons/shared-data' +import type { LoadedPipette } from '@opentrons/shared-data' import type { CommandTextData } from '../types' -export function getLoadedLabware( - commandTextData: CompletedProtocolAnalysis | RunData | CommandTextData, - labwareId: string -): LoadedLabware | undefined { - // NOTE: old analysis contains a object dictionary of labware entities by id, this case is supported for backwards compatibility purposes - return Array.isArray(commandTextData.labware) - ? commandTextData.labware.find(l => l.id === labwareId) - : commandTextData.labware[labwareId] -} export function getLoadedPipette( commandTextData: CommandTextData, mount: string @@ -25,15 +10,3 @@ export function getLoadedPipette( ? commandTextData.pipettes.find(l => l.mount === mount) : commandTextData.pipettes[mount] } -export function getLoadedModule( - commandTextData: - | CompletedProtocolAnalysis - | RunData - | Omit, - moduleId: string -): LoadedModule | undefined { - // NOTE: old analysis contains a object dictionary of module entities by id, this case is supported for backwards compatibility purposes - return Array.isArray(commandTextData.modules) - ? commandTextData.modules.find(l => l.id === moduleId) - : commandTextData.modules[moduleId] -} diff --git a/app/src/molecules/Command/utils/getModuleDisplayLocation.ts b/app/src/molecules/Command/utils/getModuleDisplayLocation.ts deleted file mode 100644 index fa5e527d218..00000000000 --- a/app/src/molecules/Command/utils/getModuleDisplayLocation.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { getLoadedModule } from './accessors' - -import type { CommandTextData } from '../types' - -export function getModuleDisplayLocation( - commandTextData: Omit, - moduleId: string -): string { - const loadedModule = getLoadedModule(commandTextData, moduleId) - return loadedModule != null ? loadedModule.location.slotName : '' -} diff --git a/app/src/molecules/Command/utils/getModuleModel.ts b/app/src/molecules/Command/utils/getModuleModel.ts deleted file mode 100644 index fdac4850331..00000000000 --- a/app/src/molecules/Command/utils/getModuleModel.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { getLoadedModule } from './accessors' - -import type { ModuleModel } from '@opentrons/shared-data' -import type { CommandTextData } from '../types' - -export function getModuleModel( - commandTextData: Omit, - moduleId: string -): ModuleModel | null { - const loadedModule = getLoadedModule(commandTextData, moduleId) - return loadedModule != null ? loadedModule.model : null -}