Skip to content

Commit

Permalink
feat(components): create base deck fixture components
Browse files Browse the repository at this point in the history
creates single slot, staging area, and waste chute components to be used by the existing BaseDeck
component. BaseDeck now receives a deckConfig prop describing a robot deck configuration of fixures.
the deck fixture components render SVGs corresponding to the fixture areas and slot clips provided
by each fixture type

closes RAUT-783
  • Loading branch information
brenthagen committed Oct 10, 2023
1 parent 9fae865 commit b35dbef
Show file tree
Hide file tree
Showing 30 changed files with 804 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ import { TertiaryButton } from '../../atoms/buttons'
import { Modal } from '../../molecules/Modal'
import { LegacyModal } from '../../molecules/LegacyModal'

import type { FixtureLoadName } from '@opentrons/shared-data'
import type { Cutout, FixtureLoadName } from '@opentrons/shared-data'
import type { ModalHeaderBaseProps } from '../../molecules/Modal/types'
import type { LegacyModalProps } from '../../molecules/LegacyModal'

interface AddDeckConfigurationModalProps {
fixtureLocation: string
fixtureLocation: Cutout
setShowAddFixtureModal: (showAddFixtureModal: boolean) => void
isOnDevice?: boolean
}
Expand Down
10 changes: 6 additions & 4 deletions app/src/organisms/DeviceDetailsDeckConfiguration/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import { StyledText } from '../../atoms/text'
import { DeckFixtureSetupInstructionsModal } from './DeckFixtureSetupInstructionsModal'
import { AddDeckConfigurationModal } from './AddDeckConfigurationModal'

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

