Skip to content

Commit

Permalink
Add new sign in form styles
Browse files Browse the repository at this point in the history
[Finishes #163277930]
  • Loading branch information
rupurt committed Jan 29, 2019
1 parent 757fa2e commit 73643fd
Show file tree
Hide file tree
Showing 13 changed files with 313 additions and 172 deletions.
1 change: 1 addition & 0 deletions gui/__mocks__/fileMock.js
@@ -0,0 +1 @@
module.exports = 'test-file-stub'
8 changes: 1 addition & 7 deletions gui/__tests__/containers/SignIn.test.js
Expand Up @@ -65,12 +65,6 @@ describe('containers/SignIn', () => {
currentUrl: '/signin'
})
expect(newState.authentication.allowed).toEqual(false)
expect(newState.authentication.errors).toEqual([])
})

it('cannot submit an empty form', async () => {
const store = createStore()
const wrapper = mountSignIn(store)
expect(wrapper.find('form button').getDOMNode().disabled).toEqual(true)
expect(wrapper.text()).toContain('Your email or password is incorrect. Please try again')
})
})
5 changes: 3 additions & 2 deletions gui/src/App.js
@@ -1,8 +1,9 @@
import React, { PureComponent } from 'react'
import Layout from 'Layout'
import createStore from 'connectors/redux'
import { Provider } from 'react-redux'
import { hot } from 'react-hot-loader'
import createStore from 'connectors/redux'
import Layout from 'Layout'
import './index.css'

