mirror of
				https://github.com/open-metadata/OpenMetadata.git
				synced 2025-10-31 02:29:03 +00:00 
			
		
		
		
	supported followed data in Following widget using search api (#17689)
(cherry picked from commit 84036048baf08970e04d2710646069e18768bcc7)
This commit is contained in:
		
							parent
							
								
									69dddf0781
								
							
						
					
					
						commit
						892e53ade0
					
				| @ -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: '' })), | ||||||
|  | |||||||
| @ -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 () => { | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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, | ||||||
|           })} |           })} | ||||||
|  | |||||||
| @ -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 { | ||||||
|  |     searchQuery: jest | ||||||
|       .fn() |       .fn() | ||||||
|     .mockImplementation(() => Promise.resolve(mockUserData)), |       .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: '' })), | ||||||
| })); | })); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Ashish Gupta
						Ashish Gupta