From acc928f0adc099b999cb68dd040161a508376618 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Fri, 10 Nov 2023 13:38:52 +0100 Subject: [PATCH] catalog-react: expose next and prev functions Signed-off-by: Vincenzo Scamporlino --- .../src/hooks/useEntityListProvider.tsx | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/plugins/catalog-react/src/hooks/useEntityListProvider.tsx b/plugins/catalog-react/src/hooks/useEntityListProvider.tsx index 6dba849ba8..ef1673d69a 100644 --- a/plugins/catalog-react/src/hooks/useEntityListProvider.tsx +++ b/plugins/catalog-react/src/hooks/useEntityListProvider.tsx @@ -50,6 +50,7 @@ import { reduceEntityFilters, } from '../utils'; import { useApi } from '@backstage/core-plugin-api'; +import { QueryEntitiesResponse } from '@backstage/catalog-client'; /** @public */ export type DefaultEntityFilters = { @@ -95,6 +96,8 @@ export type EntityListContextProps< | ((prevFilters: EntityFilters) => Partial), ) => void; + next?: () => void; + prev?: () => void; /** * Filter values from query parameters. */ @@ -117,6 +120,7 @@ type OutputState = { appliedCursor?: string; entities: Entity[]; backendEntities: Entity[]; + pageInfo?: QueryEntitiesResponse['pageInfo']; }; type EntityListProviderProps = PropsWithChildren<{ @@ -141,6 +145,7 @@ export const EntityListProvider = ( // trigger a useLocation change; this would instead come from an external source, such as a manual // update of the URL or two catalog sidebar links with different catalog filters. const location = useLocation(); + const { queryParameters, cursor: initialCursor } = useMemo(() => { const parsed = qs.parse(location.search, { ignoreQueryPrefix: true, @@ -153,7 +158,7 @@ export const EntityListProvider = ( }; }, [location]); - const [cursor] = useState(initialCursor); + const [cursor, setCursor] = useState(initialCursor); const [outputState, setOutputState] = useState>( () => { @@ -199,6 +204,7 @@ export const EntityListProvider = ( appliedCursor: cursor, backendEntities: response.items, entities: response.items.filter(entityFilter), + pageInfo: response.pageInfo, }); } } else { @@ -218,6 +224,7 @@ export const EntityListProvider = ( appliedFilters: requestedFilters, backendEntities: response.items, entities: response.items.filter(entityFilter), + pageInfo: response.pageInfo, }); } } @@ -281,7 +288,7 @@ export const EntityListProvider = ( // Slight debounce on the refresh, since (especially on page load) several // filters will be calling this in rapid succession. - useDebounce(refresh, 10, [requestedFilters]); + useDebounce(refresh, 10, [requestedFilters, cursor]); const updateFilters = useCallback( ( @@ -298,6 +305,24 @@ export const EntityListProvider = ( [], ); + const next = useMemo(() => { + const newCursor = outputState.pageInfo?.nextCursor; + if (!newCursor || !props.enablePagination) { + return undefined; + } + + return () => setCursor(newCursor); + }, [outputState.pageInfo?.nextCursor, props.enablePagination]); + + const prev = useMemo(() => { + const newCursor = outputState.pageInfo?.prevCursor; + if (!newCursor || !props.enablePagination) { + return undefined; + } + + return () => setCursor(newCursor); + }, [outputState.pageInfo?.prevCursor, props.enablePagination]); + const value = useMemo( () => ({ filters: outputState.appliedFilters, @@ -307,8 +332,10 @@ export const EntityListProvider = ( queryParameters, loading, error, + next, + prev, }), - [outputState, updateFilters, queryParameters, loading, error], + [outputState, updateFilters, queryParameters, loading, error, next, prev], ); return (