Update breadcrumb and fetch new hosts when url changes

This commit is contained in:
Marliana Lara
2019-11-20 15:56:05 -05:00
parent fa144aa98f
commit faa0802d97
4 changed files with 165 additions and 201 deletions

View File

@@ -1,4 +1,4 @@
import React, { Component } from 'react';
import React, { useEffect, useState } from 'react';
import { t } from '@lingui/macro';
import { withI18n } from '@lingui/react';
import { Card, CardHeader, PageSection } from '@patternfly/react-core';
@@ -16,54 +16,26 @@ import InventorySources from './InventorySources';
import { InventoriesAPI } from '@api';
import InventoryEdit from './InventoryEdit';
class Inventory extends Component {
constructor(props) {
super(props);
function Inventory({ history, i18n, location, match, setBreadcrumb }) {
const [contentError, setContentError] = useState(null);
const [hasContentLoading, setHasContentLoading] = useState(true);
const [inventory, setInventory] = useState(null);
this.state = {
contentError: null,
hasContentLoading: true,
inventory: null,
};
this.loadInventory = this.loadInventory.bind(this);
}
async componentDidMount() {
await this.loadInventory();
}
async componentDidUpdate(prevProps) {
const { location, match } = this.props;
const url = `/inventories/inventory/${match.params.id}/`;
if (
prevProps.location.pathname.startsWith(url) &&
prevProps.location !== location &&
location.pathname === `${url}details`
) {
await this.loadInventory();
}
}
async loadInventory() {
const { setBreadcrumb, match } = this.props;
const { id } = match.params;
this.setState({ contentError: null, hasContentLoading: true });
useEffect(() => {
async function fetchData() {
try {
const { data } = await InventoriesAPI.readDetail(id);
const { data } = await InventoriesAPI.readDetail(match.params.id);
setBreadcrumb(data);
this.setState({ inventory: data });
} catch (err) {
this.setState({ contentError: err });
setInventory(data);
} catch (error) {
setContentError(error);
} finally {
this.setState({ hasContentLoading: false });
setHasContentLoading(false);
}
}
render() {
const { history, i18n, location, match } = this.props;
const { contentError, hasContentLoading, inventory } = this.state;
fetchData();
}, [match.params.id, setBreadcrumb]);
const tabsArray = [
{ name: i18n._(t`Details`), link: `${match.url}/details`, id: 0 },
@@ -85,10 +57,7 @@ class Inventory extends Component {
</CardHeader>
);
if (
location.pathname.endsWith('edit') ||
location.pathname.endsWith('add')
) {
if (location.pathname.endsWith('edit') || location.pathname.endsWith('add')) {
cardHeader = null;
}
@@ -100,9 +69,7 @@ class Inventory extends Component {
{contentError.response.status === 404 && (
<span>
{i18n._(`Inventory not found.`)}{' '}
<Link to="/inventories">
{i18n._(`View all Inventories.`)}
</Link>
<Link to="/inventories">{i18n._(`View all Inventories.`)}</Link>
</span>
)}
</ContentError>
@@ -161,7 +128,7 @@ class Inventory extends Component {
<Route
key="hosts"
path="/inventories/inventory/:id/hosts"
render={() => <InventoryHosts inventory={inventory} />}
render={() => <InventoryHosts />}
/>,
<Route
key="sources"
@@ -195,7 +162,6 @@ class Inventory extends Component {
</Card>
</PageSection>
);
}
}
export { Inventory as _Inventory };

View File

@@ -1,4 +1,5 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { createMemoryHistory } from 'history';
import { InventoriesAPI } from '@api';
import { mountWithContexts, waitForElement } from '@testUtils/enzymeHelpers';
@@ -12,28 +13,24 @@ InventoriesAPI.readDetail.mockResolvedValue({
});
describe('<Inventory />', () => {
test('initially renders succesfully', async done => {
const wrapper = mountWithContexts(
let wrapper;
test('initially renders succesfully', async () => {
await act(async () => {
wrapper = mountWithContexts(
<Inventory setBreadcrumb={() => {}} match={{ params: { id: 1 } }} />
);
await waitForElement(
wrapper,
'Inventory',
el => el.state('hasContentLoading') === true
);
await waitForElement(
wrapper,
'Inventory',
el => el.state('hasContentLoading') === false
);
await waitForElement(wrapper, '.pf-c-tabs__item', el => el.length === 6);
done();
});
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
await waitForElement(wrapper, '.pf-c-tabs__item', el => el.length === 6);
});
test('should show content error when user attempts to navigate to erroneous route', async () => {
const history = createMemoryHistory({
initialEntries: ['/inventories/inventory/1/foobar'],
});
const wrapper = mountWithContexts(<Inventory setBreadcrumb={() => {}} />, {
await act(async () => {
wrapper = mountWithContexts(<Inventory setBreadcrumb={() => {}} />, {
context: {
router: {
history,
@@ -48,6 +45,7 @@ describe('<Inventory />', () => {
},
},
});
});
await waitForElement(wrapper, 'ContentError', el => el.length === 1);
});
});

View File

@@ -20,7 +20,7 @@ const QS_CONFIG = getQSConfig('host', {
order_by: 'name',
});
function InventoryHosts({ i18n, location, match, inventory }) {
function InventoryHosts({ i18n, location, match }) {
const [actions, setActions] = useState(null);
const [contentError, setContentError] = useState(null);
const [deletionError, setDeletionError] = useState(null);
@@ -47,7 +47,7 @@ function InventoryHosts({ i18n, location, match, inventory }) {
data: { actions: optionActions },
},
] = await Promise.all([
fetchHosts(inventory.id, location.search),
fetchHosts(match.params.id, location.search),
InventoriesAPI.readOptions(),
]);
@@ -62,7 +62,7 @@ function InventoryHosts({ i18n, location, match, inventory }) {
}
fetchData();
}, [inventory, location]);
}, [match.params.id, location]);
const handleSelectAll = isSelected => {
setSelected(isSelected ? [...hosts] : []);
@@ -88,7 +88,7 @@ function InventoryHosts({ i18n, location, match, inventory }) {
try {
const {
data: { count, results },
} = await fetchHosts(inventory.id, location.search);
} = await fetchHosts(match.params.id, location.search);
setHosts(results);
setHostCount(count);

View File

@@ -81,7 +81,7 @@ describe('<InventoryHosts />', () => {
},
});
await act(async () => {
wrapper = mountWithContexts(<InventoryHosts inventory={mockInventory} />);
wrapper = mountWithContexts(<InventoryHosts />);
});
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
});