Skip to content

Commit

Permalink
feat(app, components): add assets for absorbance reader, add to app, …
Browse files Browse the repository at this point in the history
  • Loading branch information
smb2268 committed Oct 9, 2024
1 parent b808a54 commit 34a1f2f
Show file tree
Hide file tree
Showing 14 changed files with 372 additions and 24 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/src/assets/localization/en/device_details.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"about_pipette_name": "About {{name}} Pipette",
"about_pipette": "About pipette",
"abs_reader_status": "Absorbance Plate Reader Status",
"abs_reader_lid_status": "Lid status: {{status}}",
"add_fixture_description": "Add this hardware to your deck configuration. It will be referenced during protocol analysis.",
"add_to_slot": "Add to slot {{slotName}}",
"add": "Add",
Expand Down
3 changes: 3 additions & 0 deletions app/src/local-resources/modules/getModuleImage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import thermoModuleGen1HighRes from '/app/assets/images/modules/thermocyclerModu
import heaterShakerModuleHighRes from '/app/assets/images/modules/[email protected]'
import thermoModuleGen2 from '/app/assets/images/thermocycler_gen_2_closed.png'
import magneticBlockGen1 from '/app/assets/images/magnetic_block_gen_1.png'
import absorbanceReader from 'app/assets/images/opentrons_plate_reader.png'

import type { ModuleModel } from '@opentrons/shared-data'

