Skip to content

Commit

Permalink
feat(app): Enable pipette config modal and form (#3202)
Browse files Browse the repository at this point in the history
closes #3112
  • Loading branch information
Kadee80 authored Mar 13, 2019
1 parent a9164c1 commit 49c1fe9
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 16 deletions.
33 changes: 29 additions & 4 deletions app/src/components/ConfigurePipette/ConfigForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import {Formik, Form} from 'formik'

import startCase from 'lodash/startCase'
import mapValues from 'lodash/mapValues'
import forOwn from 'lodash/forOwn'
import keys from 'lodash/keys'
import pick from 'lodash/pick'
import omit from 'lodash/omit'
import set from 'lodash/set'
import forOwn from 'lodash/forOwn'
import isEmpty from 'lodash/isEmpty'

import FormButtonBar from './FormButtonBar'
Expand All @@ -33,6 +35,7 @@ type Props = {
pipette: Pipette,
pipetteConfig: PipetteConfigResponse,
updateConfig: (id: string, PipetteConfigRequest) => mixed,
showHiddenFields: boolean,
}

const PLUNGER_KEYS = ['top', 'bottom', 'blowout', 'dropTip']
Expand All @@ -57,13 +60,24 @@ export default class ConfigForm extends React.Component<Props> {
}

getVisibleFields = () => {
if (this.props.showHiddenFields) return this.props.pipetteConfig.fields
return pick(this.props.pipetteConfig.fields, [
...PLUNGER_KEYS,
...POWER_KEYS,
...TIP_KEYS,
])
}

getUnknownKeys = () => {
return keys(
omit(this.props.pipetteConfig.fields, [
...PLUNGER_KEYS,
...POWER_KEYS,
...TIP_KEYS,
])
)
}

handleSubmit = (values: FormValues) => {
const params = mapValues(values, v => {
return v === '' ? null : {value: Number(v)}
Expand All @@ -89,14 +103,17 @@ export default class ConfigForm extends React.Component<Props> {

// validate all visible fields with min and max
forOwn(fields, (field, name) => {
const value = values[name]
const value = values[name].trim()
const {min, max} = field

if (value !== '') {
const parsed = Number(value)
if (Number.isNaN(parsed)) {
set(errors, name, `number required`)
} else if (min && max && (parsed < min || value > max)) {
} else if (
typeof min === 'number' &&
typeof max === 'number' &&
(parsed < min || value > max)
) {
set(errors, name, `Min ${min} / Max ${max}`)
}
}
Expand All @@ -118,12 +135,14 @@ export default class ConfigForm extends React.Component<Props> {
render () {
const {parentUrl} = this.props
const fields = this.getVisibleFields()
const UNKNOWN_KEYS = this.getUnknownKeys()
const initialValues = mapValues(fields, f => {
return f.value !== f.default ? f.value.toString() : ''
})
const plungerFields = this.getFieldsByKey(PLUNGER_KEYS, fields)
const powerFields = this.getFieldsByKey(POWER_KEYS, fields)
const tipFields = this.getFieldsByKey(TIP_KEYS, fields)
const devFields = this.getFieldsByKey(UNKNOWN_KEYS, fields)

return (
<Formik
Expand Down Expand Up @@ -154,6 +173,12 @@ export default class ConfigForm extends React.Component<Props> {
groupLabel="Tip Pickup / Drop "
formFields={tipFields}
/>
{this.props.showHiddenFields && (
<ConfigFormGroup
groupLabel="For Dev Use Only"
formFields={devFields}
/>
)}
</FormColumn>
<FormButtonBar
buttons={[
Expand Down
6 changes: 5 additions & 1 deletion app/src/components/ConfigurePipette/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import * as React from 'react'
import {connect} from 'react-redux'
import {push} from 'react-router-redux'

import {
makeGetRobotPipettes,
makeGetRobotPipetteConfigs,
Expand All @@ -11,6 +10,7 @@ import {
makeGetPipetteRequestById,
} from '../../http-api-client'
import {chainActions} from '../../util'
import {getConfig} from '../../config'

import {getPipetteModelSpecs} from '@opentrons/shared-data'

Expand Down Expand Up @@ -39,6 +39,7 @@ type SP = {|
pipette: ?Pipette,
pipetteConfig: ?PipetteConfigResponse,
configError: ?ApiRequestError,
__featureEnabled: boolean,
|}

type DP = {|
Expand Down Expand Up @@ -72,6 +73,7 @@ function ConfigurePipette (props: Props) {
pipetteConfig={pipetteConfig}
parentUrl={parentUrl}
updateConfig={updateConfig}
showHiddenFields={props.__featureEnabled}
/>
)}
</ScrollableAlertModal>
Expand All @@ -93,10 +95,12 @@ function makeMapStateToProps (): (state: State, ownProps: OP) => SP {
pipette && configResponse && configResponse[pipette.id]
const configSetConfigCall =
pipette && getPipetteRequestById(state, ownProps.robot, pipette.id)
const devInternal = getConfig(state).devInternal
return {
pipette,
pipetteConfig,
configError: configSetConfigCall && configSetConfigCall.error,
__featureEnabled: !!devInternal && !!devInternal.allPipetteConfig,
}
}
}
Expand Down
8 changes: 0 additions & 8 deletions app/src/components/InstrumentSettings/AttachedPipettesCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// attached pipettes container card
import * as React from 'react'
import {connect} from 'react-redux'
import {getIn} from '@thi.ng/paths'

import {
makeGetRobotPipettes,
Expand All @@ -20,7 +19,6 @@ import {Card, IntervalWrapper} from '@opentrons/components'
import type {State} from '../../types'
import type {Robot} from '../../discovery'
import type {Pipette} from '../../http-api-client'
import {getConfig} from '../../config'

type OP = Robot

Expand All @@ -29,7 +27,6 @@ type SP = {
left: ?Pipette,
right: ?Pipette,
showSettings: boolean,
__featureEnabled: boolean,
}

type DP = {
Expand All @@ -39,8 +36,6 @@ type DP = {

type Props = OP & SP & DP

const __FEATURE_FLAG = 'devInternal.newPipetteConfig'

const TITLE = 'Pipettes'

export default connect(
Expand All @@ -59,15 +54,13 @@ function AttachedPipettesCard (props: Props) {
{...props.left}
onChangeClick={props.clearMove}
showSettings={props.showSettings}
__enableConfig={props.__featureEnabled}
/>
<InstrumentInfo
mount="right"
name={props.name}
{...props.right}
onChangeClick={props.clearMove}
showSettings={props.showSettings}
__enableConfig={props.__featureEnabled}
/>
</CardContentFlex>
</Card>
Expand All @@ -88,7 +81,6 @@ function makeMapStateToProps (): (state: State, ownProps: OP) => SP {
left,
right,
showSettings: !!configCall.response,
__featureEnabled: !!getIn(getConfig(state), __FEATURE_FLAG),
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions app/src/components/InstrumentSettings/InstrumentInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ type Props = {
name: string,
onChangeClick: () => mixed,
showSettings: boolean,
__enableConfig: boolean,
}

// TODO(mc, 2018-03-30): volume and channels should come from the API
Expand Down Expand Up @@ -54,7 +53,7 @@ export default function PipetteInfo (props: Props) {
<OutlineButton Component={Link} to={changeUrl} onClick={onChangeClick}>
{direction}
</OutlineButton>
{props.__enableConfig && model && showSettings && (
{model && showSettings && (
<OutlineButton Component={Link} to={configUrl}>
settings
</OutlineButton>
Expand Down
2 changes: 1 addition & 1 deletion app/src/config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export type Config = {

// internal development flags
devInternal?: {
newPipetteConfig?: boolean,
allPipetteConfig?: boolean,
manualIp?: boolean,
},
}
Expand Down

0 comments on commit 49c1fe9

Please sign in to comment.