From 608548a798cde1265674c50a80775734466550dd Mon Sep 17 00:00:00 2001 From: ncdiehl11 Date: Tue, 17 Dec 2024 14:37:05 -0500 Subject: [PATCH 1/7] feat(protocol-designer,-shared-data): add liquid class scaffolding to PD This PR introduces initial work for liquid class support in protocol designer. I create a full liquid class interface based on the API's Pydantic model. I also add utilities for getting all liquid class definitions and a feature flag to hide liquid classes from the UI. Lastly, I add some of the basic functionality for assigning a liquid class to a defined liquid, and displaying that liquid class in LiquidCard. A liquid class assigned to a defined liquid will be accessible through extended existing selectors (allIngredientNamesIds) for step forms. --- .../assets/localization/en/feature_flags.json | 4 + .../src/assets/localization/en/liquids.json | 4 + .../src/feature-flags/reducers.ts | 2 + .../src/feature-flags/selectors.ts | 4 + protocol-designer/src/feature-flags/types.ts | 2 + .../__tests__/ingredients.test.ts | 2 + .../src/labware-ingred/selectors.ts | 1 + protocol-designer/src/labware-ingred/types.ts | 10 +- protocol-designer/src/liquid-defs/utils.ts | 11 ++ .../AssignLiquidsModal/LiquidCard.tsx | 17 ++- .../AssignLiquidsModal/LiquidToolbox.tsx | 5 + .../organisms/DefineLiquidsModal/index.tsx | 58 +++++++++- .../__tests__/MaterialsListModal.test.tsx | 1 + .../__tests__/LiquidsOverflowMenu.test.tsx | 1 + .../ProtocolOverview/LiquidDefinitions.tsx | 29 +++-- .../__tests__/LiquidDefinitions.test.tsx | 3 + shared-data/js/index.ts | 1 + shared-data/js/liquidClasses.ts | 8 ++ shared-data/js/types.ts | 100 ++++++++++++++++++ 19 files changed, 245 insertions(+), 18 deletions(-) create mode 100644 protocol-designer/src/liquid-defs/utils.ts create mode 100644 shared-data/js/liquidClasses.ts diff --git a/protocol-designer/src/assets/localization/en/feature_flags.json b/protocol-designer/src/assets/localization/en/feature_flags.json index 9a13b327be8..92a074088ba 100644 --- a/protocol-designer/src/assets/localization/en/feature_flags.json +++ b/protocol-designer/src/assets/localization/en/feature_flags.json @@ -31,5 +31,9 @@ "OT_PD_ENABLE_REACT_SCAN": { "title": "Enable React Scan", "description": "Enable React Scan support for components rendering check" + }, + "OT_PD_ENABLE_LIQUID_CLASSES": { + "title": "Enable liquid classes", + "description": "Enable liquid classes support" } } diff --git a/protocol-designer/src/assets/localization/en/liquids.json b/protocol-designer/src/assets/localization/en/liquids.json index ebd4800dacb..36a31cf8116 100644 --- a/protocol-designer/src/assets/localization/en/liquids.json +++ b/protocol-designer/src/assets/localization/en/liquids.json @@ -10,6 +10,10 @@ "display_color": "Color", "liquid_volume": "Liquid volume by well", "liquid": "Liquid", + "liquid_class": { + "title": "Liquid class", + "tooltip": "Applies predefined pipetting settings to transfer and mix steps using this liquid" + }, "liquids_added": "Liquids added", "liquids": "Liquids", "microliters": "µL", diff --git a/protocol-designer/src/feature-flags/reducers.ts b/protocol-designer/src/feature-flags/reducers.ts index 42782c88479..bcffd39c5e7 100644 --- a/protocol-designer/src/feature-flags/reducers.ts +++ b/protocol-designer/src/feature-flags/reducers.ts @@ -30,6 +30,8 @@ const initialFlags: Flags = { OT_PD_ENABLE_HOT_KEYS_DISPLAY: process.env.OT_PD_ENABLE_HOT_KEYS_DISPLAY === '1' || true, OT_PD_ENABLE_REACT_SCAN: process.env.OT_PD_ENABLE_REACT_SCAN === '1' || false, + OT_PD_ENABLE_LIQUID_CLASSES: + process.env.OT_PD_ENABLE_REACT_SCAN === '1' || false, } // @ts-expect-error(sa, 2021-6-10): cannot use string literals as action type // TODO IMMEDIATELY: refactor this to the old fashioned way if we cannot have type safety: https://github.com/redux-utilities/redux-actions/issues/282#issuecomment-595163081 diff --git a/protocol-designer/src/feature-flags/selectors.ts b/protocol-designer/src/feature-flags/selectors.ts index 72b25fca895..6b8a70f8b30 100644 --- a/protocol-designer/src/feature-flags/selectors.ts +++ b/protocol-designer/src/feature-flags/selectors.ts @@ -45,3 +45,7 @@ export const getEnableReactScan: Selector = createSelector( getFeatureFlagData, flags => flags.OT_PD_ENABLE_REACT_SCAN ?? false ) +export const getEnableLiquidClasses: Selector = createSelector( + getFeatureFlagData, + flags => flags.OT_PD_ENABLE_LIQUID_CLASSES ?? false +) diff --git a/protocol-designer/src/feature-flags/types.ts b/protocol-designer/src/feature-flags/types.ts index 84bab18e474..6840786d149 100644 --- a/protocol-designer/src/feature-flags/types.ts +++ b/protocol-designer/src/feature-flags/types.ts @@ -36,6 +36,7 @@ export type FlagTypes = | 'OT_PD_ENABLE_RETURN_TIP' | 'OT_PD_ENABLE_HOT_KEYS_DISPLAY' | 'OT_PD_ENABLE_REACT_SCAN' + | 'OT_PD_ENABLE_LIQUID_CLASSES' // flags that are not in this list only show in prerelease mode export const userFacingFlags: FlagTypes[] = [ 'OT_PD_DISABLE_MODULE_RESTRICTIONS', @@ -49,5 +50,6 @@ export const allFlags: FlagTypes[] = [ 'OT_PD_ENABLE_COMMENT', 'OT_PD_ENABLE_RETURN_TIP', 'OT_PD_ENABLE_REACT_SCAN', + 'OT_PD_ENABLE_LIQUID_CLASSES', ] export type Flags = Partial> diff --git a/protocol-designer/src/labware-ingred/__tests__/ingredients.test.ts b/protocol-designer/src/labware-ingred/__tests__/ingredients.test.ts index b771cd16bbf..c81883001ac 100644 --- a/protocol-designer/src/labware-ingred/__tests__/ingredients.test.ts +++ b/protocol-designer/src/labware-ingred/__tests__/ingredients.test.ts @@ -19,6 +19,7 @@ describe('DUPLICATE_LABWARE action', () => { wellDetailsByLocation: null, concentration: '50 mol/ng', description: '', + liquidClass: null, displayColor: '#b925ff', serialize: false, }, @@ -27,6 +28,7 @@ describe('DUPLICATE_LABWARE action', () => { wellDetailsByLocation: null, concentration: '100%', description: '', + liquidClass: null, displayColor: '#ffd600', serialize: false, }, diff --git a/protocol-designer/src/labware-ingred/selectors.ts b/protocol-designer/src/labware-ingred/selectors.ts index eb7767af225..25ee8bc0966 100644 --- a/protocol-designer/src/labware-ingred/selectors.ts +++ b/protocol-designer/src/labware-ingred/selectors.ts @@ -113,6 +113,7 @@ const allIngredientNamesIds: Selector< ingredientId: ingredId, name: ingreds[ingredId].name, displayColor: ingreds[ingredId].displayColor, + liquidClass: ingreds[ingredId].liquidClass, })) }) const getLabwareSelectionMode: Selector = createSelector( diff --git a/protocol-designer/src/labware-ingred/types.ts b/protocol-designer/src/labware-ingred/types.ts index 6e9567722f3..65fbdd22d75 100644 --- a/protocol-designer/src/labware-ingred/types.ts +++ b/protocol-designer/src/labware-ingred/types.ts @@ -19,23 +19,21 @@ export interface WellContents { selected?: boolean maxVolume?: number } -export type ContentsByWell = { - [wellName: string]: WellContents -} | null -export interface WellContentsByLabware { - [labwareId: string]: ContentsByWell -} +export type ContentsByWell = Record | null +export type WellContentsByLabware = Record // ==== INGREDIENTS ==== export type OrderedLiquids = Array<{ ingredientId: string name: string | null | undefined displayColor: string | null | undefined + liquidClass: string | null | undefined }> // TODO: Ian 2018-10-15 audit & rename these confusing types export interface LiquidGroup { name: string | null | undefined description: string | null | undefined displayColor: string + liquidClass: string | null serialize: boolean } export type IngredInputs = LiquidGroup & { diff --git a/protocol-designer/src/liquid-defs/utils.ts b/protocol-designer/src/liquid-defs/utils.ts new file mode 100644 index 00000000000..a8478665f7e --- /dev/null +++ b/protocol-designer/src/liquid-defs/utils.ts @@ -0,0 +1,11 @@ +import { getAllLiquidClassDefs } from '@opentrons/shared-data' + +const liquidClassDefs = getAllLiquidClassDefs() +export const getLiquidClassDisplayName = ( + liquidClass: string | null +): string | null => { + if (liquidClass == null) { + return null + } + return liquidClassDefs[liquidClass]?.displayName ?? null +} diff --git a/protocol-designer/src/organisms/AssignLiquidsModal/LiquidCard.tsx b/protocol-designer/src/organisms/AssignLiquidsModal/LiquidCard.tsx index a422b4b210e..4f33b968db4 100644 --- a/protocol-designer/src/organisms/AssignLiquidsModal/LiquidCard.tsx +++ b/protocol-designer/src/organisms/AssignLiquidsModal/LiquidCard.tsx @@ -20,6 +20,7 @@ import { } from '@opentrons/components' import { LINE_CLAMP_TEXT_STYLE } from '../../atoms' +import { getEnableLiquidClasses } from '../../feature-flags/selectors' import { removeWellsContents } from '../../labware-ingred/actions' import { selectors as labwareIngredSelectors } from '../../labware-ingred/selectors' import { getLabwareEntities } from '../../step-forms/selectors' @@ -34,7 +35,7 @@ interface LiquidCardProps { export function LiquidCard(props: LiquidCardProps): JSX.Element { const { info } = props - const { name, color, liquidIndex } = info + const { name, color, liquidClassDisplayName, liquidIndex } = info const { t } = useTranslation('liquids') const dispatch = useDispatch() const [isExpanded, setIsExpanded] = useState(false) @@ -49,6 +50,7 @@ export function LiquidCard(props: LiquidCardProps): JSX.Element { const allWellContentsForActiveItem = useSelector( wellContentsSelectors.getAllWellContentsForActiveItem ) + const enableLiquidClasses = useSelector(getEnableLiquidClasses) const wellContents = allWellContentsForActiveItem != null && labwareId != null ? allWellContentsForActiveItem[labwareId] @@ -104,13 +106,24 @@ export function LiquidCard(props: LiquidCardProps): JSX.Element { > - + {name} + {liquidClassDisplayName != null && enableLiquidClasses ? ( + + ) : null} { if (liquidGroupId != null) { @@ -107,13 +117,14 @@ export function DefineLiquidsModal( const initialValues: LiquidEditFormValues = { name: selectedIngredFields?.name ?? '', displayColor: selectedIngredFields?.displayColor ?? swatchColors(liquidId), + liquidClass: selectedIngredFields?.liquidClass ?? '', description: selectedIngredFields?.description ?? '', serialize: selectedIngredFields?.serialize ?? false, } const { handleSubmit, - formState: { errors, touchedFields }, + formState, control, watch, setValue, @@ -125,11 +136,14 @@ export function DefineLiquidsModal( }) const name = watch('name') const color = watch('displayColor') + const liquidClass = watch('liquidClass') + const { errors, touchedFields } = formState const handleLiquidEdits = (values: LiquidEditFormValues): void => { saveForm({ name: values.name, displayColor: values.displayColor, + liquidClass: values.liquidClass ? values.liquidClass : null, description: values.description ?? null, serialize: values.serialize ?? false, }) @@ -142,6 +156,15 @@ export function DefineLiquidsModal( return `#${toHex(r)}${toHex(g)}${toHex(b)}${toHex(alpha)}` } + const liquidClassOptions = [ + { name: 'Choose an option', value: '' }, + ...Object.entries(liquidClassDefs).map( + ([liquidClassDefName, { displayName }]) => { + return { name: displayName, value: liquidClassDefName } + } + ), + ] + return ( { @@ -202,7 +225,10 @@ export function DefineLiquidsModal( ) : null} - + + {enableLiquidClasses ? ( + + ( + value === liquidClass + ) ?? liquidClassOptions[0] + } + onClick={value => { + field.onChange(value) + setValue('liquidClass', value) + }} + /> + )} + /> + + ) : null} { ingredientId: mockId, name: 'mockName', displayColor: 'mockDisplayColor', + liquidClass: null, }, ], } diff --git a/protocol-designer/src/pages/Designer/__tests__/LiquidsOverflowMenu.test.tsx b/protocol-designer/src/pages/Designer/__tests__/LiquidsOverflowMenu.test.tsx index 45fbebe5494..6e646fb6db7 100644 --- a/protocol-designer/src/pages/Designer/__tests__/LiquidsOverflowMenu.test.tsx +++ b/protocol-designer/src/pages/Designer/__tests__/LiquidsOverflowMenu.test.tsx @@ -42,6 +42,7 @@ describe('SlotOverflowMenu', () => { displayColor: 'mockColor', name: 'mockname', ingredientId: '0', + liquidClass: null, }, ]) }) diff --git a/protocol-designer/src/pages/ProtocolOverview/LiquidDefinitions.tsx b/protocol-designer/src/pages/ProtocolOverview/LiquidDefinitions.tsx index 378f14e13ad..dbe4e068a86 100644 --- a/protocol-designer/src/pages/ProtocolOverview/LiquidDefinitions.tsx +++ b/protocol-designer/src/pages/ProtocolOverview/LiquidDefinitions.tsx @@ -9,6 +9,7 @@ import { ListItemDescriptor, SPACING, StyledText, + Tag, } from '@opentrons/components' import { LINE_CLAMP_TEXT_STYLE } from '../../atoms' @@ -55,14 +56,28 @@ export function LiquidDefinitions({ } content={ - - {liquid.description != null && liquid.description !== '' - ? liquid.description - : t('na')} - + {liquid.description || liquid.liquidClass == null ? ( + + {liquid.description != null && liquid.description !== '' + ? liquid.description + : t('na')} + + ) : null} + {liquid.liquidClass != null ? ( + + ) : null} + } /> diff --git a/protocol-designer/src/pages/ProtocolOverview/__tests__/LiquidDefinitions.test.tsx b/protocol-designer/src/pages/ProtocolOverview/__tests__/LiquidDefinitions.test.tsx index 832cea4d800..e0105eb238a 100644 --- a/protocol-designer/src/pages/ProtocolOverview/__tests__/LiquidDefinitions.test.tsx +++ b/protocol-designer/src/pages/ProtocolOverview/__tests__/LiquidDefinitions.test.tsx @@ -21,6 +21,7 @@ const mockAllIngredientGroupFields = { name: 'EtOH', displayColor: '#b925ff', description: 'Immer fisch Hergestllter EtOH', + liquidClass: null, serialize: false, liquidGroupId: '0', }, @@ -28,6 +29,7 @@ const mockAllIngredientGroupFields = { name: '10mM Tris pH8,5', displayColor: '#ffd600', description: null, + liquidClass: null, serialize: false, liquidGroupId: '1', }, @@ -35,6 +37,7 @@ const mockAllIngredientGroupFields = { name: 'Amplicon PCR sample + AMPure XP beads', displayColor: '#9dffd8', description: '25µl Amplicon PCR + 20 µl AMPure XP beads', + liquidClass: null, serialize: false, liquidGroupId: '2', }, diff --git a/shared-data/js/index.ts b/shared-data/js/index.ts index 9a8d2e6c39f..50be81a940e 100644 --- a/shared-data/js/index.ts +++ b/shared-data/js/index.ts @@ -10,6 +10,7 @@ export * from './gripper' export * from './helpers' export * from './labware' export * from './labwareTools' +export * from './liquidClasses' export * from './modules' export * from './pipettes' export * from './protocols' diff --git a/shared-data/js/liquidClasses.ts b/shared-data/js/liquidClasses.ts new file mode 100644 index 00000000000..d97db8afa47 --- /dev/null +++ b/shared-data/js/liquidClasses.ts @@ -0,0 +1,8 @@ +import waterV1Uncasted from '../liquid-class/definitions/1/water.json' +import type { LiquidClass } from '.' + +const waterV1 = waterV1Uncasted as LiquidClass + +const defs = { waterV1 } + +export const getAllLiquidClassDefs = (): Record => defs diff --git a/shared-data/js/types.ts b/shared-data/js/types.ts index 71c932a35d4..6abe511bb8f 100644 --- a/shared-data/js/types.ts +++ b/shared-data/js/types.ts @@ -693,6 +693,106 @@ export interface Liquid { displayColor?: string } +// TODO(ND, 12/17/2024): investigate why typescript doesn't allow Array<[number, number]> +type LiquidHandlingPropertyByVolume = number[][] +type PositionReference = + | 'well-bottom' + | 'well-top' + | 'well-center' + | 'liquid-meniscus' +type BlowoutLocation = 'source' | 'destination' | 'trash' +interface DelayParams { + duration: number +} +interface DelayProperties { + enable: boolean + params?: DelayParams +} +interface TouchTipParams { + zOffset: number + mmToEdge: number + speed: number +} +interface TouchTipProperties { + enable: boolean + params?: TouchTipParams +} + +interface MixParams { + repetitions: number + volume: number +} +interface MixProperties { + enable: boolean + params?: MixParams +} +interface BlowoutParams { + location: BlowoutLocation + flowRate: number +} +interface BlowoutProperties { + enable: boolean + params?: BlowoutParams +} +interface Submerge { + positionReference: PositionReference + offset: Coordinates + speed: number + delay: DelayProperties +} +interface BaseRetract { + positionReference: PositionReference + offset: Coordinates + speed: number + airGapByVolume: LiquidHandlingPropertyByVolume + touchTip: TouchTipProperties + delay: DelayProperties +} +type RetractAspirate = BaseRetract +interface RetractDispense extends BaseRetract { + blowout: BlowoutProperties +} +interface BaseLiquidHandlingProperties { + submerge: Submerge + retract: RetractType + positionReference: PositionReference + offset: Coordinates + flowRateByVolume: LiquidHandlingPropertyByVolume + correctionByVolume: LiquidHandlingPropertyByVolume + delay: DelayProperties +} +interface AspirateProperties + extends BaseLiquidHandlingProperties { + preWet: boolean + mix: MixProperties +} +interface SingleDispenseProperties + extends BaseLiquidHandlingProperties { + mix: MixProperties + pushOutByVolume: LiquidHandlingPropertyByVolume +} +interface MultiDispenseProperties { + conditioningByVolume: LiquidHandlingPropertyByVolume + disposalByVolume: LiquidHandlingPropertyByVolume +} +interface ByTipTypeSetting { + tiprack: string + aspirate: AspirateProperties + singleDispense: SingleDispenseProperties + multiDispense?: MultiDispenseProperties +} +interface ByPipetteSetting { + pipetteModel: string + byTipType: ByTipTypeSetting[] +} +export interface LiquidClass { + liquidClassName: string + displayName: string + schemaVersion: number + namespace: string + byPipette: ByPipetteSetting[] +} + export interface AnalysisError { id: string detail: string From e6b2407cd2d0bfbb9f0d05e2e15f15dcc8d30a67 Mon Sep 17 00:00:00 2001 From: ncdiehl11 Date: Tue, 17 Dec 2024 14:58:39 -0500 Subject: [PATCH 2/7] hide liquiddefinitions liquidclasses behind ff --- .../src/pages/ProtocolOverview/LiquidDefinitions.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/protocol-designer/src/pages/ProtocolOverview/LiquidDefinitions.tsx b/protocol-designer/src/pages/ProtocolOverview/LiquidDefinitions.tsx index dbe4e068a86..2f85515edf4 100644 --- a/protocol-designer/src/pages/ProtocolOverview/LiquidDefinitions.tsx +++ b/protocol-designer/src/pages/ProtocolOverview/LiquidDefinitions.tsx @@ -1,4 +1,5 @@ import { useTranslation } from 'react-i18next' +import { useSelector } from 'react-redux' import { ALIGN_CENTER, DIRECTION_COLUMN, @@ -12,6 +13,7 @@ import { Tag, } from '@opentrons/components' import { LINE_CLAMP_TEXT_STYLE } from '../../atoms' +import { getEnableLiquidClasses } from '../../feature-flags/selectors' import type { AllIngredGroupFields } from '../../labware-ingred/types' @@ -23,6 +25,7 @@ export function LiquidDefinitions({ allIngredientGroupFields, }: LiquidDefinitionsProps): JSX.Element { const { t } = useTranslation('protocol_overview') + const enableLiquidClasses = useSelector(getEnableLiquidClasses) return ( @@ -60,7 +63,9 @@ export function LiquidDefinitions({ flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing4} > - {liquid.description || liquid.liquidClass == null ? ( + {liquid.description || + liquid.liquidClass == null || + !enableLiquidClasses ? ( ) : null} - {liquid.liquidClass != null ? ( + {liquid.liquidClass && enableLiquidClasses ? ( Date: Tue, 17 Dec 2024 15:39:19 -0500 Subject: [PATCH 3/7] refactor LiquidDefinitions content --- .../ProtocolOverview/LiquidDefinitions.tsx | 114 ++++++++++-------- 1 file changed, 65 insertions(+), 49 deletions(-) diff --git a/protocol-designer/src/pages/ProtocolOverview/LiquidDefinitions.tsx b/protocol-designer/src/pages/ProtocolOverview/LiquidDefinitions.tsx index 2f85515edf4..b55b615eb11 100644 --- a/protocol-designer/src/pages/ProtocolOverview/LiquidDefinitions.tsx +++ b/protocol-designer/src/pages/ProtocolOverview/LiquidDefinitions.tsx @@ -14,8 +14,38 @@ import { } from '@opentrons/components' import { LINE_CLAMP_TEXT_STYLE } from '../../atoms' import { getEnableLiquidClasses } from '../../feature-flags/selectors' +import { getLiquidClassDisplayName } from '../../liquid-defs/utils' -import type { AllIngredGroupFields } from '../../labware-ingred/types' +import type { + AllIngredGroupFields, + IngredInputs, +} from '../../labware-ingred/types' + +const getLiquidDescription = ( + liquid: IngredInputs, + enableLiquidClasses: boolean +): JSX.Element | null => { + const { description, liquidClass } = liquid + const liquidClassDisplayName = getLiquidClassDisplayName(liquidClass) + const liquidClassInfo = + !enableLiquidClasses || liquidClassDisplayName == null ? null : ( + + ) + + return liquidClassInfo == null && !description ? null : ( + + {description ? ( + + {description} + + ) : null} + {liquidClassInfo} + + ) +} interface LiquidDefinitionsProps { allIngredientGroupFields: AllIngredGroupFields @@ -34,59 +64,45 @@ export function LiquidDefinitions({ {Object.keys(allIngredientGroupFields).length > 0 ? ( - Object.values(allIngredientGroupFields).map((liquid, index) => ( - - - - { + return ( + + - {liquid.name} - - - } - content={ - - {liquid.description || - liquid.liquidClass == null || - !enableLiquidClasses ? ( + + + {liquid.name} + + + } + content={ + getLiquidDescription(liquid, enableLiquidClasses) ?? ( - {liquid.description != null && liquid.description !== '' - ? liquid.description - : t('na')} + {t('na')} - ) : null} - {liquid.liquidClass && enableLiquidClasses ? ( - - ) : null} - - } - /> - - )) + ) + } + /> + + ) + }) ) : ( )} From 997baec84a7dde506ec0412e8048929f13b151d6 Mon Sep 17 00:00:00 2001 From: ncdiehl11 Date: Tue, 17 Dec 2024 16:05:10 -0500 Subject: [PATCH 4/7] fix tests --- .../pages/ProtocolOverview/__tests__/LiquidDefinitions.test.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/protocol-designer/src/pages/ProtocolOverview/__tests__/LiquidDefinitions.test.tsx b/protocol-designer/src/pages/ProtocolOverview/__tests__/LiquidDefinitions.test.tsx index e0105eb238a..3c088a338d6 100644 --- a/protocol-designer/src/pages/ProtocolOverview/__tests__/LiquidDefinitions.test.tsx +++ b/protocol-designer/src/pages/ProtocolOverview/__tests__/LiquidDefinitions.test.tsx @@ -8,6 +8,8 @@ import { LiquidDefinitions } from '../LiquidDefinitions' import type { ComponentProps } from 'react' import type { InfoScreen } from '@opentrons/components' +vi.mock('../../../feature-flags/selectors') + vi.mock('@opentrons/components', async importOriginal => { const actual = await importOriginal() return { From b583dd9cd63710aca1f6bb6e84b13f9a2dc5e8a0 Mon Sep 17 00:00:00 2001 From: ncdiehl11 Date: Tue, 17 Dec 2024 16:26:21 -0500 Subject: [PATCH 5/7] clean up types and test --- protocol-designer/src/labware-ingred/types.ts | 4 ++-- protocol-designer/src/liquid-defs/utils.ts | 6 +++++- .../src/organisms/DefineLiquidsModal/index.tsx | 8 ++++---- .../src/pages/ProtocolOverview/LiquidDefinitions.tsx | 1 + .../ProtocolOverview/__tests__/LiquidDefinitions.test.tsx | 2 +- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/protocol-designer/src/labware-ingred/types.ts b/protocol-designer/src/labware-ingred/types.ts index 65fbdd22d75..667a16e339a 100644 --- a/protocol-designer/src/labware-ingred/types.ts +++ b/protocol-designer/src/labware-ingred/types.ts @@ -30,8 +30,8 @@ export type OrderedLiquids = Array<{ }> // TODO: Ian 2018-10-15 audit & rename these confusing types export interface LiquidGroup { - name: string | null | undefined - description: string | null | undefined + name: string | null + description: string | null displayColor: string liquidClass: string | null serialize: boolean diff --git a/protocol-designer/src/liquid-defs/utils.ts b/protocol-designer/src/liquid-defs/utils.ts index a8478665f7e..cb9bc9398c9 100644 --- a/protocol-designer/src/liquid-defs/utils.ts +++ b/protocol-designer/src/liquid-defs/utils.ts @@ -7,5 +7,9 @@ export const getLiquidClassDisplayName = ( if (liquidClass == null) { return null } - return liquidClassDefs[liquidClass]?.displayName ?? null + if (!(liquidClass in liquidClassDefs)) { + console.warn(`Liquid class ${liquidClass} not found`) + return null + } + return liquidClassDefs[liquidClass].displayName } diff --git a/protocol-designer/src/organisms/DefineLiquidsModal/index.tsx b/protocol-designer/src/organisms/DefineLiquidsModal/index.tsx index cb00a323ac8..a89052d27a6 100644 --- a/protocol-designer/src/organisms/DefineLiquidsModal/index.tsx +++ b/protocol-designer/src/organisms/DefineLiquidsModal/index.tsx @@ -45,9 +45,9 @@ import type { LiquidGroup } from '../../labware-ingred/types' interface LiquidEditFormValues { name: string displayColor: string - description?: string | null - liquidClass: string | null - serialize?: boolean + description: string + liquidClass: string + serialize: boolean [key: string]: unknown } @@ -144,7 +144,7 @@ export function DefineLiquidsModal( name: values.name, displayColor: values.displayColor, liquidClass: values.liquidClass ? values.liquidClass : null, - description: values.description ?? null, + description: values.description ? values.description : null, serialize: values.serialize ?? false, }) } diff --git a/protocol-designer/src/pages/ProtocolOverview/LiquidDefinitions.tsx b/protocol-designer/src/pages/ProtocolOverview/LiquidDefinitions.tsx index b55b615eb11..e9da36c4bae 100644 --- a/protocol-designer/src/pages/ProtocolOverview/LiquidDefinitions.tsx +++ b/protocol-designer/src/pages/ProtocolOverview/LiquidDefinitions.tsx @@ -65,6 +65,7 @@ export function LiquidDefinitions({ {Object.keys(allIngredientGroupFields).length > 0 ? ( Object.values(allIngredientGroupFields).map((liquid, index) => { + console.log(getLiquidDescription(liquid, enableLiquidClasses)) return ( Date: Tue, 17 Dec 2024 16:36:51 -0500 Subject: [PATCH 6/7] fix colorpicker zindex --- protocol-designer/src/organisms/DefineLiquidsModal/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/protocol-designer/src/organisms/DefineLiquidsModal/index.tsx b/protocol-designer/src/organisms/DefineLiquidsModal/index.tsx index a89052d27a6..3e2e90d8d94 100644 --- a/protocol-designer/src/organisms/DefineLiquidsModal/index.tsx +++ b/protocol-designer/src/organisms/DefineLiquidsModal/index.tsx @@ -205,6 +205,7 @@ export function DefineLiquidsModal( left="4.375rem" top="4.6875rem" ref={chooseColorWrapperRef} + zIndex={2} > Date: Tue, 17 Dec 2024 18:02:31 -0500 Subject: [PATCH 7/7] add todo for migration --- protocol-designer/src/labware-ingred/types.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/protocol-designer/src/labware-ingred/types.ts b/protocol-designer/src/labware-ingred/types.ts index 667a16e339a..6b7628735d8 100644 --- a/protocol-designer/src/labware-ingred/types.ts +++ b/protocol-designer/src/labware-ingred/types.ts @@ -22,11 +22,12 @@ export interface WellContents { export type ContentsByWell = Record | null export type WellContentsByLabware = Record // ==== INGREDIENTS ==== +// TODO(ND: 12/17/2024): add migration for liquids in >8.3.0 export type OrderedLiquids = Array<{ ingredientId: string - name: string | null | undefined - displayColor: string | null | undefined - liquidClass: string | null | undefined + name?: string | null + displayColor?: string | null + liquidClass?: string | null }> // TODO: Ian 2018-10-15 audit & rename these confusing types export interface LiquidGroup {