diff --git a/awx/ui/src/screens/Inventory/ConstructedInventoryDetail/ConstructedInventoryDetail.js b/awx/ui/src/screens/Inventory/ConstructedInventoryDetail/ConstructedInventoryDetail.js
index d8e136646b..6108dc2330 100644
--- a/awx/ui/src/screens/Inventory/ConstructedInventoryDetail/ConstructedInventoryDetail.js
+++ b/awx/ui/src/screens/Inventory/ConstructedInventoryDetail/ConstructedInventoryDetail.js
@@ -5,6 +5,8 @@ import { t } from '@lingui/macro';
import {
Button,
Chip,
+ Label,
+ LabelGroup,
TextList,
TextListItem,
TextListItemVariants,
@@ -114,6 +116,10 @@ function ConstructedInventoryDetail({ inventory }) {
wsInventorySource.summary_fields?.current_job ||
wsInventorySource.summary_fields?.last_job ||
null;
+ const wsInventory = {
+ ...inventory,
+ ...wsInventorySource?.summary_fields?.inventory,
+ };
const { request: deleteInventory, error: deleteError } = useRequest(
useCallback(async () => {
@@ -180,19 +186,19 @@ function ConstructedInventoryDetail({ inventory }) {
/>
@@ -204,7 +210,7 @@ function ConstructedInventoryDetail({ inventory }) {
/>
@@ -266,22 +272,25 @@ function ConstructedInventoryDetail({ inventory }) {
fullWidth
label={t`Input Inventories`}
value={
-
+
{inputInventories?.map((inputInventory) => (
- (
+
+ {content}
+
+ )}
>
-
- {inputInventory.name}
-
-
+ {inputInventory.name}
+
))}
-
+
}
isEmpty={inputInventories?.length === 0}
/>
diff --git a/awx/ui/src/screens/Inventory/shared/useWsInventorySourcesDetails.js b/awx/ui/src/screens/Inventory/shared/useWsInventorySourcesDetails.js
index e93f28f58b..e010b8916a 100644
--- a/awx/ui/src/screens/Inventory/shared/useWsInventorySourcesDetails.js
+++ b/awx/ui/src/screens/Inventory/shared/useWsInventorySourcesDetails.js
@@ -1,16 +1,17 @@
import { useState, useEffect } from 'react';
import useWebsocket from 'hooks/useWebsocket';
+import { InventorySourcesAPI } from 'api';
-export default function useWsInventorySourcesDetails(initialSources) {
- const [sources, setSources] = useState(initialSources);
+export default function useWsInventorySourcesDetails(initialSource) {
+ const [source, setSource] = useState(initialSource);
const lastMessage = useWebsocket({
jobs: ['status_changed'],
control: ['limit_reached_1'],
});
useEffect(() => {
- setSources(initialSources);
- }, [initialSources]);
+ setSource(initialSource);
+ }, [initialSource]);
useEffect(
() => {
@@ -21,22 +22,37 @@ export default function useWsInventorySourcesDetails(initialSources) {
) {
return;
}
- const updateSource = {
- ...sources,
- summary_fields: {
- ...sources.summary_fields,
- current_job: {
- id: lastMessage.unified_job_id,
- status: lastMessage.status,
- finished: lastMessage.finished,
- },
- },
- };
- setSources(updateSource);
+ if (
+ ['successful', 'failed', 'error', 'cancelled'].includes(
+ lastMessage.status
+ )
+ ) {
+ fetchSource();
+ }
+ setSource(updateSource(source, lastMessage));
},
[lastMessage] // eslint-disable-line react-hooks/exhaustive-deps
);
- return sources;
+ async function fetchSource() {
+ const { data } = await InventorySourcesAPI.readDetail(source.id);
+ setSource(data);
+ }
+
+ return source;
+}
+
+function updateSource(source, message) {
+ return {
+ ...source,
+ summary_fields: {
+ ...source.summary_fields,
+ current_job: {
+ id: message.unified_job_id,
+ status: message.status,
+ finished: message.finished,
+ },
+ },
+ };
}
diff --git a/awx/ui/src/screens/Inventory/shared/useWsInventorySourcesDetails.test.js b/awx/ui/src/screens/Inventory/shared/useWsInventorySourcesDetails.test.js
index 25fb97850b..d1f1e17009 100644
--- a/awx/ui/src/screens/Inventory/shared/useWsInventorySourcesDetails.test.js
+++ b/awx/ui/src/screens/Inventory/shared/useWsInventorySourcesDetails.test.js
@@ -1,9 +1,12 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import WS from 'jest-websocket-mock';
+import { InventorySourcesAPI } from 'api';
import { mountWithContexts } from '../../../../testUtils/enzymeHelpers';
import useWsInventorySourceDetails from './useWsInventorySourcesDetails';
+jest.mock('../../../api/models/InventorySources');
+
function TestInner() {
return
;
}
@@ -111,6 +114,27 @@ describe('useWsProject', () => {
status: 'running',
finished: null,
});
+
+ expect(InventorySourcesAPI.readDetail).toHaveBeenCalledTimes(0);
+ InventorySourcesAPI.readDetail.mockResolvedValue({
+ data: {},
+ });
+ await act(async () => {
+ mockServer.send(
+ JSON.stringify({
+ group_name: 'jobs',
+ inventory_id: 1,
+ status: 'successful',
+ type: 'inventory_update',
+ unified_job_id: 2,
+ unified_job_template_id: 1,
+ inventory_source_id: 1,
+ })
+ );
+ });
+ expect(InventorySourcesAPI.readDetail).toHaveBeenCalledTimes(1);
+
+ jest.clearAllMocks();
WS.clean();
});
});