Skip to content

Commit

Permalink
add editableCutoutIds to deck configurator
Browse files Browse the repository at this point in the history
  • Loading branch information
b-cooper committed Apr 17, 2024
1 parent 716d812 commit f7def1b
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 96 deletions.
24 changes: 12 additions & 12 deletions app/src/organisms/DeviceDetailsDeckConfiguration/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,20 +120,20 @@ export function DeviceDetailsDeckConfiguration({
newDeckConfig = deckConfig.map(cutoutConfig =>
cutoutConfig.cutoutId in groupMap
? {
...cutoutConfig,
cutoutFixtureId: replacementFixtureId,
opentronsModuleSerialNumber: undefined,
}
...cutoutConfig,
cutoutFixtureId: replacementFixtureId,
opentronsModuleSerialNumber: undefined,
}
: cutoutConfig
)
} else {
newDeckConfig = deckConfig.map(cutoutConfig =>
cutoutConfig.cutoutId === cutoutId
? {
...cutoutConfig,
cutoutFixtureId: replacementFixtureId,
opentronsModuleSerialNumber: undefined,
}
...cutoutConfig,
cutoutFixtureId: replacementFixtureId,
opentronsModuleSerialNumber: undefined,
}
: cutoutConfig
)
}
Expand Down Expand Up @@ -269,10 +269,10 @@ export function DeviceDetailsDeckConfiguration({
flexDirection={DIRECTION_COLUMN}
>
<DeckConfigurator
readOnly={
isRunRunning ||
isMaintenanceRunExisting ||
isEstopNotDisengaged
editableCutoutIds={
(isRunRunning ||
isMaintenanceRunExisting ||
isEstopNotDisengaged) ? [] : deckConfig.map(({ cutoutId }) => cutoutId)
}
deckConfig={deckConfig}
handleClickAdd={handleClickAdd}
Expand Down
74 changes: 33 additions & 41 deletions app/src/organisms/ModuleWizardFlows/SelectLocation.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import * as React from 'react'
import isEqual from 'lodash/isEqual'
import { useTranslation } from 'react-i18next'
import { css } from 'styled-components'
import { useUpdateDeckConfigurationMutation } from '@opentrons/react-api-client'
import {
getModuleDisplayName,
THERMOCYCLER_MODULE_TYPE,
getDeckDefFromRobotType,
FLEX_ROBOT_TYPE,
getCutoutIdsFromModuleSlotName,
getCutoutFixturesForModuleModel,
SINGLE_CENTER_SLOT_FIXTURE,
SINGLE_CENTER_CUTOUTS,
SINGLE_LEFT_SLOT_FIXTURE,
SINGLE_RIGHT_CUTOUTS,
SINGLE_RIGHT_SLOT_FIXTURE,
getFixtureIdByCutoutIdFromModuleAnchorCutoutId,
SINGLE_SLOT_FIXTURES,
} from '@opentrons/shared-data'
import {
DeckLocationSelect,
DeckConfigurator,
RESPONSIVENESS,
SIZE_1,
SPACING,
Expand All @@ -31,7 +32,6 @@ import type {
DeckConfiguration,
CutoutFixtureId,
CutoutId,
ModuleLocation,
} from '@opentrons/shared-data'

export const BODY_STYLE = css`
Expand All @@ -46,7 +46,7 @@ interface SelectLocationProps extends ModuleCalibrationWizardStepProps {
availableSlotNames: string[]
occupiedCutouts: CutoutConfig[]
deckConfig: DeckConfiguration
fixtureIdByCutoutId: { [cutoutId in CutoutId]?: CutoutFixtureId }
configuredFixtureIdByCutoutId: { [cutoutId in CutoutId]?: CutoutFixtureId }
}
export const SelectLocation = (
props: SelectLocationProps
Expand All @@ -55,9 +55,7 @@ export const SelectLocation = (
proceed,
attachedModule,
deckConfig,
availableSlotNames,
occupiedCutouts,
fixtureIdByCutoutId,
configuredFixtureIdByCutoutId,
} = props
const { t } = useTranslation('module_wizard_flows')
const moduleName = getModuleDisplayName(attachedModule.moduleModel)
Expand All @@ -80,24 +78,27 @@ export const SelectLocation = (
</>
)

const handleSetLocation = (loc: ModuleLocation): void => {
const moduleFixtures = getCutoutFixturesForModuleModel(
attachedModule.moduleModel,
deckDef
)
const selectedCutoutIds = getCutoutIdsFromModuleSlotName(
loc.slotName,
moduleFixtures,
deckDef
)
if (
selectedCutoutIds.every(
selectedCutoutId => !(selectedCutoutId in fixtureIdByCutoutId)
)
) {
const moduleFixtures = getCutoutFixturesForModuleModel(
attachedModule.moduleModel,
deckDef
)
const mayMountToCutoutIds = moduleFixtures.reduce<CutoutId[]>((acc, { mayMountTo }) => [...acc, ...mayMountTo], [])
const editableCutoutIds = deckConfig.reduce<CutoutId[]>((acc, { cutoutId, cutoutFixtureId, opentronsModuleSerialNumber }) => {

const isCurrentConfiguration = Object.values(configuredFixtureIdByCutoutId).includes(cutoutFixtureId) && attachedModule.serialNumber === opentronsModuleSerialNumber
if (mayMountToCutoutIds.includes(cutoutId) &&
(isCurrentConfiguration || SINGLE_SLOT_FIXTURES.includes(cutoutFixtureId))) {
return [...acc, cutoutId]
}
return acc
}, [])

const handleAddFixture = (anchorCutoutId: CutoutId): void => {
const selectedFixtureIdByCutoutIds = getFixtureIdByCutoutIdFromModuleAnchorCutoutId(anchorCutoutId, moduleFixtures)
if (!isEqual(selectedFixtureIdByCutoutIds, configuredFixtureIdByCutoutId)) {
updateDeckConfiguration(
deckConfig.map(cc => {
if (cc.cutoutId in fixtureIdByCutoutId) {
if (cc.cutoutId in configuredFixtureIdByCutoutId) {
let replacementFixtureId: CutoutFixtureId = SINGLE_LEFT_SLOT_FIXTURE
if (SINGLE_CENTER_CUTOUTS.includes(cc.cutoutId)) {
replacementFixtureId = SINGLE_CENTER_SLOT_FIXTURE
Expand All @@ -109,13 +110,10 @@ export const SelectLocation = (
cutoutFixtureId: replacementFixtureId,
opentronsModuleSerialNumber: undefined,
}
} else if (selectedCutoutIds.includes(cc.cutoutId)) {
} else if (cc.cutoutId in selectedFixtureIdByCutoutIds) {
return {
...cc,
cutoutFixtureId:
Object.values(fixtureIdByCutoutId)[0] ??
moduleFixtures[0]?.id ??
cc.cutoutFixtureId,
cutoutFixtureId: selectedFixtureIdByCutoutIds[cc.cutoutId] ?? cc.cutoutFixtureId,
opentronsModuleSerialNumber: attachedModule.serialNumber,
}
} else {
Expand All @@ -129,18 +127,12 @@ export const SelectLocation = (
<GenericWizardTile
header={t('select_location')}
rightHandBody={
<DeckLocationSelect
deckDef={deckDef}
selectedLocation={{
slotName: cutoutConfig?.cutoutId.replace('cutout', '') ?? '',
}}
setSelectedLocation={handleSetLocation}
availableSlotNames={availableSlotNames}
occupiedCutouts={occupiedCutouts}
isThermocycler={
attachedModule.moduleType === THERMOCYCLER_MODULE_TYPE
}
showTooltipOnDisabled={true}
<DeckConfigurator
deckConfig={deckConfig}
handleClickAdd={handleAddFixture}
handleClickRemove={() => console.log('remove')}
editableCutoutIds={editableCutoutIds}
height="250px"
/>
}
bodyText={bodyText}
Expand Down
2 changes: 1 addition & 1 deletion app/src/organisms/ModuleWizardFlows/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ export const ModuleWizardFlows = (
availableSlotNames={availableSlotNames}
deckConfig={deckConfig}
occupiedCutouts={occupiedCutouts}
fixtureIdByCutoutId={fixtureIdByCutoutId}
configuredFixtureIdByCutoutId={fixtureIdByCutoutId}
/>
)
} else if (currentStep.section === SECTIONS.PLACE_ADAPTER) {
Expand Down
2 changes: 1 addition & 1 deletion app/src/organisms/QuickTransferFlow/CreateNewTransfer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export function CreateNewTransfer(props: CreateNewTransferProps): JSX.Element {
<Flex width="50%">
<DeckConfigurator
deckConfig={deckConfig}
readOnly
editableCutoutIds={[]}
handleClickAdd={() => {}}
handleClickRemove={() => {}}
additionalStaticFixtures={[
Expand Down
59 changes: 22 additions & 37 deletions components/src/hardware-sim/DeckConfigurator/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,43 +44,30 @@ interface DeckConfiguratorProps {
) => void
lightFill?: string
darkFill?: string
readOnly?: boolean
editableCutoutIds?: CutoutId[]
showExpansion?: boolean
children?: React.ReactNode
additionalStaticFixtures?: Array<{ location: CutoutId; label: string }>
height?: string
}

export function DeckConfigurator(props: DeckConfiguratorProps): JSX.Element {
const {
deckConfig,
handleClickAdd,
handleClickRemove,
additionalStaticFixtures,
children,
lightFill = COLORS.grey35,
darkFill = COLORS.black90,
readOnly = false,
editableCutoutIds = deckConfig.map(({ cutoutId }) => cutoutId),
showExpansion = true,
additionalStaticFixtures,
children,
height = "455px"
} = props
const deckDef = getDeckDefFromRobotType(FLEX_ROBOT_TYPE)

// restrict configuration to certain locations
const configurableFixtureLocations: CutoutId[] = [
'cutoutA1',
'cutoutB1',
'cutoutC1',
'cutoutD1',
'cutoutA2',
'cutoutB2',
'cutoutC2',
'cutoutD2',
'cutoutA3',
'cutoutB3',
'cutoutC3',
'cutoutD3',
]
const configurableDeckConfig = deckConfig.filter(({ cutoutId }) =>
configurableFixtureLocations.includes(cutoutId)
editableCutoutIds.includes(cutoutId)
)

const stagingAreaFixtures = configurableDeckConfig.filter(
Expand All @@ -96,13 +83,11 @@ export function DeckConfigurator(props: DeckConfiguratorProps): JSX.Element {
cutoutFixtureId != null &&
WASTE_CHUTE_STAGING_AREA_FIXTURES.includes(cutoutFixtureId)
)
const emptyFixtures = readOnly
? []
: configurableDeckConfig.filter(
({ cutoutFixtureId }) =>
cutoutFixtureId != null &&
SINGLE_SLOT_FIXTURES.includes(cutoutFixtureId)
)
const emptyCutouts = configurableDeckConfig.filter(
({ cutoutFixtureId }) =>
cutoutFixtureId != null &&
SINGLE_SLOT_FIXTURES.includes(cutoutFixtureId)
)
const trashBinFixtures = configurableDeckConfig.filter(
({ cutoutFixtureId }) => cutoutFixtureId === TRASH_BIN_ADAPTER_FIXTURE
)
Expand All @@ -125,7 +110,7 @@ export function DeckConfigurator(props: DeckConfiguratorProps): JSX.Element {

return (
<RobotCoordinateSpace
height="455px"
height={height}
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
viewBox={`${deckDef.cornerOffsetFromOrigin[0]} ${deckDef.cornerOffsetFromOrigin[1]} ${deckDef.dimensions[0]} ${deckDef.dimensions[1]}`}
>
Expand All @@ -145,12 +130,12 @@ export function DeckConfigurator(props: DeckConfiguratorProps): JSX.Element {
<StagingAreaConfigFixture
key={cutoutId}
deckDefinition={deckDef}
handleClickRemove={readOnly ? undefined : handleClickRemove}
handleClickRemove={editableCutoutIds.includes(cutoutId) ? handleClickRemove : undefined}
fixtureLocation={cutoutId}
cutoutFixtureId={cutoutFixtureId}
/>
))}
{emptyFixtures.map(({ cutoutId }) => (
{emptyCutouts.map(({ cutoutId }) => (
<EmptyConfigFixture
key={cutoutId}
deckDefinition={deckDef}
Expand All @@ -162,7 +147,7 @@ export function DeckConfigurator(props: DeckConfiguratorProps): JSX.Element {
<WasteChuteConfigFixture
key={cutoutId}
deckDefinition={deckDef}
handleClickRemove={readOnly ? undefined : handleClickRemove}
handleClickRemove={editableCutoutIds.includes(cutoutId) ? handleClickRemove : undefined}
fixtureLocation={cutoutId}
cutoutFixtureId={cutoutFixtureId}
/>
Expand All @@ -171,7 +156,7 @@ export function DeckConfigurator(props: DeckConfiguratorProps): JSX.Element {
<WasteChuteConfigFixture
key={cutoutId}
deckDefinition={deckDef}
handleClickRemove={readOnly ? undefined : handleClickRemove}
handleClickRemove={editableCutoutIds.includes(cutoutId) ? handleClickRemove : undefined}
fixtureLocation={cutoutId}
cutoutFixtureId={cutoutFixtureId}
hasStagingAreas
Expand All @@ -181,7 +166,7 @@ export function DeckConfigurator(props: DeckConfiguratorProps): JSX.Element {
<TrashBinConfigFixture
key={cutoutId}
deckDefinition={deckDef}
handleClickRemove={readOnly ? undefined : handleClickRemove}
handleClickRemove={editableCutoutIds.includes(cutoutId) ? handleClickRemove : undefined}
fixtureLocation={cutoutId}
cutoutFixtureId={cutoutFixtureId}
/>
Expand All @@ -190,7 +175,7 @@ export function DeckConfigurator(props: DeckConfiguratorProps): JSX.Element {
<TemperatureModuleFixture
key={cutoutId}
deckDefinition={deckDef}
handleClickRemove={readOnly ? undefined : handleClickRemove}
handleClickRemove={editableCutoutIds.includes(cutoutId) ? handleClickRemove : undefined}
fixtureLocation={cutoutId}
cutoutFixtureId={cutoutFixtureId}
/>
Expand All @@ -199,7 +184,7 @@ export function DeckConfigurator(props: DeckConfiguratorProps): JSX.Element {
<HeaterShakerFixture
key={cutoutId}
deckDefinition={deckDef}
handleClickRemove={readOnly ? undefined : handleClickRemove}
handleClickRemove={editableCutoutIds.includes(cutoutId) ? handleClickRemove : undefined}
fixtureLocation={cutoutId}
cutoutFixtureId={cutoutFixtureId}
/>
Expand All @@ -208,7 +193,7 @@ export function DeckConfigurator(props: DeckConfiguratorProps): JSX.Element {
<MagneticBlockFixture
key={cutoutId}
deckDefinition={deckDef}
handleClickRemove={readOnly ? undefined : handleClickRemove}
handleClickRemove={editableCutoutIds.includes(cutoutId) ? handleClickRemove : undefined}
fixtureLocation={cutoutId}
cutoutFixtureId={cutoutFixtureId}
hasStagingArea={
Expand All @@ -220,7 +205,7 @@ export function DeckConfigurator(props: DeckConfiguratorProps): JSX.Element {
<ThermocyclerFixture
key={cutoutId}
deckDefinition={deckDef}
handleClickRemove={readOnly ? undefined : handleClickRemove}
handleClickRemove={editableCutoutIds.includes(cutoutId) ? handleClickRemove : undefined}
fixtureLocation={cutoutId}
cutoutFixtureId={cutoutFixtureId}
/>
Expand Down
15 changes: 11 additions & 4 deletions shared-data/js/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,10 @@ export function getCutoutFixturesForModuleModel(
}, [])
}

export function getFixtureIdByCutoutIdFromModuleSlotName(
slotName: string,
export function getFixtureIdByCutoutIdFromModuleAnchorCutoutId(
anchorCutoutId: CutoutId | null,
moduleFixtures: CutoutFixture[], // cutout fixtures for a specific module model
deckDef: DeckDefinition
): { [cutoutId in CutoutId]?: CutoutFixtureId } {
const anchorCutoutId = getCutoutIdForSlotName(slotName, deckDef)
// find the first fixture for this specific module model that may mount to the cutout implied by the slotName
const anchorFixture = moduleFixtures.find(fixture =>
fixture.mayMountTo.some(cutoutId => cutoutId === anchorCutoutId)
Expand All @@ -190,6 +188,15 @@ export function getFixtureIdByCutoutIdFromModuleSlotName(
return {}
}

export function getFixtureIdByCutoutIdFromModuleSlotName(
slotName: string,
moduleFixtures: CutoutFixture[], // cutout fixtures for a specific module model
deckDef: DeckDefinition
): { [cutoutId in CutoutId]?: CutoutFixtureId } {
const anchorCutoutId = getCutoutIdForSlotName(slotName, deckDef)
return getFixtureIdByCutoutIdFromModuleAnchorCutoutId(anchorCutoutId, moduleFixtures)
}

export function getCutoutIdsFromModuleSlotName(
slotName: string,
moduleFixtures: CutoutFixture[], // cutout fixtures for a specific module model
Expand Down

0 comments on commit f7def1b

Please sign in to comment.