From a288f944dc6a74af3c99f5f1d42c6002159287ea Mon Sep 17 00:00:00 2001 From: Christina Jenks <christina.jenks@ess.eu> Date: Thu, 12 Oct 2023 13:12:51 +0000 Subject: [PATCH] CE-1954: fix api calls not aborting on unmount or paging actions --- package-lock.json | 14 ++++---- package.json | 2 +- .../AdministerUndeployment.js | 7 ++-- src/components/IOC/IOCTable/IOCStatus.js | 3 +- src/components/common/User/UserIOCList.js | 10 ++++-- .../common/User/UserOperationList.js | 10 ++++-- .../common/notification/Watchers.js | 14 +++++--- .../deployments/DeploymentJobOutput.js | 11 ++++-- src/components/records/RecordSearch.js | 10 ++++-- .../DeploymentLineChart.js | 9 +++-- .../HostStatistics/HostStatistics.js | 33 ++++++++++++++--- .../statistics/IOCStatistics/IOCStatistics.js | 33 ++++++++++++++--- .../OperationChart/OperationChart.js | 9 +++-- src/hooks/Polling.js | 20 ++++++++--- src/stories/views/IOC/IocListView.stories.js | 27 ++++++++++++++ src/views/IOC/IOCDetailsContainer.js | 4 ++- src/views/IOC/IOCDetailsView.js | 35 ++++++++++++------- src/views/IOC/IOCListView.js | 17 +++++++-- src/views/host/HostDetailsView.js | 10 ++++-- src/views/host/HostListView.js | 10 ++++-- src/views/jobs/JobListView.js | 11 ++++-- src/views/records/RecordListView.js | 10 ++++-- src/views/statistics/StatisticsView.js | 21 +++++++---- 23 files changed, 259 insertions(+), 71 deletions(-) create mode 100644 src/stories/views/IOC/IocListView.stories.js diff --git a/package-lock.json b/package-lock.json index d1f8551b..959f3bab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "@ahooksjs/use-url-state": "^3.5.0", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@ess-ics/ce-ui-common": "^0.4.1", + "@ess-ics/ce-ui-common": "^0.4.2", "@fontsource/roboto": "^4.1.0", "@mui/icons-material": "^5.14.1", "@mui/material": "^5.14.1", @@ -2655,9 +2655,9 @@ } }, "node_modules/@ess-ics/ce-ui-common": { - "version": "0.4.1", - "resolved": "https://artifactory.esss.lu.se/artifactory/api/npm/ics-npm/@ess-ics/ce-ui-common/-/ce-ui-common-0.4.1.tgz", - "integrity": "sha1-xsfA4ukUWTChYXrb0J681o7sKmc=", + "version": "0.4.2", + "resolved": "https://artifactory.esss.lu.se/artifactory/api/npm/ics-npm/@ess-ics/ce-ui-common/-/ce-ui-common-0.4.2.tgz", + "integrity": "sha1-bHkj1S9gtfMc3yF9gn1tSzwPJ6E=", "dependencies": { "@fontsource/titillium-web": "^4.5.9", "@mui/x-data-grid-pro": "^6.5.0", @@ -41722,9 +41722,9 @@ "dev": true }, "@ess-ics/ce-ui-common": { - "version": "0.4.1", - "resolved": "https://artifactory.esss.lu.se/artifactory/api/npm/ics-npm/@ess-ics/ce-ui-common/-/ce-ui-common-0.4.1.tgz", - "integrity": "sha1-xsfA4ukUWTChYXrb0J681o7sKmc=", + "version": "0.4.2", + "resolved": "https://artifactory.esss.lu.se/artifactory/api/npm/ics-npm/@ess-ics/ce-ui-common/-/ce-ui-common-0.4.2.tgz", + "integrity": "sha1-bHkj1S9gtfMc3yF9gn1tSzwPJ6E=", "requires": { "@fontsource/titillium-web": "^4.5.9", "@mui/x-data-grid-pro": "^6.5.0", diff --git a/package.json b/package.json index 7a41cc6e..3eedaea6 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "@ahooksjs/use-url-state": "^3.5.0", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@ess-ics/ce-ui-common": "^0.4.1", + "@ess-ics/ce-ui-common": "^0.4.2", "@fontsource/roboto": "^4.1.0", "@mui/icons-material": "^5.14.1", "@mui/material": "^5.14.1", diff --git a/src/components/IOC/AdministerUndeployment/AdministerUndeployment.js b/src/components/IOC/AdministerUndeployment/AdministerUndeployment.js index c6f175f6..4a034dbd 100644 --- a/src/components/IOC/AdministerUndeployment/AdministerUndeployment.js +++ b/src/components/IOC/AdministerUndeployment/AdministerUndeployment.js @@ -13,12 +13,15 @@ import { Tooltip, LinearProgress } from "@mui/material"; -import { SimpleAccordion, ConfirmationDialog } from "@ess-ics/ce-ui-common"; +import { + SimpleAccordion, + ConfirmationDialog, + useAPIMethod +} from "@ess-ics/ce-ui-common"; import Alert from "@mui/material/Alert"; import AccessControl from "../../auth/AccessControl"; import { IocActiveDeployment } from "../../../api/DataTypes"; import { apiContext } from "../../../api/DeployApi"; -import { useAPIMethod } from "@ess-ics/ce-ui-common/dist/hooks/API"; export default function AdministerUndeployment({ ioc, buttonDisabled }) { const navigate = useNavigate(); diff --git a/src/components/IOC/IOCTable/IOCStatus.js b/src/components/IOC/IOCTable/IOCStatus.js index d67a352b..14e51ff3 100644 --- a/src/components/IOC/IOCTable/IOCStatus.js +++ b/src/components/IOC/IOCTable/IOCStatus.js @@ -21,8 +21,7 @@ export const IOCStatus = ({ id, activeDeployment }) => { dataReady } = useAPIMethod({ fcn: client.apis.Monitoring.fetchIocStatus, - params, - call: true + params }); return ( diff --git a/src/components/common/User/UserIOCList.js b/src/components/common/User/UserIOCList.js index aac7a9ec..4f5aa493 100644 --- a/src/components/common/User/UserIOCList.js +++ b/src/components/common/User/UserIOCList.js @@ -14,7 +14,8 @@ export function UserIocList({ userName }) { value: iocs, wrapper: getIocs, loading, - dataReady + dataReady, + abort } = useAPIMethod({ fcn: client.apis.IOCs.listIocs, call: false @@ -39,11 +40,16 @@ export function UserIocList({ userName }) { requestParams.created_by = userName; getIocs(requestParams); - }, [getIocs, pagination, userName]); + + return () => { + abort(); + }; + }, [getIocs, pagination, userName, abort]); // Invoked by Table on change to pagination const onPage = (params) => { setPagination(params); + abort(); }; return ( diff --git a/src/components/common/User/UserOperationList.js b/src/components/common/User/UserOperationList.js index 75372ca2..016621e9 100644 --- a/src/components/common/User/UserOperationList.js +++ b/src/components/common/User/UserOperationList.js @@ -14,7 +14,8 @@ export function UserOperationList({ userName }) { value: operations, wrapper: getOperations, loading, - dataReady + dataReady, + abort } = useAPIMethod({ fcn: client.apis.Deployments.listOperations, call: false @@ -38,11 +39,16 @@ export function UserOperationList({ userName }) { requestParams.user = userName; getOperations(requestParams); - }, [getOperations, pagination, userName]); + + return () => { + abort(); + }; + }, [getOperations, pagination, userName, abort]); // Invoked by Table on change to pagination const onPage = (params) => { setPagination(params); + abort(); }; return ( diff --git a/src/components/common/notification/Watchers.js b/src/components/common/notification/Watchers.js index 209783f3..fd0a8867 100644 --- a/src/components/common/notification/Watchers.js +++ b/src/components/common/notification/Watchers.js @@ -29,7 +29,8 @@ export function DeploymentWatcher({ value: deployment, wrapper: getDeployment, loading: deploymentLoading, - dataReady: deploymentDataReady + dataReady: deploymentDataReady, + abort: abortGetDeployment } = useAPIMethod({ fcn: client.apis.Deployments.fetchOperation, call: false, @@ -45,7 +46,8 @@ export function DeploymentWatcher({ value: deploymentJob, wrapper: getDeploymentJob, loading: jobLoading, - dataReady: jobDataReady + dataReady: jobDataReady, + abort: abortGetDeploymentJob } = useAPIMethod({ fcn: client.apis.Deployments.fetchJobDetails, params: deploymentJobParams @@ -54,13 +56,17 @@ export function DeploymentWatcher({ useSafePolling( getDeployment, deploymentLoading || !deploymentDataReady, - STATUS_POLL_INTERVAL + STATUS_POLL_INTERVAL, + true, + abortGetDeployment ); useSafePolling( getDeploymentJob, jobLoading || !jobDataReady, - STATUS_POLL_INTERVAL + STATUS_POLL_INTERVAL, + true, + abortGetDeploymentJob ); const deploymentStatus = useMemo( diff --git a/src/components/deployments/DeploymentJobOutput.js b/src/components/deployments/DeploymentJobOutput.js index 6356477e..c34141e3 100644 --- a/src/components/deployments/DeploymentJobOutput.js +++ b/src/components/deployments/DeploymentJobOutput.js @@ -26,7 +26,8 @@ export function DeploymentJobOutput({ deploymentJob }) { value: log, wrapper: getLogById, loading: logLoading, - dataReady: logDataReady + dataReady: logDataReady, + abort: abortGetLogById } = useAPIMethod({ fcn: client.apis.Deployments.fetchDeploymentJobLog, params @@ -44,7 +45,13 @@ export function DeploymentJobOutput({ deploymentJob }) { finalResultsNeeded.current = !deploymentJob.finished; } }, [deploymentJob.finished, deploymentJob.id, getLogById]); - useSafePolling(getLog, logLoading || !logDataReady, LOG_POLL_INTERVAL); + useSafePolling( + getLog, + logLoading || !logDataReady, + LOG_POLL_INTERVAL, + true, + abortGetLogById + ); const dataReady = useCallback(() => { return deploymentJob?.started; diff --git a/src/components/records/RecordSearch.js b/src/components/records/RecordSearch.js index 2aeba701..39fc9f7b 100644 --- a/src/components/records/RecordSearch.js +++ b/src/components/records/RecordSearch.js @@ -22,7 +22,8 @@ export function RecordSearch({ iocName, rowType }) { value: records, wrapper: getRecords, loading, - dataReady + dataReady, + abort } = useAPIMethod({ fcn: client.apis.Records.findAllRecords, call: false @@ -110,7 +111,11 @@ export function RecordSearch({ iocName, rowType }) { requestParams.pv_status = recordFilter; requestParams.record_name = deserialize(urlState.query); getRecords(requestParams); - }, [getRecords, recordFilter, urlState.query, pagination]); + + return () => { + abort(); + }; + }, [getRecords, recordFilter, urlState.query, pagination, abort]); // Callback for searchbar, called whenever user updates search const setSearch = useCallback( @@ -123,6 +128,7 @@ export function RecordSearch({ iocName, rowType }) { // Invoked by Table on change to pagination const onPage = (params) => { setPagination(params); + abort(); }; return ( diff --git a/src/components/statistics/DeploymentLineChart/DeploymentLineChart.js b/src/components/statistics/DeploymentLineChart/DeploymentLineChart.js index 809384c9..b22de827 100644 --- a/src/components/statistics/DeploymentLineChart/DeploymentLineChart.js +++ b/src/components/statistics/DeploymentLineChart/DeploymentLineChart.js @@ -17,13 +17,18 @@ export default function DeploymentLineChart({ title, chartLabel, iocDeployments, - getIOCDeployments + getIOCDeployments, + abortGetIOCDeployments }) { const theme = useTheme(); useEffect(() => { getIOCDeployments(); - }, [getIOCDeployments]); + + return () => { + abortGetIOCDeployments(); + }; + }, [getIOCDeployments, abortGetIOCDeployments]); const GRAPH_THRESHOLD = 0.05; diff --git a/src/components/statistics/HostStatistics/HostStatistics.js b/src/components/statistics/HostStatistics/HostStatistics.js index 5ffe42dd..6b9302fe 100644 --- a/src/components/statistics/HostStatistics/HostStatistics.js +++ b/src/components/statistics/HostStatistics/HostStatistics.js @@ -12,15 +12,27 @@ export function HostStatistics() { // Do not call on render; when one of these finishes then it and the others // will be called again on the next render; this causes an infinite loop. - const { value: hostsRegistered, wrapper: getHostsRegistered } = useAPIMethod({ + const { + value: hostsRegistered, + wrapper: getHostsRegistered, + abort: abortGetHostsRegistered + } = useAPIMethod({ fcn: client.apis.Statistics.calculateStatistics, call: false }); - const { value: hostsWithIocs, wrapper: getHostsWithIocs } = useAPIMethod({ + const { + value: hostsWithIocs, + wrapper: getHostsWithIocs, + abort: abortGetHostsWithIocs + } = useAPIMethod({ fcn: client.apis.Statistics.calculateStatistics, call: false }); - const { value: hostsReachable, wrapper: getHostsReachable } = useAPIMethod({ + const { + value: hostsReachable, + wrapper: getHostsReachable, + abort: abortGetHostsReachable + } = useAPIMethod({ fcn: client.apis.Statistics.calculateStatistics, call: false }); @@ -29,7 +41,20 @@ export function HostStatistics() { getHostsRegistered({ statistics_type: "HOSTS_REGISTERED" }); getHostsWithIocs({ statistics_type: "HOSTS_WITH_IOCS" }); getHostsReachable({ statistics_type: "HOSTS_REACHABLE" }); - }, [getHostsRegistered, getHostsWithIocs, getHostsReachable]); + + return () => { + abortGetHostsRegistered(); + abortGetHostsWithIocs(); + abortGetHostsReachable(); + }; + }, [ + getHostsRegistered, + getHostsWithIocs, + getHostsReachable, + abortGetHostsRegistered, + abortGetHostsWithIocs, + abortGetHostsReachable + ]); const hostStats = { "Registered IOC-hosts": renderValue(hostsRegistered?.value), diff --git a/src/components/statistics/IOCStatistics/IOCStatistics.js b/src/components/statistics/IOCStatistics/IOCStatistics.js index ced1af4c..2da06824 100644 --- a/src/components/statistics/IOCStatistics/IOCStatistics.js +++ b/src/components/statistics/IOCStatistics/IOCStatistics.js @@ -13,15 +13,27 @@ export function IOCStatistics() { // Do not call on render; when one of these finishes then it and the others // will be called again on the next render; this causes an infinite loop. - const { value: iocsRegistered, wrapper: getIocsRegistered } = useAPIMethod({ + const { + value: iocsRegistered, + wrapper: getIocsRegistered, + abort: abortGetIocsRegistered + } = useAPIMethod({ fcn: client.apis.Statistics.calculateStatistics, call: false }); - const { value: iocsDeployed, wrapper: getIocsDeployed } = useAPIMethod({ + const { + value: iocsDeployed, + wrapper: getIocsDeployed, + abort: abortGetIocsDeployed + } = useAPIMethod({ fcn: client.apis.Statistics.calculateStatistics, call: false }); - const { value: iocsReachable, wrapper: getIocsReachable } = useAPIMethod({ + const { + value: iocsReachable, + wrapper: getIocsReachable, + abort: abortGetIocsReachable + } = useAPIMethod({ fcn: client.apis.Statistics.calculateStatistics, call: false }); @@ -30,7 +42,20 @@ export function IOCStatistics() { getIocsRegistered({ statistics_type: "IOCS_REGISTERED" }); getIocsDeployed({ statistics_type: "IOCS_DEPLOYED" }); getIocsReachable({ statistics_type: "IOCS_RUNNING" }); - }, [getIocsDeployed, getIocsReachable, getIocsRegistered]); + + return () => { + abortGetIocsRegistered(); + abortGetIocsDeployed(); + abortGetIocsReachable(); + }; + }, [ + abortGetIocsDeployed, + abortGetIocsReachable, + abortGetIocsRegistered, + getIocsDeployed, + getIocsReachable, + getIocsRegistered + ]); const iocStats = { "Registered IOCs": renderValue(iocsRegistered?.value), diff --git a/src/components/statistics/OperationChart/OperationChart.js b/src/components/statistics/OperationChart/OperationChart.js index d6198aa4..8a4236f6 100644 --- a/src/components/statistics/OperationChart/OperationChart.js +++ b/src/components/statistics/OperationChart/OperationChart.js @@ -17,13 +17,18 @@ import { export default function OperationChart({ title, iocDeployments, - getIOCDeployments + getIOCDeployments, + abortGetIOCDeployments }) { const theme = useTheme(); useEffect(() => { getIOCDeployments(); - }, [getIOCDeployments]); + + return () => { + abortGetIOCDeployments(); + }; + }, [getIOCDeployments, abortGetIOCDeployments]); return iocDeployments ? ( <> diff --git a/src/hooks/Polling.js b/src/hooks/Polling.js index c8a9de5f..bb238475 100644 --- a/src/hooks/Polling.js +++ b/src/hooks/Polling.js @@ -1,14 +1,24 @@ import { useCallback, useEffect, useRef } from "react"; -export function useInterval(callback, interval, call = false) { +const defaultCleanup = () => {}; + +export function useInterval( + callback, + interval, + call = false, + cleanup = defaultCleanup +) { useEffect(() => { if (call) callback(); // call the callback right away const id = setInterval(callback, interval); - return () => clearInterval(id); - }, [call, callback, interval]); + return () => { + clearInterval(id); + cleanup(); + }; + }, [call, callback, interval, cleanup]); } -export function useSafePolling(callback, busy, interval, call = true) { +export function useSafePolling(callback, busy, interval, call = true, cleanup) { const busyRef = useRef(busy); busyRef.current = busy; @@ -17,5 +27,5 @@ export function useSafePolling(callback, busy, interval, call = true) { callback(); } }, [callback, busyRef]); - useInterval(poll, interval, call); + useInterval(poll, interval, call, cleanup); } diff --git a/src/stories/views/IOC/IocListView.stories.js b/src/stories/views/IOC/IocListView.stories.js new file mode 100644 index 00000000..ab112954 --- /dev/null +++ b/src/stories/views/IOC/IocListView.stories.js @@ -0,0 +1,27 @@ +import React from "react"; +import { AppHarness } from "../../../mocks/AppHarness"; +import { rest } from "msw"; +import { handlers } from "../../../mocks/handlers"; +import { IOCListView } from "../../../views/IOC/IOCListView"; + +export default { + title: "Views/IOC/IocListView" +}; + +const Template = () => ( + <AppHarness> + <IOCListView /> + </AppHarness> +); + +export const Default = () => <Template />; + +export const LoadingAsyncCells = () => <Template />; +LoadingAsyncCells.parameters = { + msw: { + handlers: [ + rest.get("*/iocs/*", (req, res, ctx) => res(ctx.delay("infinite"))), + ...handlers + ] + } +}; diff --git a/src/views/IOC/IOCDetailsContainer.js b/src/views/IOC/IOCDetailsContainer.js index 00aee004..239c6fcc 100644 --- a/src/views/IOC/IOCDetailsContainer.js +++ b/src/views/IOC/IOCDetailsContainer.js @@ -26,7 +26,8 @@ export function IOCDetailsContainer({ id }) { value: ioc, wrapper: getIOC, loading, - error: fetchError + error: fetchError, + abort: abortGetIOC } = useAPIMethod({ fcn: client.apis.IOCs.getIoc, params @@ -59,6 +60,7 @@ export function IOCDetailsContainer({ id }) { <IOCDetailsView ioc={ioc} getIOC={getIOC} + abortGetIOC={abortGetIOC} loading={loading} /> ) : ( diff --git a/src/views/IOC/IOCDetailsView.js b/src/views/IOC/IOCDetailsView.js index 6fe8961a..f8be1d64 100644 --- a/src/views/IOC/IOCDetailsView.js +++ b/src/views/IOC/IOCDetailsView.js @@ -27,7 +27,14 @@ import { usePagination } from "../../hooks/pagination"; import { apiContext } from "../../api/DeployApi"; const IOC_POLL_INTERVAL = 10000; -export function IOCDetailsView({ ioc, getIOC, loading }) { +export function IOCDetailsView({ ioc, getIOC, abortGetIOC, loading }) { + const { setTitle } = useContext(GlobalAppBarContext); + useEffect(() => { + if (ioc) { + setTitle(applicationTitle(`IOC Details: ${ioc.namingName}`)); + } + }, [ioc, setTitle]); + const [urlState, setUrlState] = useUrlState( { tab: "Status", @@ -45,7 +52,8 @@ export function IOCDetailsView({ ioc, getIOC, loading }) { value: operations, wrapper: getOperations, loading: operationsLoading, - dataReady: operationsDataReady + dataReady: operationsDataReady, + abort: abortGetOperations } = useAPIMethod({ fcn: client.apis.Deployments.listOperations, call: false @@ -64,7 +72,8 @@ export function IOCDetailsView({ ioc, getIOC, loading }) { value: ongoingCommand, wrapper: getOngoingCommand, loading: ongoingCommandLoading, - dataReady: ongoingCommandDataReady + dataReady: ongoingCommandDataReady, + abort: abortGetOngoingCommand } = useAPIMethod({ fcn: client.apis.Deployments.listOperations, params: ongoingCommandParams, @@ -116,13 +125,16 @@ export function IOCDetailsView({ ioc, getIOC, loading }) { // Invoked by Table on change to pagination const onPage = (params) => { setJobPagination(params); + abortGetOperations(); }; - useSafePolling(getIOC, loading, IOC_POLL_INTERVAL); + useSafePolling(getIOC, loading, IOC_POLL_INTERVAL, true, abortGetIOC); useSafePolling( getOngoingCommand, ongoingCommandLoading || !ongoingCommandDataReady, - IOC_POLL_INTERVAL + IOC_POLL_INTERVAL, + true, + abortGetOngoingCommand ); useEffect(() => { @@ -138,7 +150,11 @@ export function IOCDetailsView({ ioc, getIOC, loading }) { let requestParams = initRequestParams(jobPagination); requestParams.ioc_id = ioc.id; getOperations(requestParams); - }, [getOperations, jobPagination, ioc]); + + return () => { + abortGetOperations(); + }; + }, [getOperations, jobPagination, ioc, abortGetOperations]); const handleClick = () => { navigate(-1); @@ -160,13 +176,6 @@ export function IOCDetailsView({ ioc, getIOC, loading }) { [getIOC] ); - const { setTitle } = useContext(GlobalAppBarContext); - useEffect(() => { - if (ioc) { - setTitle(applicationTitle(`IOC Details: ${ioc.namingName}`)); - } - }, [ioc, setTitle]); - const statusTab = ( <Tab key="Status" diff --git a/src/views/IOC/IOCListView.js b/src/views/IOC/IOCListView.js index 98d2913e..eb64c08e 100644 --- a/src/views/IOC/IOCListView.js +++ b/src/views/IOC/IOCListView.js @@ -30,7 +30,8 @@ export function IOCListView() { value: iocs, wrapper: getIocs, loading, - dataReady + dataReady, + abort } = useAPIMethod({ fcn: client.apis.IOCs.listIocs, call: false @@ -118,6 +119,7 @@ export function IOCListView() { // Invoked by Table on change to pagination const onPage = (params) => { setPagination(params); + abort(); }; useEffect(() => { @@ -129,7 +131,18 @@ export function IOCListView() { requestParams.deployment_status = deploymentStatus; getIocs(requestParams); - }, [getIocs, urlPagination, deploymentStatus, urlState.query, pagination]); + + return () => { + abort(); + }; + }, [ + getIocs, + urlPagination, + deploymentStatus, + urlState.query, + pagination, + abort + ]); // Callback for searchbar, called whenever user updates search const setSearch = useCallback( diff --git a/src/views/host/HostDetailsView.js b/src/views/host/HostDetailsView.js index d82ac468..350f6d60 100644 --- a/src/views/host/HostDetailsView.js +++ b/src/views/host/HostDetailsView.js @@ -48,7 +48,8 @@ export function HostDetailsView({ id, host }) { value: iocs, wrapper: getIocs, loading, - dataReady + dataReady, + abort: abortGetIocs } = useAPIMethod({ fcn: client.apis.Hosts.findAssociatedIocsByHostId, call: false @@ -111,6 +112,7 @@ export function HostDetailsView({ id, host }) { // Invoked by Table on change to pagination const onPage = (params) => { setPagination(params); + abortGetIocs(); }; useEffect(() => { @@ -119,7 +121,11 @@ export function HostDetailsView({ id, host }) { requestParams.host_csentry_id = id; getIocs(requestParams); - }, [getIocs, urlPagination, id]); + + return () => { + abortGetIocs(); + }; + }, [getIocs, urlPagination, id, abortGetIocs]); function listToString(list) { if (list) { diff --git a/src/views/host/HostListView.js b/src/views/host/HostListView.js index f4a773d8..06a365e3 100644 --- a/src/views/host/HostListView.js +++ b/src/views/host/HostListView.js @@ -34,7 +34,8 @@ export function HostListView() { const { value: hosts, wrapper: getHosts, - loading + loading, + abort } = useAPIMethod({ fcn: client.apis.Hosts.listHosts, call: false @@ -128,7 +129,11 @@ export function HostListView() { ); requestParams.filter = hostFilter; getHosts(requestParams); - }, [getHosts, hostFilter, urlState.query, pagination]); + + return () => { + abort(); + }; + }, [getHosts, hostFilter, urlState.query, pagination, abort]); // Callback for searchbar, called whenever user updates search const setSearch = useCallback( @@ -141,6 +146,7 @@ export function HostListView() { // Invoked by Table on change to pagination const onPage = (params) => { setPagination(params); + abort(); }; const content = ( diff --git a/src/views/jobs/JobListView.js b/src/views/jobs/JobListView.js index 6c6e0a76..0ac7543d 100644 --- a/src/views/jobs/JobListView.js +++ b/src/views/jobs/JobListView.js @@ -22,7 +22,8 @@ export function JobListView() { value: operations, wrapper: getOperations, loading, - dataReady + dataReady, + abort } = useAPIMethod({ fcn: client.apis.Deployments.listOperations, call: false @@ -122,12 +123,17 @@ export function JobListView() { } getOperations(requestParams); + + return () => { + abort(); + }; }, [ getOperations, urlPagination, urlState.query, urlState.job_type, - deploymentStatus + deploymentStatus, + abort ]); const setSearch = useCallback( @@ -140,6 +146,7 @@ export function JobListView() { // Invoked by Table on change to pagination const onPage = (params) => { setPagination(params); + abort(); }; const content = ( diff --git a/src/views/records/RecordListView.js b/src/views/records/RecordListView.js index ac35ce4a..e0dba8ee 100644 --- a/src/views/records/RecordListView.js +++ b/src/views/records/RecordListView.js @@ -35,7 +35,8 @@ export function RecordListView() { value: records, wrapper: getRecords, loading, - dataReady + dataReady, + abort } = useAPIMethod({ fcn: client.apis.Records.findAllRecords, call: false @@ -126,7 +127,11 @@ export function RecordListView() { requestParams.pv_status = recordFilter; requestParams.record_name = deserialize(urlState.query); getRecords(requestParams); - }, [getRecords, recordFilter, urlState.query, pagination]); + + return () => { + abort(); + }; + }, [getRecords, recordFilter, urlState.query, pagination, abort]); // Callback for searchbar, called whenever user updates search const setSearch = useCallback( @@ -139,6 +144,7 @@ export function RecordListView() { // Invoked by Table on change to pagination const onPage = (params) => { setPagination(params); + abort(); }; let content = ( diff --git a/src/views/statistics/StatisticsView.js b/src/views/statistics/StatisticsView.js index 414f4731..31d380c3 100644 --- a/src/views/statistics/StatisticsView.js +++ b/src/views/statistics/StatisticsView.js @@ -34,16 +34,23 @@ export function StatisticsView() { const theme = useTheme(); - const { value: iocsOverTime, wrapper: getIocsOverTime } = useAPIMethod({ + const { + value: iocsOverTime, + wrapper: getIocsOverTime, + abort: abortGetIocsOverTime + } = useAPIMethod({ fcn: client.apis.Statistics.activeIocHistory, call: false }); - const { value: operationStatistics, wrapper: getOperationStatistics } = - useAPIMethod({ - fcn: client.apis.Statistics.operationHistory, - call: false - }); + const { + value: operationStatistics, + wrapper: getOperationStatistics, + abort: abortGetOperationStatistics + } = useAPIMethod({ + fcn: client.apis.Statistics.operationHistory, + call: false + }); return ( <StyledRootPaper> @@ -74,6 +81,7 @@ export function StatisticsView() { title="Operations over time" iocDeployments={operationStatistics} getIOCDeployments={getOperationStatistics} + abortGetIOCDeployments={abortGetOperationStatistics} /> </Box> </Grid> @@ -95,6 +103,7 @@ export function StatisticsView() { chartLabel="Active IOCs over time" iocDeployments={iocsOverTime} getIOCDeployments={getIocsOverTime} + abortGetIOCDeployments={abortGetIocsOverTime} /> </Box> </Grid> -- GitLab