Skip to content

Commit

Permalink
feat(app): Display reachable but non-connectable robots (#2455)
Browse files Browse the repository at this point in the history
Closes #2345
  • Loading branch information
Kadee80 authored and mcous committed Oct 10, 2018
1 parent e4418e5 commit 8785ea8
Show file tree
Hide file tree
Showing 40 changed files with 658 additions and 498 deletions.
28 changes: 25 additions & 3 deletions app/src/analytics/__tests__/make-event.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,38 @@ describe('analytics events map', () => {
})

test('robot:CONNECT_RESPONSE -> robotConnected event', () => {
const state = (name) => ({
const state = name => ({
robot: {
connection: {
connectRequest: {name},
},
},
discovery: {
robotsByName: {
wired: [{ip: 'foo', port: 123, ok: true, local: true}],
wireless: [{ip: 'bar', port: 456, ok: true, local: false}],
wired: [
{
name: 'wired',
ip: 'foo',
port: 123,
ok: true,
serverOk: true,
local: true,
health: {},
serverHealth: {},
},
],
wireless: [
{
name: 'wireless',
ip: 'bar',
port: 456,
ok: true,
serverOk: true,
local: false,
health: {},
serverHealth: {},
},
],
},
},
})
Expand Down
6 changes: 3 additions & 3 deletions app/src/analytics/make-event.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// redux action types to analytics events map
import createLogger from '../logger'
import {selectors as robotSelectors} from '../robot'
import {getConnectableRobots} from '../discovery'

import type {State, Action} from '../types'

Expand All @@ -19,8 +20,7 @@ export default function makeEvent (state: State, action: Action): ?Event {

case 'robot:CONNECT_RESPONSE':
const name = state.robot.connection.connectRequest.name
const robot = robotSelectors.getDiscovered(state)
.find(r => r.name === name)
const robot = getConnectableRobots(state).find(r => r.name === name)

if (!robot) {
log.warn('No robot found for connect response')
Expand All @@ -31,7 +31,7 @@ export default function makeEvent (state: State, action: Action): ?Event {
name: 'robotConnect',
properties: {
success: !action.payload.error,
method: robot.wired ? 'usb' : 'wifi',
method: robot.local ? 'usb' : 'wifi',
error: (action.payload.error && action.payload.error.message) || '',
},
}
Expand Down
3 changes: 2 additions & 1 deletion app/src/components/ChangePipette/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {getPipette, getPipetteNames} from '@opentrons/shared-data'

import type {PipetteConfig} from '@opentrons/shared-data'
import type {State, Dispatch} from '../../types'
import type {Robot, Mount} from '../../robot'
import type {Mount} from '../../robot'
import type {Robot} from '../../discovery'
import type {Direction, ChangePipetteProps} from './types'

import type {RobotHome, RobotMove} from '../../http-api-client'
Expand Down
5 changes: 2 additions & 3 deletions app/src/components/ConnectPanel/RobotItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ import {connect} from 'react-redux'
import {withRouter, type ContextRouter} from 'react-router'

import type {State, Dispatch} from '../../types'
import type {Robot} from '../../discovery'
import type {ViewableRobot} from '../../discovery'
import {actions as robotActions, selectors as robotSelectors} from '../../robot'
import {makeGetRobotUpdateInfo} from '../../http-api-client'

import {RobotListItem} from './RobotListItem.js'

type OP = {|
...$Exact<Robot>,
...$Exact<ViewableRobot>,
...ContextRouter,
|}

Expand Down
2 changes: 1 addition & 1 deletion app/src/components/ConnectPanel/RobotLink.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {NavLink} from 'react-router-dom'

import type {HoverTooltipHandlers} from '@opentrons/components'
import cx from 'classnames'
import styles from './connect-panel.css'
import styles from './styles.css'

type LinkProps = {
children: React.Node,
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/ConnectPanel/RobotList.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @flow
// list of robots
import * as React from 'react'
import styles from './connect-panel.css'
import styles from './styles.css'

type ListProps = {
children: React.Node,
Expand Down
93 changes: 19 additions & 74 deletions app/src/components/ConnectPanel/RobotListItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
import * as React from 'react'
import {NotificationIcon, Icon} from '@opentrons/components'

import {CONNECTABLE} from '../../discovery'
import {ToggleButton} from '../controls'
import RobotLink from './RobotLink'
import styles from './connect-panel.css'
import styles from './styles.css'

// circular type dependency, thanks flow
import type {RobotItemProps} from './RobotItem'
Expand All @@ -14,34 +15,40 @@ export function RobotListItem (props: RobotItemProps) {
const {
name,
local,
status,
connected,
selected,
upgradable,
connect,
disconnect,
} = props
const connectable = status === CONNECTABLE
const onClick = connected ? disconnect : connect

return (
<li className={styles.robot_group}>
<React.Fragment>
<RobotLink url={`/robots/${name}`} className={styles.robot_item} exact>
<NotificationIcon
name={local ? 'usb' : 'wifi'}
className={styles.robot_item_icon}
childName={upgradable ? 'circle' : null}
childClassName={styles.notification}
/>
<RobotLink url={`/robots/${name}`} className={styles.robot_item} exact>
<NotificationIcon
name={local ? 'usb' : 'wifi'}
className={styles.robot_item_icon}
childName={upgradable ? 'circle' : null}
childClassName={styles.notification}
/>

<p className={styles.link_text}>{name}</p>
<p className={styles.link_text}>{name}</p>

{connectable ? (
<ToggleButton
toggledOn={connected}
onClick={onClick}
className={styles.robot_item_icon}
/>
</RobotLink>
{selected && (
) : (
<Icon name="chevron-right" className={styles.robot_item_icon} />
)}
</RobotLink>
{connectable &&
selected && (
<RobotLink
url={`/robots/${name}/instruments`}
className={styles.instrument_item}
Expand All @@ -50,68 +57,6 @@ export function RobotListItem (props: RobotItemProps) {
<Icon name="chevron-right" className={styles.robot_item_icon} />
</RobotLink>
)}
</React.Fragment>
</li>
)
}

// TODO (ka 2018-10-5): Separate Connectable and Reachable Robots
// export function ConnectableRobot (props: ItemProps) {
// const {
// name,
// wired,
// selected,
// isConnected,
// upgradable,
// connect,
// disconnect,
// } = props
// const onClick = isConnected ? disconnect : connect
// return (
// <React.Fragment>
// <RobotLink url={`/robots/${name}`} className={styles.robot_item} exact>
// <NotificationIcon
// name={wired ? 'usb' : 'wifi'}
// className={styles.robot_item_icon}
// childName={upgradable ? 'circle' : null}
// childClassName={styles.notification}
// />
//
// <p className={styles.link_text}>{name}</p>
//
// <ToggleButton
// toggledOn={isConnected}
// onClick={onClick}
// className={styles.robot_item_icon}
// />
// </RobotLink>
// {selected && (
// <RobotLink
// url={`/robots/${name}/instruments`}
// className={styles.instrument_item}
// >
// <p className={styles.link_text}>Pipettes & Modules</p>
// <Icon name="chevron-right" className={styles.robot_item_icon} />
// </RobotLink>
// )}
// </React.Fragment>
// )
// }

// export function ReachableRobotItem (props: ReachableProps) {
// const {name, wired, upgradable} = props
// return (
// <RobotLink url={`/robots/${name}`} className={styles.robot_item} exact>
// <NotificationIcon
// name={wired ? 'usb' : 'wifi'}
// className={styles.robot_item_icon}
// childName={upgradable ? 'circle' : null}
// childClassName={styles.notification}
// />
//
// <p className={styles.link_text}>{name}</p>
//
// <Icon name="chevron-right" className={styles.robot_item_icon} />
// </RobotLink>
// )
// }
2 changes: 1 addition & 1 deletion app/src/components/ConnectPanel/ScanButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import * as React from 'react'
import {Icon, PrimaryButton} from '@opentrons/components'

import styles from './connect-panel.css'
import styles from './styles.css'

type Props = {
isScanning: boolean,
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/ConnectPanel/ScanStatus.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as React from 'react'

import ScanButton from './ScanButton'

import styles from './connect-panel.css'
import styles from './styles.css'

type Props = {
onScanClick: () => mixed,
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/ConnectPanel/UnreachableRobotItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as React from 'react'
import type {UnreachableRobot} from '../../discovery'
import {Icon, HoverTooltip} from '@opentrons/components'
import RobotLink from './RobotLink'
import styles from './connect-panel.css'
import styles from './styles.css'

export default function UnreachableRobotItem (props: UnreachableRobot) {
const {name} = props
Expand Down
30 changes: 16 additions & 14 deletions app/src/components/ConnectPanel/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// @flow
import * as React from 'react'
import {connect} from 'react-redux'
import orderBy from 'lodash/orderBy'

import type {State, Dispatch} from '../../types'

Expand Down Expand Up @@ -48,29 +49,30 @@ function ConnectPanel (props: Props) {
<ScanStatus {...props} />
<RobotList>
{props.robots.map(robot => <RobotItem key={robot.name} {...robot} />)}
{props.reachableRobots
.concat(props.unreachableRobots)
.map(robot => <UnreachableRobotItem key={robot.name} {...robot} />)}
{/*
{props.connectableRobots.map((robot) => (
<RobotItem key={robot.name} {...robot} />
))}
{props.reachableRobots.map((robot) => (
<RobotItem key={robot.name} {...robot} />
))}
*/}
{props.reachableRobots.map(robot => (
<RobotItem key={robot.name} {...robot} />
))}
{props.unreachableRobots.map(robot => (
<UnreachableRobotItem key={robot.name} {...robot} />
))}
</RobotList>
</SidePanel>
)
}

const robotOrder = [['connected', 'local', 'name'], ['desc', 'desc', 'asc']]
const reachableOrder = [['local', 'name'], ['desc', 'asc']]
const unreachableOrder = [['name'], ['asc']]

function mapStateToProps (state: State): StateProps {
const robots = getConnectableRobots(state)
const reachableRobots = getReachableRobots(state)
const unreachableRobots = getUnreachableRobots(state)

return {
robots,
reachableRobots: getReachableRobots(state),
unreachableRobots: getUnreachableRobots(state),
robots: orderBy(robots, ...robotOrder),
reachableRobots: orderBy(reachableRobots, ...reachableOrder),
unreachableRobots: orderBy(unreachableRobots, ...unreachableOrder),
found: robots.length > 0,
isScanning: getScanning(state),
}
Expand Down
File renamed without changes.
8 changes: 4 additions & 4 deletions app/src/components/InstrumentSettings/AttachedModulesCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
import * as React from 'react'
import {connect} from 'react-redux'

import type {State, Dispatch} from '../../types'
import type {Module} from '../../http-api-client'
import type {Robot} from '../../robot'

import {RefreshCard} from '@opentrons/components'
import {fetchModules, makeGetRobotModules} from '../../http-api-client'
import ModulesCardContents from './ModulesCardContents'

import type {State, Dispatch} from '../../types'
import type {Module} from '../../http-api-client'
import type {Robot} from '../../discovery'

type OP = Robot

type SP = {
Expand Down
8 changes: 4 additions & 4 deletions app/src/components/InstrumentSettings/AttachedPipettesCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
import * as React from 'react'
import {connect} from 'react-redux'

import type {State} from '../../types'
import type {Robot} from '../../robot'
import type {Pipette} from '../../http-api-client'
import {makeGetRobotPipettes, fetchPipettes, clearMoveResponse} from '../../http-api-client'

import InstrumentInfo from './InstrumentInfo'
import {CardContentFlex} from '../layout'
import {RefreshCard} from '@opentrons/components'

import type {State} from '../../types'
import type {Robot} from '../../discovery'
import type {Pipette} from '../../http-api-client'

type OP = Robot

type SP = {
Expand Down
4 changes: 2 additions & 2 deletions app/src/components/InstrumentSettings/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
// robot status panel with connect button
import * as React from 'react'

import type {Robot} from '../../robot'

import AttachedPipettesCard from './AttachedPipettesCard'
import AttachedModulesCard from './AttachedModulesCard'
import {CardContainer, CardRow} from '../layout'

import type {Robot} from '../../discovery'

type Props = Robot

export default function InstrumentSettings (props: Props) {
Expand Down
Loading

0 comments on commit 8785ea8

Please sign in to comment.