Merge pull request #7186 from jakemcdermott/ui-next-route-config

Relocate route config, remove route render props, refactor top-level routes

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
This commit is contained in:
softwarefactory-project-zuul[bot]
2020-06-02 14:41:50 +00:00
committed by GitHub
4 changed files with 244 additions and 252 deletions

View File

@@ -136,12 +136,7 @@ class App extends Component {
version, version,
configError, configError,
} = this.state; } = this.state;
const { const { i18n, routeConfig = [], navLabel = '', children } = this.props;
i18n,
render = () => {},
routeGroups = [],
navLabel = '',
} = this.props;
const header = ( const header = (
<PageHeader <PageHeader
@@ -167,7 +162,7 @@ class App extends Component {
nav={ nav={
<Nav aria-label={navLabel} theme="dark"> <Nav aria-label={navLabel} theme="dark">
<NavList> <NavList>
{routeGroups.map(({ groupId, groupTitle, routes }) => ( {routeConfig.map(({ groupId, groupTitle, routes }) => (
<NavExpandableGroup <NavExpandableGroup
key={groupId} key={groupId}
groupId={groupId} groupId={groupId}
@@ -194,7 +189,7 @@ class App extends Component {
version, version,
}} }}
> >
{render({ routeGroups })} {children}
</ConfigProvider> </ConfigProvider>
</Page> </Page>
<About <About

View File

@@ -30,27 +30,27 @@ describe('<App />', () => {
}); });
test('expected content is rendered', () => { test('expected content is rendered', () => {
const routeConfig = [
{
groupTitle: 'Group One',
groupId: 'group_one',
routes: [
{ title: 'Foo', path: '/foo' },
{ title: 'Bar', path: '/bar' },
],
},
{
groupTitle: 'Group Two',
groupId: 'group_two',
routes: [{ title: 'Fiz', path: '/fiz' }],
},
];
const appWrapper = mountWithContexts( const appWrapper = mountWithContexts(
<App <App routeConfig={routeConfig}>
routeGroups={[ {routeConfig.map(({ groupId }) => (
{ <div key={groupId} id={groupId} />
groupTitle: 'Group One', ))}
groupId: 'group_one', </App>
routes: [
{ title: 'Foo', path: '/foo' },
{ title: 'Bar', path: '/bar' },
],
},
{
groupTitle: 'Group Two',
groupId: 'group_two',
routes: [{ title: 'Fiz', path: '/fiz' }],
},
]}
render={({ routeGroups }) =>
routeGroups.map(({ groupId }) => <div key={groupId} id={groupId} />)
}
/>
); );
// page components // page components
@@ -64,7 +64,6 @@ describe('<App />', () => {
expect(appWrapper.find('a[href="/#/bar"]').length).toBe(1); expect(appWrapper.find('a[href="/#/bar"]').length).toBe(1);
expect(appWrapper.find('a[href="/#/fiz"]').length).toBe(1); expect(appWrapper.find('a[href="/#/fiz"]').length).toBe(1);
// inline render
expect(appWrapper.find('#group_one').length).toBe(1); expect(appWrapper.find('#group_one').length).toBe(1);
expect(appWrapper.find('#group_two').length).toBe(1); expect(appWrapper.find('#group_two').length).toBe(1);
}); });

View File

@@ -2,41 +2,18 @@ import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import { Route, Switch, Redirect } from 'react-router-dom'; import { Route, Switch, Redirect } from 'react-router-dom';
import { I18n } from '@lingui/react'; import { I18n } from '@lingui/react';
import { t } from '@lingui/macro';
import '@patternfly/react-core/dist/styles/base.css'; import '@patternfly/react-core/dist/styles/base.css';
import { isAuthenticated } from './util/auth'; import { isAuthenticated } from './util/auth';
import Background from './components/Background'; import Background from './components/Background';
import Applications from './screens/Application';
import Credentials from './screens/Credential';
import CredentialTypes from './screens/CredentialType';
import Dashboard from './screens/Dashboard';
import Hosts from './screens/Host';
import InstanceGroups from './screens/InstanceGroup';
import Inventory from './screens/Inventory';
import InventoryScripts from './screens/InventoryScript';
import { Jobs } from './screens/Job';
import Login from './screens/Login';
import ManagementJobs from './screens/ManagementJob';
import NotificationTemplates from './screens/NotificationTemplate';
import Organizations from './screens/Organization';
import Portal from './screens/Portal';
import Projects from './screens/Project';
import Schedules from './screens/Schedule';
import AuthSettings from './screens/AuthSetting';
import JobsSettings from './screens/JobsSetting';
import SystemSettings from './screens/SystemSetting';
import UISettings from './screens/UISetting';
import License from './screens/License';
import Teams from './screens/Team';
import Templates from './screens/Template';
import Users from './screens/User';
import NotFound from './screens/NotFound'; import NotFound from './screens/NotFound';
import Login from './screens/Login';
import App from './App'; import App from './App';
import RootProvider from './RootProvider'; import RootProvider from './RootProvider';
import { BrandName } from './variables'; import { BrandName } from './variables';
import getRouteConfig from './routeConfig';
// eslint-disable-next-line import/prefer-default-export // eslint-disable-next-line import/prefer-default-export
export function main(render) { export function main(render) {
@@ -56,21 +33,19 @@ export function main(render) {
/> />
); );
const defaultRedirect = () => { const AppRoute = ({ auth, children, ...rest }) =>
if (isAuthenticated(document.cookie)) { // eslint-disable-next-line no-nested-ternary
return <Redirect to="/home" />; auth ? (
} isAuthenticated(document.cookie) ? (
return ( <Route {...rest}>{children}</Route>
<Switch> ) : (
{removeTrailingSlash}
<Route
path="/login"
render={() => <Login isAuthenticated={isAuthenticated} />}
/>
<Redirect to="/login" /> <Redirect to="/login" />
</Switch> )
) : isAuthenticated(document.cookie) ? (
<Redirect to="/home" />
) : (
<Route {...rest}>{children}</Route>
); );
};
return render( return render(
<RootProvider> <RootProvider>
@@ -79,191 +54,33 @@ export function main(render) {
<Background> <Background>
<Switch> <Switch>
{removeTrailingSlash} {removeTrailingSlash}
<Route path="/login" render={defaultRedirect} /> <AppRoute path="/login">
<Route exact path="/" render={defaultRedirect} /> <Login isAuthenticated={isAuthenticated} />
<Route </AppRoute>
render={() => { <AppRoute exact path="/">
if (!isAuthenticated(document.cookie)) { <Login isAuthenticated={isAuthenticated} />
return <Redirect to="/login" />; </AppRoute>
} <AppRoute auth>
return ( <App routeConfig={getRouteConfig(i18n)}>
<App <Switch>
navLabel={i18n._(t`Primary Navigation`)} {getRouteConfig(i18n)
routeGroups={[ .flatMap(({ routes }) => routes)
{ .map(({ path, screen: Screen }) => (
groupTitle: i18n._(t`Views`), <AppRoute
groupId: 'views_group', auth
routes: [ key={path}
{ path={path}
title: i18n._(t`Dashboard`), render={({ match }) => <Screen match={match} />}
path: '/home', />
component: Dashboard, ))
}, .concat(
{ <AppRoute auth key="not-found" path="*">
title: i18n._(t`Jobs`), <NotFound />
path: '/jobs', </AppRoute>
component: Jobs, )}
}, </Switch>
{ </App>
title: i18n._(t`Schedules`), </AppRoute>
path: '/schedules',
component: Schedules,
},
{
title: i18n._(t`My View`),
path: '/portal',
component: Portal,
},
],
},
{
groupTitle: i18n._(t`Resources`),
groupId: 'resources_group',
routes: [
{
title: i18n._(t`Templates`),
path: '/templates',
component: Templates,
},
{
title: i18n._(t`Credentials`),
path: '/credentials',
component: Credentials,
},
{
title: i18n._(t`Projects`),
path: '/projects',
component: Projects,
},
{
title: i18n._(t`Inventories`),
path: '/inventories',
component: Inventory,
},
{
title: i18n._(t`Hosts`),
path: '/hosts',
component: Hosts,
},
{
title: i18n._(t`Inventory Scripts`),
path: '/inventory_scripts',
component: InventoryScripts,
},
],
},
{
groupTitle: i18n._(t`Access`),
groupId: 'access_group',
routes: [
{
title: i18n._(t`Organizations`),
path: '/organizations',
component: Organizations,
},
{
title: i18n._(t`Users`),
path: '/users',
component: Users,
},
{
title: i18n._(t`Teams`),
path: '/teams',
component: Teams,
},
],
},
{
groupTitle: i18n._(t`Administration`),
groupId: 'administration_group',
routes: [
{
title: i18n._(t`Credential Types`),
path: '/credential_types',
component: CredentialTypes,
},
{
title: i18n._(t`Notifications`),
path: '/notification_templates',
component: NotificationTemplates,
},
{
title: i18n._(t`Management Jobs`),
path: '/management_jobs',
component: ManagementJobs,
},
{
title: i18n._(t`Instance Groups`),
path: '/instance_groups',
component: InstanceGroups,
},
{
title: i18n._(t`Integrations`),
path: '/applications',
component: Applications,
},
],
},
{
groupTitle: i18n._(t`Settings`),
groupId: 'settings_group',
routes: [
{
title: i18n._(t`Authentication`),
path: '/auth_settings',
component: AuthSettings,
},
{
title: i18n._(t`Jobs`),
path: '/jobs_settings',
component: JobsSettings,
},
{
title: i18n._(t`System`),
path: '/system_settings',
component: SystemSettings,
},
{
title: i18n._(t`User Interface`),
path: '/ui_settings',
component: UISettings,
},
{
title: i18n._(t`License`),
path: '/license',
component: License,
},
],
},
]}
render={({ routeGroups }) => {
const routeList = routeGroups
.reduce(
(allRoutes, { routes }) => allRoutes.concat(routes),
[]
)
.map(({ component: PageComponent, path }) => (
<Route
key={path}
path={path}
render={({ match }) => (
<PageComponent match={match} />
)}
/>
));
routeList.push(
<Route
key="not-found"
path="*"
component={NotFound}
/>
);
return <Switch>{routeList}</Switch>;
}}
/>
);
}}
/>
</Switch> </Switch>
</Background> </Background>
)} )}

View File

@@ -0,0 +1,181 @@
import { t } from '@lingui/macro';
import Applications from './screens/Application';
import Credentials from './screens/Credential';
import CredentialTypes from './screens/CredentialType';
import Dashboard from './screens/Dashboard';
import Hosts from './screens/Host';
import InstanceGroups from './screens/InstanceGroup';
import Inventory from './screens/Inventory';
import InventoryScripts from './screens/InventoryScript';
import { Jobs } from './screens/Job';
import ManagementJobs from './screens/ManagementJob';
import NotificationTemplates from './screens/NotificationTemplate';
import Organizations from './screens/Organization';
import Portal from './screens/Portal';
import Projects from './screens/Project';
import Schedules from './screens/Schedule';
import AuthSettings from './screens/AuthSetting';
import JobsSettings from './screens/JobsSetting';
import SystemSettings from './screens/SystemSetting';
import UISettings from './screens/UISetting';
import License from './screens/License';
import Teams from './screens/Team';
import Templates from './screens/Template';
import Users from './screens/User';
// Ideally, this should just be a regular object that we export, but we
// need the i18n. When lingui3 arrives, we will be able to import i18n
// directly and we can replace this function with a simple export.
function getRouteConfig(i18n) {
return [
{
groupTitle: i18n._(t`Views`),
groupId: 'views_group',
routes: [
{
title: i18n._(t`Dashboard`),
path: '/home',
screen: Dashboard,
},
{
title: i18n._(t`Jobs`),
path: '/jobs',
screen: Jobs,
},
{
title: i18n._(t`Schedules`),
path: '/schedules',
screen: Schedules,
},
{
title: i18n._(t`My View`),
path: '/portal',
screen: Portal,
},
],
},
{
groupTitle: i18n._(t`Resources`),
groupId: 'resources_group',
routes: [
{
title: i18n._(t`Templates`),
path: '/templates',
screen: Templates,
},
{
title: i18n._(t`Credentials`),
path: '/credentials',
screen: Credentials,
},
{
title: i18n._(t`Projects`),
path: '/projects',
screen: Projects,
},
{
title: i18n._(t`Inventories`),
path: '/inventories',
screen: Inventory,
},
{
title: i18n._(t`Hosts`),
path: '/hosts',
screen: Hosts,
},
{
title: i18n._(t`Inventory Scripts`),
path: '/inventory_scripts',
screen: InventoryScripts,
},
],
},
{
groupTitle: i18n._(t`Access`),
groupId: 'access_group',
routes: [
{
title: i18n._(t`Organizations`),
path: '/organizations',
screen: Organizations,
},
{
title: i18n._(t`Users`),
path: '/users',
screen: Users,
},
{
title: i18n._(t`Teams`),
path: '/teams',
screen: Teams,
},
],
},
{
groupTitle: i18n._(t`Administration`),
groupId: 'administration_group',
routes: [
{
title: i18n._(t`Credential Types`),
path: '/credential_types',
screen: CredentialTypes,
},
{
title: i18n._(t`Notifications`),
path: '/notification_templates',
screen: NotificationTemplates,
},
{
title: i18n._(t`Management Jobs`),
path: '/management_jobs',
screen: ManagementJobs,
},
{
title: i18n._(t`Instance Groups`),
path: '/instance_groups',
screen: InstanceGroups,
},
{
title: i18n._(t`Integrations`),
path: '/applications',
screen: Applications,
},
],
},
{
groupTitle: i18n._(t`Settings`),
groupId: 'settings_group',
routes: [
{
title: i18n._(t`Authentication`),
path: '/auth_settings',
screen: AuthSettings,
},
{
title: i18n._(t`Jobs`),
path: '/jobs_settings',
screen: JobsSettings,
},
{
title: i18n._(t`System`),
path: '/system_settings',
screen: SystemSettings,
},
{
title: i18n._(t`User Interface`),
path: '/ui_settings',
screen: UISettings,
},
{
title: i18n._(t`License`),
path: '/license',
screen: License,
},
],
},
];
}
export default getRouteConfig;