diff --git a/app/src/components/InstrumentSettings/AttachedModulesCard.js b/app/src/components/InstrumentSettings/AttachedModulesCard.js index 8e9841e0316..5e08d59372d 100644 --- a/app/src/components/InstrumentSettings/AttachedModulesCard.js +++ b/app/src/components/InstrumentSettings/AttachedModulesCard.js @@ -4,23 +4,15 @@ import * as React from 'react' import {connect} from 'react-redux' import type {State} from '../../types' - +import type {Module} from '../../http-api-client' import {Card} from '@opentrons/components' import {getModulesOn} from '../../config' import ModulesCardContents from './ModulesCardContents' -type Module = { - slot: number, - name: string, - status: string, - serial: number, - fw_version: string -} - type SP = { modulesFlag: ?boolean, inProgress?: ?boolean, - modules?: Array, // modulesBySlot? + modules?: Array, fetchModules?: () => mixed } @@ -28,6 +20,24 @@ type Props = SP const TITLE = 'Modules' +const STUBBED_MODULE_DATA = [ + { + name: 'temp_deck', + model: 'temp_deck', + serial: '123123124', + fwVersion: '1.2.13', + status: '86', + displayName: 'Temperature Module' + }, + { + name: 'mag_deck', + model: 'mag_deck', + serial: '123123124', + fwVersion: '1.2.13', + status: 'disengaged', + displayName: 'Magnetic Bead Module' + } +] export default connect(mapStateToProps, null)(AttachedModulesCard) // TODO (ka 2018-6-29): change this to a refresh card once we have endpoints @@ -38,7 +48,7 @@ function AttachedModulesCard (props: Props) { title={TITLE} column > - + ) } @@ -47,6 +57,7 @@ function AttachedModulesCard (props: Props) { function mapStateToProps (state: State): SP { return { - modulesFlag: getModulesOn(state) + modulesFlag: getModulesOn(state), + modules: STUBBED_MODULE_DATA } } diff --git a/app/src/components/InstrumentSettings/ModulesCardContents.js b/app/src/components/InstrumentSettings/ModulesCardContents.js index ee9fd88e49c..c66ad00d0fc 100644 --- a/app/src/components/InstrumentSettings/ModulesCardContents.js +++ b/app/src/components/InstrumentSettings/ModulesCardContents.js @@ -1,18 +1,22 @@ // @flow import * as React from 'react' -import styles from './styles.css' +import type {Module} from '../../http-api-client' +import ModuleItem, {NoModulesMessage} from '../ModuleItem' type Props = { - modules?: any + modules: Array, } export default function ModulesCardContents (props: Props) { - return ( - -

No modules detected.

- -

Connect a module to your robot via USB, then power it on. - Press the refresh icon to the top to detect your module.

-
- ) + const modulesFound = props.modules[0] + if (modulesFound) { + return ( + + {props.modules.map((mod, index) => ( + + ))} + + ) + } + return () } diff --git a/app/src/components/InstrumentSettings/styles.css b/app/src/components/InstrumentSettings/styles.css index a3ec1b0f247..5209751a895 100644 --- a/app/src/components/InstrumentSettings/styles.css +++ b/app/src/components/InstrumentSettings/styles.css @@ -47,9 +47,3 @@ order: 3; } } - -.modules_description { - @apply --font-body-2-dark; - - margin: 0.5rem 0; -} diff --git a/app/src/components/ModuleItem/ModuleImage.js b/app/src/components/ModuleItem/ModuleImage.js new file mode 100644 index 00000000000..4598f34d424 --- /dev/null +++ b/app/src/components/ModuleItem/ModuleImage.js @@ -0,0 +1,27 @@ +// @flow +import * as React from 'react' + +import styles from './styles.css' + +type Props = { + name: string +} + +export default function ModuleImage (props: Props) { + const imgSrc = getModuleImg(props.name) + return ( +
+ +
+ ) +} + +function getModuleImg (name: string) { + return MODULE_IMGS[name] +} + +// TODO (ka 2018-7-10): replace with design assets onces available +const MODULE_IMGS = { + 'temp_deck': require('./images/module-temp@3x.png'), + 'mag_deck': require('./images/module-mag@3x.png') +} diff --git a/app/src/components/ModuleItem/ModuleInfo.js b/app/src/components/ModuleItem/ModuleInfo.js new file mode 100644 index 00000000000..0ba8319cfde --- /dev/null +++ b/app/src/components/ModuleItem/ModuleInfo.js @@ -0,0 +1,23 @@ +// @flow +import * as React from 'react' + +import type {Module} from '../../http-api-client' + +import {LabeledValue} from '@opentrons/components' + +import styles from './styles.css' + +export default function ModuleInfo (props: Module) { + return ( +
+
+ + +
+
+ + +
+
+ ) +} diff --git a/app/src/components/ModuleItem/ModuleUpdate.js b/app/src/components/ModuleItem/ModuleUpdate.js new file mode 100644 index 00000000000..cdb09948502 --- /dev/null +++ b/app/src/components/ModuleItem/ModuleUpdate.js @@ -0,0 +1,26 @@ +// @flow +import * as React from 'react' + +import {OutlineButton} from '@opentrons/components' + +import styles from './styles.css' + +type Props = { + availableUpdate?: ?string +} + +export default function ModuleUpdate (props: Props) { + const {availableUpdate} = props + const buttonText = availableUpdate + ? 'update' + : 'updated' + return ( +
+ + {buttonText} + +
+ ) +} diff --git a/app/src/components/ModuleItem/NoModulesMessage.js b/app/src/components/ModuleItem/NoModulesMessage.js new file mode 100644 index 00000000000..7e530c01e99 --- /dev/null +++ b/app/src/components/ModuleItem/NoModulesMessage.js @@ -0,0 +1,14 @@ +// @flow +import * as React from 'react' +import styles from './styles.css' + +export default function NoModulesMessage () { + return ( + +

