Fix(ui): Additional query call in user profile page (#21856)

* fix additional query call in user profile page

* added unit test
This commit is contained in:
Shrushti Polekar 2025-06-20 11:23:29 +05:30 committed by GitHub
parent 7035c9e107
commit c729bd51ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 51 additions and 30 deletions

View File

@ -137,6 +137,9 @@ const AssetsTabs = forwardRef(
const [data, setData] = useState<SearchedDataProps['data']>([]);
const [quickFilterQuery, setQuickFilterQuery] =
useState<QueryFilterInterface>();
const [totalAssetCount, setTotalAssetCount] = useState<number>(
assetCount ?? 0
);
const {
currentPage,
@ -239,6 +242,9 @@ const AssetsTabs = forwardRef(
handlePagingChange({ total: res.hits.total.value ?? 0 });
setData(hits);
setAggregations(getAggregations(res?.aggregations));
if (assetCount === undefined) {
setTotalAssetCount(res.hits.total.value ?? 0);
}
hits[0] && setSelectedCard(hits[0]._source);
} catch {
// Nothing here
@ -246,7 +252,7 @@ const AssetsTabs = forwardRef(
setIsLoading(false);
}
},
[activeFilter, currentPage, pageSize, searchValue, queryParam]
[activeFilter, currentPage, pageSize, searchValue, queryParam, assetCount]
);
const hideNotification = () => {
@ -815,10 +821,10 @@ const AssetsTabs = forwardRef(
id="asset-tab">
<Row
className={classNames('filters-row gap-2 p-md', {
'h-full': assetCount === 0,
'h-full': totalAssetCount === 0,
})}
gutter={[0, 20]}>
{assetCount > 0 && (
{totalAssetCount > 0 && (
<>
<Col className="d-flex items-center gap-3" span={24}>
<Dropdown
@ -899,7 +905,7 @@ const AssetsTabs = forwardRef(
}
/>
</div>
{!isLoading && permissions?.EditAll && assetCount > 0 && (
{!isLoading && permissions?.EditAll && totalAssetCount > 0 && (
<div
className={classNames('asset-tab-delete-notification', {
visible: selectedItems.size > 0,

View File

@ -31,7 +31,7 @@ export interface AssetsTabsProps {
onRemoveAsset?: () => void;
entityFqn?: string;
permissions: OperationPermission;
assetCount: number;
assetCount?: number;
onAssetClick?: (asset?: EntityDetailsObjectInterface) => void;
isSummaryPanelOpen: boolean;
isEntityDeleted?: boolean;

View File

@ -17,6 +17,7 @@ import React, { ReactNode } from 'react';
import { MemoryRouter } from 'react-router-dom';
import { AuthProvider } from '../../../generated/settings/settings';
import { useApplicationStore } from '../../../hooks/useApplicationStore';
import { searchQuery } from '../../../rest/searchAPI';
import { mockAccessData, mockUserData, mockUserRole } from './mocks/User.mocks';
import Users from './Users.component';
import { UserPageTabs } from './Users.interface';
@ -96,7 +97,19 @@ jest.mock(
);
jest.mock('../../Glossary/GlossaryTerms/tabs/AssetsTabs.component', () => {
return jest.fn().mockReturnValue(<p>AssetsTabs</p>);
return jest.fn().mockImplementation((props) => {
React.useEffect(() => {
if (props.queryFilter === 'my-data') {
searchQuery({
searchIndex: ['all'] as any,
query: '*',
filters: props.queryFilter,
});
}
}, [props.queryFilter]);
return <p>AssetsTabs</p>;
});
});
jest.mock(
@ -201,6 +214,16 @@ jest.mock('../../ProfileCard/ProfileSectionUserDetailsCard.component', () => {
));
});
jest.mock('../../../rest/searchAPI', () => ({
searchQuery: jest.fn().mockResolvedValue({
hits: {
hits: [],
total: { value: 0 },
},
aggregations: {},
}),
}));
describe('Test User Component', () => {
it('Should render user component', async () => {
await act(async () => {
@ -357,4 +380,19 @@ describe('Test User Component', () => {
(await screen.findByTestId('access-token'))?.closest('.ant-tabs-tab')
).toHaveClass('ant-tabs-tab-disabled');
});
it('MyData tab should make query call only once on initial load', async () => {
mockParams.tab = UserPageTabs.MY_DATA;
await act(async () => {
render(<Users userData={mockUserData} {...mockProp} />, {
wrapper: MemoryRouter,
});
});
const assetComponent = await screen.findByText('AssetsTabs');
expect(assetComponent).toBeInTheDocument();
expect(searchQuery).toHaveBeenCalledTimes(1);
});
});

View File

@ -20,12 +20,10 @@ import { useHistory, useParams } from 'react-router-dom';
import { ROUTES } from '../../../constants/constants';
import { useLimitStore } from '../../../context/LimitsProvider/useLimitsStore';
import { EntityType } from '../../../enums/entity.enum';
import { SearchIndex } from '../../../enums/search.enum';
import { useAuth } from '../../../hooks/authHooks';
import { useApplicationStore } from '../../../hooks/useApplicationStore';
import useCustomLocation from '../../../hooks/useCustomLocation/useCustomLocation';
import { useFqn } from '../../../hooks/useFqn';
import { searchData } from '../../../rest/miscAPI';
import { restoreUser } from '../../../rest/userAPI';
import { DEFAULT_ENTITY_PERMISSION } from '../../../utils/PermissionsUtils';
import { getUserPath } from '../../../utils/RouterUtils';
@ -62,7 +60,6 @@ const Users = ({
const { tab: activeTab = UserPageTabs.ACTIVITY, subTab } =
useParams<{ tab: UserPageTabs; subTab: ActivityFeedTabs }>();
const { fqn: decodedUsername } = useFqn();
const [assetCount, setAssetCount] = useState<number>(0);
const { isAdminUser } = useAuth();
const history = useHistory();
const location = useCustomLocation();
@ -81,16 +78,6 @@ const Users = ({
[decodedUsername]
);
const fetchAssetsCount = async (query: string) => {
try {
const res = await searchData('', 1, 0, query, '', '', SearchIndex.ALL);
setAssetCount(res.data.hits.total.value ?? 0);
} catch {
setAssetCount(0);
}
};
const initLimits = async () => {
const limits = await getResourceLimit('user', false);
@ -140,7 +127,6 @@ const Users = ({
<Col flex="auto">
<div className="user-layout-scroll">
<AssetsTabs
assetCount={assetCount}
isSummaryPanelOpen={Boolean(previewAsset)}
permissions={{ ...DEFAULT_ENTITY_PERMISSION, Create: true }}
onAddAsset={() => history.push(ROUTES.EXPLORE)}
@ -160,7 +146,7 @@ const Users = ({
)}
</Row>
),
[previewAsset, assetCount, handleAssetClick, setPreviewAsset, currentTab]
[previewAsset, handleAssetClick, setPreviewAsset, currentTab]
);
useEffect(() => {
if (
@ -278,15 +264,6 @@ const Users = ({
]
);
useEffect(() => {
if ([UserPageTabs.MY_DATA, UserPageTabs.FOLLOWING].includes(activeTab)) {
fetchAssetsCount(
activeTab === UserPageTabs.MY_DATA
? queryFilters.myData
: queryFilters.following
);
}
}, [activeTab]);
const handleRestoreUser = useCallback(async () => {
try {
await restoreUser(userData.id);