supported followed data in Following widget using search api (#17689)

(cherry picked from commit 84036048baf08970e04d2710646069e18768bcc7)
This commit is contained in:
Ashish Gupta 2024-09-05 18:14:12 +05:30
parent 69dddf0781
commit 892e53ade0
5 changed files with 53 additions and 39 deletions

View File

@ -96,9 +96,15 @@ jest.mock('../../../../rest/feedsAPI', () => ({
.mockImplementation(() => mockActiveAnnouncementData), .mockImplementation(() => mockActiveAnnouncementData),
})); }));
jest.mock('../../../../rest/userAPI', () => ({ jest.mock('../../../../rest/searchAPI', () => {
getUserById: jest.fn().mockImplementation(() => mockUserData), return {
})); searchQuery: jest
.fn()
.mockImplementation(() =>
Promise.resolve({ hits: { hits: [], total: { value: 0 } } })
),
};
});
jest.mock('react-router-dom', () => ({ jest.mock('react-router-dom', () => ({
useLocation: jest.fn().mockImplementation(() => ({ pathname: '' })), useLocation: jest.fn().mockImplementation(() => ({ pathname: '' })),

View File

@ -19,12 +19,13 @@ import RGL, { Layout, WidthProvider } from 'react-grid-layout';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Link, useHistory } from 'react-router-dom'; import { Link, useHistory } from 'react-router-dom';
import gridBgImg from '../../../../assets/img/grid-bg-img.png'; import gridBgImg from '../../../../assets/img/grid-bg-img.png';
import { KNOWLEDGE_LIST_LENGTH } from '../../../../constants/constants';
import { import {
GlobalSettingOptions, GlobalSettingOptions,
GlobalSettingsMenuCategory, GlobalSettingsMenuCategory,
} from '../../../../constants/GlobalSettings.constants'; } from '../../../../constants/GlobalSettings.constants';
import { LandingPageWidgetKeys } from '../../../../enums/CustomizablePage.enum'; import { LandingPageWidgetKeys } from '../../../../enums/CustomizablePage.enum';
import { TabSpecificField } from '../../../../enums/entity.enum'; import { SearchIndex } from '../../../../enums/search.enum';
import { Document } from '../../../../generated/entity/docStore/document'; import { Document } from '../../../../generated/entity/docStore/document';
import { EntityReference } from '../../../../generated/entity/type'; import { EntityReference } from '../../../../generated/entity/type';
import { useApplicationStore } from '../../../../hooks/useApplicationStore'; import { useApplicationStore } from '../../../../hooks/useApplicationStore';
@ -32,7 +33,7 @@ import { useFqn } from '../../../../hooks/useFqn';
import { useGridLayoutDirection } from '../../../../hooks/useGridLayoutDirection'; import { useGridLayoutDirection } from '../../../../hooks/useGridLayoutDirection';
import { WidgetConfig } from '../../../../pages/CustomizablePage/CustomizablePage.interface'; import { WidgetConfig } from '../../../../pages/CustomizablePage/CustomizablePage.interface';
import '../../../../pages/MyDataPage/my-data.less'; import '../../../../pages/MyDataPage/my-data.less';
import { getUserById } from '../../../../rest/userAPI'; import { searchQuery } from '../../../../rest/searchAPI';
import { Transi18next } from '../../../../utils/CommonUtils'; import { Transi18next } from '../../../../utils/CommonUtils';
import { import {
getAddWidgetHandler, getAddWidgetHandler,
@ -82,7 +83,7 @@ function CustomizeMyData({
); );
const [isWidgetModalOpen, setIsWidgetModalOpen] = useState<boolean>(false); const [isWidgetModalOpen, setIsWidgetModalOpen] = useState<boolean>(false);
const [isResetModalOpen, setIsResetModalOpen] = useState<boolean>(false); const [isResetModalOpen, setIsResetModalOpen] = useState<boolean>(false);
const [followedData, setFollowedData] = useState<Array<EntityReference>>(); const [followedData, setFollowedData] = useState<Array<EntityReference>>([]);
const [followedDataCount, setFollowedDataCount] = useState(0); const [followedDataCount, setFollowedDataCount] = useState(0);
const [isLoadingOwnedData, setIsLoadingOwnedData] = useState<boolean>(false); const [isLoadingOwnedData, setIsLoadingOwnedData] = useState<boolean>(false);
const [saving, setSaving] = useState<boolean>(false); const [saving, setSaving] = useState<boolean>(false);
@ -139,23 +140,22 @@ function CustomizeMyData({
setIsWidgetModalOpen(false); setIsWidgetModalOpen(false);
}, []); }, []);
const fetchMyData = async () => { const fetchUserFollowedData = async () => {
if (!currentUser?.id) { if (!currentUser?.id) {
return; return;
} }
setIsLoadingOwnedData(true); setIsLoadingOwnedData(true);
try { try {
const userData = await getUserById(currentUser?.id, { const res = await searchQuery({
fields: [TabSpecificField.FOLLOWS, TabSpecificField.OWNS], pageSize: KNOWLEDGE_LIST_LENGTH,
searchIndex: SearchIndex.ALL,
query: '*',
filters: `followers:${currentUser.id}`,
}); });
if (userData) { setFollowedDataCount(res?.hits?.total.value ?? 0);
const follows: EntityReference[] = userData.follows ?? []; setFollowedData(res.hits.hits.map((hit) => hit._source));
setFollowedDataCount(follows.length);
setFollowedData(follows.slice(0, 8));
}
} catch (err) { } catch (err) {
setFollowedData([]);
showErrorToast(err as AxiosError); showErrorToast(err as AxiosError);
} finally { } finally {
setIsLoadingOwnedData(false); setIsLoadingOwnedData(false);
@ -175,8 +175,8 @@ function CustomizeMyData({
layout.map((widget) => ( layout.map((widget) => (
<div data-grid={widget} id={widget.i} key={widget.i}> <div data-grid={widget} id={widget.i} key={widget.i}>
{getWidgetFromKey({ {getWidgetFromKey({
followedData: followedData ?? [], followedData,
followedDataCount: followedDataCount, followedDataCount,
isLoadingOwnedData: isLoadingOwnedData, isLoadingOwnedData: isLoadingOwnedData,
widgetConfig: widget, widgetConfig: widget,
handleOpenAddWidgetModal: handleOpenAddWidgetModal, handleOpenAddWidgetModal: handleOpenAddWidgetModal,
@ -238,7 +238,7 @@ function CustomizeMyData({
}, []); }, []);
useEffect(() => { useEffect(() => {
fetchMyData(); fetchUserFollowedData();
}, []); }, []);
const handleSave = async () => { const handleSave = async () => {

View File

@ -55,6 +55,7 @@ export const REFRESH_TOKEN_KEY = 'refreshToken';
export const USER_DATA_SIZE = 5; export const USER_DATA_SIZE = 5;
export const INITIAL_PAGING_VALUE = 1; export const INITIAL_PAGING_VALUE = 1;
export const JSON_TAB_SIZE = 2; export const JSON_TAB_SIZE = 2;
export const KNOWLEDGE_LIST_LENGTH = 8;
export const PAGE_SIZE = 10; export const PAGE_SIZE = 10;
export const PAGE_SIZE_BASE = 15; export const PAGE_SIZE_BASE = 15;
export const PAGE_SIZE_MEDIUM = 25; export const PAGE_SIZE_MEDIUM = 25;

View File

@ -26,8 +26,12 @@ import ActivityFeedProvider from '../../components/ActivityFeed/ActivityFeedProv
import Loader from '../../components/common/Loader/Loader'; import Loader from '../../components/common/Loader/Loader';
import WelcomeScreen from '../../components/MyData/WelcomeScreen/WelcomeScreen.component'; import WelcomeScreen from '../../components/MyData/WelcomeScreen/WelcomeScreen.component';
import PageLayoutV1 from '../../components/PageLayoutV1/PageLayoutV1'; import PageLayoutV1 from '../../components/PageLayoutV1/PageLayoutV1';
import { LOGGED_IN_USER_STORAGE_KEY } from '../../constants/constants'; import {
import { EntityType, TabSpecificField } from '../../enums/entity.enum'; KNOWLEDGE_LIST_LENGTH,
LOGGED_IN_USER_STORAGE_KEY,
} from '../../constants/constants';
import { EntityType } from '../../enums/entity.enum';
import { SearchIndex } from '../../enums/search.enum';
import { Thread } from '../../generated/entity/feed/thread'; import { Thread } from '../../generated/entity/feed/thread';
import { PageType } from '../../generated/system/ui/page'; import { PageType } from '../../generated/system/ui/page';
import { EntityReference } from '../../generated/type/entityReference'; import { EntityReference } from '../../generated/type/entityReference';
@ -36,7 +40,7 @@ import { useApplicationStore } from '../../hooks/useApplicationStore';
import { useGridLayoutDirection } from '../../hooks/useGridLayoutDirection'; import { useGridLayoutDirection } from '../../hooks/useGridLayoutDirection';
import { getDocumentByFQN } from '../../rest/DocStoreAPI'; import { getDocumentByFQN } from '../../rest/DocStoreAPI';
import { getActiveAnnouncement } from '../../rest/feedsAPI'; import { getActiveAnnouncement } from '../../rest/feedsAPI';
import { getUserById } from '../../rest/userAPI'; import { searchQuery } from '../../rest/searchAPI';
import { getWidgetFromKey } from '../../utils/CustomizableLandingPageUtils'; import { getWidgetFromKey } from '../../utils/CustomizableLandingPageUtils';
import customizePageClassBase from '../../utils/CustomizePageClassBase'; import customizePageClassBase from '../../utils/CustomizePageClassBase';
import { showErrorToast } from '../../utils/ToastUtils'; import { showErrorToast } from '../../utils/ToastUtils';
@ -48,7 +52,7 @@ const ReactGridLayout = WidthProvider(RGL);
const MyDataPage = () => { const MyDataPage = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const { currentUser, selectedPersona } = useApplicationStore(); const { currentUser, selectedPersona } = useApplicationStore();
const [followedData, setFollowedData] = useState<Array<EntityReference>>(); const [followedData, setFollowedData] = useState<Array<EntityReference>>([]);
const [followedDataCount, setFollowedDataCount] = useState(0); const [followedDataCount, setFollowedDataCount] = useState(0);
const [isLoadingOwnedData, setIsLoadingOwnedData] = useState<boolean>(false); const [isLoadingOwnedData, setIsLoadingOwnedData] = useState<boolean>(false);
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
@ -109,23 +113,22 @@ const MyDataPage = () => {
return () => updateWelcomeScreen(false); return () => updateWelcomeScreen(false);
}, []); }, []);
const fetchMyData = async () => { const fetchUserFollowedData = async () => {
if (!currentUser?.id) { if (!currentUser?.id) {
return; return;
} }
setIsLoadingOwnedData(true); setIsLoadingOwnedData(true);
try { try {
const userData = await getUserById(currentUser?.id, { const res = await searchQuery({
fields: [TabSpecificField.FOLLOWS, TabSpecificField.OWNS], pageSize: KNOWLEDGE_LIST_LENGTH,
searchIndex: SearchIndex.ALL,
query: '*',
filters: `followers:${currentUser.id}`,
}); });
if (userData) { setFollowedDataCount(res?.hits?.total.value ?? 0);
const follows: EntityReference[] = userData.follows ?? []; setFollowedData(res.hits.hits.map((hit) => hit._source));
setFollowedDataCount(follows.length);
setFollowedData(follows.slice(0, 8));
}
} catch (err) { } catch (err) {
setFollowedData([]);
showErrorToast(err as AxiosError); showErrorToast(err as AxiosError);
} finally { } finally {
setIsLoadingOwnedData(false); setIsLoadingOwnedData(false);
@ -134,7 +137,7 @@ const MyDataPage = () => {
useEffect(() => { useEffect(() => {
if (currentUser) { if (currentUser) {
fetchMyData(); fetchUserFollowedData();
} }
}, [currentUser]); }, [currentUser]);
@ -152,8 +155,8 @@ const MyDataPage = () => {
<div data-grid={widget} key={widget.i}> <div data-grid={widget} key={widget.i}>
{getWidgetFromKey({ {getWidgetFromKey({
announcements: announcements, announcements: announcements,
followedData: followedData ?? [], followedData,
followedDataCount: followedDataCount, followedDataCount,
isLoadingOwnedData: isLoadingOwnedData, isLoadingOwnedData: isLoadingOwnedData,
widgetConfig: widget, widgetConfig: widget,
})} })}

View File

@ -103,11 +103,15 @@ jest.mock('../../rest/feedsAPI', () => ({
.fn() .fn()
.mockImplementation(() => Promise.resolve(mockActiveAnnouncementData)), .mockImplementation(() => Promise.resolve(mockActiveAnnouncementData)),
})); }));
jest.mock('../../rest/userAPI', () => ({ jest.mock('../../rest/searchAPI', () => {
getUserById: jest return {
.fn() searchQuery: jest
.mockImplementation(() => Promise.resolve(mockUserData)), .fn()
})); .mockImplementation(() =>
Promise.resolve({ hits: { hits: [], total: { value: 0 } } })
),
};
});
jest.mock('react-router-dom', () => ({ jest.mock('react-router-dom', () => ({
useLocation: jest.fn().mockImplementation(() => ({ pathname: '' })), useLocation: jest.fn().mockImplementation(() => ({ pathname: '' })),
})); }));