Skip to content

Commit

Permalink
fix(protocol-designer): fix recurring deleted labware bug (#2299)
Browse files Browse the repository at this point in the history
make labware access by id always maybe typed (?Labware) so flow ensures safe access
  • Loading branch information
IanLondon authored Sep 18, 2018
1 parent 72b9084 commit ebb44e1
Show file tree
Hide file tree
Showing 9 changed files with 29 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ const mapSTP = (state: BaseState, ownProps: OP): SP => {
let wellHeightMM = null
if (formData && formData[labwareFieldName]) {
const labwareById = labwareIngredsSelectors.getLabware(state)
// TODO: BC 2018-08-29 protect for the case where selected labware gets deleted
const labwareDef = getLabware(labwareById[formData[labwareFieldName]].type)
const labware = labwareById[formData[labwareFieldName]]
const labwareDef = labware && labware.type && getLabware(labware.type)
if (labwareDef) {
// NOTE: only taking depth of first well in labware def, UI not currently equipped for multiple depths
const firstWell = labwareDef.wells['A1']
Expand Down
2 changes: 1 addition & 1 deletion protocol-designer/src/containers/SelectablePlate.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ function mapStateToProps (state: BaseState, ownProps: OP): SP {
containerId,
wellContents,
getTipProps: getTipProps || noop,
containerType: labware.type,
containerType: labware ? labware.type : 'missing labware',
selectable,
}
}
Expand Down
5 changes: 3 additions & 2 deletions protocol-designer/src/file-data/selectors/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ export const getLabwareLiquidState: Selector<StepGeneration.LabwareLiquidState>
acc: StepGeneration.LabwareLiquidState,
labwareId
): StepGeneration.LabwareLiquidState => {
const allWells = getAllWellsForLabware(allLabware[labwareId].type)
const labwareType = allLabware[labwareId] && allLabware[labwareId].type
const allWells = labwareType ? getAllWellsForLabware(labwareType) : []
const liquidStateForLabwareAllWells = allWells.reduce(
(innerAcc: StepGeneration.SingleLabwareLiquidState, well) => ({
...innerAcc,
Expand All @@ -46,7 +47,7 @@ export const getLabwareLiquidState: Selector<StepGeneration.LabwareLiquidState>
}
)

function labwareConverter (labwareAppState: {[labwareId: string]: Labware}): {[labwareId: string]: StepGeneration.LabwareData} {
function labwareConverter (labwareAppState: {[labwareId: string]: ?Labware}): {[labwareId: string]: StepGeneration.LabwareData} {
// Convert internal PD labware objects into JSON spec labware objects
// (just removes keys & makes flow happy)
return mapValues(labwareAppState, (l: Labware): StepGeneration.LabwareData => ({
Expand Down
20 changes: 12 additions & 8 deletions protocol-designer/src/labware-ingred/reducers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ const renameLabwareFormMode = handleActions({
}, false)

type ContainersState = {
[id: string]: Labware,
[id: string]: ?Labware,
}

const initialLabwareState: ContainersState = {
Expand All @@ -95,10 +95,14 @@ const initialLabwareState: ContainersState = {
},
}

function getNextDisambiguationNumber (allContainers: ContainersState, labwareType: string): number {
const allIds = Object.keys(allContainers)
const sameTypeLabware = allIds.filter(containerId => allContainers[containerId].type === labwareType)
const disambigNumbers = sameTypeLabware.map(containerId => allContainers[containerId].disambiguationNumber)
function getNextDisambiguationNumber (allLabwareById: ContainersState, labwareType: string): number {
const allIds = Object.keys(allLabwareById)
const sameTypeLabware = allIds.filter(labwareId =>
allLabwareById[labwareId] &&
allLabwareById[labwareId].type === labwareType)
const disambigNumbers = sameTypeLabware.map(labwareId =>
(allLabwareById[labwareId] &&
allLabwareById[labwareId].disambiguationNumber) || 0)

return disambigNumbers.length > 0
? Math.max(...disambigNumbers) + 1
Expand Down Expand Up @@ -282,7 +286,7 @@ const rootReducer = combineReducers({
// SELECTORS
const rootSelector = (state: BaseState): RootState => state.labwareIngred

const getLabware: Selector<{[labwareId: string]: Labware}> = createSelector(
const getLabware: Selector<{[labwareId: string]: ?Labware}> = createSelector(
rootSelector,
rootState => rootState.containers
)
Expand Down Expand Up @@ -311,8 +315,8 @@ const getIngredientNames: Selector<{[ingredId: string]: string}> = createSelecto
)

const _loadedContainersBySlot = (containers: ContainersState) =>
reduce(containers, (acc, container: Labware, containerId) => (container.slot)
? {...acc, [container.slot]: container.type}
reduce(containers, (acc, labware: ?Labware) => (labware && labware.slot)
? {...acc, [labware.slot]: labware.type}
: acc
, {})

Expand Down
9 changes: 6 additions & 3 deletions protocol-designer/src/steplist/actions/handleFormChange.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ function handleFormChange (payload: ChangeFormPayload, getState: GetState): Chan
} else if (multiToSingle) {
// multi-channel to single-channel: convert primary wells to all wells
const labwareId = unsavedForm.labware
const labwareType = labwareId && labwareIngredSelectors.getLabware(baseState)[labwareId].type
const labware = labwareId && labwareIngredSelectors.getLabware(baseState)[labwareId]
const labwareType = labware && labware.type

updateOverrides = {
...updateOverrides,
Expand All @@ -158,8 +159,10 @@ function handleFormChange (payload: ChangeFormPayload, getState: GetState): Chan
const sourceLabwareId = unsavedForm['aspirate_labware']
const destLabwareId = unsavedForm['dispense_labware']

const sourceLabwareType = sourceLabwareId && labwareIngredSelectors.getLabware(baseState)[sourceLabwareId].type
const destLabwareType = destLabwareId && labwareIngredSelectors.getLabware(baseState)[destLabwareId].type
const sourceLabware = sourceLabwareId && labwareIngredSelectors.getLabware(baseState)[sourceLabwareId]
const sourceLabwareType = sourceLabware && sourceLabware.type
const destLabware = destLabwareId && labwareIngredSelectors.getLabware(baseState)[destLabwareId]
const destLabwareType = destLabware && destLabware.type

updateOverrides = {
...updateOverrides,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ const mixFormToArgs = (formData: FormData, context: StepFormContext): Validation
const orderSecond = formData.aspirate_wellOrder_second
if (context && context.labware && labware) {
const labwareById = context.labware
const labwareType = labwareById[labware].type
const labwareDef = getLabware(labwareType)
const labwareDef = labwareById[labware] && getLabware(labwareById[labware].type)
if (labwareDef) {
const allWellsOrdered = orderWells(labwareDef.ordering, orderFirst, orderSecond)
wells = intersection(allWellsOrdered, wells)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ const transferLikeFormToArgs = (formData: FormData, context: StepFormContext): T
if (context && context.labware) {
const labwareById = context.labware
if (stepType !== 'distribute' && sourceLabware) {
const sourceLabwareDef = getLabware(labwareById[sourceLabware].type)
const sourceLabwareDef = labwareById[sourceLabware] && getLabware(labwareById[sourceLabware].type)
if (sourceLabwareDef) {
const allWellsOrdered = orderWells(sourceLabwareDef.ordering, aspirate_wellOrder_first, aspirate_wellOrder_second)
sourceWells = intersection(allWellsOrdered, sourceWells)
Expand All @@ -119,7 +119,7 @@ const transferLikeFormToArgs = (formData: FormData, context: StepFormContext): T
}
}
if (stepType !== 'consolidate' && destLabware) {
const destLabwareDef = getLabware(labwareById[destLabware].type)
const destLabwareDef = labwareById[destLabware] && getLabware(labwareById[destLabware].type)
if (destLabwareDef) {
const allWellsOrdered = orderWells(destLabwareDef.ordering, dispense_wellOrder_first, dispense_wellOrder_second)
destWells = intersection(allWellsOrdered, destWells)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
import type { Labware } from '../../../labware-ingred/types'

export type StepFormContext = {
labware?: ?{[labwareId: string]: Labware},
labware?: ?{[labwareId: string]: ?Labware},
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const wellContentsAllLabware: Selector<WellContentsByLabware> = createSelector(
return {
...acc,
[labwareId]: _getWellContents(
_labware[labwareId].type,
_labware[labwareId] && _labware[labwareId].type,
ingredsForLabware,
// Only give _getWellContents the selection data if it's a selected container
isSelectedLabware ? _selectedWells : null,
Expand Down

0 comments on commit ebb44e1

Please sign in to comment.