diff --git a/awx/ui_next/src/components/JobList/JobList.jsx b/awx/ui_next/src/components/JobList/JobList.jsx index 435b20d96d..029e42d0cd 100644 --- a/awx/ui_next/src/components/JobList/JobList.jsx +++ b/awx/ui_next/src/components/JobList/JobList.jsx @@ -42,7 +42,6 @@ function JobList({ i18n, defaultParams, showTypeColumn = false }) { error: contentError, isLoading, request: fetchJobs, - setValue, } = useRequest( useCallback( async () => { @@ -58,31 +57,18 @@ function JobList({ i18n, defaultParams, showTypeColumn = false }) { fetchJobs(); }, [fetchJobs]); - const { request: addJobsById } = useRequest( - useCallback( - async ids => { - if (!ids.length) { - return; - } - const params = parseQueryString(QS_CONFIG, location.search); - params.id__in = ids.join(','); - const { data } = await UnifiedJobsAPI.read({ ...params }); - setValue(prev => { - const deDuplicated = data.results.filter( - job => !prev.results.find(j => j.id === job.id) - ); - const mergedJobsList = [...deDuplicated, ...prev.results]; - return { - results: mergedJobsList.slice(0, params.page_size), - count: prev.count + data.count, - }; - }); - }, - [location, setValue] // eslint-disable-line react-hooks/exhaustive-deps - ) + // TODO: update QS_CONFIG to be safe for deps array + const fetchJobsById = useCallback( + async ids => { + const params = parseQueryString(QS_CONFIG, location.search); + params.id__in = ids.join(','); + const { data } = await UnifiedJobsAPI.read(params); + return data.results; + }, + [location.search] // eslint-disable-line react-hooks/exhaustive-deps ); - const jobs = useWsJobs(results, addJobsById, !!defaultParams); + const jobs = useWsJobs(results, fetchJobsById, !!defaultParams); const isAllSelected = selected.length === jobs.length && selected.length > 0; const { diff --git a/awx/ui_next/src/components/JobList/JobList.test.jsx b/awx/ui_next/src/components/JobList/JobList.test.jsx index f2d1e6f71d..bd5b3f8cde 100644 --- a/awx/ui_next/src/components/JobList/JobList.test.jsx +++ b/awx/ui_next/src/components/JobList/JobList.test.jsx @@ -218,7 +218,7 @@ describe('', () => { jest.restoreAllMocks(); }); - test('error is shown when job not successfully deleted from api', async () => { + test.only('error is shown when job not successfully deleted from api', async () => { JobsAPI.destroy.mockImplementation(() => { throw new Error({ response: { diff --git a/awx/ui_next/src/components/JobList/useWsJobs.js b/awx/ui_next/src/components/JobList/useWsJobs.js index ab543d6d8e..574c50d1b4 100644 --- a/awx/ui_next/src/components/JobList/useWsJobs.js +++ b/awx/ui_next/src/components/JobList/useWsJobs.js @@ -5,7 +5,7 @@ export default function useWsJobs(initialJobs, fetchJobsById, filtersApplied) { const [jobs, setJobs] = useState(initialJobs); const [lastMessage, setLastMessage] = useState(null); const [jobsToFetch, setJobsToFetch] = useState([]); - const throttleJobsToFetch = useThrottle(jobsToFetch, 5000); + const throttledJobsToFetch = useThrottle(jobsToFetch, 5000); useEffect(() => { setJobs(initialJobs); @@ -17,11 +17,20 @@ export default function useWsJobs(initialJobs, fetchJobsById, filtersApplied) { } }; useEffect(() => { - if (throttleJobsToFetch.length) { - fetchJobsById(throttleJobsToFetch); + (async () => { + if (!throttledJobsToFetch.length) { + return; + } setJobsToFetch([]); - } - }, [throttleJobsToFetch, fetchJobsById]); + const newJobs = await fetchJobsById(throttledJobsToFetch); + const deduplicated = newJobs.filter( + job => !jobs.find(j => j.id === job.id) + ); + if (deduplicated.length) { + setJobs([...deduplicated, ...jobs]); + } + })(); + }, [throttledJobsToFetch, fetchJobsById]); // eslint-disable-line react-hooks/exhaustive-deps const ws = useRef(null);