From 9070b213272b9c4fd9743532c0a95d603cf996db Mon Sep 17 00:00:00 2001 From: Katie Adee Date: Mon, 18 Jun 2018 13:00:33 -0400 Subject: [PATCH] refactor(app): Standardize modals and pages (#1705) * refactor(app): Standardize modals and pages --- app/src/components/App.js | 21 ++--- .../components/LabwareCalibration/index.js | 51 ++----------- .../components/LabwareCalibration/styles.css | 20 +---- app/src/components/Page.css | 5 -- app/src/components/Page.js | 16 ---- app/src/components/Page/PageWrapper.js | 20 +++++ app/src/components/Page/index.js | 25 ++++++ app/src/components/Page/styles.css | 17 +++++ app/src/components/RobotSettings/index.js | 6 +- app/src/components/SessionHeader/index.js | 7 +- app/src/pages/AppSettings.js | 76 ------------------- app/src/pages/Calibrate/Instruments.js | 9 ++- app/src/pages/Calibrate/Labware.js | 67 ++++++++++++---- app/src/pages/More/AppSettings.js | 12 ++- app/src/pages/More/Resources.js | 4 +- app/src/pages/Robots.js | 26 +++++-- app/src/pages/Run.js | 13 ++-- .../__snapshots__/modals.test.js.snap | 2 +- components/src/modals/ModalPage.js | 2 +- components/src/modals/modals.css | 18 ++++- components/src/styles/positioning.css | 6 ++ 21 files changed, 202 insertions(+), 221 deletions(-) delete mode 100644 app/src/components/Page.css delete mode 100644 app/src/components/Page.js create mode 100644 app/src/components/Page/PageWrapper.js create mode 100644 app/src/components/Page/index.js create mode 100644 app/src/components/Page/styles.css delete mode 100644 app/src/pages/AppSettings.js diff --git a/app/src/components/App.js b/app/src/components/App.js index f48702b8162..4212229bf1d 100644 --- a/app/src/components/App.js +++ b/app/src/components/App.js @@ -3,6 +3,7 @@ import {Switch, Route, Redirect} from 'react-router' import NavBar from './nav-bar' +import {PageWrapper} from '../components/Page' import SidePanel from '../pages/SidePanel' import Robots from '../pages/Robots' import More from '../pages/More' @@ -18,15 +19,17 @@ export default function App () {
- - - - - - - - - + + + + + + + + + + +
) } diff --git a/app/src/components/LabwareCalibration/index.js b/app/src/components/LabwareCalibration/index.js index eabaf987aad..c095589b8a7 100644 --- a/app/src/components/LabwareCalibration/index.js +++ b/app/src/components/LabwareCalibration/index.js @@ -1,60 +1,21 @@ // @flow // info panel and controls for labware calibration page import * as React from 'react' -import {connect} from 'react-redux' -import {Redirect, Route, withRouter} from 'react-router' -import {push} from 'react-router-redux' - -import { - selectors as robotSelectors, - type Labware -} from '../../robot' - +import {withRouter} from 'react-router' +import type {Labware} from '../../robot' import DeckMap from '../DeckMap' import InfoBox from './InfoBox' -import ConfirmModal from './ConfirmModal' - -type OwnProps = {slot: ?string, url: string} -type StateProps = {labware: ?Labware} -type DispatchProps = {onBackClick: () => void} -type Props = StateProps & DispatchProps & OwnProps -export default withRouter( - connect(mapStateToProps, mapDispatchToProps)(LabwareCalibration) -) +type Props = { + labware: ?Labware +} +export default withRouter(LabwareCalibration) function LabwareCalibration (props: Props) { - const {url, labware, onBackClick} = props - return (
- { - if (!labware || labware.calibration === 'confirmed') { - return ( - - ) - } - - return ( - - ) - }} />
) } - -function mapStateToProps (state, ownProps: OwnProps): StateProps { - // TODO(mc, 2018-02-05): getCurrentLabware selector - const labware = robotSelectors.getLabware(state) - const currentLabware = labware.find((lw) => lw.slot === ownProps.slot) - - return {labware: currentLabware} -} - -function mapDispatchToProps (dispatch, ownProps: OwnProps): DispatchProps { - return { - onBackClick: () => { dispatch(push(ownProps.url)) } - } -} diff --git a/app/src/components/LabwareCalibration/styles.css b/app/src/components/LabwareCalibration/styles.css index a17b4362e4f..ac7d0ae1665 100644 --- a/app/src/components/LabwareCalibration/styles.css +++ b/app/src/components/LabwareCalibration/styles.css @@ -1,11 +1,5 @@ @import '@opentrons/components'; -.modal { - @apply --modal; - - padding: 6rem 4rem; -} - .title_bar { position: absolute; top: 0; @@ -13,16 +7,6 @@ right: 0; } -.modal_contents { - z-index: 1; - width: 100%; - max-width: 38rem; - margin: auto; - background-color: white; - padding: 2rem; - border-radius: 0.5rem; -} - .in_progress_contents { background-color: transparent; @@ -34,11 +18,11 @@ .position_diagram, .jog_container { width: 100%; - margin: 1rem 0; + margin: 0.5rem 0; } .position_diagram { - padding: 1rem 2rem; + padding: 0.5rem 2rem; } .diagram_title { diff --git a/app/src/components/Page.css b/app/src/components/Page.css deleted file mode 100644 index ed34046fec8..00000000000 --- a/app/src/components/Page.css +++ /dev/null @@ -1,5 +0,0 @@ -.task { - flex: 1 1; - position: relative; - overflow-y: scroll; -} diff --git a/app/src/components/Page.js b/app/src/components/Page.js deleted file mode 100644 index 2f46f7a55ee..00000000000 --- a/app/src/components/Page.js +++ /dev/null @@ -1,16 +0,0 @@ -// task component -import React from 'react' - -import styles from './Page.css' -import LostConnectionAlert from './LostConnectionAlert' -import {AnalyticsSettingsModal} from './analytics-settings' - -export default function Page (props) { - return ( -
- {props.children} - - -
- ) -} diff --git a/app/src/components/Page/PageWrapper.js b/app/src/components/Page/PageWrapper.js new file mode 100644 index 00000000000..0fa87dca322 --- /dev/null +++ b/app/src/components/Page/PageWrapper.js @@ -0,0 +1,20 @@ +// @flow +import * as React from 'react' + +import LostConnectionAlert from '../LostConnectionAlert' +import {AnalyticsSettingsModal} from '../analytics-settings' + +import styles from './styles.css' + +type Props = { + children: React.Node +} +export default function PageWrapper (props: Props) { + return ( +
+ {props.children} + + +
+ ) +} diff --git a/app/src/components/Page/index.js b/app/src/components/Page/index.js new file mode 100644 index 00000000000..399370801d1 --- /dev/null +++ b/app/src/components/Page/index.js @@ -0,0 +1,25 @@ +// @flow +import * as React from 'react' + +import styles from './styles.css' +import {TitleBar, type TitleBarProps} from '@opentrons/components' +import PageWrapper from './PageWrapper' + +type Props = { + titleBarProps?: TitleBarProps, + children: React.Node, +} + +export default function Page (props: Props) { + const {titleBarProps, children} = props + return ( +
+ {titleBarProps && ( + + )} + {children} +
+ ) +} + +export {PageWrapper} diff --git a/app/src/components/Page/styles.css b/app/src/components/Page/styles.css new file mode 100644 index 00000000000..e463536cdba --- /dev/null +++ b/app/src/components/Page/styles.css @@ -0,0 +1,17 @@ +:root { + --relative-fill: { + width: 100%; + height: 100%; + position: relative; + } +} + +.relative { + @apply --relative-fill; +} + +.task { + @apply --relative-fill; + + overflow-y: auto; +} diff --git a/app/src/components/RobotSettings/index.js b/app/src/components/RobotSettings/index.js index 9472ba46f31..93da24513bb 100644 --- a/app/src/components/RobotSettings/index.js +++ b/app/src/components/RobotSettings/index.js @@ -1,7 +1,6 @@ // @flow // robot status panel with connect button import * as React from 'react' -import {Route} from 'react-router' import type {Robot} from '../../robot' import StatusCard from './StatusCard' @@ -41,11 +40,8 @@ export default function RobotSettings (props: Props) { - ( - - )} /> ) } -export {ConnectAlertModal} +export {ConnectAlertModal, UpdateModal} diff --git a/app/src/components/SessionHeader/index.js b/app/src/components/SessionHeader/index.js index a94cf45ea6e..dd0360aa6ce 100644 --- a/app/src/components/SessionHeader/index.js +++ b/app/src/components/SessionHeader/index.js @@ -1,7 +1,6 @@ import React from 'react' import {connect} from 'react-redux' import {Link} from 'react-router-dom' -import {TitleBar} from '@opentrons/components' import { selectors as robotSelectors @@ -10,15 +9,11 @@ import { export default connect(mapStateToProps)(SessionHeader) function SessionHeader (props) { - const title = ( + return ( {props.sessionName} ) - - return ( - - ) } function mapStateToProps (state) { diff --git a/app/src/pages/AppSettings.js b/app/src/pages/AppSettings.js deleted file mode 100644 index fe9043c4b2a..00000000000 --- a/app/src/pages/AppSettings.js +++ /dev/null @@ -1,76 +0,0 @@ -// @flow -// view info about the app and update -import React from 'react' -import {connect} from 'react-redux' -import {Route, Switch, Redirect, type ContextRouter} from 'react-router' -import {push} from 'react-router-redux' - -import type {State} from '../types' -import type {ShellUpdate} from '../shell' -import { - getShellUpdate, - checkForShellUpdates, - downloadShellUpdate, - quitAndInstallShellUpdate, - setUpdateSeen -} from '../shell' - -import Page from '../components/Page' -import AppSettings, {AppUpdateModal} from '../components/AppSettings' - -type OP = ContextRouter - -type SP = { - update: ShellUpdate, -} - -type DP = { - checkForUpdates: () => mixed, - downloadUpdate: () => mixed, - quitAndInstall: () => mixed, - closeUpdateModal: () => mixed, -} - -type Props = OP & SP & DP - -export default connect(mapStateToProps, mapDispatchToProps)(AppSettingsPage) - -function AppSettingsPage (props: Props) { - const {update, match: {path}} = props - - return ( - - - - ( - - )} /> - { - if (update.available && !update.seen) { - return () - } - - return null - }} /> - - - ) -} - -function mapStateToProps (state: State): SP { - return { - update: getShellUpdate(state) - } -} - -function mapDispatchToProps (dispatch: Dispatch): DP { - return { - checkForUpdates: () => dispatch(checkForShellUpdates()), - downloadUpdate: () => dispatch(downloadShellUpdate()), - quitAndInstall: () => quitAndInstallShellUpdate(), - closeUpdateModal: () => { - dispatch(setUpdateSeen()) - dispatch(push('/menu/app')) - } - } -} diff --git a/app/src/pages/Calibrate/Instruments.js b/app/src/pages/Calibrate/Instruments.js index 427149aca3e..0a36a29ab23 100644 --- a/app/src/pages/Calibrate/Instruments.js +++ b/app/src/pages/Calibrate/Instruments.js @@ -37,17 +37,18 @@ function SetupInstrumentsPage (props: Props) { } return ( - - + )}} + > - {currentInstrument && ( + {!!currentInstrument && ( )} - {currentInstrument && ( + {!!currentInstrument && ( ( void} -export default withRouter(connect(mapStateToProps)(SetupDeckPage)) +type Props = ContextRouter & StateProps & OwnProps & DispatchProps -function SetupDeckPage (props: Props) { - const {deckPopulated, match: {url, params: {slot}}} = props +export default withRouter(connect(mapStateToProps, mapDispatchToProps)(SetupDeckPage)) +function SetupDeckPage (props: Props) { + const {labware, deckPopulated, onBackClick, match: {url, params: {slot}}} = props return ( - - - + + )}} + > + + {!deckPopulated && ( )} - + { + if (!labware || labware.calibration === 'confirmed') { + return ( + + ) + } + + return ( + + ) + }} /> + ) } -function mapStateToProps (state): StateProps { +function mapStateToProps (state, ownProps: OwnProps): StateProps { + const {match: {url, params: {slot}}} = ownProps + const labware = robotSelectors.getLabware(state) + const currentLabware = labware.find((lw) => lw.slot === slot) + + return { + deckPopulated: !!robotSelectors.getDeckPopulated(state), + labware: currentLabware, + slot, + url + } +} + +function mapDispatchToProps (dispatch, ownProps: OwnProps): DispatchProps { + const {match: {url}} = ownProps return { - deckPopulated: !!robotSelectors.getDeckPopulated(state) + onBackClick: () => { dispatch(push(url)) } } } diff --git a/app/src/pages/More/AppSettings.js b/app/src/pages/More/AppSettings.js index 1648d152c4c..dc402c3ec1d 100644 --- a/app/src/pages/More/AppSettings.js +++ b/app/src/pages/More/AppSettings.js @@ -1,6 +1,6 @@ // @flow // view info about the app and update -import React from 'react' +import * as React from 'react' import {connect} from 'react-redux' import {Route, Switch, Redirect, type ContextRouter} from 'react-router' import {push} from 'react-router-redux' @@ -39,8 +39,12 @@ function AppSettingsPage (props: Props) { const {update, match: {path}} = props return ( - - + + + + ( @@ -53,7 +57,7 @@ function AppSettingsPage (props: Props) { return null }} /> - + ) } diff --git a/app/src/pages/More/Resources.js b/app/src/pages/More/Resources.js index 5f069f54d09..70a3dda154a 100644 --- a/app/src/pages/More/Resources.js +++ b/app/src/pages/More/Resources.js @@ -3,7 +3,9 @@ import Page from '../../components/Page' import Resources from '../../components/Resources' export default function ResourcesPage () { return ( - + ) diff --git a/app/src/pages/Robots.js b/app/src/pages/Robots.js index c58dbb8fdfc..60910c0a32f 100644 --- a/app/src/pages/Robots.js +++ b/app/src/pages/Robots.js @@ -1,6 +1,6 @@ // @flow // connect and configure robots page -import React from 'react' +import * as React from 'react' import {connect} from 'react-redux' import {withRouter, Route, Redirect, type ContextRouter} from 'react-router' @@ -9,9 +9,12 @@ import type {Robot} from '../robot' import {selectors as robotSelectors, actions as robotActions} from '../robot' import createLogger from '../logger' -import {TitleBar, Splash} from '@opentrons/components' +import {Splash} from '@opentrons/components' import Page from '../components/Page' -import RobotSettings, {ConnectAlertModal} from '../components/RobotSettings' +import RobotSettings, { + ConnectAlertModal, + UpdateModal +} from '../components/RobotSettings' import ChangePipette from '../components/ChangePipette' import CalibrateDeck from '../components/CalibrateDeck' import ConnectBanner from '../components/RobotSettings/ConnectBanner' @@ -57,10 +60,17 @@ function RobotSettingsPage (props: Props) { // TODO(mc, 2018-05-08): pass parentUrl to RobotSettings return ( - - - - + + + + + + + ( + + )} /> ( @@ -73,7 +83,7 @@ function RobotSettingsPage (props: Props) { {showConnectAlert && ( )} - + ) } diff --git a/app/src/pages/Run.js b/app/src/pages/Run.js index c41899033e8..b8a868b60dc 100644 --- a/app/src/pages/Run.js +++ b/app/src/pages/Run.js @@ -1,6 +1,6 @@ // @flow // run task component -import React from 'react' +import * as React from 'react' import {Route} from 'react-router' import Page from '../components/Page' import SessionHeader from '../components/SessionHeader' @@ -8,10 +8,13 @@ import RunLog, {ConfirmCancelModal} from '../components/RunLog' export default function RunPage () { return ( - - - + + )}} + > + + - + ) } diff --git a/components/src/__tests__/__snapshots__/modals.test.js.snap b/components/src/__tests__/__snapshots__/modals.test.js.snap index b5d43ab27a0..4aaadab4710 100644 --- a/components/src/__tests__/__snapshots__/modals.test.js.snap +++ b/components/src/__tests__/__snapshots__/modals.test.js.snap @@ -145,7 +145,7 @@ exports[`modals Modal renders correctly with optional heading 1`] = ` exports[`modals ModalPage renders correctly 1`] = `
+
diff --git a/components/src/modals/modals.css b/components/src/modals/modals.css index 20217e4cb7d..f7648796453 100644 --- a/components/src/modals/modals.css +++ b/components/src/modals/modals.css @@ -6,18 +6,29 @@ z-index: 1; width: 100%; max-width: 38rem; - margin: auto; + margin: 0 auto; padding: 1rem; border-radius: 0.5rem; } } .modal { - @apply --modal; + @apply --absolute-fill; + @apply --center-children; padding: 4rem; } +.modal_page { + @apply --absolute-fill; + + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + padding: 5rem 2rem 1rem; +} + .overlay { @apply --absolute-fill; @@ -42,7 +53,8 @@ @apply --modal-contents; background-color: white; - min-width: 38rem; + max-height: 100%; + overflow-y: auto; } .modal_page_heading { diff --git a/components/src/styles/positioning.css b/components/src/styles/positioning.css index 0d18be3efc2..39da9eb617e 100644 --- a/components/src/styles/positioning.css +++ b/components/src/styles/positioning.css @@ -13,6 +13,12 @@ align-items: center; }; + --flex-start: { + display: flex; + justify-content: flex-start; + align-items: center; + } + --modal: { @apply --absolute-fill; @apply --center-children;