From 9c6df685574164f9fecebe48df04464cc482a65a Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Wed, 2 Jan 2019 01:35:34 -0500 Subject: [PATCH] decouple App and Login components --- __tests__/App.test.jsx | 26 +--- src/App.jsx | 163 +++++++++++---------- src/index.jsx | 325 ++++++++++++++++++++++------------------- 3 files changed, 259 insertions(+), 255 deletions(-) diff --git a/__tests__/App.test.jsx b/__tests__/App.test.jsx index d69dab8929..5c9bc7d195 100644 --- a/__tests__/App.test.jsx +++ b/__tests__/App.test.jsx @@ -1,12 +1,12 @@ import React from 'react'; import { HashRouter as Router } from 'react-router-dom'; + import { shallow, mount } from 'enzyme'; import App from '../src/App'; import api from '../src/api'; import { API_LOGOUT, API_CONFIG } from '../src/endpoints'; import Dashboard from '../src/pages/Dashboard'; -import Login from '../src/pages/Login'; import { asyncFlush } from '../jest.setup'; const DEFAULT_ACTIVE_GROUP = 'views_group'; @@ -24,30 +24,6 @@ describe('', () => { expect(appWrapper.length).toBe(1); }); - test('renders login page when not authenticated', () => { - api.isAuthenticated = jest.fn(); - api.isAuthenticated.mockReturnValue(false); - - const appWrapper = mount(); - - const login = appWrapper.find(Login); - expect(login.length).toBe(1); - const dashboard = appWrapper.find(Dashboard); - expect(dashboard.length).toBe(0); - }); - - test('renders dashboard when authenticated', () => { - api.isAuthenticated = jest.fn(); - api.isAuthenticated.mockReturnValue(true); - - const appWrapper = mount(); - - const dashboard = appWrapper.find(Dashboard); - expect(dashboard.length).toBe(1); - const login = appWrapper.find(Login); - expect(login.length).toBe(0); - }); - test('onNavToggle sets state.isNavOpen to opposite', () => { const appWrapper = shallow(); expect(appWrapper.state().isNavOpen).toBe(true); diff --git a/src/App.jsx b/src/App.jsx index c64bbb022e..2ef0aa65f8 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,6 +1,4 @@ -import React, { Fragment } from 'react'; -import { ConfigContext } from './context'; - +import React, { Component } from 'react'; import { Redirect, Switch, @@ -20,15 +18,15 @@ import { global_breakpoint_md as breakpointMd } from '@patternfly/react-tokens'; import api from './api'; import { API_LOGOUT, API_CONFIG } from './endpoints'; +import { ConfigContext } from './context'; -import Login from './pages/Login'; import HelpDropdown from './components/HelpDropdown'; import LogoutButton from './components/LogoutButton'; import TowerLogo from './components/TowerLogo'; import NavExpandableGroup from './components/NavExpandableGroup'; -class App extends React.Component { - constructor(props) { +class App extends Component { + constructor (props) { super(props); // initialize with a closed navbar if window size is small @@ -47,13 +45,21 @@ class App extends React.Component { }; onLogoClick = () => { - this.setState({ activeGroup: 'views_group' }); + this.setState({ + activeGroup: 'views_group' + }); } onDevLogout = async () => { await api.get(API_LOGOUT); - this.setState({ activeGroup: 'views_group', activeItem: 'views_group_dashboard' }); - } + + this.setState({ + activeGroup: 'views_group', + activeItem: 'views_group_dashboard', + }); + + window.location.replace('/#/login'); + }; async componentDidMount() { // Grab our config data from the API and store in state @@ -67,80 +73,77 @@ class App extends React.Component { render () { const { config, isNavOpen } = this.state; - const { logo, loginInfo, navLabel, routeGroups = [] } = this.props; + const { navLabel = '', routeGroups = [] } = this.props; + + const header = ( + this.onNavToggle()} + logo={( + + )} + toolbar={( + + + + + + + this.onDevLogout()} + /> + + + + )} + /> + ); + + const sidebar = ( + + + {routeGroups.map(params => ( + + ))} + + + )} + /> + ); return ( - api.isAuthenticated () ? ( - - } /> - } /> - ( - - this.onNavToggle()} - logo={( - - )} - toolbar={( - - - - - - - this.onDevLogout()} - /> - - - - )} - /> + + + { + // + // Extract a flattened array of all route params from the provided route config + // and use it to render route components. + // + // [{ routes }, { routes }] -> [route, route, route] -> () + // + routeGroups + .reduce((allRoutes, { routes }) => allRoutes.concat(routes), []) + .map(({ component: Component, path }) => ( + ( + )} - sidebar={( - - - { - routeGroups.map(params => ) - } - - - )} - /> - )} - > - { - // - // Extract a flattened array of all route params from the provided route config - // and use it to render route components. - // - // [{ routes }, { routes }] -> [route, route, route] -> () - // - routeGroups - .reduce((allRoutes, { routes }) => allRoutes.concat(routes), []) - .map(({ component: Component, path }) => ( - } /> - )) - } - - - )} /> - - ) : ( - - } /> - - - ) + /> + )) + } + + ); } } diff --git a/src/index.jsx b/src/index.jsx index ed95e8b74e..bfd56e2960 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -1,7 +1,9 @@ import React from 'react'; import { render } from 'react-dom'; import { - HashRouter as Router, + HashRouter, + Redirect, + Route, Switch, } from 'react-router-dom'; import { @@ -59,8 +61,23 @@ export async function main () { const { data } = await api.getRoot(); const { custom_logo, custom_login_info } = data; + const loginRoutes = ( + + ( + + )} + /> + + + ); + render( - + {({ i18n }) => ( - + {!api.isAuthenticated() ? loginRoutes : ( + + } /> + } /> + ( + + )} + /> + + )} )} - , el); + , el); }; export default main();