interface DeviceDetailsDeckConfigurationProps {
robotName: string
}
Expand All @@ -47,17 +49,17 @@ export function DeviceDetailsDeckConfiguration({
const [
targetFixtureLocation,
setTargetFixtureLocation,
] = React.useState<string>('')
] = React.useState<Cutout | null>(null)

const deckConfig = useDeckConfigurationQuery().data ?? []
const { updateDeckConfiguration } = useUpdateDeckConfigurationMutation()

const handleClickAdd = (fixtureLocation: string): void => {
const handleClickAdd = (fixtureLocation: Cutout): void => {
setTargetFixtureLocation(fixtureLocation)
setShowAddFixtureModal(true)
}

const handleClickRemove = (fixtureLocation: string): void => {
const handleClickRemove = (fixtureLocation: Cutout): void => {
updateDeckConfiguration({
fixtureLocation,
loadName: STANDARD_SLOT_LOAD_NAME,
Expand All @@ -71,7 +73,7 @@ export function DeviceDetailsDeckConfiguration({

return (
<>
{showAddFixtureModal ? (
{showAddFixtureModal && targetFixtureLocation != null ? (
<AddDeckConfigurationModal
fixtureLocation={targetFixtureLocation}
setShowAddFixtureModal={setShowAddFixtureModal}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,24 @@ import {
Box,
} from '@opentrons/components'
import {
Fixture,
FixtureLoadName,
getFixtureDisplayName,
getModuleDisplayName,
ModuleModel,
STANDARD_SLOT_LOAD_NAME,
} from '@opentrons/shared-data'
import { Portal } from '../../../../App/portal'
import { LegacyModal } from '../../../../molecules/LegacyModal'
import { StyledText } from '../../../../atoms/text'

import type {
Cutout,
Fixture,
FixtureLoadName,
ModuleModel,
} from '@opentrons/shared-data'

interface LocationConflictModalProps {
onCloseClick: () => void
cutout: string
cutout: Cutout
requiredFixture?: FixtureLoadName
requiredModule?: ModuleModel
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { LocationConflictModal } from './LocationConflictModal'
import { getFixtureImage } from './utils'

import type { LoadedFixturesBySlot } from '@opentrons/api-client'
import type { Cutout } from '@opentrons/shared-data'

interface SetupFixtureListProps {
loadedFixturesBySlot: LoadedFixturesBySlot
Expand Down Expand Up @@ -100,7 +101,7 @@ export const SetupFixtureList = (props: SetupFixtureListProps): JSX.Element => {
interface FixtureListItemProps {
loadedFixtures: LoadFixtureRunTimeCommand[]
loadName: FixtureLoadName
cutout: string
cutout: Cutout
commandId: string
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import { ModuleWizardFlows } from '../../../ModuleWizardFlows'
import { LocationConflictModal } from './LocationConflictModal'
import { getModuleImage } from './utils'

import type { ModuleModel, Fixture } from '@opentrons/shared-data'
import type { Cutout, ModuleModel, Fixture } from '@opentrons/shared-data'
import type { AttachedModule } from '../../../../redux/modules/types'
import type { ProtocolCalibrationStatus } from '../../hooks'

Expand Down Expand Up @@ -351,7 +351,8 @@ export function ModulesListItem({
{showLocationConflictModal ? (
<LocationConflictModal
onCloseClick={() => setShowLocationConflictModal(false)}
cutout={slotName}
// TODO(bh, 2023-10-10): when module caddies are fixtures, narrow slotName to Cutout and remove type assertion
cutout={slotName as Cutout}
requiredModule={moduleModel}
/>
) : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ const MAGNETIC_MODULE_INFO = {
nestedLabwareId: null,
nestedLabwareDisplayName: null,
protocolLoadOrder: 0,
slotName: '1',
slotName: 'D1',
}

const TEMPERATURE_MODULE_INFO = {
Expand All @@ -122,12 +122,12 @@ const TEMPERATURE_MODULE_INFO = {
nestedLabwareId: null,
nestedLabwareDisplayName: null,
protocolLoadOrder: 0,
slotName: '1',
slotName: 'D1',
}

const mockFixture = {
fixtureId: 'mockId',
fixtureLocation: '1',
fixtureLocation: 'D1',
loadName: STAGING_AREA_LOAD_NAME,
} as Fixture

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ export function MoveLabwareInterventionContent({
loadedModules={run.modules}
loadedLabware={run.labware}
// TODO(bh, 2023-07-19): read trash slot name from protocol
trashSlotName={robotType === 'OT-3 Standard' ? 'A3' : undefined}
trashLocation={robotType === 'OT-3 Standard' ? 'A3' : undefined}
backgroundItems={
<>
{moduleRenderInfo.map(
Expand Down
4 changes: 3 additions & 1 deletion app/src/resources/deck_configuration/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useDeckConfigurationQuery } from '@opentrons/react-api-client'
import { STANDARD_SLOT_LOAD_NAME } from '@opentrons/shared-data'

Check failure on line 2 in app/src/resources/deck_configuration/hooks.ts

View workflow job for this annotation

GitHub Actions / js checks

'@opentrons/shared-data' imported multiple times

Check failure on line 2 in app/src/resources/deck_configuration/hooks.ts

View workflow job for this annotation

GitHub Actions / js checks

Duplicate identifier 'STANDARD_SLOT_LOAD_NAME'.

import type { Fixture, LoadFixtureRunTimeCommand } from '@opentrons/shared-data'

Expand Down Expand Up @@ -34,7 +35,8 @@ export function useLoadedFixturesConfigStatus(
configurationStatus = CONFIGURED
} else if (
deckConfigurationAtLocation != null &&
deckConfigurationAtLocation.loadName !== loadedFixture.params.loadName
deckConfigurationAtLocation.loadName !== loadedFixture.params.loadName &&
deckConfigurationAtLocation.loadName !== STANDARD_SLOT_LOAD_NAME
) {
configurationStatus = CONFLICTING
}
Expand Down
34 changes: 30 additions & 4 deletions components/src/hardware-sim/BaseDeck/BaseDeck.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import * as React from 'react'
import fixture_96_plate from '@opentrons/shared-data/labware/fixtures/2/fixture_96_plate.json'
import fixture_tiprack_1000_ul from '@opentrons/shared-data/labware/fixtures/2/fixture_tiprack_1000_ul.json'
import { FLEX_ROBOT_TYPE, LabwareDefinition2 } from '@opentrons/shared-data'
import {
DeckConfiguration,
FLEX_ROBOT_TYPE,
LabwareDefinition2,
} from '@opentrons/shared-data'

import type { Meta, StoryObj } from '@storybook/react'
import {
EXTENDED_DECK_CONFIG_FIXTURE,
STANDARD_SLOT_DECK_CONFIG_FIXTURE,
} from './__fixtures__'
import { BaseDeck as BaseDeckComponent } from './'
import {
HEATERSHAKER_MODULE_V1,
Expand All @@ -15,16 +23,30 @@ import {
const meta: Meta<React.ComponentProps<typeof BaseDeckComponent>> = {
component: BaseDeckComponent,
title: 'Library/Molecules/Simulation/BaseDeck',
argTypes: {
deckConfig: {
// options: [
// EXTENDED_DECK_CONFIG_FIXTURE,
// STANDARD_SLOT_DECK_CONFIG_FIXTURE,
// ],
options: ['single slot deck', 'staging area deck'],
control: { type: 'radio' },
},
},
} as Meta

export default meta
type Story = StoryObj<React.ComponentProps<typeof BaseDeckComponent>>

const getDeckConfig = (args: any): DeckConfiguration =>
args.deckConfig === 'staging area deck'
? EXTENDED_DECK_CONFIG_FIXTURE
: STANDARD_SLOT_DECK_CONFIG_FIXTURE

export const BaseDeck: Story = {
render: args => <BaseDeckComponent {...args} />,
args: {
robotType: FLEX_ROBOT_TYPE,
trashSlotName: 'A3',
deckConfig: EXTENDED_DECK_CONFIG_FIXTURE,
labwareLocations: [
{
labwareLocation: { slotName: 'C2' },
Expand All @@ -48,7 +70,7 @@ export const BaseDeck: Story = {
nestedLabwareDef: fixture_96_plate as LabwareDefinition2,
},
{
moduleLocation: { slotName: 'D3' },
moduleLocation: { slotName: 'B3' },
moduleModel: HEATERSHAKER_MODULE_V1,
nestedLabwareDef: fixture_96_plate as LabwareDefinition2,
},
Expand All @@ -61,4 +83,8 @@ export const BaseDeck: Story = {
darkFill: 'rebeccapurple',
lightFill: 'lavender',
},
render: args => {
const deckConfig = getDeckConfig(args)
return <BaseDeckComponent {...args} deckConfig={deckConfig} />
},
}
Loading

0 comments on commit b35dbef

Please sign in to comment.