Merge pull request #6228 from jakemcdermott/6191-fix-unnecessary-panel-reload-02

Fix unnecessary panel reload and refactor top-level host and inventory routing components

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
This commit is contained in:
softwarefactory-project-zuul[bot]
2020-03-09 20:03:44 +00:00
committed by GitHub
5 changed files with 137 additions and 182 deletions

View File

@@ -9,7 +9,7 @@ import {
useRouteMatch, useRouteMatch,
useLocation, useLocation,
} from 'react-router-dom'; } from 'react-router-dom';
import { Card, CardActions } from '@patternfly/react-core'; import { Card, CardActions, PageSection } from '@patternfly/react-core';
import { TabbedCardHeader } from '@components/Card'; import { TabbedCardHeader } from '@components/Card';
import CardCloseButton from '@components/CardCloseButton'; import CardCloseButton from '@components/CardCloseButton';
@@ -34,11 +34,8 @@ function Host({ i18n, setBreadcrumb }) {
useEffect(() => { useEffect(() => {
(async () => { (async () => {
setContentError(null); setContentError(null);
setHasContentLoading(true);
try { try {
const { data } = await HostsAPI.readDetail(match.params.id); const { data } = await HostsAPI.readDetail(match.params.id);
setHost(data); setHost(data);
setBreadcrumb(data); setBreadcrumb(data);
} catch (error) { } catch (error) {
@@ -47,7 +44,7 @@ function Host({ i18n, setBreadcrumb }) {
setHasContentLoading(false); setHasContentLoading(false);
} }
})(); })();
}, [location]); // eslint-disable-line react-hooks/exhaustive-deps }, [match.params.id, location, setBreadcrumb]);
const tabsArray = [ const tabsArray = [
{ {
@@ -72,75 +69,73 @@ function Host({ i18n, setBreadcrumb }) {
}, },
]; ];
let cardHeader = (
<TabbedCardHeader>
<RoutedTabs tabsArray={tabsArray} />
<CardActions>
<CardCloseButton linkTo="/hosts" />
</CardActions>
</TabbedCardHeader>
);
if (location.pathname.endsWith('edit')) {
cardHeader = null;
}
if (hasContentLoading) { if (hasContentLoading) {
return <ContentLoading />; return (
<PageSection>
<Card>
<ContentLoading />
</Card>
</PageSection>
);
} }
if (!hasContentLoading && contentError) { if (contentError) {
return ( return (
<Card> <PageSection>
<ContentError error={contentError}> <Card>
{contentError.response && contentError.response.status === 404 && ( <ContentError error={contentError}>
<span> {contentError?.response?.status === 404 && (
{i18n._(`Host not found.`)}{' '} <span>
<Link to="/hosts">{i18n._(`View all Hosts.`)}</Link> {i18n._(`Host not found.`)}{' '}
</span> <Link to="/hosts">{i18n._(`View all Hosts.`)}</Link>
)} </span>
</ContentError> )}
</Card> </ContentError>
</Card>
</PageSection>
); );
} }
return ( return (
<Card> <PageSection>
{cardHeader} <Card>
<Switch> {location.pathname.endsWith('edit') ? null : (
<Redirect from="/hosts/:id" to="/hosts/:id/details" exact /> <TabbedCardHeader>
{host && [ <RoutedTabs tabsArray={tabsArray} />
<Route path="/hosts/:id/details" key="details"> <CardActions>
<HostDetail host={host} /> <CardCloseButton linkTo="/hosts" />
</Route>, </CardActions>
<Route path="/hosts/:id/edit" key="edit"> </TabbedCardHeader>
<HostEdit host={host} /> )}
</Route>, <Switch>
<Route path="/hosts/:id/facts" key="facts"> <Redirect from="/hosts/:id" to="/hosts/:id/details" exact />
<HostFacts host={host} /> {host && [
</Route>, <Route path="/hosts/:id/details" key="details">
<Route path="/hosts/:id/groups" key="groups"> <HostDetail host={host} />
<HostGroups host={host} /> </Route>,
</Route>, <Route path="/hosts/:id/edit" key="edit">
<Route path="/hosts/:id/completed_jobs" key="completed-jobs"> <HostEdit host={host} />
<JobList defaultParams={{ job__hosts: host.id }} /> </Route>,
</Route>, <Route path="/hosts/:id/facts" key="facts">
]} <HostFacts host={host} />
<Route </Route>,
key="not-found" <Route path="/hosts/:id/groups" key="groups">
path="*" <HostGroups host={host} />
render={() => </Route>,
!hasContentLoading && ( <Route path="/hosts/:id/completed_jobs" key="completed-jobs">
<ContentError isNotFound> <JobList defaultParams={{ job__hosts: host.id }} />
<Link to={`${match.url}/details`}> </Route>,
{i18n._(`View Host Details`)} ]}
</Link> <Route key="not-found" path="*">
</ContentError> <ContentError isNotFound>
) <Link to={`${match.url}/details`}>
} {i18n._(`View Host Details`)}
/> </Link>
</Switch> </ContentError>
</Card> </Route>
</Switch>
</Card>
</PageSection>
); );
} }

View File

@@ -1,8 +1,8 @@
import React, { Fragment, useState, useEffect, useCallback } from 'react'; import React, { useState, useEffect, useCallback } from 'react';
import { useLocation, useRouteMatch } from 'react-router-dom'; import { useLocation, useRouteMatch } from 'react-router-dom';
import { withI18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Card } from '@patternfly/react-core'; import { Card, PageSection } from '@patternfly/react-core';
import { HostsAPI } from '@api'; import { HostsAPI } from '@api';
import AlertModal from '@components/AlertModal'; import AlertModal from '@components/AlertModal';
@@ -95,7 +95,7 @@ function HostList({ i18n }) {
actions && Object.prototype.hasOwnProperty.call(actions, 'POST'); actions && Object.prototype.hasOwnProperty.call(actions, 'POST');
return ( return (
<Fragment> <PageSection>
<Card> <Card>
<PaginatedDataList <PaginatedDataList
contentError={contentError} contentError={contentError}
@@ -173,7 +173,7 @@ function HostList({ i18n }) {
<ErrorDetail error={deletionError} /> <ErrorDetail error={deletionError} />
</AlertModal> </AlertModal>
)} )}
</Fragment> </PageSection>
); );
} }

