Skip to content

Commit

Permalink
feat(protocol-designer): update mix form design (#3247)
Browse files Browse the repository at this point in the history
Closes #3141
  • Loading branch information
IanLondon authored Mar 25, 2019
1 parent 7d09d0a commit 57ee363
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 105 deletions.
7 changes: 6 additions & 1 deletion components/src/forms/forms.css
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@
background-color: var(--c-warning-light);
}

.dropdown {
background-color: var(--c-light-gray);
}

.dropdown_field {
position: relative;

Expand Down Expand Up @@ -211,7 +215,8 @@
}

/* stylelint-disable no-descending-specificity */
& input {
& input,
& .suffix {
color: var(--c-med-gray);
}
}
19 changes: 1 addition & 18 deletions protocol-designer/src/components/StepEditForm/StepEditForm.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,8 @@
justify-content: flex-start;
}

/* TODO: Ian 2019-03-14 delete probably (just used for Mix) */
.fixed_width {
width: 17rem;
}

.field,
.small_field,
.medium_field,
.large_field {
margin-right: 0.5rem;
}
Expand All @@ -43,11 +37,6 @@
width: 12rem;
}

/* TODO Ian 2019-03-15: needed in mix form before update. When you do mix form, delete this if it's not needed */
.medium_field {
width: 8rem;
}

.small_field {
width: 5.75rem;
}
Expand All @@ -71,13 +60,6 @@
margin-bottom: 1rem;
}

/* TODO Ian 2019-03-14: probably delete this */
.mix_hidden_fields {
margin: 0 0 0 1rem;
min-width: 0;
width: 14rem;
}

.no_label {
margin-top: 0.5rem;
}
Expand Down Expand Up @@ -116,6 +98,7 @@
display: flex;
justify-content: space-between;
margin-bottom: 0.5rem;
min-height: 4rem;
}

