App: update app and routes

The App and Routes components are updated for compatibility with React
Router v5 and to follow updates made to RedHatInsights'
frontend-starter-app. Mainly, we no longer map our Routes to another
component and our main components are lazy loaded instead of mapped to
an asyncComponent. Also, the App component is rewritten to use react
hooks and remove unneccessary bloat.
This commit is contained in:
Jacob Kozol 2021-11-16 21:40:58 +01:00 committed by jkozol
parent 32cc379d6a
commit f1d00b3b2d
4 changed files with 37 additions and 113 deletions

View file

@ -1,61 +1,46 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { withRouter } from 'react-router-dom';
import { connect } from 'react-redux';
import React, { useEffect, useState } from 'react';
import { useHistory } from 'react-router-dom';
import { Routes } from './Routes';
import '@patternfly/patternfly/patternfly-addons.css';
import './App.scss';
import { NotificationsPortal } from '@redhat-cloud-services/frontend-components-notifications';
import { getRegistry } from '@redhat-cloud-services/frontend-components-utilities/Registry';
import NotificationsPortal from '@redhat-cloud-services/frontend-components-notifications/NotificationPortal';
import { notificationsReducer } from '@redhat-cloud-services/frontend-components-notifications/redux';
import api from './api.js';
import PermissionDenied from './Components/LandingPage/PermissionDenied';
class App extends Component {
constructor() {
super();
const App = (props) => {
const [ permission, setPermission ] = useState(false);
const history = useHistory();
this.state = {
permission: false,
};
}
componentDidMount () {
useEffect(() => {
const registry = getRegistry();
registry.register({ notifications: notificationsReducer });
insights.chrome.init();
insights.chrome.identifyApp('image-builder').catch(() => {
/* We are not in the menu so this call is allowed to fail */
});
this.appNav = insights.chrome.on('APP_NAVIGATION', event => this.props.history.push(`/${event.navId}`));
insights.chrome.auth.getUser().then(data => {
this.setState({ identity: data.identity });
api.getVersion().then(() => {
this.setState({ permission: true });
}).catch(() => {
this.setState({ permission: false });
});
});
}
insights.chrome.identifyApp('image-builder');
componentWillUnmount () {
this.appNav();
}
api.getVersion().then(() => {
setPermission(true);
}).catch(() => {
setPermission(false);
});
render () {
return (
<React.Fragment>
<NotificationsPortal />
{ this.state.permission ? <Routes childProps={ this.props } /> : <PermissionDenied /> }
</React.Fragment>
const unregister = insights.chrome.on('APP_NAVIGATION', (event) =>
history.push(`/${event.navId}`)
);
}
}
return () => {
unregister();
};
}, []);
App.propTypes = {
history: PropTypes.object
return (
<React.Fragment>
<NotificationsPortal />
{ permission ? <Routes childProps={ props } /> : <PermissionDenied /> }
</React.Fragment>
);
};
/**
* withRouter: https://reacttraining.com/react-router/web/api/withRouter
* connect: https://github.com/reactjs/react-redux/blob/master/docs/api.md
* https://reactjs.org/docs/higher-order-components.html
*/
export default withRouter (connect()(App));
export default App;

View file

@ -1,7 +1,6 @@
/* global COMMITHASH */
import React, { Component } from 'react';
import { withRouter } from 'react-router-dom';
import { PageHeader, PageHeaderTitle } from '@redhat-cloud-services/frontend-components';
@ -68,4 +67,4 @@ https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/up
}
}
export default withRouter(LandingPage);
export default LandingPage;

View file

@ -1,26 +1,14 @@
import React, { lazy } from 'react';
import { Route, Switch, Redirect } from 'react-router-dom';
import PropTypes from 'prop-types';
import React from 'react';
import asyncComponent from './Utilities/asyncComponent';
const LandingPage = asyncComponent(() => import('./Components/LandingPage/LandingPage'));
const CreateImageWizard = asyncComponent(() => import('./Components/CreateImageWizard/CreateImageWizard'));
const InsightsRoute = ({ component: Component, title, ...rest }) => {
title ? document.title = title : null;
return (<Route { ...rest } component={ Component } />);
};
InsightsRoute.propTypes = {
component: PropTypes.func,
title: PropTypes.string
};
const LandingPage = lazy(() => import('./Components/LandingPage/LandingPage'));
const CreateImageWizard = lazy(() => import('./Components/CreateImageWizard/CreateImageWizard'));
export const Routes = () => {
return (
<Switch>
<InsightsRoute exact path='/landing' component={ LandingPage } />
<InsightsRoute exact path='/imagewizard' component={ CreateImageWizard } />
<Route exact path='/landing' component={ LandingPage } />
<Route exact path='/imagewizard' component={ CreateImageWizard } />
<Redirect to='/landing' />
</Switch>
);

View file

@ -1,48 +0,0 @@
import React, { Component } from 'react';
import { Skeleton } from '@redhat-cloud-services/frontend-components';
/**
* Webpack allows loading components asynchronously by using import().
*
* Ex) const Component = asyncComponent(() => import('component');
*
* class aClass extends React.Component {
* render() {
* return (<Component prop1="prop1" prop2="prop2" ... />);
* }
* }
*
* https://reactjs.org/docs/higher-order-components.html
*
* @param importComponent a function that contains and async import statement
* Ex) () => import('react-component')
*
* @returns {AsyncComponent} The imported component or can return a loading
*/
export default function asyncComponent(importComponent) {
class AsyncComponent extends Component {
constructor(props) {
super(props);
this.state = {
component: null
};
}
async componentDidMount() {
const { default: component } = await importComponent();
this.setState({
component
});
}
render() {
const C = this.state.component;
return C ? <C { ...this.props } /> : <Skeleton />;
}
}
return AsyncComponent;
}