From 7aa8495d1aba3047f490066026305f583d3d3b40 Mon Sep 17 00:00:00 2001 From: Keith Grant Date: Tue, 9 Jun 2020 15:24:15 -0700 Subject: [PATCH] debounce fetching of individual jobs --- .../src/components/JobList/JobList.jsx | 23 ++++++++----- .../src/components/JobList/useWsJobs.js | 34 +++++++++++++++++-- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/awx/ui_next/src/components/JobList/JobList.jsx b/awx/ui_next/src/components/JobList/JobList.jsx index 933284c776..bdd17cd46c 100644 --- a/awx/ui_next/src/components/JobList/JobList.jsx +++ b/awx/ui_next/src/components/JobList/JobList.jsx @@ -61,19 +61,24 @@ function JobList({ i18n, defaultParams, showTypeColumn = false }) { const { request: addJobsById } = useRequest( useCallback( async ids => { + if (!ids.length) { + return; + } const params = parseQueryString(QS_CONFIG, location.search); - params.id__in = ids; + params.id__in = ids.join(','); const { data } = await UnifiedJobsAPI.read({ ...params }); - const mergedJobsList = [...data.results, ...results].slice( - 0, - params.page_size - ); - setValue({ - results: mergedJobsList, - count: count + data.count, + setValue(prev => { + const mergedJobsList = [...data.results, ...prev.results].slice( + 0, + params.page_size + ); + return { + results: mergedJobsList, + count: prev.count + data.count, + }; }); }, - [location, setValue, QS_CONFIG] // eslint-disable-line react-hooks/exhaustive-deps + [location, setValue] // eslint-disable-line react-hooks/exhaustive-deps ) ); diff --git a/awx/ui_next/src/components/JobList/useWsJobs.js b/awx/ui_next/src/components/JobList/useWsJobs.js index f96295d0d7..02a9c1671b 100644 --- a/awx/ui_next/src/components/JobList/useWsJobs.js +++ b/awx/ui_next/src/components/JobList/useWsJobs.js @@ -3,10 +3,24 @@ import { useState, useEffect, useRef } from 'react'; export default function useWsJobs(initialJobs, fetchJobsById, filtersApplied) { const [jobs, setJobs] = useState(initialJobs); const [lastMessage, setLastMessage] = useState(null); + const [jobsToFetch, setJobsToFetch] = useState([]); + const debouncedJobsToFetch = useDebounce(jobsToFetch, 5000); useEffect(() => { setJobs(initialJobs); }, [initialJobs]); + const enqueueJobId = id => { + if (!jobsToFetch.includes(id)) { + setJobsToFetch(ids => ids.concat(id)); + } + }; + useEffect(() => { + if (debouncedJobsToFetch.length) { + fetchJobsById(debouncedJobsToFetch); + setJobsToFetch([]); + } + }, [debouncedJobsToFetch, fetchJobsById]); + const ws = useRef(null); useEffect(() => { @@ -15,7 +29,7 @@ export default function useWsJobs(initialJobs, fetchJobsById, filtersApplied) { } if (filtersApplied) { if (['completed', 'failed', 'error'].includes(lastMessage.status)) { - fetchJobsById([lastMessage.unified_job_id]); + enqueueJobId(lastMessage.unified_job_id); } return; } @@ -25,7 +39,7 @@ export default function useWsJobs(initialJobs, fetchJobsById, filtersApplied) { if (index > -1) { setJobs(updateJob(jobs, index, lastMessage)); } else { - fetchJobsById([lastMessage.unified_job_id]); + enqueueJobId(lastMessage.unified_job_id); } }, [lastMessage]); // eslint-disable-line react-hooks/exhaustive-deps @@ -85,3 +99,19 @@ function updateJob(jobs, index, message) { }; return [...jobs.slice(0, index), job, ...jobs.slice(index + 1)]; } + +function useDebounce(value, delay) { + const [debouncedValue, setDebouncedValue] = useState(value); + + useEffect(() => { + const timeout = setTimeout(() => { + setDebouncedValue(value); + }, delay); + + return () => { + clearTimeout(timeout); + }; + }, [value, delay]); + + return debouncedValue; +}