fix(ui/browse): Fix bug where browse would not paginate when leaving a nested container (#14483)

This commit is contained in:
Andrew Sikowitz 2025-09-15 13:41:41 -07:00 committed by GitHub
parent f38c25dabb
commit 29f717b7d1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 42 additions and 50 deletions

View File

@ -1,4 +1,5 @@
import { FolderOutlined } from '@ant-design/icons'; import { FolderOutlined } from '@ant-design/icons';
import { Loader } from '@components';
import { Typography } from 'antd'; import { Typography } from 'antd';
import React from 'react'; import React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
@ -71,7 +72,7 @@ const BrowseNode = () => {
trackSelectNodeEvent(isNowSelected ? 'select' : 'deselect', 'browse'); trackSelectNodeEvent(isNowSelected ? 'select' : 'deselect', 'browse');
}; };
const { error, groups, loaded, observable, path, retry } = useBrowsePagination({ const { error, groups, loading, loaded, observable, path, retry } = useBrowsePagination({
skip: !isOpen || !browseResultGroup.hasSubGroups, skip: !isOpen || !browseResultGroup.hasSubGroups,
}); });
@ -118,6 +119,7 @@ const BrowseNode = () => {
<BrowseNode /> <BrowseNode />
</BrowseProvider> </BrowseProvider>
))} ))}
{loading && <Loader size="sm" />}
{error && <SidebarLoadingError onClickRetry={retry} />} {error && <SidebarLoadingError onClickRetry={retry} />}
{observable} {observable}
</ExpandableNode.Body> </ExpandableNode.Body>

View File

@ -1,3 +1,4 @@
import { Loader } from '@components';
import { Typography } from 'antd'; import { Typography } from 'antd';
import React from 'react'; import React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
@ -82,7 +83,7 @@ const PlatformNode = ({ iconSize = 20, hasOnlyOnePlatform = false, toggleCollaps
trackSelectNodeEvent(isNowPlatformOnlySelected ? 'select' : 'deselect', 'platform'); trackSelectNodeEvent(isNowPlatformOnlySelected ? 'select' : 'deselect', 'platform');
}; };
const { error, groups, loaded, observable, path, retry } = useBrowsePagination({ skip: !isOpen }); const { error, groups, loading, loaded, observable, path, retry } = useBrowsePagination({ skip: !isOpen });
const color = REDESIGN_COLORS.TEXT_HEADING; const color = REDESIGN_COLORS.TEXT_HEADING;
@ -169,6 +170,7 @@ const PlatformNode = ({ iconSize = 20, hasOnlyOnePlatform = false, toggleCollaps
<BrowseNode /> <BrowseNode />
</BrowseProvider> </BrowseProvider>
))} ))}
{loading && <Loader size="sm" />}
{error && <SidebarLoadingError onClickRetry={retry} />} {error && <SidebarLoadingError onClickRetry={retry} />}
{observable} {observable}
</ExpandableNode.Body> </ExpandableNode.Body>

View File

@ -1,11 +1,11 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import React, { useCallback, useMemo, useRef, useState } from 'react';
import { useBrowsePath, useEntityType } from '@app/searchV2/sidebar/BrowseContext'; import { useBrowsePath, useEntityType } from '@app/searchV2/sidebar/BrowseContext';
import { BROWSE_LOAD_MORE_MARGIN, BROWSE_PAGE_SIZE } from '@app/searchV2/sidebar/constants'; import { BROWSE_LOAD_MORE_MARGIN, BROWSE_PAGE_SIZE } from '@app/searchV2/sidebar/constants';
import { useSidebarFilters } from '@app/searchV2/sidebar/useSidebarFilters'; import { useSidebarFilters } from '@app/searchV2/sidebar/useSidebarFilters';
import useIntersect from '@app/shared/useIntersect'; import useIntersect from '@app/shared/useIntersect';
import { GetBrowseResultsV2Query, useGetBrowseResultsV2LazyQuery } from '@graphql/browseV2.generated'; import { GetBrowseResultsV2Query, useGetBrowseResultsV2Query } from '@graphql/browseV2.generated';
type Props = { type Props = {
skip: boolean; skip: boolean;
@ -33,62 +33,49 @@ const useBrowsePagination = ({ skip }: Props) => {
const total = latestData?.browseV2?.total ?? -1; const total = latestData?.browseV2?.total ?? -1;
const done = !!latestData && groups.length >= total; const done = !!latestData && groups.length >= total;
const [getBrowseResultsV2, { data, error, refetch }] = useGetBrowseResultsV2LazyQuery({ const [start, setStart] = useState(0);
const { loading, error, refetch } = useGetBrowseResultsV2Query({
skip,
fetchPolicy: 'cache-first', fetchPolicy: 'cache-first',
variables: {
input: {
type,
path,
start,
count: BROWSE_PAGE_SIZE,
orFilters: sidebarFilters.orFilters,
viewUrn: sidebarFilters.viewUrn,
query: sidebarFilters.query,
},
},
onCompleted: (data) => {
const newStart = data?.browseV2?.start ?? -1;
if (newStart === 0) initializing.current = false;
if (initializing.current || !data || newStart < 0) return;
setStartToBrowseMap((previousMap) => {
const newMap: typeof previousMap = { [newStart]: data };
Object.keys(previousMap)
.map(Number)
.forEach((previousStart) => {
if (previousStart < newStart) newMap[previousStart] = previousMap[previousStart];
});
return newMap;
});
},
}); });
const retry = () => { const retry = () => {
if (refetch) refetch(); if (refetch) refetch();
}; };
const getBrowseResultsV2WithDeps = useCallback(
(start: number) => {
if (skip) return;
getBrowseResultsV2({
variables: {
input: {
type,
path,
start,
count: BROWSE_PAGE_SIZE,
orFilters: sidebarFilters.orFilters,
viewUrn: sidebarFilters.viewUrn,
query: sidebarFilters.query,
},
},
});
},
[getBrowseResultsV2, path, sidebarFilters.orFilters, sidebarFilters.query, sidebarFilters.viewUrn, skip, type],
);
useEffect(() => {
initializing.current = true;
getBrowseResultsV2WithDeps(0);
}, [getBrowseResultsV2WithDeps]);
useEffect(() => {
const newStart = data?.browseV2?.start ?? -1;
if (newStart === 0) initializing.current = false;
if (initializing.current || !data || newStart < 0) return;
setStartToBrowseMap((previousMap) => {
const newMap: typeof previousMap = { [newStart]: data };
Object.keys(previousMap)
.map(Number)
.forEach((previousStart) => {
if (previousStart < newStart) newMap[previousStart] = previousMap[previousStart];
});
return newMap;
});
}, [data]);
const advancePage = useCallback(() => { const advancePage = useCallback(() => {
const newStart = latestStart + BROWSE_PAGE_SIZE; const newStart = latestStart + BROWSE_PAGE_SIZE;
if (initializing.current || error || done || latestStart < 0 || total <= 0 || newStart >= total) return; if (initializing.current || error || done || latestStart < 0 || total <= 0 || newStart >= total) return;
getBrowseResultsV2WithDeps(newStart); setStart(newStart);
}, [done, error, getBrowseResultsV2WithDeps, latestStart, total]); }, [done, error, latestStart, total]);
const { observableRef } = useIntersect({ const { observableRef } = useIntersect({
skip, skip,
@ -97,6 +84,7 @@ const useBrowsePagination = ({ skip }: Props) => {
}); });
return { return {
loading: start > 0 && loading, // Don't display loading indicator for first page
loaded: !!latestData || !!error, loaded: !!latestData || !!error,
error, error,
groups, groups,