Replace withRouter with react-router hooks in RoutedTabs

This commit is contained in:
Marliana Lara 2020-01-20 17:25:21 -05:00
parent 8b10da9589
commit 0952bae09f
No known key found for this signature in database
GPG Key ID: 38C73B40DFA809EE
14 changed files with 68 additions and 143 deletions

View File

@ -1,7 +1,7 @@
import React from 'react';
import { shape, string, number, arrayOf, node, oneOfType } from 'prop-types';
import { Tab, Tabs as PFTabs } from '@patternfly/react-core';
import { withRouter } from 'react-router-dom';
import { useHistory } from 'react-router-dom';
import styled from 'styled-components';
const Tabs = styled(PFTabs)`
@ -37,7 +37,8 @@ const Tabs = styled(PFTabs)`
`;
function RoutedTabs(props) {
const { history, tabsArray } = props;
const { tabsArray } = props;
const history = useHistory();
const getActiveTabId = () => {
const match = tabsArray.find(tab => tab.link === history.location.pathname);
@ -68,12 +69,8 @@ function RoutedTabs(props) {
</Tabs>
);
}
RoutedTabs.propTypes = {
history: shape({
location: shape({
pathname: string.isRequired,
}).isRequired,
}).isRequired,
tabsArray: arrayOf(
shape({
id: number.isRequired,
@ -83,5 +80,4 @@ RoutedTabs.propTypes = {
).isRequired,
};
export { RoutedTabs as _RoutedTabs };
export default withRouter(RoutedTabs);
export default RoutedTabs;

View File

@ -1,10 +1,9 @@
/* eslint-disable react/jsx-pascal-case */
import React from 'react';
import { mount, shallow } from 'enzyme';
import { mount } from 'enzyme';
import { Router } from 'react-router-dom';
import { createMemoryHistory } from 'history';
import { Tab } from '@patternfly/react-core';
import RoutedTabs, { _RoutedTabs } from './RoutedTabs';
import RoutedTabs from './RoutedTabs';
let wrapper;
let history;
@ -21,32 +20,24 @@ describe('<RoutedTabs />', () => {
history = createMemoryHistory({
initialEntries: ['/organizations/19/teams'],
});
});
test('RoutedTabs renders successfully', () => {
wrapper = shallow(<_RoutedTabs tabsArray={tabs} history={history} />);
expect(wrapper.find(Tab)).toHaveLength(4);
});
test('Given a URL the correct tab is active', async () => {
wrapper = mount(
<Router history={history}>
<RoutedTabs tabsArray={tabs} />
</Router>
);
});
test('RoutedTabs renders successfully', () => {
expect(wrapper.find('Tabs li')).toHaveLength(4);
});
test('Given a URL the correct tab is active', async () => {
expect(history.location.pathname).toEqual('/organizations/19/teams');
expect(wrapper.find('Tabs').prop('activeKey')).toBe(3);
});
test('should update history when new tab selected', async () => {
wrapper = mount(
<Router history={history}>
<RoutedTabs tabsArray={tabs} />
</Router>
);
wrapper.find('Tabs').prop('onSelect')({}, 2);
wrapper.find('Tabs').invoke('onSelect')({}, 2);
wrapper.update();
expect(history.location.pathname).toEqual('/organizations/19/access');

View File

@ -5,7 +5,6 @@ import { Card, PageSection } from '@patternfly/react-core';
import {
Switch,
useParams,
useHistory,
useLocation,
Route,
Redirect,
@ -22,7 +21,6 @@ function Credential({ i18n, setBreadcrumb }) {
const [credential, setCredential] = useState(null);
const [contentError, setContentError] = useState(null);
const [hasContentLoading, setHasContentLoading] = useState(true);
const history = useHistory();
const location = useLocation();
const { id } = useParams();
@ -53,7 +51,7 @@ function Credential({ i18n, setBreadcrumb }) {
let cardHeader = hasContentLoading ? null : (
<TabbedCardHeader>
<RoutedTabs history={history} tabsArray={tabsArray} />
<RoutedTabs tabsArray={tabsArray} />
<CardCloseButton linkTo="/credentials" />
</TabbedCardHeader>
);

View File

@ -74,6 +74,7 @@ class Host extends Component {
render() {
const { location, match, history, i18n } = this.props;
const { host, hasContentLoading, isInitialized, contentError } = this.state;
const tabsArray = [
{
name: i18n._(t`Details`),
@ -96,6 +97,7 @@ class Host extends Component {
id: 3,
},
];
if (!history.location.pathname.startsWith('/hosts')) {
tabsArray.unshift({
name: (
@ -108,14 +110,10 @@ class Host extends Component {
id: 99,
});
}
let cardHeader = (
<TabbedCardHeader>
<RoutedTabs
match={match}
history={history}
labeltext={i18n._(t`Host detail tabs`)}
tabsArray={tabsArray}
/>
<RoutedTabs tabsArray={tabsArray} />
<CardCloseButton linkTo="/hosts" />
</TabbedCardHeader>
);
@ -124,10 +122,6 @@ class Host extends Component {
cardHeader = null;
}
if (!match) {
cardHeader = null;
}
if (location.pathname.endsWith('edit')) {
cardHeader = null;
}
@ -150,6 +144,7 @@ class Host extends Component {
</Card>
);
}
const redirect = location.pathname.startsWith('/hosts') ? (
<Redirect from="/hosts/:id" to="/hosts/:id/details" exact />
) : (
@ -159,6 +154,7 @@ class Host extends Component {
exact
/>
);
return (
<Card className="awx-c-card">
{cardHeader}
@ -185,7 +181,7 @@ class Host extends Component {
'/hosts/:id/edit',
'/inventories/inventory/:id/hosts/:hostId/edit',
]}
render={() => <HostEdit match={match} host={host} />}
render={() => <HostEdit host={host} />}
/>
)}
{host && (

View File

@ -7,7 +7,6 @@ import {
Route,
Redirect,
Link,
useHistory,
useLocation,
useRouteMatch,
} from 'react-router-dom';
@ -30,7 +29,6 @@ function Inventory({ i18n, setBreadcrumb }) {
const [contentError, setContentError] = useState(null);
const [hasContentLoading, setHasContentLoading] = useState(true);
const [inventory, setInventory] = useState(null);
const history = useHistory();
const location = useLocation();
const match = useRouteMatch({
path: '/inventories/inventory/:id',
@ -67,7 +65,7 @@ function Inventory({ i18n, setBreadcrumb }) {
let cardHeader = hasContentLoading ? null : (
<TabbedCardHeader>
<RoutedTabs history={history} tabsArray={tabsArray} />
<RoutedTabs tabsArray={tabsArray} />
<CardCloseButton linkTo="/inventories" />
</TabbedCardHeader>
);
@ -80,6 +78,7 @@ function Inventory({ i18n, setBreadcrumb }) {
) {
cardHeader = null;
}
if (hasContentLoading) {
return <ContentLoading />;
}
@ -117,7 +116,6 @@ function Inventory({ i18n, setBreadcrumb }) {
path="/inventories/inventory/:id/details"
render={() => (
<InventoryDetail
match={match}
hasInventoryLoading={hasContentLoading}
inventory={inventory}
/>
@ -133,9 +131,7 @@ function Inventory({ i18n, setBreadcrumb }) {
path="/inventories/inventory/:id/hosts"
render={() => (
<InventoryHosts
match={match}
setBreadcrumb={setBreadcrumb}
i18n={i18n}
inventory={inventory}
/>
)}
@ -155,8 +151,6 @@ function Inventory({ i18n, setBreadcrumb }) {
path="/inventories/inventory/:id/groups"
render={() => (
<InventoryGroups
location={location}
match={match}
setBreadcrumb={setBreadcrumb}
inventory={inventory}
/>

View File

@ -1,9 +1,16 @@
import React, { useEffect, useState } from 'react';
import { t } from '@lingui/macro';
import { withI18n } from '@lingui/react';
import { Switch, Route, withRouter, Link, Redirect } from 'react-router-dom';
import { CaretLeftIcon } from '@patternfly/react-icons';
import {
Switch,
Route,
Link,
Redirect,
useLocation,
useParams,
} from 'react-router-dom';
import { CaretLeftIcon } from '@patternfly/react-icons';
import { GroupsAPI } from '@api';
import CardCloseButton from '@components/CardCloseButton';
import RoutedTabs from '@components/RoutedTabs';
@ -13,15 +20,17 @@ import { TabbedCardHeader } from '@components/Card';
import InventoryGroupEdit from '../InventoryGroupEdit/InventoryGroupEdit';
import InventoryGroupDetail from '../InventoryGroupDetail/InventoryGroupDetail';
function InventoryGroups({ i18n, match, setBreadcrumb, inventory, history }) {
function InventoryGroup({ i18n, setBreadcrumb, inventory }) {
const [inventoryGroup, setInventoryGroup] = useState(null);
const [contentLoading, setContentLoading] = useState(true);
const [contentError, setContentError] = useState(null);
const { id: inventoryId, groupId } = useParams();
const location = useLocation();
useEffect(() => {
const loadData = async () => {
try {
const { data } = await GroupsAPI.readDetail(match.params.groupId);
const { data } = await GroupsAPI.readDetail(groupId);
setInventoryGroup(data);
setBreadcrumb(inventory, data);
} catch (err) {
@ -32,12 +41,7 @@ function InventoryGroups({ i18n, match, setBreadcrumb, inventory, history }) {
};
loadData();
}, [
history.location.pathname,
match.params.groupId,
inventory,
setBreadcrumb,
]);
}, [location.pathname, groupId, inventory, setBreadcrumb]);
const tabsArray = [
{
@ -80,7 +84,7 @@ function InventoryGroups({ i18n, match, setBreadcrumb, inventory, history }) {
}
if (
inventoryGroup.summary_fields.inventory.id !== parseInt(match.params.id, 10)
inventoryGroup.summary_fields.inventory.id !== parseInt(inventoryId, 10)
) {
return (
<ContentError>
@ -99,12 +103,12 @@ function InventoryGroups({ i18n, match, setBreadcrumb, inventory, history }) {
let cardHeader = null;
if (
history.location.pathname.includes('groups/') &&
!history.location.pathname.endsWith('edit')
location.pathname.includes('groups/') &&
!location.pathname.endsWith('edit')
) {
cardHeader = (
<TabbedCardHeader>
<RoutedTabs history={history} tabsArray={tabsArray} />
<RoutedTabs tabsArray={tabsArray} />
<CardCloseButton
linkTo={`/inventories/inventory/${inventory.id}/groups`}
/>
@ -124,15 +128,9 @@ function InventoryGroups({ i18n, match, setBreadcrumb, inventory, history }) {
<Route
key="edit"
path="/inventories/inventory/:id/groups/:groupId/edit"
render={() => {
return (
<InventoryGroupEdit
inventory={inventory}
inventoryGroup={inventoryGroup}
/>
);
}}
/>,
>
<InventoryGroupEdit inventoryGroup={inventoryGroup} />
</Route>,
<Route
key="details"
path="/inventories/inventory/:id/groups/:groupId/details"
@ -161,5 +159,5 @@ function InventoryGroups({ i18n, match, setBreadcrumb, inventory, history }) {
);
}
export { InventoryGroups as _InventoryGroups };
export default withI18n()(withRouter(InventoryGroups));
export { InventoryGroup as _InventoryGroup };
export default withI18n()(InventoryGroup);

View File

@ -60,7 +60,7 @@ class SmartInventory extends Component {
}
render() {
const { history, i18n, location, match } = this.props;
const { i18n, location, match } = this.props;
const { contentError, hasContentLoading, inventory } = this.state;
const tabsArray = [
@ -76,7 +76,7 @@ class SmartInventory extends Component {
let cardHeader = hasContentLoading ? null : (
<TabbedCardHeader>
<RoutedTabs history={history} tabsArray={tabsArray} />
<RoutedTabs tabsArray={tabsArray} />
<CardCloseButton linkTo="/inventories" />
</TabbedCardHeader>
);
@ -119,7 +119,6 @@ class SmartInventory extends Component {
path="/inventories/smart_inventory/:id/details"
render={() => (
<SmartInventoryDetail
match={match}
hasSmartInventoryLoading={hasContentLoading}
inventory={inventory}
/>

View File

@ -56,7 +56,7 @@ class Job extends Component {
}
render() {
const { history, match, i18n, lookup } = this.props;
const { match, i18n, lookup } = this.props;
const { job, contentError, hasContentLoading, isInitialized } = this.state;
let jobType;
@ -71,7 +71,7 @@ class Job extends Component {
let cardHeader = (
<TabbedCardHeader>
<RoutedTabs match={match} history={history} tabsArray={tabsArray} />
<RoutedTabs tabsArray={tabsArray} />
<CardCloseButton linkTo="/jobs" />
</TabbedCardHeader>
);
@ -80,10 +80,6 @@ class Job extends Component {
cardHeader = null;
}
if (!match) {
cardHeader = null;
}
if (!hasContentLoading && contentError) {
return (
<PageSection>

View File

@ -97,7 +97,7 @@ class Organization extends Component {
}
render() {
const { location, match, me, history, i18n } = this.props;
const { location, match, me, i18n } = this.props;
const {
organization,
@ -131,12 +131,7 @@ class Organization extends Component {
let cardHeader = (
<TabbedCardHeader>
<RoutedTabs
match={match}
history={history}
labeltext={i18n._(t`Organization detail tabs`)}
tabsArray={tabsArray}
/>
<RoutedTabs tabsArray={tabsArray} />
<CardCloseButton linkTo="/organizations" />
</TabbedCardHeader>
);
@ -145,10 +140,6 @@ class Organization extends Component {
cardHeader = null;
}
if (!match) {
cardHeader = null;
}
if (location.pathname.endsWith('edit')) {
cardHeader = null;
}
@ -185,19 +176,14 @@ class Organization extends Component {
{organization && (
<Route
path="/organizations/:id/edit"
render={() => (
<OrganizationEdit match={match} organization={organization} />
)}
render={() => <OrganizationEdit organization={organization} />}
/>
)}
{organization && (
<Route
path="/organizations/:id/details"
render={() => (
<OrganizationDetail
match={match}
organization={organization}
/>
<OrganizationDetail organization={organization} />
)}
/>
)}

View File

@ -104,7 +104,7 @@ class Project extends Component {
}
render() {
const { location, match, me, history, i18n } = this.props;
const { location, match, me, i18n } = this.props;
const {
project,
@ -151,12 +151,7 @@ class Project extends Component {
let cardHeader = (
<TabbedCardHeader>
<RoutedTabs
match={match}
history={history}
labeltext={i18n._(t`Project detail tabs`)}
tabsArray={tabsArray}
/>
<RoutedTabs tabsArray={tabsArray} />
<CardCloseButton linkTo="/projects" />
</TabbedCardHeader>
);
@ -165,10 +160,6 @@ class Project extends Component {
cardHeader = null;
}
if (!match) {
cardHeader = null;
}
if (location.pathname.endsWith('edit')) {
cardHeader = null;
}
@ -199,7 +190,7 @@ class Project extends Component {
{project && (
<Route
path="/projects/:id/edit"
render={() => <ProjectEdit match={match} project={project} />}
render={() => <ProjectEdit project={project} />}
/>
)}
{project && (

View File

@ -59,7 +59,7 @@ class Team extends Component {
}
render() {
const { location, match, history, i18n } = this.props;
const { location, match, i18n } = this.props;
const { team, contentError, hasContentLoading, isInitialized } = this.state;
@ -71,12 +71,7 @@ class Team extends Component {
let cardHeader = (
<TabbedCardHeader>
<RoutedTabs
match={match}
history={history}
labeltext={i18n._(t`Team detail tabs`)}
tabsArray={tabsArray}
/>
<RoutedTabs tabsArray={tabsArray} />
<CardCloseButton linkTo="/teams" />
</TabbedCardHeader>
);
@ -85,10 +80,6 @@ class Team extends Component {
cardHeader = null;
}
if (!match) {
cardHeader = null;
}
if (location.pathname.endsWith('edit')) {
cardHeader = null;
}
@ -119,7 +110,7 @@ class Team extends Component {
{team && (
<Route
path="/teams/:id/edit"
render={() => <TeamEdit match={match} team={team} />}
render={() => <TeamEdit team={team} />}
/>
)}
{team && (

View File

@ -80,7 +80,7 @@ class Template extends Component {
}
render() {
const { history, i18n, location, match, me } = this.props;
const { i18n, location, match, me } = this.props;
const {
contentError,
hasContentLoading,
@ -123,7 +123,7 @@ class Template extends Component {
let cardHeader = (
<TabbedCardHeader>
<RoutedTabs history={history} tabsArray={tabsArray} />
<RoutedTabs tabsArray={tabsArray} />
<CardCloseButton linkTo="/templates" />
</TabbedCardHeader>
);
@ -165,7 +165,6 @@ class Template extends Component {
path="/templates/:templateType/:id/details"
render={() => (
<JobTemplateDetail
match={match}
hasTemplateLoading={hasContentLoading}
template={template}
/>

View File

@ -53,7 +53,7 @@ class WorkflowJobTemplate extends Component {
}
render() {
const { history, i18n, location, match } = this.props;
const { i18n, location, match } = this.props;
const { contentError, hasContentLoading, template } = this.state;
const tabsArray = [
@ -67,7 +67,7 @@ class WorkflowJobTemplate extends Component {
let cardHeader = hasContentLoading ? null : (
<TabbedCardHeader>
<RoutedTabs history={history} tabsArray={tabsArray} />
<RoutedTabs tabsArray={tabsArray} />
<CardCloseButton linkTo="/templates" />
</TabbedCardHeader>
);
@ -109,7 +109,6 @@ class WorkflowJobTemplate extends Component {
path="/templates/workflow_job_template/:id/details"
render={() => (
<WorkflowJobTemplateDetail
match={match}
hasTemplateLoading={hasContentLoading}
template={template}
/>

View File

@ -62,7 +62,7 @@ class User extends Component {
}
render() {
const { location, match, history, i18n } = this.props;
const { location, match, i18n } = this.props;
const { user, contentError, hasContentLoading, isInitialized } = this.state;
@ -80,12 +80,7 @@ class User extends Component {
let cardHeader = (
<TabbedCardHeader>
<RoutedTabs
match={match}
history={history}
labeltext={i18n._(t`User detail tabs`)}
tabsArray={tabsArray}
/>
<RoutedTabs tabsArray={tabsArray} />
<CardCloseButton linkTo="/users" />
</TabbedCardHeader>
);
@ -94,10 +89,6 @@ class User extends Component {
cardHeader = null;
}
if (!match) {
cardHeader = null;
}
if (location.pathname.endsWith('edit')) {
cardHeader = null;
}
@ -128,7 +119,7 @@ class User extends Component {
{user && (
<Route
path="/users/:id/edit"
render={() => <UserEdit match={match} user={user} />}
render={() => <UserEdit user={user} />}
/>
)}
{user && (