From a93f50d82daa0126bb90de1946b0d982a1ea09b7 Mon Sep 17 00:00:00 2001 From: IanLondon Date: Tue, 17 Sep 2019 13:12:35 -0400 Subject: [PATCH 1/5] feat(protocol-designer): avoid use of labware "format" closes #3894 --- .../components/labware/SelectableLabware.js | 7 +- protocol-designer/src/labware-defs/actions.js | 2 +- .../formLevel/handleFormChange/utils.js | 2 +- .../src/top-selectors/substep-highlight.js | 2 +- .../src/top-selectors/tip-contents/index.js | 15 ++- protocol-designer/src/ui/labware/selectors.js | 26 ++-- protocol-designer/src/utils/index.js | 7 ++ .../src/well-selection/test/utils.test.js | 108 ----------------- protocol-designer/src/well-selection/utils.js | 61 ---------- .../js/helpers/__tests__/wellSets.test.js | 114 ++++++++++++++++++ .../js/helpers/canPipetteUseLabware.js | 14 +-- shared-data/js/helpers/index.js | 4 +- shared-data/js/helpers/wellSets.js | 73 +++++++++++ 13 files changed, 224 insertions(+), 211 deletions(-) delete mode 100644 protocol-designer/src/well-selection/test/utils.test.js delete mode 100644 protocol-designer/src/well-selection/utils.js create mode 100644 shared-data/js/helpers/__tests__/wellSets.test.js create mode 100644 shared-data/js/helpers/wellSets.js diff --git a/protocol-designer/src/components/labware/SelectableLabware.js b/protocol-designer/src/components/labware/SelectableLabware.js index 26ea0475d28..b438da9f456 100644 --- a/protocol-designer/src/components/labware/SelectableLabware.js +++ b/protocol-designer/src/components/labware/SelectableLabware.js @@ -2,9 +2,12 @@ import * as React from 'react' import reduce from 'lodash/reduce' -import { getCollidingWells, arrayToWellGroup } from '../../utils' +import { + arrayToWellGroup, + getCollidingWells, + getWellSetForMultichannel, +} from '../../utils' import { SELECTABLE_WELL_CLASS } from '../../constants' -import { getWellSetForMultichannel } from '../../well-selection/utils' import SingleLabware from './SingleLabware' import SelectionRect from '../SelectionRect' import WellTooltip from './WellTooltip' diff --git a/protocol-designer/src/labware-defs/actions.js b/protocol-designer/src/labware-defs/actions.js index 400a052db72..7a98763a7c5 100644 --- a/protocol-designer/src/labware-defs/actions.js +++ b/protocol-designer/src/labware-defs/actions.js @@ -8,7 +8,7 @@ import uniqBy from 'lodash/uniqBy' import labwareSchema from '@opentrons/shared-data/labware/schemas/2.json' import { getLabwareDefURI } from '@opentrons/shared-data' import * as labwareDefSelectors from './selectors' -import { getAllWellSetsForLabware } from '../well-selection/utils' +import { getAllWellSetsForLabware } from '../utils' import type { LabwareDefinition2 } from '@opentrons/shared-data' import type { GetState, ThunkAction, ThunkDispatch } from '../types' import type { LabwareUploadMessage } from './types' diff --git a/protocol-designer/src/steplist/formLevel/handleFormChange/utils.js b/protocol-designer/src/steplist/formLevel/handleFormChange/utils.js index 3eac1d755d8..9af7fecbbc3 100644 --- a/protocol-designer/src/steplist/formLevel/handleFormChange/utils.js +++ b/protocol-designer/src/steplist/formLevel/handleFormChange/utils.js @@ -3,8 +3,8 @@ import assert from 'assert' import round from 'lodash/round' import uniq from 'lodash/uniq' import { canPipetteUseLabware } from '@opentrons/shared-data' +import { getWellSetForMultichannel } from '../../../utils' import { getPipetteCapacity } from '../../../pipettes/pipetteData' -import { getWellSetForMultichannel } from '../../../well-selection/utils' import type { LabwareDefinition2, PipetteChannels, diff --git a/protocol-designer/src/top-selectors/substep-highlight.js b/protocol-designer/src/top-selectors/substep-highlight.js index 1222af04657..a44312587eb 100644 --- a/protocol-designer/src/top-selectors/substep-highlight.js +++ b/protocol-designer/src/top-selectors/substep-highlight.js @@ -1,6 +1,7 @@ // @flow import { createSelector } from 'reselect' import { getWellNamePerMultiTip } from '@opentrons/shared-data' +import { getWellSetForMultichannel } from '../utils' import type { Command } from '@opentrons/shared-data/protocol/flowTypes/schemaV3' import mapValues from 'lodash/mapValues' @@ -10,7 +11,6 @@ import * as StepGeneration from '../step-generation' import { selectors as stepFormSelectors } from '../step-forms' import { selectors as fileDataSelectors } from '../file-data' import { selectors as stepsSelectors } from '../ui/steps' -import { getWellSetForMultichannel } from '../well-selection/utils' import type { WellGroup } from '@opentrons/components' import type { Selector } from '../types' diff --git a/protocol-designer/src/top-selectors/tip-contents/index.js b/protocol-designer/src/top-selectors/tip-contents/index.js index bdf98a78f4e..36e54fdf76d 100644 --- a/protocol-designer/src/top-selectors/tip-contents/index.js +++ b/protocol-designer/src/top-selectors/tip-contents/index.js @@ -3,14 +3,14 @@ import { createSelector } from 'reselect' import noop from 'lodash/noop' import reduce from 'lodash/reduce' import mapValues from 'lodash/mapValues' -import type { WellGroup } from '@opentrons/components' +import { getWellSetForMultichannel } from '../../utils' import * as StepGeneration from '../../step-generation' import { allSubsteps as getAllSubsteps } from '../substeps' import { START_TERMINAL_ITEM_ID, END_TERMINAL_ITEM_ID } from '../../steplist' import { selectors as stepFormSelectors } from '../../step-forms' import { selectors as stepsSelectors } from '../../ui/steps' import { selectors as fileDataSelectors } from '../../file-data' -import { getWellSetForMultichannel } from '../../well-selection/utils' +import type { WellGroup } from '@opentrons/components' import type { LabwareDefinition2 } from '@opentrons/shared-data' import type { Command } from '@opentrons/shared-data/protocol/flowTypes/schemaV3' import type { OutputSelector } from 'reselect' @@ -226,12 +226,11 @@ export const getTipsForCurrentStep: GetTipSelector = createSelector( const hoveredSubstepData = substepsForStep.multiRows[substepIndex][0] // just use first multi row - const wellSet = hoveredSubstepData.activeTips - ? getWellSetForMultichannel( - labwareDef, - hoveredSubstepData.activeTips.well - ) - : [] + let wellSet: ?Array = [] + const hoveredTipWell = hoveredSubstepData.activeTips?.well + if (hoveredTipWell != null) { + wellSet = getWellSetForMultichannel(labwareDef, hoveredTipWell) + } highlighted = (hoveredSubstepData && diff --git a/protocol-designer/src/ui/labware/selectors.js b/protocol-designer/src/ui/labware/selectors.js index e6d9d1f1cc8..d6083394225 100644 --- a/protocol-designer/src/ui/labware/selectors.js +++ b/protocol-designer/src/ui/labware/selectors.js @@ -2,11 +2,7 @@ import { createSelector } from 'reselect' import mapValues from 'lodash/mapValues' import reduce from 'lodash/reduce' -import { - getIsTiprack, - getLabwareDisplayName, - getLabwareFormat, -} from '@opentrons/shared-data' +import { getIsTiprack, getLabwareDisplayName } from '@opentrons/shared-data' import { selectors as stepFormSelectors } from '../../step-forms' import { selectors as labwareIngredSelectors } from '../../labware-ingred/selectors' @@ -57,16 +53,16 @@ export const getDisposalLabwareOptions: Selector = createSelector( reduce( labwareEntities, (acc: Options, labware: LabwareEntity, labwareId): Options => { - if (getLabwareFormat(labware.def) === 'trash') { - return [ - ...acc, - { - name: names[labwareId], - value: labwareId, - }, - ] - } - return acc + // TODO: Ian 2019-09-17 if we create a way to distinguish "intended for disposal" + // labware, use that here as a filter. + // Until then, allow all labware to be used for disposal + return [ + ...acc, + { + name: names[labwareId], + value: labwareId, + }, + ] }, [] ) diff --git a/protocol-designer/src/utils/index.js b/protocol-designer/src/utils/index.js index 5f05dc90e15..8e440e3f487 100644 --- a/protocol-designer/src/utils/index.js +++ b/protocol-designer/src/utils/index.js @@ -1,5 +1,6 @@ // @flow import uuidv1 from 'uuid/v1' +import { makeWellSetHelpers } from '@opentrons/shared-data' import type { WellGroup } from '@opentrons/components' import type { BoundingRect, GenericRect } from '../collision-types' @@ -70,3 +71,9 @@ export const getCollidingWells = ( // TODO IMMEDIATELY use where appropriate export const arrayToWellGroup = (w: Array): WellGroup => w.reduce((acc, wellName) => ({ ...acc, [wellName]: null }), {}) + +// cross-PD memoization of well set utils +export const { + getAllWellSetsForLabware, + getWellSetForMultichannel, +} = makeWellSetHelpers() diff --git a/protocol-designer/src/well-selection/test/utils.test.js b/protocol-designer/src/well-selection/test/utils.test.js deleted file mode 100644 index 7b86cc74808..00000000000 --- a/protocol-designer/src/well-selection/test/utils.test.js +++ /dev/null @@ -1,108 +0,0 @@ -import fixture_12_trough from '@opentrons/shared-data/labware/fixtures/2/fixture_12_trough.json' -import fixture_96_plate from '@opentrons/shared-data/labware/fixtures/2/fixture_96_plate.json' -import fixture_384_plate from '@opentrons/shared-data/labware/fixtures/2/fixture_384_plate.json' -import { getWellSetForMultichannel } from '../utils' - -describe('getWellSetForMultichannel (integration test)', () => { - test('96-flat', () => { - const labware = fixture_96_plate - expect(getWellSetForMultichannel(labware, 'A1')).toEqual([ - 'A1', - 'B1', - 'C1', - 'D1', - 'E1', - 'F1', - 'G1', - 'H1', - ]) - - expect(getWellSetForMultichannel(labware, 'B1')).toEqual([ - 'A1', - 'B1', - 'C1', - 'D1', - 'E1', - 'F1', - 'G1', - 'H1', - ]) - - expect(getWellSetForMultichannel(labware, 'H1')).toEqual([ - 'A1', - 'B1', - 'C1', - 'D1', - 'E1', - 'F1', - 'G1', - 'H1', - ]) - - expect(getWellSetForMultichannel(labware, 'A2')).toEqual([ - 'A2', - 'B2', - 'C2', - 'D2', - 'E2', - 'F2', - 'G2', - 'H2', - ]) - }) - - test('invalid well', () => { - const labware = fixture_96_plate - expect(getWellSetForMultichannel(labware, 'A13')).toBeFalsy() - }) - - test('trough-12row', () => { - const labware = fixture_12_trough - expect(getWellSetForMultichannel(labware, 'A1')).toEqual([ - 'A1', - 'A1', - 'A1', - 'A1', - 'A1', - 'A1', - 'A1', - 'A1', - ]) - - expect(getWellSetForMultichannel(labware, 'A2')).toEqual([ - 'A2', - 'A2', - 'A2', - 'A2', - 'A2', - 'A2', - 'A2', - 'A2', - ]) - }) - - test('384-plate', () => { - const labware = fixture_384_plate - expect(getWellSetForMultichannel(labware, 'C1')).toEqual([ - 'A1', - 'C1', - 'E1', - 'G1', - 'I1', - 'K1', - 'M1', - 'O1', - ]) - - expect(getWellSetForMultichannel(labware, 'F2')).toEqual([ - 'B2', - 'D2', - 'F2', - 'H2', - 'J2', - 'L2', - 'N2', - 'P2', - ]) - }) -}) diff --git a/protocol-designer/src/well-selection/utils.js b/protocol-designer/src/well-selection/utils.js deleted file mode 100644 index e6ed56759bf..00000000000 --- a/protocol-designer/src/well-selection/utils.js +++ /dev/null @@ -1,61 +0,0 @@ -// @flow -import { - getWellNamePerMultiTip, - getLabwareDefURI, -} from '@opentrons/shared-data' -import type { LabwareDefinition2 } from '@opentrons/shared-data' - -type WellSetByPrimaryWell = Array> - -/** Compute all well sets for a labware type. - * A well set is array of 8 wells that an 8 channel pipettes can fit into, - * eg ['A1', 'C1', 'E1', 'G1', 'I1', 'K1', 'M1', 'O1'] is a well set in a 384 plate. - **/ -function _getAllWellSetsForLabware( - labwareDef: LabwareDefinition2 -): WellSetByPrimaryWell { - const allWells: Array = Object.keys(labwareDef.wells) - return allWells.reduce( - (acc: WellSetByPrimaryWell, well: string): WellSetByPrimaryWell => { - const wellSet = getWellNamePerMultiTip(labwareDef, well) - return wellSet === null ? acc : [...acc, wellSet] - }, - [] - ) -} - -let cache: { - [labwareDefURI: string]: ?{ - labwareDef: LabwareDefinition2, - wellSetByPrimaryWell: WellSetByPrimaryWell, - }, -} = {} - -// memoized -export const getAllWellSetsForLabware = ( - labwareDef: LabwareDefinition2 -): WellSetByPrimaryWell => { - const labwareDefURI = getLabwareDefURI(labwareDef) - const c = cache[labwareDefURI] - // use cached version only if labwareDef is shallowly equal, in case - // custom labware defs are changed without giving them a new URI - if (c && c.labwareDef === labwareDef) { - return c.wellSetByPrimaryWell - } - const wellSetByPrimaryWell = _getAllWellSetsForLabware(labwareDef) - cache[labwareDefURI] = { labwareDef, wellSetByPrimaryWell } - return wellSetByPrimaryWell -} - -export function getWellSetForMultichannel( - labwareDef: LabwareDefinition2, - well: string -): ?Array { - /** Given a well for a labware, returns the well set it belongs to (or null) - * for 8-channel access. - * Ie: C2 for 96-flat => ['A2', 'B2', 'C2', ... 'H2'] - * Or A1 for trough => ['A1', 'A1', 'A1', ...] - **/ - const allWellSets = getAllWellSetsForLabware(labwareDef) - return allWellSets.find((wellSet: Array) => wellSet.includes(well)) -} diff --git a/shared-data/js/helpers/__tests__/wellSets.test.js b/shared-data/js/helpers/__tests__/wellSets.test.js new file mode 100644 index 00000000000..8a72fd6143a --- /dev/null +++ b/shared-data/js/helpers/__tests__/wellSets.test.js @@ -0,0 +1,114 @@ +// @flow +import fixture_12_trough from '../../../labware/fixtures/2/fixture_12_trough.json' +import fixture_96_plate from '../../../labware/fixtures/2/fixture_96_plate.json' +import fixture_384_plate from '../../../labware/fixtures/2/fixture_384_plate.json' +import { makeWellSetHelpers } from '../wellSets' + +describe('getWellSetForMultichannel (integration test)', () => { + let getWellSetForMultichannel + beforeEach(() => { + const helpers = makeWellSetHelpers() + getWellSetForMultichannel = helpers.getWellSetForMultichannel + }) + test('96-flat', () => { + const labwareDef = fixture_96_plate + expect(getWellSetForMultichannel(labwareDef, 'A1')).toEqual([ + 'A1', + 'B1', + 'C1', + 'D1', + 'E1', + 'F1', + 'G1', + 'H1', + ]) + + expect(getWellSetForMultichannel(labwareDef, 'B1')).toEqual([ + 'A1', + 'B1', + 'C1', + 'D1', + 'E1', + 'F1', + 'G1', + 'H1', + ]) + + expect(getWellSetForMultichannel(labwareDef, 'H1')).toEqual([ + 'A1', + 'B1', + 'C1', + 'D1', + 'E1', + 'F1', + 'G1', + 'H1', + ]) + + expect(getWellSetForMultichannel(labwareDef, 'A2')).toEqual([ + 'A2', + 'B2', + 'C2', + 'D2', + 'E2', + 'F2', + 'G2', + 'H2', + ]) + }) + + test('invalid well', () => { + const labwareDef = fixture_96_plate + expect(getWellSetForMultichannel(labwareDef, 'A13')).toBeFalsy() + }) + + test('trough-12row', () => { + const labwareDef = fixture_12_trough + expect(getWellSetForMultichannel(labwareDef, 'A1')).toEqual([ + 'A1', + 'A1', + 'A1', + 'A1', + 'A1', + 'A1', + 'A1', + 'A1', + ]) + + expect(getWellSetForMultichannel(labwareDef, 'A2')).toEqual([ + 'A2', + 'A2', + 'A2', + 'A2', + 'A2', + 'A2', + 'A2', + 'A2', + ]) + }) + + test('384-plate', () => { + const labwareDef = fixture_384_plate + expect(getWellSetForMultichannel(labwareDef, 'C1')).toEqual([ + 'A1', + 'C1', + 'E1', + 'G1', + 'I1', + 'K1', + 'M1', + 'O1', + ]) + + expect(getWellSetForMultichannel(labwareDef, 'F2')).toEqual([ + 'B2', + 'D2', + 'F2', + 'H2', + 'J2', + 'L2', + 'N2', + 'P2', + ]) + }) +}) diff --git a/shared-data/js/helpers/canPipetteUseLabware.js b/shared-data/js/helpers/canPipetteUseLabware.js index dc0165293a0..7d065131ac7 100644 --- a/shared-data/js/helpers/canPipetteUseLabware.js +++ b/shared-data/js/helpers/canPipetteUseLabware.js @@ -1,23 +1,15 @@ // @flow -import { getLabwareFormat } from './' import type { LabwareDefinition2 } from '../types' import type { PipetteNameSpecs } from '../pipettes' -const FORMAT_METADATA = { - '96Standard': { multichannelAccess: true }, - '384Standard': { multichannelAccess: true }, - trough: { multichannelAccess: true }, - irregular: { multichannelAccess: false }, - trash: { multichannelAccess: true }, -} - export const canPipetteUseLabware = ( pipetteSpec: PipetteNameSpecs, labwareDef: LabwareDefinition2 ): ?boolean => { if (pipetteSpec.channels === 1) { + // assume all labware can be used by single-channel return true } - const format = getLabwareFormat(labwareDef) - return FORMAT_METADATA[format].multichannelAccess + + return false // TODO IMMEDIATELY } diff --git a/shared-data/js/helpers/index.js b/shared-data/js/helpers/index.js index 97561e7c08c..cb8e3a9f95b 100644 --- a/shared-data/js/helpers/index.js +++ b/shared-data/js/helpers/index.js @@ -9,6 +9,7 @@ export { getWellNamePerMultiTip } from './getWellNamePerMultiTip' export { default as getWellTotalVolume } from './getWellTotalVolume' export { default as wellIsRect } from './wellIsRect' export * from './volume' +export * from './wellSets' export const getLabwareDefIsStandard = (def: LabwareDefinition2): boolean => def?.namespace === OPENTRONS_LABWARE_NAMESPACE @@ -41,9 +42,6 @@ export const getLabwareDisplayName = (labwareDef: LabwareDefinition2) => { return displayName } -export const getLabwareFormat = (labwareDef: LabwareDefinition2) => - labwareDef.parameters.format - export const getTiprackVolume = (labwareDef: LabwareDefinition2): number => { assert( labwareDef.parameters.isTiprack, diff --git a/shared-data/js/helpers/wellSets.js b/shared-data/js/helpers/wellSets.js new file mode 100644 index 00000000000..a4bf10af1bc --- /dev/null +++ b/shared-data/js/helpers/wellSets.js @@ -0,0 +1,73 @@ +// @flow +// A "well set" is array of wells corresponding to each tip of an 8 channel pipette. +// Eg ['A1', 'C1', 'E1', 'G1', 'I1', 'K1', 'M1', 'O1'] is a well set in a 384 plate. +// +// A trough-like well that encompasses all 8 tips at once has a well set +// ['A1', 'A1', 'A1', 'A1', 'A1', 'A1', 'A1', 'A1'] +// +// Well sets are determined by geometry. +// +// Labware with multiple positions for an 8-channel pipette have multiple well sets. +// For example, a 96 plate has 12 well sets, one for each column. +// A 384 plate has 48 well sets, 2 for each column b/c it has staggered columns. +// +// If a labware has no possible well sets, then it is not compatible with multi-channel pipettes. +import { getLabwareDefURI } from '@opentrons/shared-data' +import { getWellNamePerMultiTip } from './getWellNamePerMultiTip' +import type { LabwareDefinition2 } from '../types' + +type WellSetByPrimaryWell = Array> + +// Compute all well sets for a labware def (non-memoized) +export function _getAllWellSetsForLabware( + labwareDef: LabwareDefinition2 +): WellSetByPrimaryWell { + const allWells: Array = Object.keys(labwareDef.wells) + return allWells.reduce( + (acc: WellSetByPrimaryWell, well: string): WellSetByPrimaryWell => { + const wellSet = getWellNamePerMultiTip(labwareDef, well) + return wellSet === null ? acc : [...acc, wellSet] + }, + [] + ) +} + +// creates memoized getAllWellSetsForLabware + getWellSetForMultichannel fns. +export const makeWellSetHelpers = () => { + let cache: { + [labwareDefURI: string]: ?{| + labwareDef: LabwareDefinition2, + wellSetByPrimaryWell: WellSetByPrimaryWell, + |}, + } = {} + + const getAllWellSetsForLabware = ( + labwareDef: LabwareDefinition2 + ): WellSetByPrimaryWell => { + const labwareDefURI = getLabwareDefURI(labwareDef) + const c = cache[labwareDefURI] + // use cached version only if labwareDef is shallowly equal, in case + // custom labware defs are changed without giving them a new URI + if (c && c.labwareDef === labwareDef) { + return c.wellSetByPrimaryWell + } + const wellSetByPrimaryWell = _getAllWellSetsForLabware(labwareDef) + cache[labwareDefURI] = { labwareDef, wellSetByPrimaryWell } + return wellSetByPrimaryWell + } + + const getWellSetForMultichannel = ( + labwareDef: LabwareDefinition2, + well: string + ): ?Array => { + /** Given a well for a labware, returns the well set it belongs to (or null) + * for 8-channel access. + * Ie: C2 for 96-flat => ['A2', 'B2', 'C2', ... 'H2'] + * Or A1 for trough => ['A1', 'A1', 'A1', ...] + **/ + const allWellSets = getAllWellSetsForLabware(labwareDef) + return allWellSets.find((wellSet: Array) => wellSet.includes(well)) + } + + return { getAllWellSetsForLabware, getWellSetForMultichannel } +} From 92de0faac8c9e1e0a0e69a16fa4a6a649c6631a7 Mon Sep 17 00:00:00 2001 From: IanLondon Date: Tue, 17 Sep 2019 13:49:57 -0400 Subject: [PATCH 2/5] finish canPipetteUseLabware fn --- .../src/steplist/formLevel/errors.js | 2 +- .../formLevel/handleFormChange/utils.js | 3 +- protocol-designer/src/utils/index.js | 1 + .../js/helpers/canPipetteUseLabware.js | 15 ---------- shared-data/js/helpers/index.js | 1 - shared-data/js/helpers/wellSets.js | 30 ++++++++++++++++++- 6 files changed, 32 insertions(+), 20 deletions(-) delete mode 100644 shared-data/js/helpers/canPipetteUseLabware.js diff --git a/protocol-designer/src/steplist/formLevel/errors.js b/protocol-designer/src/steplist/formLevel/errors.js index 09c8513048b..c74cd4013fc 100644 --- a/protocol-designer/src/steplist/formLevel/errors.js +++ b/protocol-designer/src/steplist/formLevel/errors.js @@ -1,7 +1,7 @@ // @flow import * as React from 'react' import { getWellRatio } from '../utils' -import { canPipetteUseLabware } from '@opentrons/shared-data' +import { canPipetteUseLabware } from '../../utils' import type { StepFieldName } from '../../form-types' /******************* diff --git a/protocol-designer/src/steplist/formLevel/handleFormChange/utils.js b/protocol-designer/src/steplist/formLevel/handleFormChange/utils.js index 9af7fecbbc3..8f6d2a103bd 100644 --- a/protocol-designer/src/steplist/formLevel/handleFormChange/utils.js +++ b/protocol-designer/src/steplist/formLevel/handleFormChange/utils.js @@ -2,8 +2,7 @@ import assert from 'assert' import round from 'lodash/round' import uniq from 'lodash/uniq' -import { canPipetteUseLabware } from '@opentrons/shared-data' -import { getWellSetForMultichannel } from '../../../utils' +import { getWellSetForMultichannel, canPipetteUseLabware } from '../../../utils' import { getPipetteCapacity } from '../../../pipettes/pipetteData' import type { LabwareDefinition2, diff --git a/protocol-designer/src/utils/index.js b/protocol-designer/src/utils/index.js index 8e440e3f487..dd6c44ef1f2 100644 --- a/protocol-designer/src/utils/index.js +++ b/protocol-designer/src/utils/index.js @@ -74,6 +74,7 @@ export const arrayToWellGroup = (w: Array): WellGroup => // cross-PD memoization of well set utils export const { + canPipetteUseLabware, getAllWellSetsForLabware, getWellSetForMultichannel, } = makeWellSetHelpers() diff --git a/shared-data/js/helpers/canPipetteUseLabware.js b/shared-data/js/helpers/canPipetteUseLabware.js deleted file mode 100644 index 7d065131ac7..00000000000 --- a/shared-data/js/helpers/canPipetteUseLabware.js +++ /dev/null @@ -1,15 +0,0 @@ -// @flow -import type { LabwareDefinition2 } from '../types' -import type { PipetteNameSpecs } from '../pipettes' - -export const canPipetteUseLabware = ( - pipetteSpec: PipetteNameSpecs, - labwareDef: LabwareDefinition2 -): ?boolean => { - if (pipetteSpec.channels === 1) { - // assume all labware can be used by single-channel - return true - } - - return false // TODO IMMEDIATELY -} diff --git a/shared-data/js/helpers/index.js b/shared-data/js/helpers/index.js index cb8e3a9f95b..a750af1b2ff 100644 --- a/shared-data/js/helpers/index.js +++ b/shared-data/js/helpers/index.js @@ -4,7 +4,6 @@ import uniq from 'lodash/uniq' import { OPENTRONS_LABWARE_NAMESPACE } from '../constants' import type { LabwareDefinition2 } from '../types' -export { canPipetteUseLabware } from './canPipetteUseLabware' export { getWellNamePerMultiTip } from './getWellNamePerMultiTip' export { default as getWellTotalVolume } from './getWellTotalVolume' export { default as wellIsRect } from './wellIsRect' diff --git a/shared-data/js/helpers/wellSets.js b/shared-data/js/helpers/wellSets.js index a4bf10af1bc..0ec72bc01a4 100644 --- a/shared-data/js/helpers/wellSets.js +++ b/shared-data/js/helpers/wellSets.js @@ -13,8 +13,10 @@ // // If a labware has no possible well sets, then it is not compatible with multi-channel pipettes. import { getLabwareDefURI } from '@opentrons/shared-data' +import uniq from 'lodash/uniq' import { getWellNamePerMultiTip } from './getWellNamePerMultiTip' import type { LabwareDefinition2 } from '../types' +import type { PipetteNameSpecs } from '../pipettes' type WellSetByPrimaryWell = Array> @@ -69,5 +71,31 @@ export const makeWellSetHelpers = () => { return allWellSets.find((wellSet: Array) => wellSet.includes(well)) } - return { getAllWellSetsForLabware, getWellSetForMultichannel } + const canPipetteUseLabware = ( + pipetteSpec: PipetteNameSpecs, + labwareDef: LabwareDefinition2 + ): ?boolean => { + if (pipetteSpec.channels === 1) { + // assume all labware can be used by single-channel + return true + } + + const allWellSets = getAllWellSetsForLabware(labwareDef) + return allWellSets.some(wellSet => { + const uniqueWells = uniq(wellSet) + // if all wells are non-null, and there are either 1 (reservoir-like) + // or 8 (well plate-like) unique wells in the set, + // then assume multi-channel will work + return ( + uniqueWells.every(well => well != null) && + [1, 8].includes(uniqueWells.length) + ) + }) + } + + return { + getAllWellSetsForLabware, + getWellSetForMultichannel, + canPipetteUseLabware, + } } From 57a97a2466e2ffc2b2bacbd9446a1a09c14b0e03 Mon Sep 17 00:00:00 2001 From: IanLondon Date: Tue, 17 Sep 2019 13:55:27 -0400 Subject: [PATCH 3/5] rebase on edge for formatting --- CONTRIBUTING.md | 27 +++++++------ app-shell/src/buildroot/index.js | 20 ++++++---- .../ModuleLiveStatusCards/ThermocyclerCard.js | 8 +++- components/src/deck/Deck.js | 40 ++++++++++--------- components/src/deck/LabwareRender.js | 4 +- components/src/deck/LabwareRender.md | 8 +++- .../src/labware-creator/labwareFormSchema.js | 19 ++++----- .../LabwareSelectionModal/LabwarePreview.js | 4 +- .../StepEditForm/fields/ChangeTip/index.js | 4 +- .../src/components/labware/SingleLabware.js | 4 +- .../src/file-data/selectors/commands.js | 4 +- .../src/step-forms/reducers/index.js | 16 ++++---- .../src/step-forms/selectors/index.js | 4 +- protocol-designer/src/step-forms/utils.js | 4 +- .../commandCreators/compound/transfer.js | 4 +- .../getNextRobotStateAndWarnings/index.js | 4 +- .../formLevel/handleFormChange/utils.js | 8 +++- .../stepFormToArgs/moveLiquidFormToArgs.js | 8 +++- .../src/steplist/generateSubsteps.js | 4 +- .../src/steplist/substepTimeline.js | 8 +++- .../src/top-selectors/well-contents/index.js | 4 +- protocol-designer/src/ui/steps/selectors.js | 4 +- .../js/helpers/getWellNamePerMultiTip.js | 4 +- shared-data/js/helpers/getWellTotalVolume.js | 4 +- 24 files changed, 138 insertions(+), 80 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b69c09a7aef..430dda11707 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -399,11 +399,9 @@ If you create the key as `~/.ssh/robot_key` and `~/.ssh/robot_key.pub` then `mak Our release process is still a work-in-progress. The app and API projects are currently versioned together to ensure interoperability. - 1. Ensure you have a buildroot release created in GitHub with all the changes you want in this release, if any. If there are no buildroot changes, you don't have to create a new release; the last tag in buildroot is used for release builds. 2. Checkout `edge` and make a release branch, without any new changes. The branch name should match `release_*` to make `make bump` usage easier and make it clear this is a release. - ```shell git checkout edge git pull @@ -432,26 +430,28 @@ git push origin v${version} 12. Run QA on this release. If issues are found, create PRs targeted on the release branch. To create new alpha releases, repeat steps 4-11. 13. Once QA is a pass, bump to the target release version (review [the section below](#make-bump-usage) again) 14. Fix up the autogenerated changelogs to remove the references to alpha versions and make sure the release version has all changes since the latest release - - Make sure the comparison link is to the latest release verison (e.g.: `compare/v3.11.4...v3.12.0)` instead of `compare/v3.12.0-alpha.1...v3.12.0)`) - - Delete the sub-sections that relate only to alpha releases, so that the changelog is against the latest actual release + +- Make sure the comparison link is to the latest release verison (e.g.: `compare/v3.11.4...v3.12.0)` instead of `compare/v3.12.0-alpha.1...v3.12.0)`) +- Delete the sub-sections that relate only to alpha releases, so that the changelog is against the latest actual release + 15. Do a NORMAL MERGE into `master`. Do NOT squash or rebase. This should be done from your local command line (and will succeed as long as the release PR is reviewed and status checks have passed): ```shell -# note: make sure you have pulled the latest changes for branch +# note: make sure you have pulled the latest changes for branch # release_${version} locally before merging into master git checkout master git merge --ff-only release_${version} git push origin master ``` -15. Tag the release: +15. Tag the release: ```shell git tag -a v${version} -m 'chore(release): ${version}' git push origin v${version} ``` -16. Open a PR of `master` into `edge`. Give the PR a name like `chore(release): Merge changes from ${version} into edge`. Once it passes, on the command line merge it into `edge`: +16. Open a PR of `master` into `edge`. Give the PR a name like `chore(release): Merge changes from ${version} into edge`. Once it passes, on the command line merge it into `edge`: ```shell git checkout edge @@ -466,7 +466,6 @@ git merge --no-ff master 1. Ensure you have a buildroot release created in GitHub with all the changes you want to see, if any. If there aren't any, you don't have to create a new buildroot release; by default, the last tag is used for release builds. 2. Checkout `master` and make a release branch, without any new changes. The branch name should match `hotfix_*` to make it clear this is a hotfix, and make `make bump` usage simpler. - ```shell git checkout master git pull @@ -495,26 +494,28 @@ git push origin v${version} 12. Run QA on this release. If issues are found, create PRs targeted on the release branch. To create new alpha releases, repeat steps 4-11. 13. Once QA is a pass, bump to your target version (review [the section below](#make-bump-usage) again) 14. Fix up the autogenerated changelogs to remove the references to alpha versions and make sure the release version has all changes since the last release - - Make sure the comparison link is to the latest release verison (e.g.: `compare/v3.11.4...v3.12.0)` instead of `compare/v3.12.0-alpha.1...v3.12.0)`) - - Delete the sub-sections that relate only to alpha releases, so that the changelog is against the latest actual release + +- Make sure the comparison link is to the latest release verison (e.g.: `compare/v3.11.4...v3.12.0)` instead of `compare/v3.12.0-alpha.1...v3.12.0)`) +- Delete the sub-sections that relate only to alpha releases, so that the changelog is against the latest actual release + 15. Do a NORMAL MERGE into `master`. Do NOT squash or rebase. This should be done from your local command line (and will succeed as long as the release PR is reviewed and status checks have passed): ```shell -# note: make sure you have pulled the latest changes for branch +# note: make sure you have pulled the latest changes for branch # release_${version} locally before merging into master git checkout master git merge --ff-only release_${version} git push origin master ``` -15. Tag the release: +15. Tag the release: ```shell git tag -a v${version} -m 'chore(release): ${version}' git push origin v${version} ``` -16. Open a PR of `master` into `edge`. Give the PR a name like `chore(release): Merge changes from ${version} into edge`. Once it passes, on the command line merge it into `edge`: +16. Open a PR of `master` into `edge`. Give the PR a name like `chore(release): Merge changes from ${version} into edge`. Once it passes, on the command line merge it into `edge`: ```shell git checkout edge diff --git a/app-shell/src/buildroot/index.js b/app-shell/src/buildroot/index.js index f1d633722ac..5043f4085d0 100644 --- a/app-shell/src/buildroot/index.js +++ b/app-shell/src/buildroot/index.js @@ -43,14 +43,18 @@ export function registerBuildrootUpdate(dispatch: Dispatch) { log.info('Starting robot premigration', { robot }) startPremigration(robot) - .then((): BuildrootAction => ({ - type: 'buildroot:PREMIGRATION_DONE', - payload: robot.name, - })) - .catch((error: Error): BuildrootAction => ({ - type: 'buildroot:PREMIGRATION_ERROR', - payload: { message: error.message }, - })) + .then( + (): BuildrootAction => ({ + type: 'buildroot:PREMIGRATION_DONE', + payload: robot.name, + }) + ) + .catch( + (error: Error): BuildrootAction => ({ + type: 'buildroot:PREMIGRATION_ERROR', + payload: { message: error.message }, + }) + ) .then(dispatch) break diff --git a/app/src/components/ModuleLiveStatusCards/ThermocyclerCard.js b/app/src/components/ModuleLiveStatusCards/ThermocyclerCard.js index ec7aa04c0f3..64819ed1a4a 100644 --- a/app/src/components/ModuleLiveStatusCards/ThermocyclerCard.js +++ b/app/src/components/ModuleLiveStatusCards/ThermocyclerCard.js @@ -72,12 +72,16 @@ const ThermocyclerCard = ({ , row: number): Array => { - return columns.map((slot: DeckSlotId, col: number): React.Node => { - if (slot === TRASH_SLOTNAME) return null + return columns.map( + (slot: DeckSlotId, col: number): React.Node => { + if (slot === TRASH_SLOTNAME) return null - const props = { - slot, - width: SLOT_RENDER_WIDTH, - height: SLOT_RENDER_HEIGHT, - } - const transform = `translate(${[ - SLOT_RENDER_WIDTH * col + SLOT_SPACING_MM * (col + 1), - SLOT_RENDER_HEIGHT * row + SLOT_SPACING_MM * (row + 1), - ].join(',')})` + const props = { + slot, + width: SLOT_RENDER_WIDTH, + height: SLOT_RENDER_HEIGHT, + } + const transform = `translate(${[ + SLOT_RENDER_WIDTH * col + SLOT_SPACING_MM * (col + 1), + SLOT_RENDER_HEIGHT * row + SLOT_SPACING_MM * (row + 1), + ].join(',')})` - return ( - // $FlowFixMe: (mc, 2019-04-18) don't know why flow doesn't like this, don't care because this is going away - - - {LabwareComponent && } - - ) - }) + return ( + // $FlowFixMe: (mc, 2019-04-18) don't know why flow doesn't like this, don't care because this is going away + + + {LabwareComponent && } + + ) + } + ) } ) } diff --git a/components/src/deck/LabwareRender.js b/components/src/deck/LabwareRender.js index 79eb2bea742..faa4075ef19 100644 --- a/components/src/deck/LabwareRender.js +++ b/components/src/deck/LabwareRender.js @@ -36,7 +36,9 @@ export default function LabwareRender(props: LabwareRenderProps) { const cornerOffsetFromSlot = props.definition.cornerOffsetFromSlot return ( {() => ( {() => ( => - (currentValue || '') - .trim() - .split(',') - .map(s => s.trim()) - .filter(Boolean) + .transform( + ( + currentValue: ?string, + originalValue: ?string + ): $PropertyType => + (currentValue || '') + .trim() + .split(',') + .map(s => s.trim()) + .filter(Boolean) ), loadName: Yup.string() diff --git a/protocol-designer/src/components/LabwareSelectionModal/LabwarePreview.js b/protocol-designer/src/components/LabwareSelectionModal/LabwarePreview.js index ae58480c6fc..1bc395b45ee 100644 --- a/protocol-designer/src/components/LabwareSelectionModal/LabwarePreview.js +++ b/protocol-designer/src/components/LabwareSelectionModal/LabwarePreview.js @@ -44,7 +44,9 @@ const LabwarePreview = (props: Props) => {
{() => } diff --git a/protocol-designer/src/components/StepEditForm/fields/ChangeTip/index.js b/protocol-designer/src/components/StepEditForm/fields/ChangeTip/index.js index d5b82946078..a7ce3976e60 100644 --- a/protocol-designer/src/components/StepEditForm/fields/ChangeTip/index.js +++ b/protocol-designer/src/components/StepEditForm/fields/ChangeTip/index.js @@ -45,7 +45,9 @@ function getDisabledChangeTipOptions( } default: { console.warn( - `getChangeTipOptions for stepType ${rawForm.stepType} not yet implemented!` + `getChangeTipOptions for stepType ${ + rawForm.stepType + } not yet implemented!` ) return null } diff --git a/protocol-designer/src/components/labware/SingleLabware.js b/protocol-designer/src/components/labware/SingleLabware.js index 51858c522fb..af3f3a8d786 100644 --- a/protocol-designer/src/components/labware/SingleLabware.js +++ b/protocol-designer/src/components/labware/SingleLabware.js @@ -8,7 +8,9 @@ type Props = React.ElementProps export default function SingleLabware(props: Props) { return ( {() => } diff --git a/protocol-designer/src/file-data/selectors/commands.js b/protocol-designer/src/file-data/selectors/commands.js index 21829ff0240..bd2ce5a3102 100644 --- a/protocol-designer/src/file-data/selectors/commands.js +++ b/protocol-designer/src/file-data/selectors/commands.js @@ -164,7 +164,9 @@ export const getRobotStateTimeline: Selector = createSe if (!reducedCommandCreator) { console.warn( - `commandCreatorFnName "${stepArgs.commandCreatorFnName}" not yet implemented for robotStateTimeline` + `commandCreatorFnName "${ + stepArgs.commandCreatorFnName + }" not yet implemented for robotStateTimeline` ) return acc } diff --git a/protocol-designer/src/step-forms/reducers/index.js b/protocol-designer/src/step-forms/reducers/index.js index f8e9b8c8d6b..af08c439cc5 100644 --- a/protocol-designer/src/step-forms/reducers/index.js +++ b/protocol-designer/src/step-forms/reducers/index.js @@ -516,13 +516,15 @@ export const labwareInvariantProperties = handleActions< state: NormalizedLabwareById, action: ReplaceCustomLabwareDef ): NormalizedLabwareById => - mapValues(state, (prev: NormalizedLabware): NormalizedLabware => - action.payload.defURIToOverwrite === prev.labwareDefURI - ? { - ...prev, - labwareDefURI: getLabwareDefURI(action.payload.newDef), - } - : prev + mapValues( + state, + (prev: NormalizedLabware): NormalizedLabware => + action.payload.defURIToOverwrite === prev.labwareDefURI + ? { + ...prev, + labwareDefURI: getLabwareDefURI(action.payload.newDef), + } + : prev ), }, initialLabwareState diff --git a/protocol-designer/src/step-forms/selectors/index.js b/protocol-designer/src/step-forms/selectors/index.js index 35b9008111d..c0c7165b668 100644 --- a/protocol-designer/src/step-forms/selectors/index.js +++ b/protocol-designer/src/step-forms/selectors/index.js @@ -75,7 +75,9 @@ function _hydrateLabwareEntity( const def = defsByURI[l.labwareDefURI] assert( def, - `could not hydrate labware ${labwareId}, missing def for URI ${l.labwareDefURI}` + `could not hydrate labware ${labwareId}, missing def for URI ${ + l.labwareDefURI + }` ) return { ...l, diff --git a/protocol-designer/src/step-forms/utils.js b/protocol-designer/src/step-forms/utils.js index 2583d9088be..cb65c7ad9db 100644 --- a/protocol-designer/src/step-forms/utils.js +++ b/protocol-designer/src/step-forms/utils.js @@ -57,7 +57,9 @@ export function denormalizePipetteEntities( const spec = getPipetteNameSpecs(pipette.name) if (!spec) { throw new Error( - `no pipette spec for pipette id "${pipetteId}", name "${pipette.name}"` + `no pipette spec for pipette id "${pipetteId}", name "${ + pipette.name + }"` ) } diff --git a/protocol-designer/src/step-generation/commandCreators/compound/transfer.js b/protocol-designer/src/step-generation/commandCreators/compound/transfer.js index 6c58532da4c..2c9408e1a53 100644 --- a/protocol-designer/src/step-generation/commandCreators/compound/transfer.js +++ b/protocol-designer/src/step-generation/commandCreators/compound/transfer.js @@ -41,7 +41,9 @@ const transfer = (args: TransferArgs): CompoundCommandCreator => ( */ assert( args.sourceWells.length === args.destWells.length, - `Transfer command creator expected N:N source-to-dest wells ratio. Got ${args.sourceWells.length}:${args.destWells.length}` + `Transfer command creator expected N:N source-to-dest wells ratio. Got ${ + args.sourceWells.length + }:${args.destWells.length}` ) // TODO Ian 2018-04-02 following ~10 lines are identical to first lines of consolidate.js... const actionName = 'transfer' diff --git a/protocol-designer/src/step-generation/getNextRobotStateAndWarnings/index.js b/protocol-designer/src/step-generation/getNextRobotStateAndWarnings/index.js index cc5212fe170..be07c6f0cd8 100644 --- a/protocol-designer/src/step-generation/getNextRobotStateAndWarnings/index.js +++ b/protocol-designer/src/step-generation/getNextRobotStateAndWarnings/index.js @@ -40,7 +40,9 @@ export default function getNextRobotStateAndWarnings( default: assert( false, - `unknown command: ${command.command} passed to getNextRobotStateAndWarning` + `unknown command: ${ + command.command + } passed to getNextRobotStateAndWarning` ) return { robotState: prevRobotState, warnings: [] } } diff --git a/protocol-designer/src/steplist/formLevel/handleFormChange/utils.js b/protocol-designer/src/steplist/formLevel/handleFormChange/utils.js index 8f6d2a103bd..a7e0da7b2c7 100644 --- a/protocol-designer/src/steplist/formLevel/handleFormChange/utils.js +++ b/protocol-designer/src/steplist/formLevel/handleFormChange/utils.js @@ -64,7 +64,9 @@ export function getMaxDisposalVolumeForMultidispense( if (!rawForm) return null assert( rawForm.path === 'multiDispense', - `getMaxDisposalVolumeForMultidispense expected multiDispense, got path ${rawForm.path}` + `getMaxDisposalVolumeForMultidispense expected multiDispense, got path ${ + rawForm.path + }` ) const volume = Number(rawForm.volume) const pipetteEntity = pipetteEntities[rawForm.pipette] @@ -82,7 +84,9 @@ export function volumeInCapacityForMulti( const volume = Number(rawForm.volume) assert( rawForm.pipette in pipetteEntities, - `volumeInCapacityForMulti expected pipette ${rawForm.pipette} to be in pipetteEntities` + `volumeInCapacityForMulti expected pipette ${ + rawForm.pipette + } to be in pipetteEntities` ) const pipetteEntity = pipetteEntities[rawForm.pipette] const pipetteCapacity = pipetteEntity && getPipetteCapacity(pipetteEntity) diff --git a/protocol-designer/src/steplist/formLevel/stepFormToArgs/moveLiquidFormToArgs.js b/protocol-designer/src/steplist/formLevel/stepFormToArgs/moveLiquidFormToArgs.js index b61675ad789..39c3275acb3 100644 --- a/protocol-designer/src/steplist/formLevel/stepFormToArgs/moveLiquidFormToArgs.js +++ b/protocol-designer/src/steplist/formLevel/stepFormToArgs/moveLiquidFormToArgs.js @@ -48,7 +48,9 @@ const moveLiquidFormToArgs = ( ): MoveLiquidStepArgs => { assert( hydratedFormData.stepType === 'moveLiquid', - `moveLiquidFormToArgs called with stepType ${hydratedFormData.stepType}, expected "moveLiquid"` + `moveLiquidFormToArgs called with stepType ${ + hydratedFormData.stepType + }, expected "moveLiquid"` ) const fields = hydratedFormData.fields @@ -185,7 +187,9 @@ const moveLiquidFormToArgs = ( sourceWellsUnordered.length === 1 || destWellsUnordered.length === 1 || sourceWellsUnordered.length === destWellsUnordered.length, - `cannot do moveLiquidFormToArgs. Mismatched wells (not 1:N, N:1, or N:N!) for path="single". Neither source (${sourceWellsUnordered.length}) nor dest (${destWellsUnordered.length}) equal 1` + `cannot do moveLiquidFormToArgs. Mismatched wells (not 1:N, N:1, or N:N!) for path="single". Neither source (${ + sourceWellsUnordered.length + }) nor dest (${destWellsUnordered.length}) equal 1` ) switch (path) { diff --git a/protocol-designer/src/steplist/generateSubsteps.js b/protocol-designer/src/steplist/generateSubsteps.js index f8720a087e6..4e26f692fc7 100644 --- a/protocol-designer/src/steplist/generateSubsteps.js +++ b/protocol-designer/src/steplist/generateSubsteps.js @@ -107,7 +107,9 @@ function transferLikeSubsteps(args: {| } else { // TODO Ian 2018-05-21 Use assert here. Should be unreachable console.warn( - `transferLikeSubsteps got unsupported stepType "${stepArgs.commandCreatorFnName}"` + `transferLikeSubsteps got unsupported stepType "${ + stepArgs.commandCreatorFnName + }"` ) return null } diff --git a/protocol-designer/src/steplist/substepTimeline.js b/protocol-designer/src/steplist/substepTimeline.js index ae6c5025a57..807378b8601 100644 --- a/protocol-designer/src/steplist/substepTimeline.js +++ b/protocol-designer/src/steplist/substepTimeline.js @@ -66,7 +66,9 @@ const substepTimelineSingle = (commandCreators: Array) => ( ) { assert( nextFrame.commands.length === 1, - `substepTimeline expected nextFrame to have only single commands for ${firstCommand.command}` + `substepTimeline expected nextFrame to have only single commands for ${ + firstCommand.command + }` ) const commandGroup = firstCommand @@ -143,7 +145,9 @@ const substepTimeline = ( ) { assert( nextFrame.commands.length === 1, - `substepTimeline expected nextFrame to have only single commands for ${firstCommand.command}` + `substepTimeline expected nextFrame to have only single commands for ${ + firstCommand.command + }` ) const { well, volume, labware } = firstCommand.params diff --git a/protocol-designer/src/top-selectors/well-contents/index.js b/protocol-designer/src/top-selectors/well-contents/index.js index bab9ebb6fab..0880e2f99b5 100644 --- a/protocol-designer/src/top-selectors/well-contents/index.js +++ b/protocol-designer/src/top-selectors/well-contents/index.js @@ -154,7 +154,9 @@ export const getAllWellContentsForActiveItem: Selector = assert( timelineIdx !== -1, - `getAllWellContentsForActiveItem got unhandled terminal id: "${activeItem.id}"` + `getAllWellContentsForActiveItem got unhandled terminal id: "${ + activeItem.id + }"` ) const liquidState = timeline[timelineIdx].robotState.liquidState.labware diff --git a/protocol-designer/src/ui/steps/selectors.js b/protocol-designer/src/ui/steps/selectors.js index 99b87f8807a..3b778f5daa9 100644 --- a/protocol-designer/src/ui/steps/selectors.js +++ b/protocol-designer/src/ui/steps/selectors.js @@ -91,7 +91,9 @@ const getHoveredStepLabware: Selector> = createSelector( if (!(stepArgs.commandCreatorFnName === 'delay')) { // TODO Ian 2018-05-08 use assert here console.warn( - `getHoveredStepLabware does not support step type "${stepArgs.commandCreatorFnName}"` + `getHoveredStepLabware does not support step type "${ + stepArgs.commandCreatorFnName + }"` ) } diff --git a/shared-data/js/helpers/getWellNamePerMultiTip.js b/shared-data/js/helpers/getWellNamePerMultiTip.js index 59f9632e058..eec777d2235 100644 --- a/shared-data/js/helpers/getWellNamePerMultiTip.js +++ b/shared-data/js/helpers/getWellNamePerMultiTip.js @@ -39,7 +39,9 @@ export function getWellNamePerMultiTip( const topWell = labwareDef.wells[topWellName] if (!topWell) { console.warn( - `well "${topWellName}" does not exist in labware ${labwareDef?.namespace}/${labwareDef?.parameters?.loadName}, cannot getWellNamePerMultiTip` + `well "${topWellName}" does not exist in labware ${ + labwareDef?.namespace + }/${labwareDef?.parameters?.loadName}, cannot getWellNamePerMultiTip` ) return null } diff --git a/shared-data/js/helpers/getWellTotalVolume.js b/shared-data/js/helpers/getWellTotalVolume.js index 8581195c0c4..ae9dc2fd1bb 100644 --- a/shared-data/js/helpers/getWellTotalVolume.js +++ b/shared-data/js/helpers/getWellTotalVolume.js @@ -8,7 +8,9 @@ const getWellTotalVolume = ( const well = labwareDef.wells[wellName] if (!well) { console.warn( - `No well "${wellName}" found for labware ${labwareDef?.namespace}/${labwareDef?.parameters?.loadName}/${labwareDef?.version}"` + `No well "${wellName}" found for labware ${labwareDef?.namespace}/${ + labwareDef?.parameters?.loadName + }/${labwareDef?.version}"` ) return null } From e91859dbbc8effee8bdd9d8327702549100cc430 Mon Sep 17 00:00:00 2001 From: IanLondon Date: Tue, 17 Sep 2019 17:26:46 -0400 Subject: [PATCH 4/5] run "make format" --- app-shell/src/buildroot/index.js | 20 ++++------ .../ModuleLiveStatusCards/ThermocyclerCard.js | 8 +--- components/src/deck/Deck.js | 40 +++++++++---------- components/src/deck/LabwareRender.js | 4 +- components/src/deck/LabwareRender.md | 8 +--- .../src/labware-creator/labwareFormSchema.js | 19 +++++---- .../LabwareSelectionModal/LabwarePreview.js | 4 +- .../StepEditForm/fields/ChangeTip/index.js | 4 +- .../src/components/labware/SingleLabware.js | 4 +- .../src/file-data/selectors/commands.js | 4 +- .../src/step-forms/reducers/index.js | 16 ++++---- .../src/step-forms/selectors/index.js | 4 +- protocol-designer/src/step-forms/utils.js | 4 +- .../commandCreators/compound/transfer.js | 4 +- .../getNextRobotStateAndWarnings/index.js | 4 +- .../formLevel/handleFormChange/utils.js | 8 +--- .../stepFormToArgs/moveLiquidFormToArgs.js | 8 +--- .../src/steplist/generateSubsteps.js | 4 +- .../src/steplist/substepTimeline.js | 8 +--- .../src/top-selectors/well-contents/index.js | 4 +- protocol-designer/src/ui/steps/selectors.js | 4 +- .../js/helpers/getWellNamePerMultiTip.js | 4 +- shared-data/js/helpers/getWellTotalVolume.js | 4 +- 23 files changed, 67 insertions(+), 124 deletions(-) diff --git a/app-shell/src/buildroot/index.js b/app-shell/src/buildroot/index.js index 5043f4085d0..f1d633722ac 100644 --- a/app-shell/src/buildroot/index.js +++ b/app-shell/src/buildroot/index.js @@ -43,18 +43,14 @@ export function registerBuildrootUpdate(dispatch: Dispatch) { log.info('Starting robot premigration', { robot }) startPremigration(robot) - .then( - (): BuildrootAction => ({ - type: 'buildroot:PREMIGRATION_DONE', - payload: robot.name, - }) - ) - .catch( - (error: Error): BuildrootAction => ({ - type: 'buildroot:PREMIGRATION_ERROR', - payload: { message: error.message }, - }) - ) + .then((): BuildrootAction => ({ + type: 'buildroot:PREMIGRATION_DONE', + payload: robot.name, + })) + .catch((error: Error): BuildrootAction => ({ + type: 'buildroot:PREMIGRATION_ERROR', + payload: { message: error.message }, + })) .then(dispatch) break diff --git a/app/src/components/ModuleLiveStatusCards/ThermocyclerCard.js b/app/src/components/ModuleLiveStatusCards/ThermocyclerCard.js index 64819ed1a4a..ec7aa04c0f3 100644 --- a/app/src/components/ModuleLiveStatusCards/ThermocyclerCard.js +++ b/app/src/components/ModuleLiveStatusCards/ThermocyclerCard.js @@ -72,16 +72,12 @@ const ThermocyclerCard = ({ , row: number): Array => { - return columns.map( - (slot: DeckSlotId, col: number): React.Node => { - if (slot === TRASH_SLOTNAME) return null + return columns.map((slot: DeckSlotId, col: number): React.Node => { + if (slot === TRASH_SLOTNAME) return null - const props = { - slot, - width: SLOT_RENDER_WIDTH, - height: SLOT_RENDER_HEIGHT, - } - const transform = `translate(${[ - SLOT_RENDER_WIDTH * col + SLOT_SPACING_MM * (col + 1), - SLOT_RENDER_HEIGHT * row + SLOT_SPACING_MM * (row + 1), - ].join(',')})` - - return ( - // $FlowFixMe: (mc, 2019-04-18) don't know why flow doesn't like this, don't care because this is going away - - - {LabwareComponent && } - - ) + const props = { + slot, + width: SLOT_RENDER_WIDTH, + height: SLOT_RENDER_HEIGHT, } - ) + const transform = `translate(${[ + SLOT_RENDER_WIDTH * col + SLOT_SPACING_MM * (col + 1), + SLOT_RENDER_HEIGHT * row + SLOT_SPACING_MM * (row + 1), + ].join(',')})` + + return ( + // $FlowFixMe: (mc, 2019-04-18) don't know why flow doesn't like this, don't care because this is going away + + + {LabwareComponent && } + + ) + }) } ) } diff --git a/components/src/deck/LabwareRender.js b/components/src/deck/LabwareRender.js index faa4075ef19..79eb2bea742 100644 --- a/components/src/deck/LabwareRender.js +++ b/components/src/deck/LabwareRender.js @@ -36,9 +36,7 @@ export default function LabwareRender(props: LabwareRenderProps) { const cornerOffsetFromSlot = props.definition.cornerOffsetFromSlot return ( {() => ( {() => ( => - (currentValue || '') - .trim() - .split(',') - .map(s => s.trim()) - .filter(Boolean) + .transform((currentValue: ?string, originalValue: ?string): $PropertyType< + ProcessedLabwareFields, + 'brandId' + > => + (currentValue || '') + .trim() + .split(',') + .map(s => s.trim()) + .filter(Boolean) ), loadName: Yup.string() diff --git a/protocol-designer/src/components/LabwareSelectionModal/LabwarePreview.js b/protocol-designer/src/components/LabwareSelectionModal/LabwarePreview.js index 1bc395b45ee..ae58480c6fc 100644 --- a/protocol-designer/src/components/LabwareSelectionModal/LabwarePreview.js +++ b/protocol-designer/src/components/LabwareSelectionModal/LabwarePreview.js @@ -44,9 +44,7 @@ const LabwarePreview = (props: Props) => {
{() => } diff --git a/protocol-designer/src/components/StepEditForm/fields/ChangeTip/index.js b/protocol-designer/src/components/StepEditForm/fields/ChangeTip/index.js index a7ce3976e60..d5b82946078 100644 --- a/protocol-designer/src/components/StepEditForm/fields/ChangeTip/index.js +++ b/protocol-designer/src/components/StepEditForm/fields/ChangeTip/index.js @@ -45,9 +45,7 @@ function getDisabledChangeTipOptions( } default: { console.warn( - `getChangeTipOptions for stepType ${ - rawForm.stepType - } not yet implemented!` + `getChangeTipOptions for stepType ${rawForm.stepType} not yet implemented!` ) return null } diff --git a/protocol-designer/src/components/labware/SingleLabware.js b/protocol-designer/src/components/labware/SingleLabware.js index af3f3a8d786..51858c522fb 100644 --- a/protocol-designer/src/components/labware/SingleLabware.js +++ b/protocol-designer/src/components/labware/SingleLabware.js @@ -8,9 +8,7 @@ type Props = React.ElementProps export default function SingleLabware(props: Props) { return ( {() => } diff --git a/protocol-designer/src/file-data/selectors/commands.js b/protocol-designer/src/file-data/selectors/commands.js index bd2ce5a3102..21829ff0240 100644 --- a/protocol-designer/src/file-data/selectors/commands.js +++ b/protocol-designer/src/file-data/selectors/commands.js @@ -164,9 +164,7 @@ export const getRobotStateTimeline: Selector = createSe if (!reducedCommandCreator) { console.warn( - `commandCreatorFnName "${ - stepArgs.commandCreatorFnName - }" not yet implemented for robotStateTimeline` + `commandCreatorFnName "${stepArgs.commandCreatorFnName}" not yet implemented for robotStateTimeline` ) return acc } diff --git a/protocol-designer/src/step-forms/reducers/index.js b/protocol-designer/src/step-forms/reducers/index.js index af08c439cc5..f8e9b8c8d6b 100644 --- a/protocol-designer/src/step-forms/reducers/index.js +++ b/protocol-designer/src/step-forms/reducers/index.js @@ -516,15 +516,13 @@ export const labwareInvariantProperties = handleActions< state: NormalizedLabwareById, action: ReplaceCustomLabwareDef ): NormalizedLabwareById => - mapValues( - state, - (prev: NormalizedLabware): NormalizedLabware => - action.payload.defURIToOverwrite === prev.labwareDefURI - ? { - ...prev, - labwareDefURI: getLabwareDefURI(action.payload.newDef), - } - : prev + mapValues(state, (prev: NormalizedLabware): NormalizedLabware => + action.payload.defURIToOverwrite === prev.labwareDefURI + ? { + ...prev, + labwareDefURI: getLabwareDefURI(action.payload.newDef), + } + : prev ), }, initialLabwareState diff --git a/protocol-designer/src/step-forms/selectors/index.js b/protocol-designer/src/step-forms/selectors/index.js index c0c7165b668..35b9008111d 100644 --- a/protocol-designer/src/step-forms/selectors/index.js +++ b/protocol-designer/src/step-forms/selectors/index.js @@ -75,9 +75,7 @@ function _hydrateLabwareEntity( const def = defsByURI[l.labwareDefURI] assert( def, - `could not hydrate labware ${labwareId}, missing def for URI ${ - l.labwareDefURI - }` + `could not hydrate labware ${labwareId}, missing def for URI ${l.labwareDefURI}` ) return { ...l, diff --git a/protocol-designer/src/step-forms/utils.js b/protocol-designer/src/step-forms/utils.js index cb65c7ad9db..2583d9088be 100644 --- a/protocol-designer/src/step-forms/utils.js +++ b/protocol-designer/src/step-forms/utils.js @@ -57,9 +57,7 @@ export function denormalizePipetteEntities( const spec = getPipetteNameSpecs(pipette.name) if (!spec) { throw new Error( - `no pipette spec for pipette id "${pipetteId}", name "${ - pipette.name - }"` + `no pipette spec for pipette id "${pipetteId}", name "${pipette.name}"` ) } diff --git a/protocol-designer/src/step-generation/commandCreators/compound/transfer.js b/protocol-designer/src/step-generation/commandCreators/compound/transfer.js index 2c9408e1a53..6c58532da4c 100644 --- a/protocol-designer/src/step-generation/commandCreators/compound/transfer.js +++ b/protocol-designer/src/step-generation/commandCreators/compound/transfer.js @@ -41,9 +41,7 @@ const transfer = (args: TransferArgs): CompoundCommandCreator => ( */ assert( args.sourceWells.length === args.destWells.length, - `Transfer command creator expected N:N source-to-dest wells ratio. Got ${ - args.sourceWells.length - }:${args.destWells.length}` + `Transfer command creator expected N:N source-to-dest wells ratio. Got ${args.sourceWells.length}:${args.destWells.length}` ) // TODO Ian 2018-04-02 following ~10 lines are identical to first lines of consolidate.js... const actionName = 'transfer' diff --git a/protocol-designer/src/step-generation/getNextRobotStateAndWarnings/index.js b/protocol-designer/src/step-generation/getNextRobotStateAndWarnings/index.js index be07c6f0cd8..cc5212fe170 100644 --- a/protocol-designer/src/step-generation/getNextRobotStateAndWarnings/index.js +++ b/protocol-designer/src/step-generation/getNextRobotStateAndWarnings/index.js @@ -40,9 +40,7 @@ export default function getNextRobotStateAndWarnings( default: assert( false, - `unknown command: ${ - command.command - } passed to getNextRobotStateAndWarning` + `unknown command: ${command.command} passed to getNextRobotStateAndWarning` ) return { robotState: prevRobotState, warnings: [] } } diff --git a/protocol-designer/src/steplist/formLevel/handleFormChange/utils.js b/protocol-designer/src/steplist/formLevel/handleFormChange/utils.js index a7e0da7b2c7..8f6d2a103bd 100644 --- a/protocol-designer/src/steplist/formLevel/handleFormChange/utils.js +++ b/protocol-designer/src/steplist/formLevel/handleFormChange/utils.js @@ -64,9 +64,7 @@ export function getMaxDisposalVolumeForMultidispense( if (!rawForm) return null assert( rawForm.path === 'multiDispense', - `getMaxDisposalVolumeForMultidispense expected multiDispense, got path ${ - rawForm.path - }` + `getMaxDisposalVolumeForMultidispense expected multiDispense, got path ${rawForm.path}` ) const volume = Number(rawForm.volume) const pipetteEntity = pipetteEntities[rawForm.pipette] @@ -84,9 +82,7 @@ export function volumeInCapacityForMulti( const volume = Number(rawForm.volume) assert( rawForm.pipette in pipetteEntities, - `volumeInCapacityForMulti expected pipette ${ - rawForm.pipette - } to be in pipetteEntities` + `volumeInCapacityForMulti expected pipette ${rawForm.pipette} to be in pipetteEntities` ) const pipetteEntity = pipetteEntities[rawForm.pipette] const pipetteCapacity = pipetteEntity && getPipetteCapacity(pipetteEntity) diff --git a/protocol-designer/src/steplist/formLevel/stepFormToArgs/moveLiquidFormToArgs.js b/protocol-designer/src/steplist/formLevel/stepFormToArgs/moveLiquidFormToArgs.js index 39c3275acb3..b61675ad789 100644 --- a/protocol-designer/src/steplist/formLevel/stepFormToArgs/moveLiquidFormToArgs.js +++ b/protocol-designer/src/steplist/formLevel/stepFormToArgs/moveLiquidFormToArgs.js @@ -48,9 +48,7 @@ const moveLiquidFormToArgs = ( ): MoveLiquidStepArgs => { assert( hydratedFormData.stepType === 'moveLiquid', - `moveLiquidFormToArgs called with stepType ${ - hydratedFormData.stepType - }, expected "moveLiquid"` + `moveLiquidFormToArgs called with stepType ${hydratedFormData.stepType}, expected "moveLiquid"` ) const fields = hydratedFormData.fields @@ -187,9 +185,7 @@ const moveLiquidFormToArgs = ( sourceWellsUnordered.length === 1 || destWellsUnordered.length === 1 || sourceWellsUnordered.length === destWellsUnordered.length, - `cannot do moveLiquidFormToArgs. Mismatched wells (not 1:N, N:1, or N:N!) for path="single". Neither source (${ - sourceWellsUnordered.length - }) nor dest (${destWellsUnordered.length}) equal 1` + `cannot do moveLiquidFormToArgs. Mismatched wells (not 1:N, N:1, or N:N!) for path="single". Neither source (${sourceWellsUnordered.length}) nor dest (${destWellsUnordered.length}) equal 1` ) switch (path) { diff --git a/protocol-designer/src/steplist/generateSubsteps.js b/protocol-designer/src/steplist/generateSubsteps.js index 4e26f692fc7..f8720a087e6 100644 --- a/protocol-designer/src/steplist/generateSubsteps.js +++ b/protocol-designer/src/steplist/generateSubsteps.js @@ -107,9 +107,7 @@ function transferLikeSubsteps(args: {| } else { // TODO Ian 2018-05-21 Use assert here. Should be unreachable console.warn( - `transferLikeSubsteps got unsupported stepType "${ - stepArgs.commandCreatorFnName - }"` + `transferLikeSubsteps got unsupported stepType "${stepArgs.commandCreatorFnName}"` ) return null } diff --git a/protocol-designer/src/steplist/substepTimeline.js b/protocol-designer/src/steplist/substepTimeline.js index 807378b8601..ae6c5025a57 100644 --- a/protocol-designer/src/steplist/substepTimeline.js +++ b/protocol-designer/src/steplist/substepTimeline.js @@ -66,9 +66,7 @@ const substepTimelineSingle = (commandCreators: Array) => ( ) { assert( nextFrame.commands.length === 1, - `substepTimeline expected nextFrame to have only single commands for ${ - firstCommand.command - }` + `substepTimeline expected nextFrame to have only single commands for ${firstCommand.command}` ) const commandGroup = firstCommand @@ -145,9 +143,7 @@ const substepTimeline = ( ) { assert( nextFrame.commands.length === 1, - `substepTimeline expected nextFrame to have only single commands for ${ - firstCommand.command - }` + `substepTimeline expected nextFrame to have only single commands for ${firstCommand.command}` ) const { well, volume, labware } = firstCommand.params diff --git a/protocol-designer/src/top-selectors/well-contents/index.js b/protocol-designer/src/top-selectors/well-contents/index.js index 0880e2f99b5..bab9ebb6fab 100644 --- a/protocol-designer/src/top-selectors/well-contents/index.js +++ b/protocol-designer/src/top-selectors/well-contents/index.js @@ -154,9 +154,7 @@ export const getAllWellContentsForActiveItem: Selector = assert( timelineIdx !== -1, - `getAllWellContentsForActiveItem got unhandled terminal id: "${ - activeItem.id - }"` + `getAllWellContentsForActiveItem got unhandled terminal id: "${activeItem.id}"` ) const liquidState = timeline[timelineIdx].robotState.liquidState.labware diff --git a/protocol-designer/src/ui/steps/selectors.js b/protocol-designer/src/ui/steps/selectors.js index 3b778f5daa9..99b87f8807a 100644 --- a/protocol-designer/src/ui/steps/selectors.js +++ b/protocol-designer/src/ui/steps/selectors.js @@ -91,9 +91,7 @@ const getHoveredStepLabware: Selector> = createSelector( if (!(stepArgs.commandCreatorFnName === 'delay')) { // TODO Ian 2018-05-08 use assert here console.warn( - `getHoveredStepLabware does not support step type "${ - stepArgs.commandCreatorFnName - }"` + `getHoveredStepLabware does not support step type "${stepArgs.commandCreatorFnName}"` ) } diff --git a/shared-data/js/helpers/getWellNamePerMultiTip.js b/shared-data/js/helpers/getWellNamePerMultiTip.js index eec777d2235..59f9632e058 100644 --- a/shared-data/js/helpers/getWellNamePerMultiTip.js +++ b/shared-data/js/helpers/getWellNamePerMultiTip.js @@ -39,9 +39,7 @@ export function getWellNamePerMultiTip( const topWell = labwareDef.wells[topWellName] if (!topWell) { console.warn( - `well "${topWellName}" does not exist in labware ${ - labwareDef?.namespace - }/${labwareDef?.parameters?.loadName}, cannot getWellNamePerMultiTip` + `well "${topWellName}" does not exist in labware ${labwareDef?.namespace}/${labwareDef?.parameters?.loadName}, cannot getWellNamePerMultiTip` ) return null } diff --git a/shared-data/js/helpers/getWellTotalVolume.js b/shared-data/js/helpers/getWellTotalVolume.js index ae9dc2fd1bb..8581195c0c4 100644 --- a/shared-data/js/helpers/getWellTotalVolume.js +++ b/shared-data/js/helpers/getWellTotalVolume.js @@ -8,9 +8,7 @@ const getWellTotalVolume = ( const well = labwareDef.wells[wellName] if (!well) { console.warn( - `No well "${wellName}" found for labware ${labwareDef?.namespace}/${ - labwareDef?.parameters?.loadName - }/${labwareDef?.version}"` + `No well "${wellName}" found for labware ${labwareDef?.namespace}/${labwareDef?.parameters?.loadName}/${labwareDef?.version}"` ) return null } From ea4b529e612236108787423aa5b3520eb1863640 Mon Sep 17 00:00:00 2001 From: IanLondon Date: Wed, 18 Sep 2019 15:00:10 -0400 Subject: [PATCH 5/5] fixup: comment typo --- shared-data/js/helpers/wellSets.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-data/js/helpers/wellSets.js b/shared-data/js/helpers/wellSets.js index 0ec72bc01a4..fff981aadff 100644 --- a/shared-data/js/helpers/wellSets.js +++ b/shared-data/js/helpers/wellSets.js @@ -1,5 +1,5 @@ // @flow -// A "well set" is array of wells corresponding to each tip of an 8 channel pipette. +// A "well set" is an array of wells corresponding to each tip of an 8 channel pipette. // Eg ['A1', 'C1', 'E1', 'G1', 'I1', 'K1', 'M1', 'O1'] is a well set in a 384 plate. // // A trough-like well that encompasses all 8 tips at once has a well set