diff --git a/awx/ui_next/src/api/models/Inventories.js b/awx/ui_next/src/api/models/Inventories.js
index 858e7a390a..becba96649 100644
--- a/awx/ui_next/src/api/models/Inventories.js
+++ b/awx/ui_next/src/api/models/Inventories.js
@@ -8,6 +8,7 @@ class Inventories extends InstanceGroupsMixin(Base) {
this.readAccessList = this.readAccessList.bind(this);
this.readHosts = this.readHosts.bind(this);
+ this.readHostDetail = this.readHostDetail.bind(this);
this.readGroups = this.readGroups.bind(this);
this.readGroupsOptions = this.readGroupsOptions.bind(this);
this.promoteGroup = this.promoteGroup.bind(this);
@@ -27,6 +28,22 @@ class Inventories extends InstanceGroupsMixin(Base) {
return this.http.get(`${this.baseUrl}${id}/hosts/`, { params });
}
+ async readHostDetail(inventoryId, hostId) {
+ const {
+ data: { results },
+ } = await this.http.get(
+ `${this.baseUrl}${inventoryId}/hosts/?id=${hostId}`
+ );
+
+ if (Array.isArray(results) && results.length) {
+ return results[0];
+ }
+
+ throw new Error(
+ `How did you get here? Host not found for Inventory ID: ${inventoryId}`
+ );
+ }
+
readGroups(id, params) {
return this.http.get(`${this.baseUrl}${id}/groups/`, { params });
}
diff --git a/awx/ui_next/src/screens/Inventory/InventoryHost/InventoryHost.jsx b/awx/ui_next/src/screens/Inventory/InventoryHost/InventoryHost.jsx
index 89121e8cd5..3c07032096 100644
--- a/awx/ui_next/src/screens/Inventory/InventoryHost/InventoryHost.jsx
+++ b/awx/ui_next/src/screens/Inventory/InventoryHost/InventoryHost.jsx
@@ -11,7 +11,7 @@ import {
} from 'react-router-dom';
import useRequest from '@util/useRequest';
-import { HostsAPI } from '@api';
+import { InventoriesAPI } from '@api';
import { Card, CardActions } from '@patternfly/react-core';
import { CaretLeftIcon } from '@patternfly/react-icons';
import { TabbedCardHeader } from '@components/Card';
@@ -35,12 +35,14 @@ function InventoryHost({ i18n, setBreadcrumb, inventory }) {
request: fetchHost,
} = useRequest(
useCallback(async () => {
- const { data } = await HostsAPI.readDetail(match.params.hostId);
-
+ const response = await InventoriesAPI.readHostDetail(
+ inventory.id,
+ match.params.hostId
+ );
return {
- host: data,
+ host: response,
};
- }, [match.params.hostId]), // eslint-disable-line react-hooks/exhaustive-deps
+ }, [inventory.id, match.params.hostId]),
{
host: null,
}
@@ -48,7 +50,7 @@ function InventoryHost({ i18n, setBreadcrumb, inventory }) {
useEffect(() => {
fetchHost();
- }, [fetchHost]);
+ }, [fetchHost, location.pathname]);
useEffect(() => {
if (inventory && host) {
@@ -89,24 +91,7 @@ function InventoryHost({ i18n, setBreadcrumb, inventory }) {
},
];
- let cardHeader = (
-
-
-
-
-
-
- );
-
- if (location.pathname.endsWith('edit')) {
- cardHeader = null;
- }
-
- if (isLoading) {
- return ;
- }
-
- if (!isLoading && contentError) {
+ if (contentError) {
return (
@@ -125,48 +110,51 @@ function InventoryHost({ i18n, setBreadcrumb, inventory }) {
return (
<>
- {cardHeader}
-
-
- {host &&
- inventory && [
-
-
- ,
-
-
- ,
-
-
- ,
- ]}
-
- !isLoading && (
-
-
- {i18n._(`View Inventory Host Details`)}
-
-
- )
- }
- />
-
+ {['edit'].some(name => location.pathname.includes(name)) ? null : (
+
+
+
+
+
+
+ )}
+
+ {isLoading && }
+
+ {!isLoading && host && (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {i18n._(`View Inventory Host Details`)}
+
+
+
+
+ )}
>
);
}
diff --git a/awx/ui_next/src/screens/Inventory/InventoryHost/InventoryHost.test.jsx b/awx/ui_next/src/screens/Inventory/InventoryHost/InventoryHost.test.jsx
index bea26df827..0d73f4d04a 100644
--- a/awx/ui_next/src/screens/Inventory/InventoryHost/InventoryHost.test.jsx
+++ b/awx/ui_next/src/screens/Inventory/InventoryHost/InventoryHost.test.jsx
@@ -1,7 +1,7 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { createMemoryHistory } from 'history';
-import { HostsAPI } from '@api';
+import { InventoriesAPI } from '@api';
import { mountWithContexts, waitForElement } from '@testUtils/enzymeHelpers';
import mockHost from '../shared/data.host.json';
import InventoryHost from './InventoryHost';
@@ -15,7 +15,7 @@ jest.mock('react-router-dom', () => ({
}),
}));
-HostsAPI.readDetail.mockResolvedValue({
+InventoriesAPI.readHostDetail.mockResolvedValue({
data: { ...mockHost },
});
@@ -54,7 +54,7 @@ describe('', () => {
});
test('should show content error when api throws error on initial render', async () => {
- HostsAPI.readDetail.mockRejectedValueOnce(new Error());
+ InventoriesAPI.readHostDetail.mockRejectedValueOnce(new Error());
await act(async () => {
wrapper = mountWithContexts(
{}} />
@@ -76,4 +76,13 @@ describe('', () => {
});
await waitForElement(wrapper, 'ContentError', el => el.length === 1);
});
+
+ test('should show content error when inventory id does not match host inventory', async () => {
+ await act(async () => {
+ wrapper = mountWithContexts(
+ {}} />
+ );
+ });
+ await waitForElement(wrapper, 'ContentError', el => el.length === 1);
+ });
});