mirror of
https://github.com/ansible/awx.git
synced 2026-02-26 07:26:03 -03:30
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:
@@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user