From e77d81dd5bc05a657ce793bc7eed3e4e0983bdda Mon Sep 17 00:00:00 2001 From: kialam Date: Wed, 2 Jan 2019 09:03:48 -0700 Subject: [PATCH] Lift config context one level higher. - Refactor About component to use config context. - Update About component unit tests. --- __tests__/components/About.test.jsx | 22 -- src/App.jsx | 304 +++++++++++----------------- src/components/About.jsx | 94 ++++----- 3 files changed, 161 insertions(+), 259 deletions(-) diff --git a/__tests__/components/About.test.jsx b/__tests__/components/About.test.jsx index e2f101d095..e20fe77057 100644 --- a/__tests__/components/About.test.jsx +++ b/__tests__/components/About.test.jsx @@ -31,26 +31,4 @@ describe('', () => { expect(onAboutModalClose).toBeCalled(); aboutWrapper.unmount(); }); - - test('sets error on api request failure', async () => { - api.get = jest.fn().mockImplementation(() => { - const err = new Error('404 error'); - err.response = { status: 404, message: 'problem' }; - return Promise.reject(err); - }); - aboutWrapper = mount( - - - - ); - - const aboutComponentInstance = aboutWrapper.find(About).instance(); - await aboutComponentInstance.componentDidMount(); - expect(aboutComponentInstance.state.error.response.status).toBe(404); - aboutWrapper.unmount(); - }); - - test('API Config endpoint is valid', () => { - expect(API_CONFIG).toBeDefined(); - }); }); diff --git a/src/App.jsx b/src/App.jsx index 361c84ec34..d08764acd7 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,11 +1,8 @@ import React, { Fragment } from 'react'; -<<<<<<< HEAD -import { I18nProvider, I18n } from '@lingui/react'; -import { t } from '@lingui/macro'; -======= import { ConfigContext } from './context'; ->>>>>>> Implement React Context API +import { I18nProvider, I18n } from '@lingui/react'; +import { t } from '@lingui/macro'; import { Redirect, Switch, @@ -66,8 +63,8 @@ const catalogs = { en, ja }; // This spits out the language and the region. Example: es-US const language = (navigator.languages && navigator.languages[0]) -|| navigator.language -|| navigator.userLanguage; + || navigator.language + || navigator.userLanguage; const languageWithoutRegionCode = language.toLowerCase().split(/[_-]+/)[0]; @@ -88,6 +85,10 @@ class App extends React.Component { this.setState(({ isNavOpen }) => ({ isNavOpen: !isNavOpen })); }; + onLogoClick = () => { + this.setState({ activeGroup: 'views_group' }); + } + onDevLogout = async () => { await api.get(API_LOGOUT); this.setState({ activeGroup: 'views_group', activeItem: 'views_group_dashboard' }); @@ -136,182 +137,121 @@ class App extends React.Component { [BackgroundImageSrc.filter]: '/assets/images/background-filter.svg' }} /> - - api.isAuthenticated()} redirectPath="/" path="/login" component={() => } /> - - } - toolbar={PageToolbar} - showNavToggle - onNavToggle={this.onNavToggle} - /> - )} - sidebar={( - - - - - - )} - /> - )} - useCondensed - > - !api.isAuthenticated()} redirectPath="/login" exact path="/" component={() => ()} /> - !api.isAuthenticated()} redirectPath="/login" path="/home" component={Dashboard} /> - !api.isAuthenticated()} redirectPath="/login" path="/jobs" component={Jobs} /> - !api.isAuthenticated()} redirectPath="/login" path="/schedules" component={Schedules} /> - !api.isAuthenticated()} redirectPath="/login" path="/portal" component={Portal} /> - !api.isAuthenticated()} redirectPath="/login" path="/templates" component={Templates} /> - !api.isAuthenticated()} redirectPath="/login" path="/credentials" component={Credentials} /> - !api.isAuthenticated()} redirectPath="/login" path="/projects" component={Projects} /> - !api.isAuthenticated()} redirectPath="/login" path="/inventories" component={Inventories} /> - !api.isAuthenticated()} redirectPath="/login" path="/inventory_scripts" component={InventoryScripts} /> - + + + api.isAuthenticated()} + redirectPath="/" + path="/login" + component={() => } + /> + + } + toolbar={PageToolbar} + showNavToggle + onNavToggle={this.onNavToggle} + /> + )} + sidebar={( + + {({ i18n }) => ( + + )} + + )} + /> + )} + useCondensed + > + !api.isAuthenticated()} redirectPath="/login" exact path="/" component={() => ()} /> + !api.isAuthenticated()} redirectPath="/login" path="/home" component={Dashboard} /> + !api.isAuthenticated()} redirectPath="/login" path="/jobs" component={Jobs} /> + !api.isAuthenticated()} redirectPath="/login" path="/schedules" component={Schedules} /> + !api.isAuthenticated()} redirectPath="/login" path="/portal" component={Portal} /> + !api.isAuthenticated()} redirectPath="/login" path="/templates" component={Templates} /> + !api.isAuthenticated()} redirectPath="/login" path="/credentials" component={Credentials} /> + !api.isAuthenticated()} redirectPath="/login" path="/projects" component={Projects} /> + !api.isAuthenticated()} redirectPath="/login" path="/inventories" component={Inventories} /> + !api.isAuthenticated()} redirectPath="/login" path="/inventory_scripts" component={InventoryScripts} /> !api.isAuthenticated()} redirectPath="/login" path="/organizations" component={Organizations} /> - - !api.isAuthenticated()} redirectPath="/login" path="/users" component={Users} /> - !api.isAuthenticated()} redirectPath="/login" path="/teams" component={Teams} /> - !api.isAuthenticated()} redirectPath="/login" path="/credential_types" component={CredentialTypes} /> - !api.isAuthenticated()} redirectPath="/login" path="/notification_templates" component={NotificationTemplates} /> - !api.isAuthenticated()} redirectPath="/login" path="/management_jobs" component={ManagementJobs} /> - !api.isAuthenticated()} redirectPath="/login" path="/instance_groups" component={InstanceGroups} /> - !api.isAuthenticated()} redirectPath="/login" path="/applications" component={Applications} /> - !api.isAuthenticated()} redirectPath="/login" path="/auth_settings" component={AuthSettings} /> - !api.isAuthenticated()} redirectPath="/login" path="/jobs_settings" component={JobsSettings} /> - !api.isAuthenticated()} redirectPath="/login" path="/system_settings" component={SystemSettings} /> - !api.isAuthenticated()} redirectPath="/login" path="/ui_settings" component={UISettings} /> - !api.isAuthenticated()} redirectPath="/login" path="/license" component={License} /> - - - + !api.isAuthenticated()} redirectPath="/login" path="/users" component={Users} /> + !api.isAuthenticated()} redirectPath="/login" path="/teams" component={Teams} /> + !api.isAuthenticated()} redirectPath="/login" path="/credential_types" component={CredentialTypes} /> + !api.isAuthenticated()} redirectPath="/login" path="/notification_templates" component={NotificationTemplates} /> + !api.isAuthenticated()} redirectPath="/login" path="/management_jobs" component={ManagementJobs} /> + !api.isAuthenticated()} redirectPath="/login" path="/instance_groups" component={InstanceGroups} /> + !api.isAuthenticated()} redirectPath="/login" path="/applications" component={Applications} /> + !api.isAuthenticated()} redirectPath="/login" path="/auth_settings" component={AuthSettings} /> + !api.isAuthenticated()} redirectPath="/login" path="/jobs_settings" component={JobsSettings} /> + !api.isAuthenticated()} redirectPath="/login" path="/system_settings" component={SystemSettings} /> + !api.isAuthenticated()} redirectPath="/login" path="/ui_settings" component={UISettings} /> + !api.isAuthenticated()} redirectPath="/login" path="/license" component={License} /> + + + + + ); diff --git a/src/components/About.jsx b/src/components/About.jsx index e5e8254e34..59917efb59 100644 --- a/src/components/About.jsx +++ b/src/components/About.jsx @@ -5,42 +5,21 @@ import { AboutModal, TextContent, TextList, - TextListItem } from '@patternfly/react-core'; + TextListItem +} from '@patternfly/react-core'; import heroImg from '@patternfly/patternfly-next/assets/images/pfbg_992.jpg'; import brandImg from '../../images/tower-logo-white.svg'; import logoImg from '../../images/tower-logo-login.svg'; -import api from '../api'; -import { API_CONFIG } from '../endpoints'; - +import { ConfigContext } from '../context'; +import PropTypes from 'prop-types'; class About extends React.Component { - unmounting = false; - constructor (props) { + constructor(props) { super(props); - - this.state = { - config: {}, - error: false - }; } - async componentDidMount () { - try { - const { data } = await api.get(API_CONFIG); - this.safeSetState({ config: data }); - } catch (error) { - this.safeSetState({ error }); - } - } - - componentWillUnmount () { - this.unmounting = true; - } - - safeSetState = obj => !this.unmounting && this.setState(obj); - createSpeechBubble = (version) => { let text = `Tower ${version}`; let top = ''; @@ -63,28 +42,27 @@ class About extends React.Component { onAboutModalClose(); }; - render () { + render() { const { isOpen } = this.props; - const { config = {}, error } = this.state; - const { ansible_version = 'loading', version = 'loading' } = config; - return ( {({ i18n }) => ( - -
-              { this.createSpeechBubble(version) }
-              {`
+          
+            {({ ansible_version, version }) =>
+              
+                
+                  {this.createSpeechBubble(version)}
+                  {`
               \\
               \\  ^__^
                   (oo)\\_______
@@ -92,22 +70,28 @@ class About extends React.Component {
                       ||----w |
                       ||     ||
                         `}
-            
+
- - - - Ansible Version - - { ansible_version } - - - { error ?
error
: ''} -
+ + + + Ansible Version + + {ansible_version} + + + + } + )}
); } } +About.contextTypes = { + ansible_version: PropTypes.string, + version: PropTypes.string, +}; + export default About;