From f106d3ba64dcecc791c3e1de983f3975eaf65525 Mon Sep 17 00:00:00 2001 From: Brent Hagen Date: Fri, 23 Aug 2024 12:01:46 -0400 Subject: [PATCH] fix(components): create BaseDeck stacking badge layer (#16099) Creates a `BaseDeck` component SVG layer solely for stacked labware badges that renders further down the DOM than all labware and modules. Fixes an issue when the stacked badge occludes adjacent slots in some OT-2 deck maps and must be layered above all labware/modules. This layered base deck render approach could be extended in the future for features like custom labware or tooltips that might also occlude adjacent deck slots. closes RQA-2927 --- .../src/hardware-sim/BaseDeck/BaseDeck.tsx | 74 ++++++++++++++++++- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/components/src/hardware-sim/BaseDeck/BaseDeck.tsx b/components/src/hardware-sim/BaseDeck/BaseDeck.tsx index 5dc076b1781..b1aefc968a7 100644 --- a/components/src/hardware-sim/BaseDeck/BaseDeck.tsx +++ b/components/src/hardware-sim/BaseDeck/BaseDeck.tsx @@ -90,6 +90,8 @@ interface BaseDeckProps { svgProps?: React.ComponentProps } +const LABWARE_OFFSET_DISPLAY_THRESHOLD = 2 + export function BaseDeck(props: BaseDeckProps): JSX.Element { const { robotType, @@ -237,6 +239,7 @@ export function BaseDeck(props: BaseDeckProps): JSX.Element { )} <> + {/* render modules, nested labware, and overlays */} {modulesOnDeck.map( ({ moduleModel, @@ -247,7 +250,6 @@ export function BaseDeck(props: BaseDeckProps): JSX.Element { moduleChildren, onLabwareClick, highlightLabware, - stacked = false, }) => { const slotPosition = getPositionFromSlotId( moduleLocation.slotName, @@ -278,11 +280,11 @@ export function BaseDeck(props: BaseDeckProps): JSX.Element { /> ) : null} {moduleChildren} - {stacked ? : null} ) : null } )} + {/* render non-module labware and overlays */} {labwareOnDeck.map( ({ labwareLocation, @@ -292,7 +294,6 @@ export function BaseDeck(props: BaseDeckProps): JSX.Element { missingTips, onLabwareClick, highlight, - stacked = false, }) => { if ( labwareLocation === 'offDeck' || @@ -323,7 +324,72 @@ export function BaseDeck(props: BaseDeckProps): JSX.Element { highlight={highlight} /> {labwareChildren} - {stacked ? : null} + + ) : null + } + )} + {/* render stacked badge on module labware */} + {modulesOnDeck.map( + ({ moduleModel, moduleLocation, stacked = false }) => { + const slotPosition = getPositionFromSlotId( + moduleLocation.slotName, + deckDef + ) + const moduleDef = getModuleDef2(moduleModel) + + const { + x: nestedLabwareOffsetX, + y: nestedLabwareOffsetY, + } = moduleDef.labwareOffset + + // labwareOffset values are more accurate than our SVG renderings, so ignore any deviations under a certain threshold + const clampedLabwareOffsetX = + Math.abs(nestedLabwareOffsetX) > LABWARE_OFFSET_DISPLAY_THRESHOLD + ? nestedLabwareOffsetX + : 0 + const clampedLabwareOffsetY = + Math.abs(nestedLabwareOffsetY) > LABWARE_OFFSET_DISPLAY_THRESHOLD + ? nestedLabwareOffsetY + : 0 + // transform to be applied to children which render within the labware interfacing surface of the module + const childrenTransform = `translate(${clampedLabwareOffsetX}, ${clampedLabwareOffsetY})` + + return slotPosition != null && stacked ? ( + + + + + + ) : null + } + )} + {/* render stacked badge on non-module labware */} + {labwareOnDeck.map( + ({ labwareLocation, definition, stacked = false }) => { + if ( + labwareLocation === 'offDeck' || + !('slotName' in labwareLocation) || + // for legacy protocols that list fixed trash as a labware, do not render + definition.parameters.loadName === + 'opentrons_1_trash_3200ml_fixed' + ) { + return null + } + + const slotPosition = getPositionFromSlotId( + labwareLocation.slotName, + deckDef + ) + + return slotPosition != null && stacked ? ( + + ) : null }