Expand All @@ -30,6 +31,8 @@ export function getModuleImage(
return thermoModuleGen2
case 'magneticBlockV1':
return magneticBlockGen1
case 'absorbanceReaderV1':
return absorbanceReader
default:
return 'Error: unknown module model'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
useHoverTooltip,
} from '@opentrons/components'
import {
ABSORBANCE_READER_TYPE,
FLEX_ROBOT_TYPE,
getCutoutIdForSlotName,
getDeckDefFromRobotType,
Expand Down Expand Up @@ -260,6 +261,7 @@ export function ModulesListItem({
if (
isFlex &&
attachedModuleMatch != null &&
attachedModuleMatch.moduleType !== ABSORBANCE_READER_TYPE &&
attachedModuleMatch.moduleOffset?.last_modified == null
) {
renderModuleStatus = (
Expand Down
85 changes: 85 additions & 0 deletions app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import {
HEATERSHAKER_MODULE_V1_FIXTURE,
MAGNETIC_BLOCK_V1_FIXTURE,
STAGING_AREA_RIGHT_SLOT_FIXTURE,
STAGING_AREA_SLOT_WITH_MAGNETIC_BLOCK_V1_FIXTURE,
TEMPERATURE_MODULE_V2_FIXTURE,
THERMOCYCLER_V2_FRONT_FIXTURE,
THERMOCYCLER_V2_REAR_FIXTURE,
TRASH_BIN_ADAPTER_FIXTURE,
WASTE_CHUTE_ONLY_FIXTURES,
WASTE_CHUTE_STAGING_AREA_FIXTURES,
} from '@opentrons/shared-data'

import magneticModule from '../../../../assets/images/magnetic_module_gen_2_transparent.png'
import temperatureModule from '../../../../assets/images/temp_deck_gen_2_transparent.png'
import thermoModuleGen1 from '../../../../assets/images/thermocycler_closed.png'
import heaterShakerModule from '../../../../assets/images/heater_shaker_module_transparent.png'
import magneticModuleHighRes from '../../../../assets/images/modules/[email protected]'
import temperatureModuleHighRes from '../../../../assets/images/modules/[email protected]'
import thermoModuleGen1HighRes from '../../../../assets/images/modules/[email protected]'
import heaterShakerModuleHighRes from '../../../../assets/images/modules/[email protected]'
import thermoModuleGen2 from '../../../../assets/images/thermocycler_gen_2_closed.png'
import magneticBlockGen1 from '../../../../assets/images/magnetic_block_gen_1.png'
import stagingAreaMagneticBlockGen1 from '../../../../assets/images/staging_area_magnetic_block_gen_1.png'
import trashBin from '../../../../assets/images/flex_trash_bin.png'
import stagingArea from '../../../../assets/images/staging_area_slot.png'
import wasteChute from '../../../../assets/images/waste_chute.png'
import wasteChuteStagingArea from '../../../../assets/images/waste_chute_with_staging_area.png'
import absorbanceReader from '../../../../assets/images/opentrons_plate_reader.png'

import type { CutoutFixtureId, ModuleModel } from '@opentrons/shared-data'

export function getModuleImage(
model: ModuleModel,
highRes: boolean = false
): string {
switch (model) {
case 'magneticModuleV1':
case 'magneticModuleV2':
return highRes ? magneticModuleHighRes : magneticModule
case 'temperatureModuleV1':
case 'temperatureModuleV2':
return highRes ? temperatureModuleHighRes : temperatureModule
case 'heaterShakerModuleV1':
return highRes ? heaterShakerModuleHighRes : heaterShakerModule
case 'thermocyclerModuleV1':
return highRes ? thermoModuleGen1HighRes : thermoModuleGen1
case 'thermocyclerModuleV2':
return thermoModuleGen2
case 'magneticBlockV1':
return magneticBlockGen1
case 'absorbanceReaderV1':
return absorbanceReader
default:
return 'Error: unknown module model'
}
}

export function getFixtureImage(cutoutFixtureId: CutoutFixtureId): string {
if (cutoutFixtureId === STAGING_AREA_RIGHT_SLOT_FIXTURE) {
return stagingArea
} else if (WASTE_CHUTE_ONLY_FIXTURES.includes(cutoutFixtureId)) {
return wasteChute
} else if (WASTE_CHUTE_STAGING_AREA_FIXTURES.includes(cutoutFixtureId)) {
return wasteChuteStagingArea
} else if (cutoutFixtureId === TRASH_BIN_ADAPTER_FIXTURE) {
return trashBin
} else if (cutoutFixtureId === THERMOCYCLER_V2_REAR_FIXTURE) {
return thermoModuleGen2
} else if (cutoutFixtureId === THERMOCYCLER_V2_FRONT_FIXTURE) {
return thermoModuleGen2
} else if (cutoutFixtureId === HEATERSHAKER_MODULE_V1_FIXTURE) {
return heaterShakerModule
} else if (cutoutFixtureId === TEMPERATURE_MODULE_V2_FIXTURE) {
return temperatureModule
} else if (cutoutFixtureId === MAGNETIC_BLOCK_V1_FIXTURE) {
return magneticBlockGen1
} else if (
cutoutFixtureId === STAGING_AREA_SLOT_WITH_MAGNETIC_BLOCK_V1_FIXTURE
) {
return stagingAreaMagneticBlockGen1
} else {
return 'Error: unknown fixture'
}
}
39 changes: 33 additions & 6 deletions app/src/organisms/ModuleCard/AbsorbanceReaderData.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useTranslation } from 'react-i18next'
import { TYPOGRAPHY, LegacyStyledText } from '@opentrons/components'
import { StyledText, COLORS } from '@opentrons/components'
import { StatusLabel } from '../../atoms/StatusLabel'

import type { AbsorbanceReaderModule } from '/app/redux/modules/types'

interface AbsorbanceReaderProps {
Expand All @@ -12,16 +14,41 @@ export const AbsorbanceReaderData = (
const { moduleData } = props
const { t } = useTranslation('device_details')

const StatusLabelProps = {
status: 'Idle',
backgroundColor: COLORS.grey30,
iconColor: COLORS.grey60,
textColor: COLORS.grey60,
pulse: false,
}
switch (moduleData.status) {
case 'measuring': {
StatusLabelProps.status = 'Reading'
StatusLabelProps.backgroundColor = COLORS.blue30
StatusLabelProps.iconColor = COLORS.blue60
StatusLabelProps.textColor = COLORS.blue60
break
}
case 'error': {
StatusLabelProps.status = 'Error'
StatusLabelProps.backgroundColor = COLORS.yellow30
StatusLabelProps.iconColor = COLORS.yellow60
StatusLabelProps.textColor = COLORS.yellow60
break
}
}

return (
<>
<LegacyStyledText
fontSize={TYPOGRAPHY.fontSizeCaption}
<StatusLabel {...StatusLabelProps} />
<StyledText
desktopStyle="bodyDefaultRegular"
data-testid="abs_module_data"
>
{t('abs_reader_status', {
status: moduleData.status,
{t('abs_reader_lid_status', {
status: moduleData.lidStatus === 'on' ? 'open' : 'closed',
})}
</LegacyStyledText>
</StyledText>
</>
)
}
18 changes: 11 additions & 7 deletions app/src/organisms/ModuleCard/ModuleOverflowMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
MODULE_MODELS_OT2_ONLY,
TEMPERATURE_MODULE_TYPE,
THERMOCYCLER_MODULE_TYPE,
ABSORBANCE_READER_TYPE,
} from '@opentrons/shared-data'
import { useCurrentRunId, useRunStatuses } from '/app/resources/runs'
import { useIsLegacySessionInProgress } from '/app/resources/legacy_sessions'
Expand Down Expand Up @@ -119,6 +120,7 @@ export const ModuleOverflowMenu = (
<Flex position={POSITION_RELATIVE}>
<MenuList>
{isFlex &&
module.moduleType !== ABSORBANCE_READER_TYPE &&
!MODULE_MODELS_OT2_ONLY.some(
modModel => modModel === module.moduleModel
) ? (
Expand Down Expand Up @@ -146,13 +148,15 @@ export const ModuleOverflowMenu = (
(item: any, index: number) => {
return (
<Fragment key={`${index}_${String(module.moduleType)}`}>
<MenuItem
onClick={() => item.onClick(item.isSecondary)}
disabled={item.disabledReason || isDisabled}
whiteSpace={NO_WRAP}
>
{item.setSetting}
</MenuItem>
{item.setSetting ? (
<MenuItem
onClick={() => item.onClick(item.isSecondary)}
disabled={item.disabledReason || isDisabled}
whiteSpace="nowrap"
>
{item.setSetting}
</MenuItem>
) : null}
{item.menuButtons}
</Fragment>
)
Expand Down
12 changes: 8 additions & 4 deletions app/src/organisms/ModuleCard/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ export function useLatchControls(module: AttachedModule): LatchControls {
}
export type MenuItemsByModuleType = {
[moduleType in AttachedModule['moduleType']]: Array<{
setSetting: string
isSecondary: boolean
setSetting?: string
isSecondary?: boolean
menuButtons: JSX.Element[] | null
onClick: (isSecondary: boolean) => void
onClick?: (isSecondary: boolean) => void
}>
}
interface ModuleOverflowMenu {
Expand Down Expand Up @@ -354,7 +354,11 @@ export function useModuleOverflowMenu(
},
},
],
absorbanceReaderType: [],
absorbanceReaderType: [
{
menuButtons: [aboutModuleBtn],
},
],
}

return {
Expand Down
4 changes: 3 additions & 1 deletion app/src/organisms/ModuleCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,9 @@ export const ModuleCard = (props: ModuleCardProps): JSX.Element | null => {
const requireModuleCalibration =
isFlex &&
!MODULE_MODELS_OT2_ONLY.some(modModel => modModel === module.moduleModel) &&
module.moduleOffset?.last_modified == null
module.moduleOffset?.last_modified == null &&
!(module.moduleType === 'absorbanceReaderType')

const isPipetteReady =
!Boolean(attachPipetteRequired) &&
!Boolean(calibratePipetteRequired) &&
Expand Down
3 changes: 3 additions & 0 deletions app/src/organisms/ModuleCard/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import thermoModuleGen1Opened from '/app/assets/images/thermocycler_open_transpa
import heaterShakerModule from '/app/assets/images/heater_shaker_module_transparent.png'
import thermoModuleGen2Closed from '/app/assets/images/thermocycler_gen_2_closed.png'
import thermoModuleGen2Opened from '/app/assets/images/thermocycler_gen_2_opened.png'
import absorbanceReader from 'app/assets/images/opentrons_plate_reader.png'

import type { AttachedModule } from '/app/redux/modules/types'

Expand All @@ -37,6 +38,8 @@ export function getModuleCardImage(attachedModule: AttachedModule): string {
} else {
return thermoModuleGen2Opened
}
case 'absorbanceReaderV1':
return absorbanceReader
// this should never be reached
default:
return 'unknown module model, this is an error'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
TYPOGRAPHY,
} from '@opentrons/components'
import {
ABSORBANCE_READER_TYPE,
getCutoutFixturesForModuleModel,
getCutoutIdsFromModuleSlotName,
getModuleDisplayName,
Expand Down Expand Up @@ -203,7 +204,8 @@ function ModuleTableItem({
)
} else if (
isModuleReady &&
module.attachedModuleMatch?.moduleOffset?.last_modified != null
(module.attachedModuleMatch?.moduleOffset?.last_modified != null ||
module.attachedModuleMatch?.moduleType === ABSORBANCE_READER_TYPE)
) {
moduleStatus = (
<Chip
Expand Down Expand Up @@ -265,7 +267,9 @@ function ModuleTableItem({
alignItems={ALIGN_CENTER}
backgroundColor={
isModuleReady &&
module.attachedModuleMatch?.moduleOffset?.last_modified != null &&
(module.attachedModuleMatch?.moduleOffset?.last_modified != null ||
module.attachedModuleMatch?.moduleType ===
ABSORBANCE_READER_TYPE) &&
conflictedFixture == null
? COLORS.green35
: isNonConnectingModule && conflictedFixture == null
Expand Down
Loading

0 comments on commit 34a1f2f

Please sign in to comment.