diff --git a/app/src/organisms/DeviceDetailsDeckConfiguration/AddDeckConfigurationModal.tsx b/app/src/organisms/DeviceDetailsDeckConfiguration/AddDeckConfigurationModal.tsx index 02e9fab7fa4..db0292d653e 100644 --- a/app/src/organisms/DeviceDetailsDeckConfiguration/AddDeckConfigurationModal.tsx +++ b/app/src/organisms/DeviceDetailsDeckConfiguration/AddDeckConfigurationModal.tsx @@ -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 } diff --git a/app/src/organisms/DeviceDetailsDeckConfiguration/index.tsx b/app/src/organisms/DeviceDetailsDeckConfiguration/index.tsx index eba66844ce7..ee6d9403d84 100644 --- a/app/src/organisms/DeviceDetailsDeckConfiguration/index.tsx +++ b/app/src/organisms/DeviceDetailsDeckConfiguration/index.tsx @@ -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 } @@ -47,17 +49,17 @@ export function DeviceDetailsDeckConfiguration({ const [ targetFixtureLocation, setTargetFixtureLocation, - ] = React.useState('') + ] = React.useState(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, @@ -71,7 +73,7 @@ export function DeviceDetailsDeckConfiguration({ return ( <> - {showAddFixtureModal ? ( + {showAddFixtureModal && targetFixtureLocation != null ? ( void - cutout: string + cutout: Cutout requiredFixture?: FixtureLoadName requiredModule?: ModuleModel } diff --git a/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/NotConfiguredModal.tsx b/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/NotConfiguredModal.tsx index be95deb66ee..c568ef1fe95 100644 --- a/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/NotConfiguredModal.tsx +++ b/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/NotConfiguredModal.tsx @@ -11,16 +11,18 @@ import { BORDERS, ALIGN_CENTER, } from '@opentrons/components' -import { FixtureLoadName, getFixtureDisplayName } from '@opentrons/shared-data' +import { getFixtureDisplayName } from '@opentrons/shared-data' import { TertiaryButton } from '../../../../atoms/buttons/TertiaryButton' import { Portal } from '../../../../App/portal' import { LegacyModal } from '../../../../molecules/LegacyModal' import { StyledText } from '../../../../atoms/text' +import type { Cutout, FixtureLoadName } from '@opentrons/shared-data' + interface NotConfiguredModalProps { onCloseClick: () => void requiredFixture: FixtureLoadName - cutout: string + cutout: Cutout } export const NotConfiguredModal = ( diff --git a/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/SetupFixtureList.tsx b/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/SetupFixtureList.tsx index f54e5d3ce39..4817fc8ca09 100644 --- a/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/SetupFixtureList.tsx +++ b/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/SetupFixtureList.tsx @@ -34,6 +34,7 @@ import { NotConfiguredModal } from './NotConfiguredModal' import { getFixtureImage } from './utils' import type { LoadedFixturesBySlot } from '@opentrons/api-client' +import type { Cutout } from '@opentrons/shared-data' interface SetupFixtureListProps { loadedFixturesBySlot: LoadedFixturesBySlot @@ -82,7 +83,6 @@ export const SetupFixtureList = (props: SetupFixtureListProps): JSX.Element => { > {map(loadedFixturesBySlot, ({ params, id }) => { const { loadName, location } = params - console.log(id) return ( { interface FixtureListItemProps { loadedFixtures: LoadFixtureRunTimeCommand[] loadName: FixtureLoadName - cutout: string + cutout: Cutout commandId: string } diff --git a/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/SetupModulesList.tsx b/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/SetupModulesList.tsx index ca4131d5821..ab64efde649 100644 --- a/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/SetupModulesList.tsx +++ b/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/SetupModulesList.tsx @@ -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' @@ -351,7 +351,8 @@ export function ModulesListItem({ {showLocationConflictModal ? ( 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} diff --git a/app/src/organisms/Devices/hooks/__tests__/useModuleRenderInfoForProtocolById.test.tsx b/app/src/organisms/Devices/hooks/__tests__/useModuleRenderInfoForProtocolById.test.tsx index b30d436bc61..9fbe83dc694 100644 --- a/app/src/organisms/Devices/hooks/__tests__/useModuleRenderInfoForProtocolById.test.tsx +++ b/app/src/organisms/Devices/hooks/__tests__/useModuleRenderInfoForProtocolById.test.tsx @@ -109,7 +109,7 @@ const MAGNETIC_MODULE_INFO = { nestedLabwareId: null, nestedLabwareDisplayName: null, protocolLoadOrder: 0, - slotName: '1', + slotName: 'D1', } const TEMPERATURE_MODULE_INFO = { @@ -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 diff --git a/app/src/organisms/InterventionModal/MoveLabwareInterventionContent.tsx b/app/src/organisms/InterventionModal/MoveLabwareInterventionContent.tsx index 81c667ba048..4a84ee449e1 100644 --- a/app/src/organisms/InterventionModal/MoveLabwareInterventionContent.tsx +++ b/app/src/organisms/InterventionModal/MoveLabwareInterventionContent.tsx @@ -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( diff --git a/app/src/resources/deck_configuration/hooks.ts b/app/src/resources/deck_configuration/hooks.ts index 29b853b6704..967d46b5119 100644 --- a/app/src/resources/deck_configuration/hooks.ts +++ b/app/src/resources/deck_configuration/hooks.ts @@ -1,10 +1,7 @@ import { useDeckConfigurationQuery } from '@opentrons/react-api-client' +import { STANDARD_SLOT_LOAD_NAME } from '@opentrons/shared-data' -import { - Fixture, - LoadFixtureRunTimeCommand, - STANDARD_SLOT_LOAD_NAME, -} from '@opentrons/shared-data' +import type { Fixture, LoadFixtureRunTimeCommand } from '@opentrons/shared-data' export const CONFIGURED = 'configured' export const CONFLICTING = 'conflicting' diff --git a/components/src/hardware-sim/BaseDeck/BaseDeck.stories.tsx b/components/src/hardware-sim/BaseDeck/BaseDeck.stories.tsx index 76d8598cabd..145707f77f5 100644 --- a/components/src/hardware-sim/BaseDeck/BaseDeck.stories.tsx +++ b/components/src/hardware-sim/BaseDeck/BaseDeck.stories.tsx @@ -1,30 +1,49 @@ 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 type { Meta, StoryObj } from '@storybook/react' -import { BaseDeck as BaseDeckComponent } from './' import { + FLEX_ROBOT_TYPE, HEATERSHAKER_MODULE_V1, MAGNETIC_BLOCK_V1, TEMPERATURE_MODULE_V2, THERMOCYCLER_MODULE_V2, -} from '@opentrons/shared-data/js' +} from '@opentrons/shared-data' + +import { + EXTENDED_DECK_CONFIG_FIXTURE, + STANDARD_SLOT_DECK_CONFIG_FIXTURE, +} from './__fixtures__' +import { BaseDeck as BaseDeckComponent } from './' + +import type { Meta, StoryObj } from '@storybook/react' +import type { + DeckConfiguration, + LabwareDefinition2, +} from '@opentrons/shared-data' const meta: Meta> = { component: BaseDeckComponent, title: 'Library/Molecules/Simulation/BaseDeck', + argTypes: { + deckConfig: { + options: ['single slot deck', 'staging area deck'], + control: { type: 'radio' }, + }, + }, } as Meta export default meta type Story = StoryObj> +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 => , args: { robotType: FLEX_ROBOT_TYPE, - trashSlotName: 'A3', + deckConfig: EXTENDED_DECK_CONFIG_FIXTURE, labwareLocations: [ { labwareLocation: { slotName: 'C2' }, @@ -48,7 +67,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, }, @@ -61,4 +80,8 @@ export const BaseDeck: Story = { darkFill: 'rebeccapurple', lightFill: 'lavender', }, + render: args => { + const deckConfig = getDeckConfig(args) + return + }, } diff --git a/components/src/hardware-sim/BaseDeck/SingleSlotFixture.tsx b/components/src/hardware-sim/BaseDeck/SingleSlotFixture.tsx new file mode 100644 index 00000000000..2dbbe04f915 --- /dev/null +++ b/components/src/hardware-sim/BaseDeck/SingleSlotFixture.tsx @@ -0,0 +1,196 @@ +import * as React from 'react' + +import { SlotBase } from './SlotBase' +import { SlotClip } from './SlotClip' + +import type { Cutout, DeckDefinition, ModuleType } from '@opentrons/shared-data' + +interface SingleSlotFixtureProps extends React.SVGProps { + cutoutLocation: Cutout + deckDefinition: DeckDefinition + moduleType?: ModuleType + fixtureBaseColor?: React.SVGProps['fill'] + slotClipColor?: React.SVGProps['stroke'] + showExtensions?: boolean +} + +export function SingleSlotFixture( + props: SingleSlotFixtureProps +): JSX.Element | null { + const { + cutoutLocation, + deckDefinition, + fixtureBaseColor, + slotClipColor, + showExtensions, + ...restProps + } = props + + // TODO(bh, 2023-10-09): migrate from "orderedSlots" to v4 "cutouts" key + const cutoutDef = deckDefinition?.locations.orderedSlots.find( + s => s.id === cutoutLocation + ) + if (cutoutDef == null) { + console.warn( + `cannot render SingleSlotFixture, no cutout named: ${cutoutDef} in deck def ${deckDefinition?.otId}` + ) + return null + } + + const contentsByCutoutLocation: { + [cutoutLocation in Cutout]: JSX.Element + } = { + A1: ( + <> + {showExtensions ? ( + + ) : null} + + + + + + + ), + A2: ( + <> + + , + , + , + + + ), + A3: ( + <> + + , + , + , + + + ), + B1: ( + <> + + , + , + , + + + ), + B2: ( + <> + + , + , + , + + + ), + B3: ( + <> + + , + , + , + + + ), + C1: ( + <> + + + + + + + ), + C2: ( + <> + + , + , + , + + + ), + C3: ( + <> + + , + , + , + + + ), + D1: ( + <> + + + + + + + ), + D2: ( + <> + + + + + + + ), + D3: ( + <> + + + + + + + ), + } + + return {contentsByCutoutLocation[cutoutLocation]} +} diff --git a/components/src/hardware-sim/BaseDeck/SlotBase.tsx b/components/src/hardware-sim/BaseDeck/SlotBase.tsx new file mode 100644 index 00000000000..5c8b7eb6100 --- /dev/null +++ b/components/src/hardware-sim/BaseDeck/SlotBase.tsx @@ -0,0 +1,5 @@ +import * as React from 'react' + +export function SlotBase(props: React.SVGProps): JSX.Element { + return +} diff --git a/components/src/hardware-sim/BaseDeck/SlotClip.tsx b/components/src/hardware-sim/BaseDeck/SlotClip.tsx new file mode 100644 index 00000000000..2a500641113 --- /dev/null +++ b/components/src/hardware-sim/BaseDeck/SlotClip.tsx @@ -0,0 +1,15 @@ +import * as React from 'react' + +import { COLORS } from '../../ui-style-constants' + +export function SlotClip(props: React.SVGProps): JSX.Element { + return ( + + ) +} diff --git a/components/src/hardware-sim/BaseDeck/StagingAreaFixture.tsx b/components/src/hardware-sim/BaseDeck/StagingAreaFixture.tsx new file mode 100644 index 00000000000..2b3d8491da6 --- /dev/null +++ b/components/src/hardware-sim/BaseDeck/StagingAreaFixture.tsx @@ -0,0 +1,112 @@ +import * as React from 'react' + +import { SlotBase } from './SlotBase' +import { SlotClip } from './SlotClip' + +import type { DeckDefinition, ModuleType } from '@opentrons/shared-data' + +export type StagingAreaLocation = 'A3' | 'B3' | 'C3' | 'D3' + +interface StagingAreaFixtureProps extends React.SVGProps { + cutoutLocation: StagingAreaLocation + deckDefinition: DeckDefinition + moduleType?: ModuleType + fixtureBaseColor?: React.SVGProps['fill'] + slotClipColor?: React.SVGProps['stroke'] + showExtensions?: boolean +} + +export function StagingAreaFixture( + props: StagingAreaFixtureProps +): JSX.Element | null { + const { + cutoutLocation, + deckDefinition, + fixtureBaseColor, + slotClipColor, + ...restProps + } = props + + // TODO(bh, 2023-10-09): migrate from "orderedSlots" to v4 "cutouts" key + const cutoutDef = deckDefinition?.locations.orderedSlots.find( + s => s.id === cutoutLocation + ) + if (cutoutDef == null) { + console.warn( + `cannot render StagingAreaFixture, no cutout named: ${cutoutDef} in deck def ${deckDefinition?.otId}` + ) + return null + } + + // TODO(bh, 2023-10-10): adjust base and clip d values if needed to fit v4 deck definition + const contentsByCutoutLocation: { + [cutoutLocation in StagingAreaLocation]: JSX.Element + } = { + A3: ( + <> + + , + , + , + + , + , + , + + + ), + B3: ( + <> + + , + , + , + + , + , + , + + + ), + C3: ( + <> + + , + , + , + + , + , + , + + + ), + D3: ( + <> + + + + + + , + , + , + + + ), + } + + return {contentsByCutoutLocation[cutoutLocation]} +} diff --git a/components/src/hardware-sim/BaseDeck/WasteChuteFixture.tsx b/components/src/hardware-sim/BaseDeck/WasteChuteFixture.tsx new file mode 100644 index 00000000000..a4ac6673bf5 --- /dev/null +++ b/components/src/hardware-sim/BaseDeck/WasteChuteFixture.tsx @@ -0,0 +1,104 @@ +import * as React from 'react' + +import { Icon } from '../../icons' +import { Flex, Text } from '../../primitives' +import { ALIGN_CENTER, DIRECTION_COLUMN, JUSTIFY_CENTER } from '../../styles' +import { BORDERS, COLORS, TYPOGRAPHY } from '../../ui-style-constants' +import { RobotCoordsForeignObject } from '../Deck/RobotCoordsForeignObject' +import { SlotBase } from './SlotBase' + +import type { DeckDefinition, ModuleType } from '@opentrons/shared-data' + +// waste chute only in cutout location D3 +export type WasteChuteLocation = 'D3' + +interface WasteChuteFixtureProps extends React.SVGProps { + cutoutLocation: WasteChuteLocation + deckDefinition: DeckDefinition + moduleType?: ModuleType + fixtureBaseColor?: React.SVGProps['fill'] + slotClipColor?: React.SVGProps['stroke'] + showExtensions?: boolean +} + +export function WasteChuteFixture( + props: WasteChuteFixtureProps +): JSX.Element | null { + const { + cutoutLocation, + deckDefinition, + fixtureBaseColor = COLORS.light1, + slotClipColor = COLORS.darkGreyEnabled, + ...restProps + } = props + + if (cutoutLocation !== 'D3') { + console.warn( + `cannot render WasteChuteFixture in given cutout location ${cutoutLocation}` + ) + return null + } + + // TODO(bh, 2023-10-09): migrate from "orderedSlots" to v4 "cutouts" key + const cutoutDef = deckDefinition?.locations.orderedSlots.find( + s => s.id === cutoutLocation + ) + if (cutoutDef == null) { + console.warn( + `cannot render WasteChuteFixture, no cutout named: ${cutoutDef} in deck def ${deckDefinition?.otId}` + ) + return null + } + + // TODO(bh, 2023-10-10): adjust base and clip d values if needed to fit v4 deck definition + return ( + + + + + ) +} + +interface WasteChuteProps { + wasteIconColor: string + backgroundColor: string +} + +/** + * a deck map foreign object representing the physical location of the waste chute connected to the deck + * based on preliminary designs + * TODO(bh, 2023-10-11): when designs and definitions settled, resolve position details etc + */ +export function WasteChute(props: WasteChuteProps): JSX.Element { + const { wasteIconColor, backgroundColor } = props + + return ( + + + + Waste chute + + + ) +} diff --git a/components/src/hardware-sim/BaseDeck/WasteChuteStagingAreaFixture.tsx b/components/src/hardware-sim/BaseDeck/WasteChuteStagingAreaFixture.tsx new file mode 100644 index 00000000000..b2cdbad8e2d --- /dev/null +++ b/components/src/hardware-sim/BaseDeck/WasteChuteStagingAreaFixture.tsx @@ -0,0 +1,68 @@ +import * as React from 'react' + +import { COLORS } from '../../ui-style-constants' +import { SlotBase } from './SlotBase' +import { SlotClip } from './SlotClip' +import { WasteChute } from './WasteChuteFixture' + +import type { DeckDefinition, ModuleType } from '@opentrons/shared-data' +import type { WasteChuteLocation } from './WasteChuteFixture' + +interface WasteChuteStagingAreaFixtureProps + extends React.SVGProps { + cutoutLocation: WasteChuteLocation + deckDefinition: DeckDefinition + moduleType?: ModuleType + fixtureBaseColor?: React.SVGProps['fill'] + slotClipColor?: React.SVGProps['stroke'] + showExtensions?: boolean +} + +export function WasteChuteStagingAreaFixture( + props: WasteChuteStagingAreaFixtureProps +): JSX.Element | null { + const { + cutoutLocation, + deckDefinition, + fixtureBaseColor = COLORS.light1, + slotClipColor = COLORS.darkGreyEnabled, + ...restProps + } = props + + if (cutoutLocation !== 'D3') { + console.warn( + `cannot render WasteChuteStagingAreaFixture in given cutout location ${cutoutLocation}` + ) + return null + } + + // TODO(bh, 2023-10-09): migrate from "orderedSlots" to v4 "cutouts" key + const cutoutDef = deckDefinition?.locations.orderedSlots.find( + s => s.id === cutoutLocation + ) + if (cutoutDef == null) { + console.warn( + `cannot render WasteChuteStagingAreaFixture, no cutout named: ${cutoutDef} in deck def ${deckDefinition?.otId}` + ) + return null + } + + // TODO(bh, 2023-10-10): adjust base and clip d values if needed to fit v4 deck definition + return ( + // TODO: render a "Waste chute" foreign object similar to FlexTrash + + + , + , + , + + + + ) +} diff --git a/components/src/hardware-sim/BaseDeck/__fixtures__/index.ts b/components/src/hardware-sim/BaseDeck/__fixtures__/index.ts new file mode 100644 index 00000000000..774d1be7352 --- /dev/null +++ b/components/src/hardware-sim/BaseDeck/__fixtures__/index.ts @@ -0,0 +1,137 @@ +import { v4 as uuidv4 } from 'uuid' + +import { + STAGING_AREA_LOAD_NAME, + STANDARD_SLOT_LOAD_NAME, + TRASH_BIN_LOAD_NAME, + WASTE_CHUTE_LOAD_NAME, +} from '@opentrons/shared-data' + +import type { DeckConfiguration } from '@opentrons/shared-data' + +export const STANDARD_SLOT_DECK_CONFIG_FIXTURE: DeckConfiguration = [ + { + fixtureLocation: 'A1', + loadName: STANDARD_SLOT_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'B1', + loadName: STANDARD_SLOT_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'C1', + loadName: STANDARD_SLOT_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'D1', + loadName: STANDARD_SLOT_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'A2', + loadName: STANDARD_SLOT_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'B2', + loadName: STANDARD_SLOT_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'C2', + loadName: STANDARD_SLOT_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'D2', + loadName: STANDARD_SLOT_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'A3', + loadName: TRASH_BIN_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'B3', + loadName: STANDARD_SLOT_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'C3', + loadName: STANDARD_SLOT_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'D3', + loadName: STANDARD_SLOT_LOAD_NAME, + fixtureId: uuidv4(), + }, +] + +// contains staging area and waste chute fixtures +export const EXTENDED_DECK_CONFIG_FIXTURE: DeckConfiguration = [ + { + fixtureLocation: 'A1', + loadName: STANDARD_SLOT_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'B1', + loadName: STANDARD_SLOT_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'C1', + loadName: TRASH_BIN_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'D1', + loadName: STANDARD_SLOT_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'A2', + loadName: STANDARD_SLOT_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'B2', + loadName: STANDARD_SLOT_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'C2', + loadName: STANDARD_SLOT_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'D2', + loadName: STANDARD_SLOT_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'A3', + loadName: STANDARD_SLOT_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'B3', + loadName: STAGING_AREA_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'C3', + loadName: STAGING_AREA_LOAD_NAME, + fixtureId: uuidv4(), + }, + { + fixtureLocation: 'D3', + loadName: WASTE_CHUTE_LOAD_NAME, + fixtureId: uuidv4(), + }, +] diff --git a/components/src/hardware-sim/BaseDeck/index.tsx b/components/src/hardware-sim/BaseDeck/index.tsx index bac8b365482..6232429f14b 100644 --- a/components/src/hardware-sim/BaseDeck/index.tsx +++ b/components/src/hardware-sim/BaseDeck/index.tsx @@ -1,6 +1,5 @@ import * as React from 'react' import { - DeckSlot, RobotType, getDeckDefFromRobotType, ModuleModel, @@ -10,16 +9,33 @@ import { inferModuleOrientationFromXCoordinate, LabwareLocation, OT2_ROBOT_TYPE, + STAGING_AREA_LOAD_NAME, + STANDARD_SLOT_LOAD_NAME, + TRASH_BIN_LOAD_NAME, + WASTE_CHUTE_LOAD_NAME, } from '@opentrons/shared-data' import { RobotCoordinateSpace } from '../RobotCoordinateSpace' import { Module } from '../Module' import { LabwareRender } from '../Labware' import { FlexTrash } from '../Deck/FlexTrash' -import { DeckSlotLocation } from '../DeckSlotLocation' import { DeckFromData } from '../Deck/DeckFromData' import { SlotLabels } from '../Deck' import { COLORS } from '../../ui-style-constants' +import { + // EXTENDED_DECK_CONFIG_FIXTURE, + STANDARD_SLOT_DECK_CONFIG_FIXTURE, +} from './__fixtures__' +import { SingleSlotFixture } from './SingleSlotFixture' +import { StagingAreaFixture } from './StagingAreaFixture' +import { WasteChuteFixture } from './WasteChuteFixture' +// import { WasteChuteStagingAreaFixture } from './WasteChuteStagingAreaFixture' + +import type { DeckConfiguration } from '@opentrons/shared-data' +import type { TrashLocation } from '../Deck/FlexTrash' +import type { StagingAreaLocation } from './StagingAreaFixture' +import type { WasteChuteLocation } from './WasteChuteFixture' + interface BaseDeckProps { robotType: RobotType labwareLocations: Array<{ @@ -32,23 +48,39 @@ interface BaseDeckProps { nestedLabwareDef?: LabwareDefinition2 innerProps?: React.ComponentProps['innerProps'] }> + deckConfig?: DeckConfiguration lightFill?: string darkFill?: string - trashSlotName?: DeckSlot['id'] children?: React.ReactNode } export function BaseDeck(props: BaseDeckProps): JSX.Element { const { robotType, - trashSlotName, moduleLocations, labwareLocations, lightFill = COLORS.light1, darkFill = COLORS.darkGreyEnabled, + // TODO(bh, 2023-10-09): remove deck config fixture for Flex after migration to v4 + // deckConfig = EXTENDED_DECK_CONFIG_FIXTURE, + deckConfig = STANDARD_SLOT_DECK_CONFIG_FIXTURE, children, } = props const deckDef = getDeckDefFromRobotType(robotType) + + const singleSlotFixtures = deckConfig.filter( + fixture => fixture.loadName === STANDARD_SLOT_LOAD_NAME + ) + const stagingAreaFixtures = deckConfig.filter( + fixture => fixture.loadName === STAGING_AREA_LOAD_NAME + ) + const trashBinFixtures = deckConfig.filter( + fixture => fixture.loadName === TRASH_BIN_LOAD_NAME + ) + const wasteChuteFixtures = deckConfig.filter( + fixture => fixture.loadName === WASTE_CHUTE_LOAD_NAME + ) + return ( ) : ( - deckDef.locations.orderedSlots.map(slotDef => ( - <> - + {singleSlotFixtures.map(fixture => ( + + ))} + {stagingAreaFixtures.map(fixture => ( + - {slotDef.id === trashSlotName ? ( + ))} + {trashBinFixtures.map(fixture => ( + + - ) : null} - - )) + + ))} + {wasteChuteFixtures.map(fixture => ( + + ))} + )} {moduleLocations.map( ({ moduleModel, moduleLocation, nestedLabwareDef, innerProps }) => { @@ -84,6 +145,7 @@ export function BaseDeck(props: BaseDeckProps): JSX.Element { ) return slotDef != null ? ( diff --git a/components/src/hardware-sim/Deck/FlexTrash.tsx b/components/src/hardware-sim/Deck/FlexTrash.tsx index 87f99b328d3..f1d07a48738 100644 --- a/components/src/hardware-sim/Deck/FlexTrash.tsx +++ b/components/src/hardware-sim/Deck/FlexTrash.tsx @@ -1,9 +1,9 @@ import * as React from 'react' import { Icon } from '../../icons' -import { Flex } from '../../primitives' +import { Flex, Text } from '../../primitives' import { ALIGN_CENTER, JUSTIFY_CENTER } from '../../styles' -import { BORDERS } from '../../ui-style-constants' +import { BORDERS, TYPOGRAPHY } from '../../ui-style-constants' import { RobotCoordsForeignObject } from './RobotCoordsForeignObject' import { getDeckDefFromRobotType } from '@opentrons/shared-data' @@ -11,8 +11,8 @@ import trashDef from '@opentrons/shared-data/labware/definitions/2/opentrons_1_t import type { RobotType } from '@opentrons/shared-data' -// only allow edge slots (columns 1 and 3) -export type TrashSlotName = +// only allow edge cutout locations (columns 1 and 3) +export type TrashLocation = | 'A1' | 'B1' | 'C1' @@ -26,7 +26,7 @@ interface FlexTrashProps { robotType: RobotType trashIconColor: string backgroundColor: string - trashSlotName?: TrashSlotName + trashLocation?: TrashLocation } /** @@ -37,18 +37,19 @@ export const FlexTrash = ({ robotType, trashIconColor, backgroundColor, - // default Flex trash slot position A3 - trashSlotName = 'A3', + trashLocation, }: FlexTrashProps): JSX.Element | null => { // be sure we don't try to render for an OT-2 if (robotType !== 'OT-3 Standard') return null const deckDef = getDeckDefFromRobotType(robotType) + // TODO(bh, 2023-10-09): migrate from "orderedSlots" to v4 "cutouts" key const trashSlot = deckDef.locations.orderedSlots.find( - slot => slot.id === trashSlotName + slot => slot.id === trashLocation ) // retrieve slot x,y positions and dimensions from deck definition for the given trash slot + // TODO(bh, 2023-10-09): refactor position, offsets, and rotation after v4 migration const [x = 0, y = 0] = trashSlot?.position ?? [] const { xDimension: slotXDimension = 0, yDimension: slotYDimension = 0 } = trashSlot?.boundingBox ?? {} @@ -59,10 +60,10 @@ export const FlexTrash = ({ // rotate trash 180 degrees in column 1 const rotateDegrees = - trashSlotName === 'A1' || - trashSlotName === 'B1' || - trashSlotName === 'C1' || - trashSlotName === 'D1' + trashLocation === 'A1' || + trashLocation === 'B1' || + trashLocation === 'C1' || + trashLocation === 'D1' ? '180' : '0' @@ -87,6 +88,17 @@ export const FlexTrash = ({ justifyContent={JUSTIFY_CENTER} width="100%" > + {rotateDegrees === '180' ? ( + + Trash + + ) : null} + {rotateDegrees === '0' ? ( + + Trash + + ) : null} diff --git a/components/src/hardware-sim/Deck/MoveLabwareOnDeck.tsx b/components/src/hardware-sim/Deck/MoveLabwareOnDeck.tsx index 38adc9e0904..55656526e1b 100644 --- a/components/src/hardware-sim/Deck/MoveLabwareOnDeck.tsx +++ b/components/src/hardware-sim/Deck/MoveLabwareOnDeck.tsx @@ -23,7 +23,7 @@ import type { DeckDefinition, } from '@opentrons/shared-data' import type { StyleProps } from '../../primitives' -import type { TrashSlotName } from './FlexTrash' +import type { TrashLocation } from './FlexTrash' const getModulePosition = ( orderedSlots: DeckSlot[], @@ -126,7 +126,7 @@ interface MoveLabwareOnDeckProps extends StyleProps { loadedLabware: LoadedLabware[] backgroundItems?: React.ReactNode deckFill?: string - trashSlotName?: TrashSlotName + trashLocation?: TrashLocation } export function MoveLabwareOnDeck( props: MoveLabwareOnDeckProps @@ -140,7 +140,7 @@ export function MoveLabwareOnDeck( loadedModules, backgroundItems = null, deckFill = '#e6e6e6', - trashSlotName, + trashLocation, ...styleProps } = props const deckDef = React.useMemo(() => getDeckDefFromRobotType(robotType), [ @@ -209,7 +209,7 @@ export function MoveLabwareOnDeck( def={deckDef} deckFill={deckFill} layerBlocklist={[]} - trashSlotName={trashSlotName} + trashLocation={trashLocation} /> )} {backgroundItems} diff --git a/components/src/hardware-sim/Deck/RobotWorkSpace.tsx b/components/src/hardware-sim/Deck/RobotWorkSpace.tsx index 360e1ba8c9a..5f36dababc5 100644 --- a/components/src/hardware-sim/Deck/RobotWorkSpace.tsx +++ b/components/src/hardware-sim/Deck/RobotWorkSpace.tsx @@ -3,7 +3,7 @@ import { StyleProps, Svg } from '../../primitives' import { StyledDeck } from './StyledDeck' import type { DeckDefinition, DeckSlot } from '@opentrons/shared-data' -import type { TrashSlotName } from './FlexTrash' +import type { TrashLocation } from './FlexTrash' export interface RobotWorkSpaceRenderProps { deckSlotsById: { [slotId: string]: DeckSlot } @@ -19,7 +19,8 @@ export interface RobotWorkSpaceProps extends StyleProps { children?: (props: RobotWorkSpaceRenderProps) => React.ReactNode deckFill?: string deckLayerBlocklist?: string[] - trashSlotName?: TrashSlotName + // TODO(bh, 2023-10-09): remove + trashSlotName?: TrashLocation trashColor?: string id?: string } @@ -84,7 +85,7 @@ export function RobotWorkSpace(props: RobotWorkSpaceProps): JSX.Element | null { deckFill={deckFill} def={deckDef} layerBlocklist={deckLayerBlocklist} - trashSlotName={trashSlotName} + trashLocation={trashSlotName} trashColor={trashColor} /> )} diff --git a/components/src/hardware-sim/Deck/StyledDeck.tsx b/components/src/hardware-sim/Deck/StyledDeck.tsx index 205b0c702ff..55e1cbfc3c9 100644 --- a/components/src/hardware-sim/Deck/StyledDeck.tsx +++ b/components/src/hardware-sim/Deck/StyledDeck.tsx @@ -5,12 +5,12 @@ import { DeckFromData } from './DeckFromData' import { FlexTrash } from './FlexTrash' import type { DeckFromDataProps } from './DeckFromData' -import type { TrashSlotName } from './FlexTrash' +import type { TrashLocation } from './FlexTrash' interface StyledDeckProps { deckFill: string trashColor?: string - trashSlotName?: TrashSlotName + trashLocation?: TrashLocation } // apply fill to .SLOT_BASE class from ot3_standard deck definition @@ -25,7 +25,7 @@ export function StyledDeck( ): JSX.Element { const { deckFill, - trashSlotName, + trashLocation, trashColor = '#757070', ...deckFromDataProps } = props @@ -33,7 +33,7 @@ export function StyledDeck( const robotType = deckFromDataProps.def.robot.model ?? 'OT-2 Standard' const trashSlotClipId = - trashSlotName != null ? `SLOT_CLIPS_${trashSlotName}` : null + trashLocation != null ? `SLOT_CLIPS_${trashLocation}` : null const trashLayerBlocklist = trashSlotClipId != null @@ -46,12 +46,12 @@ export function StyledDeck( {...deckFromDataProps} layerBlocklist={trashLayerBlocklist} /> - {trashSlotName != null ? ( + {trashLocation != null ? ( ) : null} diff --git a/components/src/hardware-sim/DeckConfigurator/EmptyFixture.tsx b/components/src/hardware-sim/DeckConfigurator/EmptyConfigFixture.tsx similarity index 90% rename from components/src/hardware-sim/DeckConfigurator/EmptyFixture.tsx rename to components/src/hardware-sim/DeckConfigurator/EmptyConfigFixture.tsx index 47302323ce2..ef579ea5bda 100644 --- a/components/src/hardware-sim/DeckConfigurator/EmptyFixture.tsx +++ b/components/src/hardware-sim/DeckConfigurator/EmptyConfigFixture.tsx @@ -11,6 +11,8 @@ import { ALIGN_CENTER, DISPLAY_FLEX, JUSTIFY_CENTER } from '../../styles' import { BORDERS, COLORS } from '../../ui-style-constants' import { RobotCoordsForeignObject } from '../Deck/RobotCoordsForeignObject' +import type { Cutout } from '@opentrons/shared-data' + // TODO: replace stubs with JSON definitions when available const standardSlotDef = { schemaVersion: 1, @@ -29,12 +31,14 @@ const standardSlotDef = { }, } -interface EmptyFixtureProps { - fixtureLocation: string - handleClickAdd: (fixtureLocation: string) => void +interface EmptyConfigFixtureProps { + fixtureLocation: Cutout + handleClickAdd: (fixtureLocation: Cutout) => void } -export function EmptyFixture(props: EmptyFixtureProps): JSX.Element { +export function EmptyConfigFixture( + props: EmptyConfigFixtureProps +): JSX.Element { const { handleClickAdd, fixtureLocation } = props const deckDef = getDeckDefFromRobotType(FLEX_ROBOT_TYPE) diff --git a/components/src/hardware-sim/DeckConfigurator/StagingAreaFixture.tsx b/components/src/hardware-sim/DeckConfigurator/StagingAreaConfigFixture.tsx similarity index 90% rename from components/src/hardware-sim/DeckConfigurator/StagingAreaFixture.tsx rename to components/src/hardware-sim/DeckConfigurator/StagingAreaConfigFixture.tsx index b89a5189c79..f8ba5b44e35 100644 --- a/components/src/hardware-sim/DeckConfigurator/StagingAreaFixture.tsx +++ b/components/src/hardware-sim/DeckConfigurator/StagingAreaConfigFixture.tsx @@ -11,6 +11,8 @@ import { ALIGN_CENTER, DISPLAY_FLEX, JUSTIFY_CENTER } from '../../styles' import { BORDERS, COLORS, SPACING, TYPOGRAPHY } from '../../ui-style-constants' import { RobotCoordsForeignObject } from '../Deck/RobotCoordsForeignObject' +import type { Cutout } from '@opentrons/shared-data' + // TODO: replace stubs with JSON definitions when available const stagingAreaDef = { schemaVersion: 1, @@ -29,13 +31,13 @@ const stagingAreaDef = { }, } -interface StagingAreaFixtureProps { - fixtureLocation: string - handleClickRemove?: (fixtureLocation: string) => void +interface StagingAreaConfigFixtureProps { + fixtureLocation: Cutout + handleClickRemove?: (fixtureLocation: Cutout) => void } -export function StagingAreaFixture( - props: StagingAreaFixtureProps +export function StagingAreaConfigFixture( + props: StagingAreaConfigFixtureProps ): JSX.Element { const { handleClickRemove, fixtureLocation } = props const deckDef = getDeckDefFromRobotType(FLEX_ROBOT_TYPE) @@ -71,7 +73,6 @@ export function StagingAreaFixture( justifyContent={JUSTIFY_CENTER} width="100%" > - {} {stagingAreaDef.metadata.displayName} diff --git a/components/src/hardware-sim/DeckConfigurator/TrashBinFixture.tsx b/components/src/hardware-sim/DeckConfigurator/TrashBinConfigFixture.tsx similarity index 89% rename from components/src/hardware-sim/DeckConfigurator/TrashBinFixture.tsx rename to components/src/hardware-sim/DeckConfigurator/TrashBinConfigFixture.tsx index 8d2da3178f8..0d78b538fb7 100644 --- a/components/src/hardware-sim/DeckConfigurator/TrashBinFixture.tsx +++ b/components/src/hardware-sim/DeckConfigurator/TrashBinConfigFixture.tsx @@ -11,13 +11,15 @@ import { ALIGN_CENTER, DISPLAY_FLEX, JUSTIFY_CENTER } from '../../styles' import { BORDERS, COLORS, SPACING, TYPOGRAPHY } from '../../ui-style-constants' import { RobotCoordsForeignObject } from '../Deck/RobotCoordsForeignObject' +import type { Cutout } from '@opentrons/shared-data' + // TODO: replace stubs with JSON definitions when available const trashBinDef = { schemaVersion: 1, version: 1, namespace: 'opentrons', metadata: { - displayName: 'Trash', + displayName: 'Trash bin', }, parameters: { loadName: 'trash_bin', @@ -29,12 +31,14 @@ const trashBinDef = { }, } -interface TrashBinFixtureProps { - fixtureLocation: string - handleClickRemove?: (fixtureLocation: string) => void +interface TrashBinConfigFixtureProps { + fixtureLocation: Cutout + handleClickRemove?: (fixtureLocation: Cutout) => void } -export function TrashBinFixture(props: TrashBinFixtureProps): JSX.Element { +export function TrashBinConfigFixture( + props: TrashBinConfigFixtureProps +): JSX.Element { const { handleClickRemove, fixtureLocation } = props const deckDef = getDeckDefFromRobotType(FLEX_ROBOT_TYPE) @@ -75,7 +79,6 @@ export function TrashBinFixture(props: TrashBinFixtureProps): JSX.Element { justifyContent={JUSTIFY_CENTER} width="100%" > - {} {trashBinDef.metadata.displayName} diff --git a/components/src/hardware-sim/DeckConfigurator/WasteChuteFixture.tsx b/components/src/hardware-sim/DeckConfigurator/WasteChuteConfigFixture.tsx similarity index 89% rename from components/src/hardware-sim/DeckConfigurator/WasteChuteFixture.tsx rename to components/src/hardware-sim/DeckConfigurator/WasteChuteConfigFixture.tsx index 0c547cbbfa1..da0b9241df7 100644 --- a/components/src/hardware-sim/DeckConfigurator/WasteChuteFixture.tsx +++ b/components/src/hardware-sim/DeckConfigurator/WasteChuteConfigFixture.tsx @@ -11,6 +11,8 @@ import { ALIGN_CENTER, DISPLAY_FLEX, JUSTIFY_CENTER } from '../../styles' import { BORDERS, COLORS, SPACING, TYPOGRAPHY } from '../../ui-style-constants' import { RobotCoordsForeignObject } from '../Deck/RobotCoordsForeignObject' +import type { Cutout } from '@opentrons/shared-data' + // TODO: replace stubs with JSON definitions when available const wasteChuteDef = { schemaVersion: 1, @@ -29,12 +31,14 @@ const wasteChuteDef = { }, } -interface WasteChuteFixtureProps { - fixtureLocation: string - handleClickRemove?: (fixtureLocation: string) => void +interface WasteChuteConfigFixtureProps { + fixtureLocation: Cutout + handleClickRemove?: (fixtureLocation: Cutout) => void } -export function WasteChuteFixture(props: WasteChuteFixtureProps): JSX.Element { +export function WasteChuteConfigFixture( + props: WasteChuteConfigFixtureProps +): JSX.Element { const { handleClickRemove, fixtureLocation } = props const deckDef = getDeckDefFromRobotType(FLEX_ROBOT_TYPE) @@ -69,7 +73,6 @@ export function WasteChuteFixture(props: WasteChuteFixtureProps): JSX.Element { justifyContent={JUSTIFY_CENTER} width="100%" > - {} {wasteChuteDef.metadata.displayName} diff --git a/components/src/hardware-sim/DeckConfigurator/index.tsx b/components/src/hardware-sim/DeckConfigurator/index.tsx index 5e82f946424..296ea7388b9 100644 --- a/components/src/hardware-sim/DeckConfigurator/index.tsx +++ b/components/src/hardware-sim/DeckConfigurator/index.tsx @@ -13,17 +13,17 @@ import { COLORS } from '../../ui-style-constants' import { DeckSlotLocation } from '../DeckSlotLocation' import { SlotLabels } from '../Deck' import { RobotCoordinateSpace } from '../RobotCoordinateSpace' -import { EmptyFixture } from './EmptyFixture' -import { StagingAreaFixture } from './StagingAreaFixture' -import { TrashBinFixture } from './TrashBinFixture' -import { WasteChuteFixture } from './WasteChuteFixture' +import { EmptyConfigFixture } from './EmptyConfigFixture' +import { StagingAreaConfigFixture } from './StagingAreaConfigFixture' +import { TrashBinConfigFixture } from './TrashBinConfigFixture' +import { WasteChuteConfigFixture } from './WasteChuteConfigFixture' -import type { DeckConfiguration } from '@opentrons/shared-data' +import type { Cutout, DeckConfiguration } from '@opentrons/shared-data' interface DeckConfiguratorProps { deckConfig: DeckConfiguration - handleClickAdd: (fixtureLocation: string) => void - handleClickRemove: (fixtureLocation: string) => void + handleClickAdd: (fixtureLocation: Cutout) => void + handleClickRemove: (fixtureLocation: Cutout) => void lightFill?: string darkFill?: string children?: React.ReactNode @@ -85,28 +85,28 @@ export function DeckConfigurator(props: DeckConfiguratorProps): JSX.Element { ))} {stagingAreaFixtures.map(fixture => ( - ))} {emptyFixtures.map(fixture => ( - ))} {wasteChuteFixtures.map(fixture => ( - ))} {trashBinFixtures.map(fixture => ( - { showExtensions?: boolean } +// TODO(bh, 2023-10-11): replace usage of this component with base deck fixtures export function DeckSlotLocation( props: DeckSlotLocationProps ): JSX.Element | null { diff --git a/protocol-designer/src/components/DeckSetup/index.tsx b/protocol-designer/src/components/DeckSetup/index.tsx index e989314ee18..04c4c5bdf1f 100644 --- a/protocol-designer/src/components/DeckSetup/index.tsx +++ b/protocol-designer/src/components/DeckSetup/index.tsx @@ -12,7 +12,7 @@ import { RobotWorkSpaceRenderProps, Module, COLORS, - TrashSlotName, + TrashLocation, } from '@opentrons/components' import { MODULES_WITH_COLLISION_ISSUES, @@ -565,7 +565,7 @@ export const DeckSetup = (): JSX.Element => { width="100%" height="100%" trashSlotName={ - trashSlot != null ? (trashSlot as TrashSlotName) : undefined + trashSlot != null ? (trashSlot as TrashLocation) : undefined } trashColor={COLORS.darkGreyEnabled} > diff --git a/protocol-designer/src/components/modals/CreateFileWizard/StagingAreaTile.tsx b/protocol-designer/src/components/modals/CreateFileWizard/StagingAreaTile.tsx index 5c54fc2095f..24f11c7b5c7 100644 --- a/protocol-designer/src/components/modals/CreateFileWizard/StagingAreaTile.tsx +++ b/protocol-designer/src/components/modals/CreateFileWizard/StagingAreaTile.tsx @@ -21,10 +21,10 @@ import { getEnableDeckModification } from '../../../feature-flags/selectors' import { GoBack } from './GoBack' import { HandleEnter } from './HandleEnter' -import type { DeckConfiguration } from '@opentrons/shared-data' +import type { Cutout, DeckConfiguration } from '@opentrons/shared-data' import type { WizardTileProps } from './types' -const STAGING_AREA_SLOTS = ['A3', 'B3', 'C3', 'D3'] +const STAGING_AREA_SLOTS: Cutout[] = ['A3', 'B3', 'C3', 'D3'] export function StagingAreaTile(props: WizardTileProps): JSX.Element | null { const { values, goBack, proceed, setFieldValue } = props diff --git a/shared-data/js/types.ts b/shared-data/js/types.ts index aaff84e60ac..911fd33244e 100644 --- a/shared-data/js/types.ts +++ b/shared-data/js/types.ts @@ -532,9 +532,23 @@ export type StatusBarAnimation = export type StatusBarAnimations = StatusBarAnimation[] // TODO(bh, 2023-09-28): refine types when settled +export type Cutout = + | 'A1' + | 'B1' + | 'C1' + | 'D1' + | 'A2' + | 'B2' + | 'C2' + | 'D2' + | 'A3' + | 'B3' + | 'C3' + | 'D3' + export interface Fixture { fixtureId: string - fixtureLocation: string + fixtureLocation: Cutout loadName: FixtureLoadName } diff --git a/shared-data/protocol/types/schemaV7/command/setup.ts b/shared-data/protocol/types/schemaV7/command/setup.ts index 920a8d3c1be..f0d3ff0b0da 100644 --- a/shared-data/protocol/types/schemaV7/command/setup.ts +++ b/shared-data/protocol/types/schemaV7/command/setup.ts @@ -6,6 +6,7 @@ import type { PipetteName, ModuleModel, FixtureLoadName, + Cutout, } from '../../../../js' export interface LoadPipetteCreateCommand extends CommonCommandCreateInfo { @@ -150,7 +151,7 @@ interface LoadLiquidParams { interface LoadLiquidResult { liquidId: string } -export type Cutout = 'B3' | 'C3' | 'D3' + interface LoadFixtureParams { location: { cutout: Cutout } loadName: FixtureLoadName