No modules detected.

+ +

Connect a module to your robot via USB, then power it on. + Press the refresh icon to the top to detect your module.

+
+ ) +} diff --git a/app/src/components/ModuleItem/images/module-mag@3x.png b/app/src/components/ModuleItem/images/module-mag@3x.png new file mode 100755 index 00000000000..339ad7901e6 Binary files /dev/null and b/app/src/components/ModuleItem/images/module-mag@3x.png differ diff --git a/app/src/components/ModuleItem/images/module-temp@3x.png b/app/src/components/ModuleItem/images/module-temp@3x.png new file mode 100755 index 00000000000..d5216a29c48 Binary files /dev/null and b/app/src/components/ModuleItem/images/module-temp@3x.png differ diff --git a/app/src/components/ModuleItem/index.js b/app/src/components/ModuleItem/index.js new file mode 100644 index 00000000000..2986b9d357b --- /dev/null +++ b/app/src/components/ModuleItem/index.js @@ -0,0 +1,27 @@ +// @flow +import * as React from 'react' + +import type {Module} from '../../http-api-client' + +import ModuleImage from './ModuleImage' +import ModuleInfo from './ModuleInfo' +import ModuleUpdate from './ModuleUpdate' +import NoModulesMessage from './NoModulesMessage' + +import styles from './styles.css' + +type Props = Module & { + availableUpdate?: ?string +} + +export default function ModuleItem (props: Props) { + return ( +
+ + + +
+ ) +} + +export {NoModulesMessage} diff --git a/app/src/components/ModuleItem/styles.css b/app/src/components/ModuleItem/styles.css new file mode 100644 index 00000000000..e9730f44c67 --- /dev/null +++ b/app/src/components/ModuleItem/styles.css @@ -0,0 +1,48 @@ +/* style sheet for module settings card on instrument settings page */ +@import '@opentrons/components'; + +.modules_description { + @apply --font-body-2-dark; + + margin: 0.5rem 0; +} + +.module_item { + width: 100%; + margin-bottom: 1rem; + display: flex; + justify-content: space-between; +} + +.module_image_wrapper { + flex-basis: 25%; + padding-right: 1rem; +} + +.module_image { + width: 100%; +} + +.module_info { + flex-basis: 55%; +} + +.grid_50 { + display: inline-block; + vertical-align: top; + width: calc(50% - 2rem); + margin: 0 1rem; + + & > div { + margin-bottom: 2rem; + } +} + +.module_update { + flex-basis: 20%; + padding-top: 4.5rem; + + & > button { + width: 8rem; + } +} diff --git a/app/src/components/layout/CardColumn.js b/app/src/components/layout/CardColumn.js index b7db6d9a530..defa072322b 100644 --- a/app/src/components/layout/CardColumn.js +++ b/app/src/components/layout/CardColumn.js @@ -3,9 +3,10 @@ import * as React from 'react' import styles from './styles.css' type Props = { - children: React.Node, + children: React.Node } -export default function CardRow (props: Props) { + +export default function CardColumn (props: Props) { return (
{props.children} diff --git a/app/src/http-api-client/modules.js b/app/src/http-api-client/modules.js index d76da17b5ae..fe77ac8479c 100644 --- a/app/src/http-api-client/modules.js +++ b/app/src/http-api-client/modules.js @@ -12,6 +12,7 @@ import {getRobotApiState} from './reducer' import client from './client' export type Module = { + name: string, model: string, serial: string, fwVersion: string,