class App extends PureComponent {
// Remove the server-side injected CSS.
Expand Down
136 changes: 35 additions & 101 deletions gui/src/Layout.js
@@ -1,115 +1,49 @@
import React from 'react'
import Routes from 'react-static-routes'
import React, { PureComponent } from 'react'
import CssBaseline from '@material-ui/core/CssBaseline'
import Grid from '@material-ui/core/Grid'
import PrivateRoute from './PrivateRoute'
import Header from 'containers/Header'
import Loading from 'components/Loading'
import Notifications from 'containers/Notifications'
import universal from 'react-universal-component'
import { Redirect } from 'react-router'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import { Router, Route, Switch } from 'react-static'
import { Redirect } from 'react-router'
import Routes from 'react-static-routes'
import { hot } from 'react-hot-loader'
import { withStyles } from '@material-ui/core/styles'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { useHooks, useState } from 'use-react-hooks'
import universal from 'react-universal-component'
import Loading from 'components/Loading'
import Private from './Private'
import PrivateRoute from './PrivateRoute'

// Asynchronously load routes that are chunked via code-splitting
// 'import' as a function must take a string. It can't take a variable.
const uniOpts = { loading: Loading }
const DashboardsIndex = universal(import('./containers/Dashboards/Index'), uniOpts)
const JobsIndex = universal(import('./containers/Jobs/Index'), uniOpts)
const JobsShow = universal(import('./containers/Jobs/Show'), uniOpts)
const JobsDefinition = universal(import('./containers/Jobs/Definition'), uniOpts)
const JobsNew = universal(import('./containers/Jobs/New'), uniOpts)
const BridgesIndex = universal(import('./containers/Bridges/Index'), uniOpts)
const BridgesNew = universal(import('./containers/Bridges/New'), uniOpts)
const BridgesShow = universal(import('./containers/Bridges/Show'), uniOpts)
const BridgesEdit = universal(import('./containers/Bridges/Edit'), uniOpts)
const JobRunsIndex = universal(import('./containers/JobRuns/Index'), uniOpts)
const JobRunsShow = universal(import('./containers/JobRuns/Show'), uniOpts)
const JobRunsShowJson = universal(import('./containers/JobRuns/ShowJson'), uniOpts)
const Configuration = universal(import('./containers/Configuration'), uniOpts)
const SignIn = universal(import('./containers/SignIn'), uniOpts)
const SignOut = universal(import('./containers/SignOut'), uniOpts)

const styles = theme => {
return {
content: {
marginTop: 0,
marginBottom: theme.spacing.unit * 5
class Layout extends PureComponent {
// Remove the server-side injected CSS.
componentDidMount () {
const jssStyles = document.getElementById('jss-server-side')
if (jssStyles && jssStyles.parentNode) {
jssStyles.parentNode.removeChild(jssStyles)
}
}
}

const Layout = useHooks(props => {
const [headerHeight, resizeHeaderHeight] = useState(0)

const onHeaderResize = (_width, height) => {
resizeHeaderHeight(height)
render () {
const { redirectTo } = this.props

return (
<React.Fragment>
<CssBaseline />

<Router>
<Switch>
<Route exact path='/signin' component={SignIn} />
<PrivateRoute exact path='/signout' component={SignOut} />
{redirectTo && <Redirect to={redirectTo} />}
<Route component={Private} />
<Routes />
</Switch>
</Router>
</React.Fragment>
)
}

const { classes, redirectTo } = props

return (<Router>
<Grid container>
<CssBaseline />
<Grid item xs={12}>
<Header
onResize={onHeaderResize}
drawerContainer={props.drawerContainer}
/>

<main
ref={ref => { props.drawerContainer = ref }}
style={{ paddingTop: headerHeight }}
>
<Notifications />

<div className={classes.content}>
<Switch>
<Route exact path='/signin' component={SignIn} />
<PrivateRoute exact path='/signout' component={SignOut} />
{redirectTo && <Redirect to={redirectTo} />}
<PrivateRoute
exact
path='/'
render={props => (
<DashboardsIndex
{...props}
recentJobRunsCount={5}
recentlyCreatedPageSize={4}
/>
)}
/>
<PrivateRoute exact path='/jobs' component={JobsIndex} />
<PrivateRoute exact path='/jobs/page/:jobPage' component={JobsIndex} />
<PrivateRoute exact path='/jobs/new' component={JobsNew} />
<PrivateRoute
exact
path='/jobs/:jobSpecId'
render={props => <JobsShow {...props} showJobRunsCount={5} />}
/>
<PrivateRoute exact path='/jobs/:jobSpecId/definition' component={JobsDefinition} />
<PrivateRoute exact path='/jobs/:jobSpecId/runs' component={JobRunsIndex} />
<PrivateRoute exact path='/jobs/:jobSpecId/runs/page/:jobRunsPage' component={JobRunsIndex} />
<PrivateRoute exact path='/jobs/:jobSpecId/runs/id/:jobRunId' component={JobRunsShow} />
<PrivateRoute exact path='/jobs/:jobSpecId/runs/id/:jobRunId/json' component={JobRunsShowJson} />
<PrivateRoute exact path='/bridges' component={BridgesIndex} />
<PrivateRoute exact path='/bridges/page/:bridgePage' component={BridgesIndex} />
<PrivateRoute exact path='/bridges/new' component={BridgesNew} />
<PrivateRoute exact path='/bridges/:bridgeId' component={BridgesShow} />
<PrivateRoute exact path='/bridges/:bridgeId/edit' component={BridgesEdit} />
<PrivateRoute exact path='/config' component={Configuration} />
<Routes />
</Switch>
</div>
</main>
</Grid>
</Grid>
</Router>)
})
}

const mapStateToProps = state => ({
redirectTo: state.redirect.to
Expand All @@ -125,4 +59,4 @@ export const ConnectedLayout = connect(
mapDispatchToProps
)(Layout)

export default hot(module)(withStyles(styles)(ConnectedLayout))
export default hot(module)(ConnectedLayout)
104 changes: 104 additions & 0 deletions gui/src/Private.js
@@ -0,0 +1,104 @@
import React from 'react'
import Routes from 'react-static-routes'
import Grid from '@material-ui/core/Grid'
import universal from 'react-universal-component'
import { Switch } from 'react-static'
import { hot } from 'react-hot-loader'
import { withStyles } from '@material-ui/core/styles'
import { useHooks, useState } from 'use-react-hooks'
import Header from 'containers/Header'
import Loading from 'components/Loading'
import Notifications from 'containers/Notifications'
import PrivateRoute from './PrivateRoute'

// Asynchronously load routes that are chunked via code-splitting
// 'import' as a function must take a string. It can't take a variable.
const uniOpts = { loading: Loading }
const DashboardsIndex = universal(import('./containers/Dashboards/Index'), uniOpts)
const JobsIndex = universal(import('./containers/Jobs/Index'), uniOpts)
const JobsShow = universal(import('./containers/Jobs/Show'), uniOpts)
const JobsDefinition = universal(import('./containers/Jobs/Definition'), uniOpts)
const JobsNew = universal(import('./containers/Jobs/New'), uniOpts)
const BridgesIndex = universal(import('./containers/Bridges/Index'), uniOpts)
const BridgesNew = universal(import('./containers/Bridges/New'), uniOpts)
const BridgesShow = universal(import('./containers/Bridges/Show'), uniOpts)
const BridgesEdit = universal(import('./containers/Bridges/Edit'), uniOpts)
const JobRunsIndex = universal(import('./containers/JobRuns/Index'), uniOpts)
const JobRunsShow = universal(import('./containers/JobRuns/Show'), uniOpts)
const JobRunsShowJson = universal(import('./containers/JobRuns/ShowJson'), uniOpts)
const Configuration = universal(import('./containers/Configuration'), uniOpts)

const styles = theme => {
return {
content: {
marginTop: 0,
marginBottom: theme.spacing.unit * 5
}
}
}

const Private = useHooks(props => {
const [headerHeight, resizeHeaderHeight] = useState(0)

const onHeaderResize = (_width, height) => {
resizeHeaderHeight(height)
}

const { classes } = props

return (
<Grid container spacing={0}>
<Grid item xs={12}>
<Header
onResize={onHeaderResize}
drawerContainer={props.drawerContainer}
/>

<main
ref={ref => { props.drawerContainer = ref }}
style={{ paddingTop: headerHeight }}
>
<Notifications />

<div className={classes.content}>
<Switch>
<PrivateRoute
exact
path='/'
render={props => (
<DashboardsIndex
{...props}
recentJobRunsCount={5}
recentlyCreatedPageSize={4}
/>
)}
/>
<PrivateRoute exact path='/jobs' component={JobsIndex} />
<PrivateRoute exact path='/jobs/page/:jobPage' component={JobsIndex} />
<PrivateRoute exact path='/jobs/new' component={JobsNew} />
<PrivateRoute
exact
path='/jobs/:jobSpecId'
render={props => <JobsShow {...props} showJobRunsCount={5} />}
/>
<PrivateRoute exact path='/jobs/:jobSpecId/definition' component={JobsDefinition} />
<PrivateRoute exact path='/jobs/:jobSpecId/runs' component={JobRunsIndex} />
<PrivateRoute exact path='/jobs/:jobSpecId/runs/page/:jobRunsPage' component={JobRunsIndex} />
<PrivateRoute exact path='/jobs/:jobSpecId/runs/id/:jobRunId' component={JobRunsShow} />
<PrivateRoute exact path='/jobs/:jobSpecId/runs/id/:jobRunId/json' component={JobRunsShowJson} />
<PrivateRoute exact path='/bridges' component={BridgesIndex} />
<PrivateRoute exact path='/bridges/page/:bridgePage' component={BridgesIndex} />
<PrivateRoute exact path='/bridges/new' component={BridgesNew} />
<PrivateRoute exact path='/bridges/:bridgeId' component={BridgesShow} />
<PrivateRoute exact path='/bridges/:bridgeId/edit' component={BridgesEdit} />
<PrivateRoute exact path='/config' component={Configuration} />
<Routes />
</Switch>
</div>
</main>
</Grid>
</Grid>
)
})

export default hot(module)(withStyles(styles)(Private))
19 changes: 7 additions & 12 deletions gui/src/components/Logo.js
@@ -1,7 +1,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import pick from 'lodash/pick'
import Image from './Image'
import logo from '../images/chainlink-operator-logo.svg'
import { withStyles } from '@material-ui/core/styles'

const styles = theme => {
Expand All @@ -16,21 +16,16 @@ const styles = theme => {
}
}

const Logo = ({ width, height }) => {
const size = { width, height }

return (
<Image
src={logo}
alt='Chainlink Operator'
{...size}
/>
)
const Logo = props => {
const imageProps = pick(props, ['src', 'width', 'height', 'alt'])
return <Image {...imageProps} />
}

Logo.propTypes = {
src: PropTypes.string.isRequired,
width: PropTypes.number,
height: PropTypes.number
height: PropTypes.number,
alt: PropTypes.string
}

export default withStyles(styles)(Logo)
21 changes: 21 additions & 0 deletions gui/src/components/Logos/Hexagon.js
@@ -0,0 +1,21 @@
import React from 'react'
import PropTypes from 'prop-types'
import Logo from '../Logo'
import src from '../../images/icon-logo-blue.svg'

const Hexagon = props => {
return (
<Logo
src={src}
alt='Chainlink Operator'
{...props}
/>
)
}

Hexagon.propTypes = {
width: PropTypes.number,
height: PropTypes.number
}

export default Hexagon
21 changes: 21 additions & 0 deletions gui/src/components/Logos/Main.js
@@ -0,0 +1,21 @@
import React from 'react'
import PropTypes from 'prop-types'
import Logo from '../Logo'
import src from '../../images/chainlink-operator-logo.svg'

const Main = props => {
return (
<Logo
src={src}
alt='Chainlink Operator'
{...props}
/>
)
}

Main.propTypes = {
width: PropTypes.number,
height: PropTypes.number
}

export default Main
4 changes: 2 additions & 2 deletions gui/src/containers/Header.js
Expand Up @@ -19,7 +19,7 @@ import IconButton from '@material-ui/core/IconButton'
import MenuIcon from '@material-ui/icons/Menu'
import Portal from '@material-ui/core/Portal'
import LoadingBar from 'components/LoadingBar'
import Logo from 'components/Logo'
import MainLogo from 'components/Logos/Main'
import AvatarMenu from 'components/AvatarMenu'
import { submitSignOut } from 'actions'
import fetchCountSelector from 'selectors/fetchCount'
Expand Down Expand Up @@ -140,7 +140,7 @@ const Header = useHooks(props => {
<Grid container alignItems='center'>
<Grid item xs={11} sm={6} md={4}>
<Link to='/'>
<Logo width={200} />
<MainLogo width={200} />
</Link>
</Grid>
<Grid item xs={1} sm={6} md={8}>
Expand Down

0 comments on commit 73643fd

Please sign in to comment.