.section_column {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// @flow
import * as React from 'react'
import {IconButton, HoverTooltip} from '@opentrons/components'
import i18n from '../../../localization'
import styles from '../StepEditForm.css'

type Props = {
className?: ?string,
collapsed?: ?boolean,
toggleCollapsed: () => mixed,
prefix: 'aspirate' | 'dispense',
children?: React.Node,
}

function AspDispSection (props: Props) {
const {children, className, collapsed, toggleCollapsed, prefix} = props

return (
<div className={className}>
<div className={styles.section_header}>
<span className={styles.section_header_text}>{prefix}</span>
<HoverTooltip
key={collapsed ? 'collapsed' : 'expanded'} // NOTE: without this key, the IconButton will not re-render unless clicked
tooltipComponent={i18n.t('tooltip.advanced_settings')}>
{(hoverTooltipHandlers) => (
<div {...hoverTooltipHandlers} onClick={toggleCollapsed} className={styles.advanced_settings_button_wrapper}>
<IconButton className={styles.advanced_settings_button} name="settings" hover={!collapsed} />
</div>
)}
</HoverTooltip>
</div>
{children}
</div>
)
}

export default AspDispSection
147 changes: 84 additions & 63 deletions protocol-designer/src/components/StepEditForm/forms/Mix.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
// @flow
import * as React from 'react'
import cx from 'classnames'
import {FormGroup, IconButton, HoverTooltip} from '@opentrons/components'
import {FormGroup} from '@opentrons/components'
import AspDispSection from './AspDispSection'

import i18n from '../../../localization'

import formStyles from '../../forms/forms.css'

import {
TextField,
CheckboxRowField,
Expand All @@ -30,83 +29,105 @@ type State = {collapsed?: boolean}
class MixForm extends React.Component<Props, State> {
state = {collapsed: true}

handleClick = (e: SyntheticEvent<>) => {
toggleCollapsed = () => {
this.setState({collapsed: !this.state.collapsed})
}
render () {
const {focusHandlers} = this.props
const {collapsed} = this.state
return (
<React.Fragment>
<div className={cx(styles.form_row, styles.start_group)}>
<PipetteField name="pipette" {...focusHandlers} />
<VolumeField label="Mix Vol:" focusHandlers={focusHandlers} stepType="mix" />
<FormGroup label='Repetitions:' className={styles.small_field}>
<TextField name="times" units='times' {...focusHandlers} />
<div className={styles.form_wrapper}>
<div className={styles.section_header}>
<span className={styles.section_header_text}>
{i18n.t('application.stepType.mix')}
</span>
</div>
<div className={styles.form_row}>
<PipetteField className={styles.large_field} name="pipette" {...focusHandlers} />
<VolumeField
label={i18n.t('form.step_edit_form.mixVolumeLabel')}
focusHandlers={focusHandlers} stepType="mix" />
<FormGroup
className={styles.small_field}
label={i18n.t('form.step_edit_form.mixRepetitions')}>
<TextField name="times" units={i18n.t('application.units.times')} {...focusHandlers} />
</FormGroup>
</div>
<div className={styles.form_row}>
<FormGroup label={i18n.t('form.step_edit_form.labwareLabel.mixLabware')} className={styles.large_field} >
<LabwareField name="labware" {...focusHandlers} />
</FormGroup>
<WellSelectionField name="wells" labwareFieldName="labware" pipetteFieldName="pipette" {...focusHandlers} />
</div>
<div className={styles.section_divider}></div>

<div className={styles.form_row}>
<div className={styles.start_group}>
<FormGroup label='Labware:'>
<LabwareField name="labware" {...focusHandlers} />
</FormGroup>
<WellSelectionField name="wells" labwareFieldName="labware" pipetteFieldName="pipette" {...focusHandlers} />
<WellOrderField prefix="mix" />
</div>
<div className={cx(styles.end_group, styles.fixed_width)}>
<FlowRateField
name='aspirate_flowRate'
label='Aspirate Flow Rate'
pipetteFieldName='pipette'
className={styles.medium_field}
flowRateType='aspirate' />
<TipPositionField fieldName="mix_mmFromBottom" />
</div>
<div className={styles.fixed_width}></div>
<div className={styles.section_wrapper}>
<AspDispSection
className={styles.section_column}
prefix='aspirate'
collapsed={collapsed}
toggleCollapsed={this.toggleCollapsed} />
<AspDispSection
className={styles.section_column}
prefix='dispense'
collapsed={collapsed}
toggleCollapsed={this.toggleCollapsed} />
</div>
<div className={cx(styles.form_row, styles.end_group)}>
<div className={cx(styles.end_group, styles.fixed_width)}>
<FlowRateField
name='dispense_flowRate'
label='Dispense Flow Rate'
pipetteFieldName='pipette'
className={styles.medium_field}
flowRateType='dispense' />
<div className={styles.small_field}></div>

{!collapsed && <div className={cx(styles.section_wrapper, styles.advanced_settings_panel)}>
<div className={styles.section_column}>
<div className={styles.form_row}>
<FlowRateField
name='aspirate_flowRate'
pipetteFieldName='pipette'
flowRateType='aspirate' />
<TipPositionField fieldName='mix_mmFromBottom' />
<WellOrderField prefix='mix' label={i18n.t('form.step_edit_form.field.well_order.label')} />
</div>
</div>

<div className={cx(styles.start_group, styles.wrap_group, styles.fixed_width)}>
<HoverTooltip tooltipComponent={i18n.t('tooltip.advanced_settings')}>
{(hoverTooltipHandlers) => (
<div {...hoverTooltipHandlers} onClick={this.handleClick} className={styles.advanced_settings_button_wrapper}>
<IconButton className={styles.advanced_settings_button} name="settings" hover={!this.state.collapsed} />
</div>
)}
</HoverTooltip>
<div className={styles.mix_hidden_fields}>
{this.state.collapsed !== true &&
<FormGroup label="Dispense Options">
<CheckboxRowField name={'mix_touchTip_checkbox'} label="Touch tip">
<TipPositionField className={cx(styles.small_field, styles.orphan_field)} fieldName={'mix_touchTip_mmFromBottom'} />
</CheckboxRowField>
<div className={styles.section_column}>
<div className={styles.form_row}>
<FlowRateField
name='dispense_flowRate'
pipetteFieldName='pipette'
flowRateType='dispense' />
</div>
<div className={styles.checkbox_column}>
<CheckboxRowField
className={styles.small_field}
label={i18n.t('form.step_edit_form.field.touchTip.label')}
name={'mix_touchTip_checkbox'}
>
<TipPositionField fieldName={'mix_touchTip_mmFromBottom'} />
</CheckboxRowField>

<CheckboxRowField name='blowout_checkbox' label='Blow out'>
<BlowoutLocationField
name="blowout_location"
className={cx(styles.medium_field, styles.orphan_field)}
{...focusHandlers} />
</CheckboxRowField>
</FormGroup>
}
<CheckboxRowField
className={styles.small_field}
label={i18n.t('form.step_edit_form.field.blowout.label')}
name='blowout_checkbox'
>
<BlowoutLocationField
className={styles.full_width}
name="blowout_location"
{...focusHandlers} />
</CheckboxRowField>
</div>
</div>
</div>
</div>}

<div className={formStyles.form_row}>
<ChangeTipField stepType="mix" name="changeTip" />
<div className={styles.section_header}>
<span className={styles.section_header_text}>
{i18n.t('form.step_edit_form.section.sterility')}
</span>
</div>
<div className={styles.section_wrapper}>
<div className={styles.form_row}>
<ChangeTipField stepType="mix" name="changeTip" />
</div>
</div>
</React.Fragment>

</div>
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
// @flow
import * as React from 'react'
import {FormGroup, IconButton, HoverTooltip} from '@opentrons/components'

import type {StepFieldName} from '../../../../steplist/fieldLevel'
import {FormGroup} from '@opentrons/components'
import i18n from '../../../../localization'

import type {FocusHandlers} from '../../types'

import {
LabwareField,
WellSelectionField,
} from '../../fields'
import AspDispSection from '../AspDispSection'

import type {StepFieldName} from '../../../../steplist/fieldLevel'
import type {FocusHandlers} from '../../types'

import styles from '../../StepEditForm.css'

Expand All @@ -30,19 +29,7 @@ function SourceDestHeaders (props: Props) {
const labwareLabel = i18n.t(`form.step_edit_form.labwareLabel.${prefix}`)

return (
<div className={className}>
<div className={styles.section_header}>
<span className={styles.section_header_text}>{prefix}</span>
<HoverTooltip
key={collapsed ? 'collapsed' : 'expanded'} // NOTE: without this key, the IconButton will not re-render unless clicked
tooltipComponent={i18n.t('tooltip.advanced_settings')}>
{(hoverTooltipHandlers) => (
<div {...hoverTooltipHandlers} onClick={toggleCollapsed} className={styles.advanced_settings_button_wrapper}>
<IconButton className={styles.advanced_settings_button} name="settings" hover={!collapsed} />
</div>
)}
</HoverTooltip>
</div>
<AspDispSection {...{className, collapsed, toggleCollapsed, prefix}}>
<div className={styles.form_row}>
<FormGroup label={labwareLabel}>
<LabwareField name={addFieldNamePrefix('labware')} {...focusHandlers} />
Expand All @@ -53,7 +40,7 @@ function SourceDestHeaders (props: Props) {
pipetteFieldName="pipette"
{...focusHandlers} />
</div>
</div>
</AspDispSection>
)
}

Expand Down
2 changes: 1 addition & 1 deletion protocol-designer/src/localization/en/application.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"units": {
"microliter": "μL",
"microliterPerSec": "μL/s",
"times": "times"
"times": "x"
},
"version": "Protocol Designer Version",
"beta": "beta",
Expand Down
6 changes: 5 additions & 1 deletion protocol-designer/src/localization/en/form.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,16 @@
},
"step_edit_form": {
"section": {
"sterility": "sterility",
"sterility&motion": "sterility & motion"
},
"labwareLabel": {
"aspirate": "source",
"dispense": "destination"
"dispense": "destination",
"mixLabware": "labware"
},
"mixVolumeLabel": "mix volume",
"mixRepetitions": "repetitions",
"multiDispenseOptionsLabel": "multi-dispense options",
"wellSelectionLabel": {
"columns": "columns",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@ export default function getDisabledFieldsMixForm (
): Set<string> {
const disabled = new Set()

if (!rawForm.pipette || !rawForm['labware']) {
if (!rawForm.pipette || !rawForm.labware) {
disabled.add('mix_touchTip_checkbox')
disabled.add('mix_mmFromBottom')
disabled.add('wells')
}

if (!rawForm.pipette) {
disabled.add('aspirate_flowRate')
disabled.add('dispense_flowRate')
}

return disabled
}

0 comments on commit 57ee363

Please sign in to comment.