diff --git a/.flowconfig b/.flowconfig index 54061f8c1f4..df93fe2c703 100644 --- a/.flowconfig +++ b/.flowconfig @@ -23,5 +23,6 @@ [options] module.name_mapper.extension='css' -> '@opentrons/components/interfaces/CSSModule.js' +module.ignore_non_literal_requires=true merge_timeout=300 esproposal.optional_chaining=enable diff --git a/app/src/components/ChangePipette/ConfirmPipette.js b/app/src/components/ChangePipette/ConfirmPipette.js index 164b53ebabc..d0fb1de4d8a 100644 --- a/app/src/components/ChangePipette/ConfirmPipette.js +++ b/app/src/components/ChangePipette/ConfirmPipette.js @@ -6,7 +6,7 @@ import { Link } from 'react-router-dom' import { Icon, PrimaryButton, ModalPage } from '@opentrons/components' import type { ChangePipetteProps } from './types' -import { getDiagramSrc } from './InstructionStep' +import { getDiagramsSrc } from './InstructionStep' import styles from './styles.css' const EXIT_BUTTON_MESSAGE = 'exit pipette setup' @@ -83,7 +83,7 @@ function StatusDetails(props: ChangePipetteProps) {
Step {props.step}
{props.children}
- {diagram === 'screws' && ( + {props.diagram === 'screws' && ( )} - + ) } - -export function getDiagramSrc(props: DiagramProps): string { - const { direction, mount, channels, diagram } = props - const channelsKey = channels === 8 ? 'multi' : 'single' - - return DIAGRAMS[direction][mount][channelsKey][diagram] -} diff --git a/app/src/components/ChangePipette/Instructions.js b/app/src/components/ChangePipette/Instructions.js index ddefaa11437..5af71053ebe 100644 --- a/app/src/components/ChangePipette/Instructions.js +++ b/app/src/components/ChangePipette/Instructions.js @@ -74,7 +74,8 @@ export default function Instructions(props: ChangePipetteProps) { } function Steps(props: ChangePipetteProps) { - const { direction } = props + const { direction, displayCategory } = props + const channels = props.actualPipette ? props.actualPipette.channels : props.wantedPipette?.channels || 1 @@ -110,11 +111,18 @@ function Steps(props: ChangePipetteProps) { step="one" diagram="screws" channels={channels} + displayCategory={displayCategory} {...props} > {stepOne} - + {stepTwo}
diff --git a/app/src/components/ChangePipette/images/attach-left-multi-GEN2-screws@3x.png b/app/src/components/ChangePipette/images/attach-left-multi-GEN2-screws@3x.png new file mode 100755 index 00000000000..4be592ce042 Binary files /dev/null and b/app/src/components/ChangePipette/images/attach-left-multi-GEN2-screws@3x.png differ diff --git a/app/src/components/ChangePipette/images/attach-left-multi-GEN2-tab@3x.png b/app/src/components/ChangePipette/images/attach-left-multi-GEN2-tab@3x.png new file mode 100755 index 00000000000..dddf4a208c3 Binary files /dev/null and b/app/src/components/ChangePipette/images/attach-left-multi-GEN2-tab@3x.png differ diff --git a/app/src/components/ChangePipette/images/attach-left-single-GEN2-screws@3x.png b/app/src/components/ChangePipette/images/attach-left-single-GEN2-screws@3x.png new file mode 100755 index 00000000000..bf4e4dd4bc3 Binary files /dev/null and b/app/src/components/ChangePipette/images/attach-left-single-GEN2-screws@3x.png differ diff --git a/app/src/components/ChangePipette/images/attach-left-single-GEN2-tab@3x.png b/app/src/components/ChangePipette/images/attach-left-single-GEN2-tab@3x.png new file mode 100755 index 00000000000..93591f98174 Binary files /dev/null and b/app/src/components/ChangePipette/images/attach-left-single-GEN2-tab@3x.png differ diff --git a/app/src/components/ChangePipette/images/attach-right-multi-GEN2-screws@3x.png b/app/src/components/ChangePipette/images/attach-right-multi-GEN2-screws@3x.png new file mode 100755 index 00000000000..12c66df1a74 Binary files /dev/null and b/app/src/components/ChangePipette/images/attach-right-multi-GEN2-screws@3x.png differ diff --git a/app/src/components/ChangePipette/images/attach-right-multi-GEN2-tab@3x.png b/app/src/components/ChangePipette/images/attach-right-multi-GEN2-tab@3x.png new file mode 100755 index 00000000000..35b9ec361e5 Binary files /dev/null and b/app/src/components/ChangePipette/images/attach-right-multi-GEN2-tab@3x.png differ diff --git a/app/src/components/ChangePipette/images/attach-right-single-GEN2-screws@3x.png b/app/src/components/ChangePipette/images/attach-right-single-GEN2-screws@3x.png new file mode 100755 index 00000000000..721edf5cc0e Binary files /dev/null and b/app/src/components/ChangePipette/images/attach-right-single-GEN2-screws@3x.png differ diff --git a/app/src/components/ChangePipette/images/attach-right-single-GEN2-tab@3x.png b/app/src/components/ChangePipette/images/attach-right-single-GEN2-tab@3x.png new file mode 100755 index 00000000000..35b9ec361e5 Binary files /dev/null and b/app/src/components/ChangePipette/images/attach-right-single-GEN2-tab@3x.png differ diff --git a/app/src/components/ChangePipette/images/detach-left-multi-GEN2-screws@3x.png b/app/src/components/ChangePipette/images/detach-left-multi-GEN2-screws@3x.png new file mode 100755 index 00000000000..6cf22af74d6 Binary files /dev/null and b/app/src/components/ChangePipette/images/detach-left-multi-GEN2-screws@3x.png differ diff --git a/app/src/components/ChangePipette/images/detach-left-multi-GEN2-tab@3x.png b/app/src/components/ChangePipette/images/detach-left-multi-GEN2-tab@3x.png new file mode 100755 index 00000000000..78ae22b34da Binary files /dev/null and b/app/src/components/ChangePipette/images/detach-left-multi-GEN2-tab@3x.png differ diff --git a/app/src/components/ChangePipette/images/detach-left-single-GEN2-screws@3x.png b/app/src/components/ChangePipette/images/detach-left-single-GEN2-screws@3x.png new file mode 100755 index 00000000000..15a86789c7d Binary files /dev/null and b/app/src/components/ChangePipette/images/detach-left-single-GEN2-screws@3x.png differ diff --git a/app/src/components/ChangePipette/images/detach-left-single-GEN2-tab@3x.png b/app/src/components/ChangePipette/images/detach-left-single-GEN2-tab@3x.png new file mode 100755 index 00000000000..78ae22b34da Binary files /dev/null and b/app/src/components/ChangePipette/images/detach-left-single-GEN2-tab@3x.png differ diff --git a/app/src/components/ChangePipette/images/detach-right-multi-GEN2-screws@3x.png b/app/src/components/ChangePipette/images/detach-right-multi-GEN2-screws@3x.png new file mode 100755 index 00000000000..d22ba068205 Binary files /dev/null and b/app/src/components/ChangePipette/images/detach-right-multi-GEN2-screws@3x.png differ diff --git a/app/src/components/ChangePipette/images/detach-right-multi-GEN2-tab@3x.png b/app/src/components/ChangePipette/images/detach-right-multi-GEN2-tab@3x.png new file mode 100755 index 00000000000..38738aebd4b Binary files /dev/null and b/app/src/components/ChangePipette/images/detach-right-multi-GEN2-tab@3x.png differ diff --git a/app/src/components/ChangePipette/images/detach-right-single-GEN2-screws@3x.png b/app/src/components/ChangePipette/images/detach-right-single-GEN2-screws@3x.png new file mode 100755 index 00000000000..9bacc52651e Binary files /dev/null and b/app/src/components/ChangePipette/images/detach-right-single-GEN2-screws@3x.png differ diff --git a/app/src/components/ChangePipette/images/detach-right-single-GEN2-tab@3x.png b/app/src/components/ChangePipette/images/detach-right-single-GEN2-tab@3x.png new file mode 100755 index 00000000000..38738aebd4b Binary files /dev/null and b/app/src/components/ChangePipette/images/detach-right-single-GEN2-tab@3x.png differ diff --git a/app/src/components/ChangePipette/index.js b/app/src/components/ChangePipette/index.js index 22ff5b56809..0e379d996ab 100644 --- a/app/src/components/ChangePipette/index.js +++ b/app/src/components/ChangePipette/index.js @@ -6,6 +6,7 @@ import { Switch, Route, withRouter, type Match } from 'react-router' import { getPipetteNameSpecs, getPipetteModelSpecs, + type PipetteDisplayCategory, } from '@opentrons/shared-data' import { getConfig } from '../../config' @@ -63,6 +64,7 @@ type SP = {| homeRequest: RobotHome, actualPipette: ?PipetteModelSpecs, displayName: string, + displayCategory: ?PipetteDisplayCategory, direction: Direction, success: boolean, attachedWrong: boolean, @@ -137,12 +139,16 @@ function makeMapStateToProps(): (State, OP) => SP { const displayName = actualPipette?.displayName || wantedPipette?.displayName || '' + const displayCategory = + actualPipette?.displayCategory || wantedPipette?.displayCategory + return { actualPipette, direction, success, attachedWrong, displayName, + displayCategory, moveRequest: getRobotMove(state, robot), homeRequest: getRobotHome(state, robot), __pipettePlusEnabled: Boolean( diff --git a/app/src/components/ChangePipette/styles.css b/app/src/components/ChangePipette/styles.css index 1a5dba50b4f..a6f0f2a552e 100644 --- a/app/src/components/ChangePipette/styles.css +++ b/app/src/components/ChangePipette/styles.css @@ -1,12 +1,11 @@ @import '@opentrons/components'; :root { - --bg-modal-transparent: { max-width: 30rem; padding-top: 3rem; background-color: transparent; - }; + } } .modal { @@ -143,3 +142,8 @@ padding-left: 2.5rem; padding-right: 2.5rem; } + +.flipped_image { + transform: scaleX(-1); + filter: FlipH; +} diff --git a/app/src/components/ChangePipette/types.js b/app/src/components/ChangePipette/types.js index da6e2ad80c4..453652863ea 100644 --- a/app/src/components/ChangePipette/types.js +++ b/app/src/components/ChangePipette/types.js @@ -2,6 +2,7 @@ import type { PipetteNameSpecs, PipetteModelSpecs, + PipetteDisplayCategory, } from '@opentrons/shared-data' import type { Mount } from '../../robot' @@ -18,6 +19,7 @@ export type ChangePipetteProps = { wantedPipette: ?PipetteNameSpecs, actualPipette: ?PipetteModelSpecs, displayName: string, + displayCategory: PipetteDisplayCategory, direction: Direction, success: boolean, attachedWrong: boolean, diff --git a/app/src/components/InstrumentSettings/InstrumentInfo.js b/app/src/components/InstrumentSettings/InstrumentInfo.js index 156f0c37974..84a3ba22b08 100644 --- a/app/src/components/InstrumentSettings/InstrumentInfo.js +++ b/app/src/components/InstrumentSettings/InstrumentInfo.js @@ -29,7 +29,7 @@ const LABEL_BY_MOUNT = { export default function PipetteInfo(props: Props) { const { mount, model, robotName, onChangeClick, showSettings } = props const label = LABEL_BY_MOUNT[mount] - const pipette = model && getPipetteModelSpecs(model) + const pipette = model ? getPipetteModelSpecs(model) : null const { displayName, channels } = pipette || {} @@ -63,7 +63,8 @@ export default function PipetteInfo(props: Props) {
{channels && ( )} diff --git a/app/src/components/calibrate-pipettes/Pipettes.js b/app/src/components/calibrate-pipettes/Pipettes.js index 4ac69894a85..8707bf23840 100644 --- a/app/src/components/calibrate-pipettes/Pipettes.js +++ b/app/src/components/calibrate-pipettes/Pipettes.js @@ -50,7 +50,7 @@ export default function Pipettes(props: Props) { description: pipetteConfig.displayName, tiprackModel: tiprack?.definition?.metadata.displayName || tiprack?.name || 'N/A', - channels: pipetteConfig.channels, + pipetteSpecs: pipetteConfig, } let showAlert = false diff --git a/components/src/__tests__/__snapshots__/instrument-diagram.test.js.snap b/components/src/__tests__/__snapshots__/instrument-diagram.test.js.snap index bee229fc18c..30450df73c2 100644 --- a/components/src/__tests__/__snapshots__/instrument-diagram.test.js.snap +++ b/components/src/__tests__/__snapshots__/instrument-diagram.test.js.snap @@ -1,8 +1,27 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`InstrumentDiagram Multi-channel GEN2 renders correctly 1`] = ` +
+ +
+`; + exports[`InstrumentDiagram Multi-channel renders correctly 1`] = `
+
+`; + +exports[`InstrumentDiagram Single-channel GEN2 renders correctly 1`] = ` +
+
@@ -11,7 +30,8 @@ exports[`InstrumentDiagram Multi-channel renders correctly 1`] = ` exports[`InstrumentDiagram Single-channel renders correctly 1`] = `
`; @@ -43,6 +63,7 @@ exports[`InstrumentGroup Renders correctly 1`] = ` className="pipette_icon" >
@@ -70,6 +91,7 @@ exports[`InstrumentGroup Renders correctly 1`] = ` className="pipette_icon" > diff --git a/components/src/__tests__/instrument-diagram.test.js b/components/src/__tests__/instrument-diagram.test.js index 88810d32434..2b929717c2f 100644 --- a/components/src/__tests__/instrument-diagram.test.js +++ b/components/src/__tests__/instrument-diagram.test.js @@ -5,13 +5,33 @@ import { InstrumentDiagram, InstrumentGroup } from '..' describe('InstrumentDiagram', () => { test('Single-channel renders correctly', () => { - const tree = Renderer.create().toJSON() + const tree = Renderer.create( + + ).toJSON() expect(tree).toMatchSnapshot() }) test('Multi-channel renders correctly', () => { - const tree = Renderer.create().toJSON() + const tree = Renderer.create( + + ).toJSON() + + expect(tree).toMatchSnapshot() + }) + + test('Single-channel GEN2 renders correctly', () => { + const tree = Renderer.create( + + ).toJSON() + + expect(tree).toMatchSnapshot() + }) + + test('Multi-channel GEN2 renders correctly', () => { + const tree = Renderer.create( + + ).toJSON() expect(tree).toMatchSnapshot() }) @@ -25,14 +45,14 @@ describe('InstrumentGroup', () => { mount: 'left', description: 'p300 8-Channel', tipType: '150', - channels: 8, + pipetteSpecs: { channels: 8, displayCategory: 'OG' }, className: 'foo', }} right={{ mount: 'right', description: 'p10 Single', tipType: '10', - channels: 1, + pipetteSpecs: { channels: 1, displayCategory: 'OG' }, isDisabled: true, className: 'blah', }} diff --git a/components/src/instrument-diagram/InstrumentDiagram.js b/components/src/instrument-diagram/InstrumentDiagram.js index 50c9c350609..c43a8fa49b1 100644 --- a/components/src/instrument-diagram/InstrumentDiagram.js +++ b/components/src/instrument-diagram/InstrumentDiagram.js @@ -1,21 +1,45 @@ // @flow import React from 'react' +import cx from 'classnames' +import type { + PipetteNameSpecs, + PipetteModelSpecs, +} from '@opentrons/shared-data' +import type { Mount } from '../robot-types' import singleSrc from './pipetteSingle.png' import multiSrc from './pipetteMulti.png' +import singleGEN2Src from './pipetteGEN2Single.png' +import multiGEN2Src from './pipetteGEN2Multi.png' +import styles from './instrument.css' type Props = { - channels?: number, + pipetteSpecs?: ?PipetteNameSpecs | ?PipetteModelSpecs, className?: string, + mount: Mount, } export default function InstrumentDiagram(props: Props) { - const { channels } = props - const imgSrc = channels === 1 ? singleSrc : multiSrc + const { pipetteSpecs, mount } = props + const { displayCategory, channels } = pipetteSpecs || {} + let imgSrc + switch (displayCategory) { + case 'GEN2': { + imgSrc = channels === 1 ? singleGEN2Src : multiGEN2Src + break + } + default: + case 'OG': { + imgSrc = channels === 1 ? singleSrc : multiSrc + } + } return (
- +
) } diff --git a/components/src/instrument-diagram/InstrumentDiagram.md b/components/src/instrument-diagram/InstrumentDiagram.md index df326d1e91e..618dffd0711 100644 --- a/components/src/instrument-diagram/InstrumentDiagram.md +++ b/components/src/instrument-diagram/InstrumentDiagram.md @@ -1,11 +1,32 @@ -Single channel: +Single channel OG: + +````js +``` + +Multi channel OG: + +```js +``` + +Single channel GEN2: ```js - -``` +``` -Multi channel: +Multi channel GEN2: ```js - -``` +``` +```` diff --git a/components/src/instrument-diagram/InstrumentGroup.md b/components/src/instrument-diagram/InstrumentGroup.md index 6d6e49e348f..c327e169c1a 100644 --- a/components/src/instrument-diagram/InstrumentGroup.md +++ b/components/src/instrument-diagram/InstrumentGroup.md @@ -3,14 +3,12 @@ left={{ mount: 'left', description: 'p300 8-Channel', - tipType: '150', - channels: 8, + pipetteSpecs: { channels: 8, displayCategory: 'OG' }, }} right={{ mount: 'right', description: 'p10 Single', - tipType: '10', - channels: 1, + pipetteSpecs: { channels: 1, displayCategory: 'GEN2' }, isDisabled: true, }} /> diff --git a/components/src/instrument-diagram/InstrumentInfo.js b/components/src/instrument-diagram/InstrumentInfo.js index 0b7ffdec850..603ba134345 100644 --- a/components/src/instrument-diagram/InstrumentInfo.js +++ b/components/src/instrument-diagram/InstrumentInfo.js @@ -1,6 +1,10 @@ // @flow import * as React from 'react' import cx from 'classnames' +import type { + PipetteNameSpecs, + PipetteModelSpecs, +} from '@opentrons/shared-data' import type { Mount } from '../robot-types' import InfoItem from './InfoItem.js' @@ -19,8 +23,8 @@ export type InstrumentInfoProps = {| tiprackModel?: string, /** if disabled, pipette & its info are grayed out */ isDisabled: boolean, - /** usually 1 or 8 */ - channels?: number, + /** specs of mounted pipette */ + pipetteSpecs?: ?PipetteModelSpecs | ?PipetteNameSpecs, /** classes to apply */ className?: string, /** classes to apply to the info group child */ @@ -49,10 +53,11 @@ export default function InstrumentInfo(props: InstrumentInfoProps) { )} {props.children} - {props.channels && ( + {props.pipetteSpecs && ( )} diff --git a/components/src/instrument-diagram/instrument.css b/components/src/instrument-diagram/instrument.css index d0f06b815c8..30cdaae87a0 100644 --- a/components/src/instrument-diagram/instrument.css +++ b/components/src/instrument-diagram/instrument.css @@ -36,6 +36,11 @@ min-height: 8rem; } +.flipped_image { + transform: scaleX(-1); + filter: FlipH; +} + .pipette_icon { grid-area: img; text-align: center; diff --git a/components/src/instrument-diagram/pipetteGEN2Multi.png b/components/src/instrument-diagram/pipetteGEN2Multi.png new file mode 100755 index 00000000000..138b48f3664 Binary files /dev/null and b/components/src/instrument-diagram/pipetteGEN2Multi.png differ diff --git a/components/src/instrument-diagram/pipetteGEN2Single.png b/components/src/instrument-diagram/pipetteGEN2Single.png new file mode 100755 index 00000000000..03ef95d1e18 Binary files /dev/null and b/components/src/instrument-diagram/pipetteGEN2Single.png differ diff --git a/protocol-designer/src/components/modals/FilePipettesModal/PipetteDiagram.js b/protocol-designer/src/components/modals/FilePipettesModal/PipetteDiagram.js index 3b9d85e1c1f..72d90d0ef4c 100644 --- a/protocol-designer/src/components/modals/FilePipettesModal/PipetteDiagram.js +++ b/protocol-designer/src/components/modals/FilePipettesModal/PipetteDiagram.js @@ -5,36 +5,31 @@ import * as React from 'react' import styles from './FilePipettesModal.css' import { InstrumentDiagram } from '@opentrons/components' -function getChannels(pipetteName: ?string): ?number { - if (!pipetteName) return null - - const pipetteData = getPipetteNameSpecs(pipetteName) - return (pipetteData && pipetteData.channels) || null -} - type Props = { leftPipette: ?string, rightPipette: ?string, } export default function PipetteDiagram(props: Props) { const { leftPipette, rightPipette } = props - const leftChannels = getChannels(leftPipette) - const rightChannels = getChannels(rightPipette) + const leftSpecs = leftPipette && getPipetteNameSpecs(leftPipette) + const rightSpecs = rightPipette && getPipetteNameSpecs(rightPipette) return ( - {leftPipette && leftChannels ? ( + {leftPipette && leftSpecs ? ( ) : (
)} - {rightPipette && rightChannels ? ( + {rightPipette && rightSpecs ? ( ) : (
diff --git a/protocol-designer/src/step-forms/selectors/index.js b/protocol-designer/src/step-forms/selectors/index.js index 78e6bda6149..c0c7165b668 100644 --- a/protocol-designer/src/step-forms/selectors/index.js +++ b/protocol-designer/src/step-forms/selectors/index.js @@ -226,7 +226,7 @@ export const getPipettesForInstrumentGroup: Selector const pipetteForInstrumentGroup: InstrumentInfoProps = { mount: pipetteOnDeck.mount, - channels: pipetteSpec ? pipetteSpec.channels : undefined, + pipetteSpecs: pipetteSpec, description: _getPipetteDisplayName(pipetteOnDeck.name), isDisabled: false, tiprackModel: getLabwareDisplayName(tiprackDef), diff --git a/shared-data/js/pipettes.js b/shared-data/js/pipettes.js index c72b2bc8b13..52eba9f8720 100644 --- a/shared-data/js/pipettes.js +++ b/shared-data/js/pipettes.js @@ -3,11 +3,12 @@ import pipetteNameSpecs from '../pipette/definitions/pipetteNameSpecs.json' import pipetteModelSpecs from '../pipette/definitions/pipetteModelSpecs.json' export type PipetteChannels = 1 | 8 +export type PipetteDisplayCategory = 'OG' | 'GEN2' export type PipetteNameSpecs = { name: string, displayName: string, - displayCategory: ?string, + displayCategory?: PipetteDisplayCategory, minVolume: number, maxVolume: number, defaultAspirateFlowRate: { value: number },