View File

@@ -4,7 +4,6 @@ import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Config } from '@contexts/Config'; import { Config } from '@contexts/Config';
import { PageSection, Card } from '@patternfly/react-core';
import Breadcrumbs from '@components/Breadcrumbs/Breadcrumbs'; import Breadcrumbs from '@components/Breadcrumbs/Breadcrumbs';
import HostList from './HostList'; import HostList from './HostList';
@@ -39,25 +38,21 @@ function Hosts({ i18n }) {
return ( return (
<> <>
<Breadcrumbs breadcrumbConfig={breadcrumbConfig} /> <Breadcrumbs breadcrumbConfig={breadcrumbConfig} />
<PageSection> <Switch>
<Card> <Route path="/hosts/add">
<Switch> <HostAdd />
<Route path="/hosts/add"> </Route>
<HostAdd /> <Route path="/hosts/:id">
</Route> <Config>
<Route path="/hosts/:id"> {({ me }) => (
<Config> <Host setBreadcrumb={buildBreadcrumbConfig} me={me || {}} />
{({ me }) => ( )}
<Host setBreadcrumb={buildBreadcrumbConfig} me={me || {}} /> </Config>
)} </Route>
</Config> <Route path="/hosts">
</Route> <HostList />
<Route path="/hosts"> </Route>
<HostList /> </Switch>
</Route>
</Switch>
</Card>
</PageSection>
</> </>
); );
} }

View File

@@ -1,4 +1,4 @@
import React, { Component, Fragment } from 'react'; import React, { Component } from 'react';
import { withI18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Route, withRouter, Switch } from 'react-router-dom'; import { Route, withRouter, Switch } from 'react-router-dom';
@@ -95,7 +95,7 @@ class Inventories extends Component {
const { match, history, location } = this.props; const { match, history, location } = this.props;
const { breadcrumbConfig } = this.state; const { breadcrumbConfig } = this.state;
return ( return (
<Fragment> <>
<Breadcrumbs breadcrumbConfig={breadcrumbConfig} /> <Breadcrumbs breadcrumbConfig={breadcrumbConfig} />
<Switch> <Switch>
<Route <Route
@@ -134,7 +134,7 @@ class Inventories extends Component {
/> />
<Route path={`${match.path}`} render={() => <InventoryList />} /> <Route path={`${match.path}`} render={() => <InventoryList />} />
</Switch> </Switch>
</Fragment> </>
); );
} }
} }

View File

