From 3273d0a3d534a3d8023e0bcf1f569295a9fe4147 Mon Sep 17 00:00:00 2001 From: David Lyon Date: Thu, 4 Apr 2024 16:16:47 -0700 Subject: [PATCH 1/5] Add useProcessStatePolling --- src/common/api/collectionsApi.ts | 2 +- src/common/hooks.ts | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/common/api/collectionsApi.ts b/src/common/api/collectionsApi.ts index d8200c5d..7b5de01b 100644 --- a/src/common/api/collectionsApi.ts +++ b/src/common/api/collectionsApi.ts @@ -8,7 +8,7 @@ const collectionsService = httpService({ url: 'services/collections', }); -type ProcessState = 'processing' | 'failed' | 'complete'; +export type ProcessState = 'processing' | 'failed' | 'complete'; type UPA = string; // Collections-specific item ID strings (not an UPA or Data Object) type KBaseId = string; diff --git a/src/common/hooks.ts b/src/common/hooks.ts index 140919c0..6c27d15b 100644 --- a/src/common/hooks.ts +++ b/src/common/hooks.ts @@ -1,6 +1,7 @@ import { QueryDefinition } from '@reduxjs/toolkit/dist/query'; import { UseQueryHookResult } from '@reduxjs/toolkit/dist/query/react/buildHooks'; import { useCallback, useEffect, useRef, useState } from 'react'; +import { toast } from 'react-hot-toast'; import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'; import { useLocation, useNavigate } from 'react-router-dom'; import type { RootState, AppDispatch } from '../app/store'; @@ -10,6 +11,7 @@ import { isValidParam, setParams, } from '../features/params/paramsSlice'; +import { ProcessState } from './api/collectionsApi'; declare global { interface Window { @@ -61,6 +63,29 @@ export const useBackoffPolling = < return result; }; +export const useProcessStatePolling = < + StateKey extends string, + ResultShape extends { [processStateKey in StateKey]: ProcessState }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + R extends UseQueryHookResult> +>( + processStateKey: StateKey, + result: R, + options?: { baseInterval?: number; rate?: number; skipPoll?: boolean } +) => { + useBackoffPolling(result, (result) => { + if (result.error || !result.data?.[processStateKey]) return false; + if (result.data[processStateKey] === 'complete') return false; + if (result.data[processStateKey] === 'failed') { + toast('ProcessState Polling Failed, see console for more info'); + // eslint-disable-next-line no-console + console.error('ProcessState Polling Failed', { result }); + return false; + } + return true; + }); +}; + export const ignoredParameterWarning = (ignored: string[]) => `Ignored parameters: ${ignored.join(', ')}`; From da3ba949da9cf82742fe293f3dbfc37e410903b2 Mon Sep 17 00:00:00 2001 From: David Lyon Date: Thu, 4 Apr 2024 16:38:10 -0700 Subject: [PATCH 2/5] Allow multiple process state keys --- src/common/hooks.ts | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/common/hooks.ts b/src/common/hooks.ts index 6c27d15b..d61d6ffd 100644 --- a/src/common/hooks.ts +++ b/src/common/hooks.ts @@ -65,25 +65,37 @@ export const useBackoffPolling = < export const useProcessStatePolling = < StateKey extends string, - ResultShape extends { [processStateKey in StateKey]: ProcessState }, + Result extends { [processStateKey in StateKey]: ProcessState }, // eslint-disable-next-line @typescript-eslint/no-explicit-any - R extends UseQueryHookResult> + R extends UseQueryHookResult> >( - processStateKey: StateKey, result: R, + processStateKeys: StateKey[], options?: { baseInterval?: number; rate?: number; skipPoll?: boolean } ) => { - useBackoffPolling(result, (result) => { - if (result.error || !result.data?.[processStateKey]) return false; - if (result.data[processStateKey] === 'complete') return false; - if (result.data[processStateKey] === 'failed') { - toast('ProcessState Polling Failed, see console for more info'); - // eslint-disable-next-line no-console - console.error('ProcessState Polling Failed', { result }); - return false; - } - return true; - }); + useBackoffPolling( + result, + (result) => { + for (let i = 0; i < processStateKeys.length; i++) { + const processStateKey = processStateKeys[i]; + if (result.error || !result.data?.[processStateKey]) return false; + if (result.data[processStateKey] === 'processing') { + continue; + } else if (result.data[processStateKey] === 'complete') { + return false; + } else if (result.data[processStateKey] === 'failed') { + toast('ProcessState Polling Failed, see console for more info'); + // eslint-disable-next-line no-console + console.error('ProcessState Polling Failed', { result }); + return false; + } else { + return false; + } + } + return true; + }, + options + ); }; export const ignoredParameterWarning = (ignored: string[]) => From 3595e31f41d7078787a51b1ef736cc439ea539fd Mon Sep 17 00:00:00 2001 From: David Lyon Date: Thu, 4 Apr 2024 16:39:09 -0700 Subject: [PATCH 3/5] useBackoffPolling --> useProcessStatePolling --- src/features/collections/MatchModal.tsx | 12 +++--------- src/features/collections/collectionsSlice.ts | 13 ++++++++----- src/features/collections/data_products/Biolog.tsx | 14 ++++---------- .../collections/data_products/Microtrait.tsx | 14 ++++---------- .../collections/data_products/SampleAttribs.tsx | 8 ++------ .../collections/data_products/TaxaCount.tsx | 9 ++------- 6 files changed, 23 insertions(+), 47 deletions(-) diff --git a/src/features/collections/MatchModal.tsx b/src/features/collections/MatchModal.tsx index 96f7177a..4736de2a 100644 --- a/src/features/collections/MatchModal.tsx +++ b/src/features/collections/MatchModal.tsx @@ -10,7 +10,7 @@ import { listObjects } from '../../common/api/workspaceApi'; import { getNarratives } from '../../common/api/searchApi'; import { parseError } from '../../common/api/utils/parseError'; import { useUpdateAppParams } from '../params/hooks'; -import { useAppDispatch, useBackoffPolling } from '../../common/hooks'; +import { useAppDispatch, useProcessStatePolling } from '../../common/hooks'; import { setLocalSelection, useCurrentSelection, @@ -54,14 +54,8 @@ const ViewMatch = ({ collectionId }: { collectionId: string }) => { const matchQuery = getMatch.useQuery(matchId || '', { skip: !matchId, }); - useBackoffPolling( - matchQuery, - (result) => - !( - Boolean(result.error) || - (Boolean(result.data?.state) && result.data?.state !== 'processing') - ) - ); + useProcessStatePolling(matchQuery, ['state'], { skipPoll: !matchId }); + const match = matchQuery.data; const matchStategy = match?.state === 'complete' diff --git a/src/features/collections/collectionsSlice.ts b/src/features/collections/collectionsSlice.ts index 555bb803..f20f191f 100644 --- a/src/features/collections/collectionsSlice.ts +++ b/src/features/collections/collectionsSlice.ts @@ -10,7 +10,7 @@ import { parseError } from '../../common/api/utils/parseError'; import { useAppDispatch, useAppSelector, - useBackoffPolling, + useProcessStatePolling, } from '../../common/hooks'; import { useAppParam } from '../params/hooks'; @@ -348,12 +348,15 @@ export const useGenerateSelectionId = ( skip: !_pendingId || !!_verifiedId, }); - useBackoffPolling(validateSelection, (result) => { - if (result.error) toast(parseError(result.error).message); - if (result.data?.state === 'processing') return true; - return false; + useProcessStatePolling(validateSelection, ['state'], { + skipPoll: !_pendingId || !!_verifiedId, }); + useEffect(() => { + if (validateSelection.error) + toast(parseError(validateSelection.error).message); + }, [validateSelection.error]); + useEffect(() => { if (validateSelection.data?.state === 'complete') { if ( diff --git a/src/features/collections/data_products/Biolog.tsx b/src/features/collections/data_products/Biolog.tsx index 7ccb3952..dab9c8d4 100644 --- a/src/features/collections/data_products/Biolog.tsx +++ b/src/features/collections/data_products/Biolog.tsx @@ -15,7 +15,7 @@ import { import { parseError } from '../../../common/api/utils/parseError'; import { DataViewLink } from '../../../common/components'; import { Pagination, usePageBounds } from '../../../common/components/Table'; -import { useAppDispatch, useBackoffPolling } from '../../../common/hooks'; +import { useAppDispatch, useProcessStatePolling } from '../../../common/hooks'; import { formatNumber } from '../../../common/utils/stringUtils'; import { useAppParam } from '../../params/hooks'; import classes from '../Collections.module.scss'; @@ -148,15 +148,9 @@ const useBiolog = (collection_id: string | undefined) => { skip: !collection_id, }); const biolog = biologQuery.data; - useBackoffPolling( - biologQuery, - (result) => { - if (matchId && result?.data?.match_state === 'processing') return true; - if (selId && result?.data?.selection_state === 'processing') return true; - return false; - }, - { skipPoll: !collection_id || !(matchId || selId) } - ); + useProcessStatePolling(biologQuery, ['match_state', 'selection_state'], { + skipPoll: !collection_id || !(matchId || selId), + }); //cache last row of each page, we should implement better backend pagination this is silly useEffect(() => { diff --git a/src/features/collections/data_products/Microtrait.tsx b/src/features/collections/data_products/Microtrait.tsx index f34d222e..61035187 100644 --- a/src/features/collections/data_products/Microtrait.tsx +++ b/src/features/collections/data_products/Microtrait.tsx @@ -15,7 +15,7 @@ import { import { parseError } from '../../../common/api/utils/parseError'; import { DataViewLink } from '../../../common/components'; import { Pagination, usePageBounds } from '../../../common/components/Table'; -import { useAppDispatch, useBackoffPolling } from '../../../common/hooks'; +import { useAppDispatch, useProcessStatePolling } from '../../../common/hooks'; import { formatNumber } from '../../../common/utils/stringUtils'; import classes from '../Collections.module.scss'; import { useMatchId, useGenerateSelectionId } from '../collectionsSlice'; @@ -151,15 +151,9 @@ const useMicrotrait = (collection_id: string | undefined) => { skip: !collection_id, }); const microtrait = microtraitQuery.data; - useBackoffPolling( - microtraitQuery, - (result) => { - if (matchId && result?.data?.match_state === 'processing') return true; - if (selId && result?.data?.selection_state === 'processing') return true; - return false; - }, - { skipPoll: !collection_id || !(matchId || selId) } - ); + useProcessStatePolling(microtraitQuery, ['match_state', 'selection_state'], { + skipPoll: !collection_id || !(matchId || selId), + }); //cache last row of each page, we should implement better backend pagination this is silly useEffect(() => { diff --git a/src/features/collections/data_products/SampleAttribs.tsx b/src/features/collections/data_products/SampleAttribs.tsx index b47569a2..77294b9c 100644 --- a/src/features/collections/data_products/SampleAttribs.tsx +++ b/src/features/collections/data_products/SampleAttribs.tsx @@ -19,7 +19,7 @@ import { usePageBounds, useTableColumns, } from '../../../common/components/Table'; -import { useAppDispatch, useBackoffPolling } from '../../../common/hooks'; +import { useAppDispatch, useProcessStatePolling } from '../../../common/hooks'; import { clearAllFilters, setFilter, @@ -127,11 +127,7 @@ export const SampleAttribs: FC<{ selectData.data?.selection_state === 'processing' ); - useBackoffPolling( - selectData, - (result) => selectionPending || !result.data?.selection_state, - { skipPoll: !selectData.data?.selection_state } - ); + useProcessStatePolling(selectData, ['selection_state']); useFilterContexts(collection_id, [ { diff --git a/src/features/collections/data_products/TaxaCount.tsx b/src/features/collections/data_products/TaxaCount.tsx index 34395ab0..2746ab33 100644 --- a/src/features/collections/data_products/TaxaCount.tsx +++ b/src/features/collections/data_products/TaxaCount.tsx @@ -13,7 +13,7 @@ import { } from '../../../common/api/collectionsApi'; import { Loader } from '../../../common/components/Loader'; import { Select, SelectOption } from '../../../common/components/Select'; -import { useBackoffPolling } from '../../../common/hooks'; +import { useProcessStatePolling } from '../../../common/hooks'; import { snakeCaseToHumanReadable } from '../../../common/utils/stringUtils'; import { useMatchId, useSelectionId } from '../collectionsSlice'; import classes from './TaxaCount.module.scss'; @@ -105,12 +105,7 @@ export const TaxaCount: FC<{ skip: !rank, }); - useBackoffPolling(countsQuery, (result) => { - if (matchId && result?.data?.match_state === 'processing') return true; - if (selectionId && result?.data?.selection_state === 'processing') - return true; - return false; - }); + useProcessStatePolling(countsQuery, ['match_state', 'selection_state']); const taxa = countsQuery.data?.data || []; From 4d5ef9d737f9f19b52dd5bfee1b7db087bd40c1c Mon Sep 17 00:00:00 2001 From: David Lyon Date: Mon, 15 Apr 2024 15:15:00 -0700 Subject: [PATCH 4/5] refactor/move process hook --- src/common/hooks.ts | 37 ----------------- src/features/collections/MatchModal.tsx | 4 +- src/features/collections/collectionsSlice.ts | 7 +--- .../collections/data_products/Biolog.tsx | 3 +- .../collections/data_products/Microtrait.tsx | 3 +- .../data_products/SampleAttribs.tsx | 4 +- .../collections/data_products/TaxaCount.tsx | 2 +- src/features/collections/hooks.ts | 41 ++++++++++++++++++- 8 files changed, 51 insertions(+), 50 deletions(-) diff --git a/src/common/hooks.ts b/src/common/hooks.ts index d61d6ffd..140919c0 100644 --- a/src/common/hooks.ts +++ b/src/common/hooks.ts @@ -1,7 +1,6 @@ import { QueryDefinition } from '@reduxjs/toolkit/dist/query'; import { UseQueryHookResult } from '@reduxjs/toolkit/dist/query/react/buildHooks'; import { useCallback, useEffect, useRef, useState } from 'react'; -import { toast } from 'react-hot-toast'; import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'; import { useLocation, useNavigate } from 'react-router-dom'; import type { RootState, AppDispatch } from '../app/store'; @@ -11,7 +10,6 @@ import { isValidParam, setParams, } from '../features/params/paramsSlice'; -import { ProcessState } from './api/collectionsApi'; declare global { interface Window { @@ -63,41 +61,6 @@ export const useBackoffPolling = < return result; }; -export const useProcessStatePolling = < - StateKey extends string, - Result extends { [processStateKey in StateKey]: ProcessState }, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - R extends UseQueryHookResult> ->( - result: R, - processStateKeys: StateKey[], - options?: { baseInterval?: number; rate?: number; skipPoll?: boolean } -) => { - useBackoffPolling( - result, - (result) => { - for (let i = 0; i < processStateKeys.length; i++) { - const processStateKey = processStateKeys[i]; - if (result.error || !result.data?.[processStateKey]) return false; - if (result.data[processStateKey] === 'processing') { - continue; - } else if (result.data[processStateKey] === 'complete') { - return false; - } else if (result.data[processStateKey] === 'failed') { - toast('ProcessState Polling Failed, see console for more info'); - // eslint-disable-next-line no-console - console.error('ProcessState Polling Failed', { result }); - return false; - } else { - return false; - } - } - return true; - }, - options - ); -}; - export const ignoredParameterWarning = (ignored: string[]) => `Ignored parameters: ${ignored.join(', ')}`; diff --git a/src/features/collections/MatchModal.tsx b/src/features/collections/MatchModal.tsx index 4736de2a..23272d8b 100644 --- a/src/features/collections/MatchModal.tsx +++ b/src/features/collections/MatchModal.tsx @@ -10,14 +10,14 @@ import { listObjects } from '../../common/api/workspaceApi'; import { getNarratives } from '../../common/api/searchApi'; import { parseError } from '../../common/api/utils/parseError'; import { useUpdateAppParams } from '../params/hooks'; -import { useAppDispatch, useProcessStatePolling } from '../../common/hooks'; +import { useAppDispatch } from '../../common/hooks'; import { setLocalSelection, useCurrentSelection, useMatchId, } from './collectionsSlice'; import { store } from '../../app/store'; -import { useParamsForNarrativeDropdown } from './hooks'; +import { useParamsForNarrativeDropdown, useProcessStatePolling } from './hooks'; import { MatcherUserParams } from './MatcherUserParams'; import Ajv from 'ajv'; import { Modal, useModalControls } from '../layout/Modal'; diff --git a/src/features/collections/collectionsSlice.ts b/src/features/collections/collectionsSlice.ts index f20f191f..5de28867 100644 --- a/src/features/collections/collectionsSlice.ts +++ b/src/features/collections/collectionsSlice.ts @@ -7,12 +7,9 @@ import { getSelection, } from '../../common/api/collectionsApi'; import { parseError } from '../../common/api/utils/parseError'; -import { - useAppDispatch, - useAppSelector, - useProcessStatePolling, -} from '../../common/hooks'; +import { useAppDispatch, useAppSelector } from '../../common/hooks'; import { useAppParam } from '../params/hooks'; +import { useProcessStatePolling } from './hooks'; interface SelectionState { current: string[]; diff --git a/src/features/collections/data_products/Biolog.tsx b/src/features/collections/data_products/Biolog.tsx index dab9c8d4..6ce5840d 100644 --- a/src/features/collections/data_products/Biolog.tsx +++ b/src/features/collections/data_products/Biolog.tsx @@ -15,11 +15,12 @@ import { import { parseError } from '../../../common/api/utils/parseError'; import { DataViewLink } from '../../../common/components'; import { Pagination, usePageBounds } from '../../../common/components/Table'; -import { useAppDispatch, useProcessStatePolling } from '../../../common/hooks'; +import { useAppDispatch } from '../../../common/hooks'; import { formatNumber } from '../../../common/utils/stringUtils'; import { useAppParam } from '../../params/hooks'; import classes from '../Collections.module.scss'; import { useGenerateSelectionId } from '../collectionsSlice'; +import { useProcessStatePolling } from '../hooks'; import { HeatMap, HeatMapCallback, MAX_HEATMAP_PAGE } from './HeatMap'; export const Biolog: FC<{ diff --git a/src/features/collections/data_products/Microtrait.tsx b/src/features/collections/data_products/Microtrait.tsx index 61035187..85fab350 100644 --- a/src/features/collections/data_products/Microtrait.tsx +++ b/src/features/collections/data_products/Microtrait.tsx @@ -15,10 +15,11 @@ import { import { parseError } from '../../../common/api/utils/parseError'; import { DataViewLink } from '../../../common/components'; import { Pagination, usePageBounds } from '../../../common/components/Table'; -import { useAppDispatch, useProcessStatePolling } from '../../../common/hooks'; +import { useAppDispatch } from '../../../common/hooks'; import { formatNumber } from '../../../common/utils/stringUtils'; import classes from '../Collections.module.scss'; import { useMatchId, useGenerateSelectionId } from '../collectionsSlice'; +import { useProcessStatePolling } from '../hooks'; import { HeatMap, HeatMapCallback, MAX_HEATMAP_PAGE } from './HeatMap'; const getUPAFromEncoded = (encoded: string) => encoded.replaceAll('_', '/'); diff --git a/src/features/collections/data_products/SampleAttribs.tsx b/src/features/collections/data_products/SampleAttribs.tsx index 77294b9c..582f8323 100644 --- a/src/features/collections/data_products/SampleAttribs.tsx +++ b/src/features/collections/data_products/SampleAttribs.tsx @@ -19,7 +19,7 @@ import { usePageBounds, useTableColumns, } from '../../../common/components/Table'; -import { useAppDispatch, useProcessStatePolling } from '../../../common/hooks'; +import { useAppDispatch } from '../../../common/hooks'; import { clearAllFilters, setFilter, @@ -31,7 +31,7 @@ import classes from './../Collections.module.scss'; import { Alert, Grid, Paper, PaperProps, Stack, Link } from '@mui/material'; import { formatNumber } from '../../../common/utils/stringUtils'; import { filterContextMode, useFilterContexts } from '../Filters'; -import { useTableViewParams } from '../hooks'; +import { useProcessStatePolling, useTableViewParams } from '../hooks'; export const SampleAttribs: FC<{ collection_id: string; diff --git a/src/features/collections/data_products/TaxaCount.tsx b/src/features/collections/data_products/TaxaCount.tsx index 2746ab33..b1d5ab8a 100644 --- a/src/features/collections/data_products/TaxaCount.tsx +++ b/src/features/collections/data_products/TaxaCount.tsx @@ -13,12 +13,12 @@ import { } from '../../../common/api/collectionsApi'; import { Loader } from '../../../common/components/Loader'; import { Select, SelectOption } from '../../../common/components/Select'; -import { useProcessStatePolling } from '../../../common/hooks'; import { snakeCaseToHumanReadable } from '../../../common/utils/stringUtils'; import { useMatchId, useSelectionId } from '../collectionsSlice'; import classes from './TaxaCount.module.scss'; import { Paper, PaperProps, Stack } from '@mui/material'; import { useFilterContexts } from '../Filters'; +import { useProcessStatePolling } from '../hooks'; export const TaxaCount: FC<{ collection_id: string; diff --git a/src/features/collections/hooks.ts b/src/features/collections/hooks.ts index 2713e31c..186db295 100644 --- a/src/features/collections/hooks.ts +++ b/src/features/collections/hooks.ts @@ -1,6 +1,10 @@ +import { QueryDefinition } from '@reduxjs/toolkit/dist/query'; +import { UseQueryHookResult } from '@reduxjs/toolkit/dist/query/react/buildHooks'; import { useMemo } from 'react'; +import { toast } from 'react-hot-toast'; +import { ProcessState } from '../../common/api/collectionsApi'; import { getNarratives } from '../../common/api/searchApi'; -import { useAppSelector } from '../../common/hooks'; +import { useAppSelector, useBackoffPolling } from '../../common/hooks'; import { FilterContext, useFilters, @@ -90,3 +94,38 @@ export const useTableViewParams = ( ] ); }; + +export const useProcessStatePolling = < + StateKey extends string, + Result extends { [processStateKey in StateKey]: ProcessState }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + R extends UseQueryHookResult> +>( + result: R, + processStateKeys: StateKey[], + options?: { baseInterval?: number; rate?: number; skipPoll?: boolean } +) => { + useBackoffPolling( + result, + (result) => { + for (let i = 0; i < processStateKeys.length; i++) { + const processStateKey = processStateKeys[i]; + if (result.error || !result.data?.[processStateKey]) return false; + if (result.data[processStateKey] === 'processing') { + continue; + } else if (result.data[processStateKey] === 'complete') { + return false; + } else if (result.data[processStateKey] === 'failed') { + toast('ProcessState Polling Failed, see console for more info'); + // eslint-disable-next-line no-console + console.error('ProcessState Polling Failed', { result }); + return false; + } else { + return false; + } + } + return true; + }, + options + ); +}; From 6a753a3ba82df1c92a2f521398b0487fab562e14 Mon Sep 17 00:00:00 2001 From: David Lyon Date: Mon, 15 Apr 2024 15:33:36 -0700 Subject: [PATCH 5/5] add polling for samples result --- .../collections/data_products/SampleAttribs.tsx | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/features/collections/data_products/SampleAttribs.tsx b/src/features/collections/data_products/SampleAttribs.tsx index 582f8323..59b32ec2 100644 --- a/src/features/collections/data_products/SampleAttribs.tsx +++ b/src/features/collections/data_products/SampleAttribs.tsx @@ -92,7 +92,8 @@ export const SampleAttribs: FC<{ [attribParams] ); // Current Data - const { data, isFetching } = getSampleAttribs.useQuery(attribParams); + const result = getSampleAttribs.useQuery(attribParams); + const { data, isFetching } = result; const { data: countData } = getSampleAttribs.useQuery(countParams); const allCountParams = useMemo( () => ({ @@ -127,6 +128,18 @@ export const SampleAttribs: FC<{ selectData.data?.selection_state === 'processing' ); + // Polling needed for main result, as it is not a primary dataproduct like genomes + const pollFor: ('match_state' | 'selection_state')[] = [ + 'match_state', + 'selection_state', + ]; + if (!attribParams.match_id) pollFor.splice(pollFor.indexOf('match_state'), 1); + if (!attribParams.selection_id) + pollFor.splice(pollFor.indexOf('selection_state'), 1); + useProcessStatePolling(result, pollFor, { + skipPoll: !(attribParams.match_id || attribParams.selection_id), + }); + // Also poll for the selection state useProcessStatePolling(selectData, ['selection_state']); useFilterContexts(collection_id, [