Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions components/src/atoms/buttons/AltPrimaryButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,17 @@ export const AltPrimaryButton = styled(Btn)`

${styleProps}

&:focus {
&:hover {
box-shadow: 0 0 0;
background-color: ${COLORS.grey35};
box-shadow: none;
}

&:active {
background-color: ${COLORS.grey40};
}

&:hover {
box-shadow: 0 0 0;
background-color: ${COLORS.grey35};
&:active:hover {
background-color: ${COLORS.grey40};
}

&:disabled {
Expand Down
4 changes: 4 additions & 0 deletions protocol-designer/src/assets/localization/en/alert.json
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@
"NEXT_TIPRACK_HAS_LID": {
"title": "Unable to pick up tips",
"body": "The next available tip rack has a lid. Remove the lid from the tip rack to pick up tips."
},
"INCOMPLETE_PICKUP": {
"title": "Incomplete tip pickup",
"body": "At least one of the selected tips is empty"
}
},
"warning": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ListButton,
ListButtonAccordion,
ListButtonAccordionContainer,
SPACING,
} from '@opentrons/components'

import { getCustomLabwareDefsByURI } from '../../../labware-defs/selectors'
Expand Down Expand Up @@ -58,6 +59,7 @@ export function SelectCustomLabware(
<ListButton
key={`ListButton_${CUSTOM_CATEGORY}`}
type="noActive"
padding={SPACING.spacing12}
onClick={() => {
handleCategoryClick(CUSTOM_CATEGORY)
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ export function SelectLabwareOnAdapter(
>
{has96Channel && loadName === ADAPTER_96_CHANNEL
? permittedTipracks.map((tiprackDefUri, index) => {
const nestedDef = defs[tiprackDefUri]
const nestedDef =
defs[tiprackDefUri] ?? customLabwareDefs[tiprackDefUri]
const stackingLabwareDefUris = getStackerDefinitions(
{
...defs,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,16 +160,6 @@ export function SelectTips(
}

const handleClickWell = (wellName: string): void => {
if (
tipState?.[wellName] === 'EMPTY' ||
!tipAccessibileStatusByWellName[wellName].isAccessible ||
(allWellsAffectedByHover.includes(wellName) &&
!areAllHoveredWellsAccessibleAndOccupied)
) {
return
}
setShowPickupsRequiredBanner(false)

const prevSelectedTipsByIndex = selectedTips.reduce<Record<string, number>>(
(acc, tipList, index) => {
const innerAcc = tipList.reduce((acc, tip) => {
Expand All @@ -180,6 +170,18 @@ export function SelectTips(
{}
)

if (
// always allow tip unselection
!(wellName in prevSelectedTipsByIndex) &&
(tipState?.[wellName] === 'EMPTY' ||
!tipAccessibileStatusByWellName[wellName].isAccessible ||
(allWellsAffectedByHover.includes(wellName) &&
!areAllHoveredWellsAccessibleAndOccupied))
) {
return
}
setShowPickupsRequiredBanner(false)

if (channels === 1 || nozzles === SINGLE) {
if (wellName in prevSelectedTipsByIndex) {
const indexToUnselect = prevSelectedTipsByIndex[wellName]
Expand Down Expand Up @@ -274,7 +276,13 @@ export function SelectTips(
status = rawState === NO ? NO : INACCESSIBLE
}
if (selectedTips.flat().some(tip => tip === wellName)) {
status = rawState === USED ? SELECTED_USED : SELECTED
const isAccessible =
tipAccessibileStatusByWellName[wellName].isAccessible
if (!isAccessible) {
status = SELECTED_ERROR
} else {
status = rawState === USED ? SELECTED_USED : SELECTED
}
} else if (allWellsAffectedByHover.includes(wellName)) {
if (
areAllHoveredWellsAccessibleAndOccupied &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,7 @@ import {
SPACING,
StyledText,
} from '@opentrons/components'
import {
getAllLiquidClassDefs,
getFlexNameConversion,
OT2_ROBOT_TYPE,
WATER_LIQUID_CLASS_NAME,
} from '@opentrons/shared-data'
import { OT2_ROBOT_TYPE } from '@opentrons/shared-data'
import {
AUTOMATIC,
getDefaultPrimaryNozzle,
Expand Down Expand Up @@ -72,28 +67,6 @@ export function TipTrackingField(props: TipTrackingFieldProps): JSX.Element {
tiprackEntity => tiprackEntity.labwareDefURI === formData.tipRack
)?.def

const allLiquidClassDefs = getAllLiquidClassDefs()
const liquidClassDef =
allLiquidClassDefs[formData.liquidClass ?? ''] ??
allLiquidClassDefs[WATER_LIQUID_CLASS_NAME]
const convertedPipetteName =
pipette != null ? getFlexNameConversion(pipette.spec) : null
const liquidClassValuesForPipette = liquidClassDef.byPipette.find(
({ pipetteModel }) => convertedPipetteName === pipetteModel
)
const liquidClassValuesForTip = liquidClassValuesForPipette?.byTipType.find(
tipObject => tipObject.tiprack === formData.tipRack
)

let airGapByVolume: Array<[number, number]> = []
// no air gap included for mix step
if (formData.stepType === 'moveLiquid') {
airGapByVolume =
(liquidClassValuesForTip?.aspirate.retract.airGapByVolume as Array<
[number, number]
>) ?? []
}

const transferPlanAndReferenceVolumes =
pipette != null && tiprackDefinition != null && formData != null
? getTransferPlanAndReferenceVolumes({
Expand All @@ -113,14 +86,14 @@ export function TipTrackingField(props: TipTrackingFieldProps): JSX.Element {
conditioningByVolume:
robotType === OT2_ROBOT_TYPE
? []
: ((liquidClassValuesForTip?.multiDispense
?.conditioningByVolume as Array<[number, number]>) ?? null),
: [[0, Number(formData.conditioning_volume ?? 0)]],
disposalByVolume:
robotType === OT2_ROBOT_TYPE
? []
: ((liquidClassValuesForTip?.multiDispense
?.disposalByVolume as Array<[number, number]>) ?? null),
aspirateAirGapByVolume: airGapByVolume,
: [[0, Number(formData.disposalVolume_volume ?? 0)]],
aspirateAirGapByVolume: [
[0, Number(formData.aspirate_airGap_volume ?? 0)],
],
})
: null

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,11 @@ const updatePatchOnPipetteChange = (

return {
...patch,
...getDefaultFields('aspirate_flowRate', 'dispense_flowRate'),
...getDefaultFields(
'aspirate_flowRate',
'dispense_flowRate',
'tips_selected'
),
nozzles,
tipRack: firstDefaultTiprackURIOnDeck,
}
Expand All @@ -148,7 +152,12 @@ const updatePatchOnTiprackChange = (
if (fieldHasChanged(rawForm, patch, 'tipRack')) {
return {
...patch,
...getDefaultFields('aspirate_flowRate', 'dispense_flowRate'),
...getDefaultFields(
'aspirate_flowRate',
'dispense_flowRate',
'tiprack_selected',
'tips_selected'
),
}
}

Expand Down Expand Up @@ -181,6 +190,32 @@ const updatePatchOnChangeTipChange = (
return patch
}

const updatePatchOnWellsSelectedChange = (
patch: FormPatch,
rawForm: FormData
): FormPatch => {
if (fieldHasChanged(rawForm, patch, 'wells')) {
return {
...patch,
...getDefaultFields('tips_selected'),
}
}
return patch
}

const updatePatchOnVolumeChange = (
patch: FormPatch,
rawForm: FormData
): FormPatch => {
if (fieldHasChanged(rawForm, patch, 'volume')) {
return {
...patch,
...getDefaultFields('tips_selected'),
}
}
return patch
}

export function dependentFieldsUpdateMix(
originalPatch: FormPatch,
rawForm: FormData, // raw = NOT hydrated
Expand Down Expand Up @@ -213,5 +248,7 @@ export function dependentFieldsUpdateMix(
chainPatch => updatePatchOnTiprackChange(chainPatch, rawForm),
chainPatch => updatePatchOnNozzlesChange(chainPatch, rawForm),
chainPatch => updatePatchOnChangeTipChange(chainPatch, rawForm),
chainPatch => updatePatchOnWellsSelectedChange(chainPatch, rawForm),
chainPatch => updatePatchOnVolumeChange(chainPatch, rawForm),
])
}
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,8 @@ const updatePatchOnPipetteChange = (
'dispense_mix_volume',
'disposalVolume_volume',
'aspirate_mmFromBottom',
'dispense_mmFromBottom'
'dispense_mmFromBottom',
'tips_selected'
),
nozzles,
aspirate_airGap_volume: airGapVolume,
Expand Down Expand Up @@ -256,7 +257,9 @@ const updatePatchOnTiprackChange = (
'dispense_flowRate',
'aspirate_mix_volume',
'dispense_mix_volume',
'disposalVolume_volume'
'disposalVolume_volume',
'tips_selected',
'tiprack_selected'
),
aspirate_airGap_volume: airGapVolume,
dispense_airGap_volume: airGapVolume,
Expand Down Expand Up @@ -646,8 +649,8 @@ export function updatePatchBlowoutFields(
if (shouldResetBlowoutLocation) {
return { ...patch, ...getDefaultFields('blowout_location') }
}
return { ...patch, ...getDefaultFields('tips_selected') }
}

return patch
}

Expand All @@ -662,7 +665,7 @@ const updatePatchOnNozzleChange = (
) {
return {
...patch,
...getDefaultFields('aspirate_wells', 'dispense_wells'),
...getDefaultFields('aspirate_wells', 'dispense_wells', 'tips_selected'),
}
}
return patch
Expand Down Expand Up @@ -732,6 +735,44 @@ const updatePatchOnChangeTipChange = (
return patch
}

const updatePatchOnWellsSelectedChange = (
patch: FormPatch,
rawForm: FormData
): FormPatch => {
if (
fieldHasChanged(rawForm, patch, 'aspirate_wells') ||
fieldHasChanged(rawForm, patch, 'dispense_wells')
) {
return {
...patch,
...getDefaultFields('tips_selected'),
}
}
return patch
}

const updatePatchOnVolumeChange = (
patch: FormPatch,
rawForm: FormData
): FormPatch => {
const relevantFields = [
'volume',
'conditioning_volume',
'disposalVolume_volume',
'aspirate_airGap_volume',
'dispense_airGap_volume,',
]
for (const field of relevantFields) {
if (fieldHasChanged(rawForm, patch, field)) {
return {
...patch,
...getDefaultFields('tips_selected'),
}
}
}
return patch
}

export function dependentFieldsUpdateMoveLiquid(
originalPatch: FormPatch,
rawForm: FormData, // raw = NOT hydrated
Expand Down Expand Up @@ -779,5 +820,7 @@ export function dependentFieldsUpdateMoveLiquid(
chainPatch => updatePatchOnPathChange(chainPatch, rawForm, pipetteEntities),
chainPatch => updatePatchOnNozzlesChange(chainPatch, rawForm),
chainPatch => updatePatchOnChangeTipChange(chainPatch, rawForm),
chainPatch => updatePatchOnWellsSelectedChange(chainPatch, rawForm),
chainPatch => updatePatchOnVolumeChange(chainPatch, rawForm),
])
}
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ describe('well selection should update', () => {
mix_mmFromBottom: DEFAULT_MM_OFFSET_FROM_BOTTOM,
mix_touchTip_mmFromTop: null,
mix_touchTip_checkbox: false,
tips_selected: [],
})
})
it('select labware with multiple wells', () => {
Expand All @@ -163,6 +164,7 @@ describe('well selection should update', () => {
mix_mmFromBottom: DEFAULT_MM_OFFSET_FROM_BOTTOM,
mix_touchTip_mmFromTop: null,
mix_touchTip_checkbox: false,
tips_selected: [],
})
})
})
Expand Down
Loading
Loading