@@ -63,24 +63,6 @@ function Inventory({ i18n, setBreadcrumb }) {
}, },
]; ];
let cardHeader = hasContentLoading ? null : (
<TabbedCardHeader>
<RoutedTabs tabsArray={tabsArray} />
<CardActions>
<CardCloseButton linkTo="/inventories" />
</CardActions>
</TabbedCardHeader>
);
if (
location.pathname.endsWith('edit') ||
location.pathname.endsWith('add') ||
location.pathname.includes('groups/') ||
location.pathname.includes('hosts/')
) {
cardHeader = null;
}
if (hasContentLoading) { if (hasContentLoading) {
return ( return (
<PageSection> <PageSection>
@@ -91,12 +73,12 @@ function Inventory({ i18n, setBreadcrumb }) {
); );
} }
if (!hasContentLoading && contentError) { if (contentError) {
return ( return (
<PageSection> <PageSection>
<Card> <Card>
<ContentError error={contentError}> <ContentError error={contentError}>
{contentError.response.status === 404 && ( {contentError.response?.status === 404 && (
<span> <span>
{i18n._(`Inventory not found.`)}{' '} {i18n._(`Inventory not found.`)}{' '}
<Link to="/inventories">{i18n._(`View all Inventories.`)}</Link> <Link to="/inventories">{i18n._(`View all Inventories.`)}</Link>
@@ -111,7 +93,16 @@ function Inventory({ i18n, setBreadcrumb }) {
return ( return (
<PageSection> <PageSection>
<Card> <Card>
{cardHeader} {['edit', 'add', 'groups/', 'hosts/'].some(name =>
location.pathname.includes(name)
) ? null : (
<TabbedCardHeader>
<RoutedTabs tabsArray={tabsArray} />
<CardActions>
<CardCloseButton linkTo="/inventories" />
</CardActions>
</TabbedCardHeader>
)}
<Switch> <Switch>
<Redirect <Redirect
from="/inventories/inventory/:id" from="/inventories/inventory/:id"
@@ -119,59 +110,39 @@ function Inventory({ i18n, setBreadcrumb }) {
exact exact
/> />
{inventory && [ {inventory && [
<Route path="/inventories/inventory/:id/details" key="details">
<InventoryDetail
inventory={inventory}
hasInventoryLoading={hasContentLoading}
/>
</Route>,
<Route path="/inventories/inventory/:id/edit" key="edit">
<InventoryEdit inventory={inventory} />
</Route>,
<Route path="/inventories/inventory/:id/hosts" key="hosts">
<InventoryHosts
inventory={inventory}
setBreadcrumb={setBreadcrumb}
/>
</Route>,
<Route path="/inventories/inventory/:id/access" key="access">
<ResourceAccessList
resource={inventory}
apiModel={InventoriesAPI}
/>
</Route>,
<Route path="/inventories/inventory/:id/groups" key="groups">
<InventoryGroups
inventory={inventory}
setBreadcrumb={setBreadcrumb}
/>
</Route>,
<Route path="/inventories/inventory/:id/sources" key="sources">
<InventorySources inventory={inventory} />
</Route>,
<Route <Route
key="details"
path="/inventories/inventory/:id/details"
render={() => (
<InventoryDetail
hasInventoryLoading={hasContentLoading}
inventory={inventory}
/>
)}
/>,
<Route
key="edit"
path="/inventories/inventory/:id/edit"
render={() => <InventoryEdit inventory={inventory} />}
/>,
<Route
key="hosts"
path="/inventories/inventory/:id/hosts"
render={() => (
<InventoryHosts
setBreadcrumb={setBreadcrumb}
inventory={inventory}
/>
)}
/>,
<Route
key="access"
path="/inventories/inventory/:id/access"
render={() => (
<ResourceAccessList
resource={inventory}
apiModel={InventoriesAPI}
/>
)}
/>,
<Route
key="groups"
path="/inventories/inventory/:id/groups"
render={() => (
<InventoryGroups
setBreadcrumb={setBreadcrumb}
inventory={inventory}
/>
)}
/>,
<Route
key="sources"
path="/inventories/inventory/:id/sources"
render={() => <InventorySources inventory={inventory} />}
/>,
<Route
key="completed_jobs"
path="/inventories/inventory/:id/completed_jobs" path="/inventories/inventory/:id/completed_jobs"
key="completed_jobs"
> >
<JobList <JobList
defaultParams={{ defaultParams={{
@@ -183,23 +154,17 @@ function Inventory({ i18n, setBreadcrumb }) {
}} }}
/> />
</Route>, </Route>,
<Route <Route path="*" key="not-found">
key="not-found" <ContentError isNotFound>
path="*" {match.params.id && (
render={() => <Link
!hasContentLoading && ( to={`/inventories/inventory/${match.params.id}/details`}
<ContentError isNotFound> >
{match.params.id && ( {i18n._(`View Inventory Details`)}
<Link </Link>
to={`/inventories/inventory/${match.params.id}/details`} )}
> </ContentError>
{i18n._(`View Inventory Details`)} </Route>,
</Link>
)}
</ContentError>
)
}
/>,
]} ]}
</Switch> </Switch>
</Card> </Card>