diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityThreadPanel/ActivityThreadPanelBody.tsx b/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityThreadPanel/ActivityThreadPanelBody.tsx index de0f7ebd4da..bf08f9e8991 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityThreadPanel/ActivityThreadPanelBody.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityThreadPanel/ActivityThreadPanelBody.tsx @@ -30,7 +30,7 @@ import { ThreadType, } from '../../../generated/entity/feed/thread'; import { Paging } from '../../../generated/type/paging'; -import { useInfiniteScroll } from '../../../hooks/useInfiniteScroll'; +import { useElementInView } from '../../../hooks/useElementInView'; import { getEntityField } from '../../../utils/FeedUtils'; import { showErrorToast } from '../../../utils/ToastUtils'; import ErrorPlaceHolder from '../../common/error-with-placeholder/ErrorPlaceHolder'; @@ -67,7 +67,7 @@ const ActivityThreadPanelBody: FC = ({ confirmStateInitialValue ); - const [elementRef, isInView] = useInfiniteScroll(observerOptions); + const [elementRef, isInView] = useElementInView(observerOptions); const [paging, setPaging] = useState({} as Paging); @@ -230,7 +230,7 @@ const ActivityThreadPanelBody: FC = ({ }, [threadLink, threadType, taskStatus]); useEffect(() => { - fetchMoreThread(isInView as boolean, paging, isThreadLoading); + fetchMoreThread(isInView, paging, isThreadLoading); }, [paging, isThreadLoading, isInView]); return ( diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.component.tsx index 14b9cbb2a88..10504dbb238 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.component.tsx @@ -42,7 +42,7 @@ import { Dashboard } from '../../generated/entity/data/dashboard'; import { ThreadType } from '../../generated/entity/feed/thread'; import { Paging } from '../../generated/type/paging'; import { LabelType, State, TagLabel } from '../../generated/type/tagLabel'; -import { useInfiniteScroll } from '../../hooks/useInfiniteScroll'; +import { useElementInView } from '../../hooks/useElementInView'; import { getCurrentUserId, getEntityPlaceHolder, @@ -123,7 +123,7 @@ const DashboardDetails = ({ const [isTagLoading, setIsTagLoading] = useState(false); const [threadLink, setThreadLink] = useState(''); - const [elementRef, isInView] = useInfiniteScroll(observerOptions); + const [elementRef, isInView] = useElementInView(observerOptions); const [threadType, setThreadType] = useState( ThreadType.Conversation ); @@ -556,7 +556,7 @@ const DashboardDetails = ({ }; useEffect(() => { - fetchMoreThread(isInView as boolean, paging, isEntityThreadLoading); + fetchMoreThread(isInView, paging, isEntityThreadLoading); }, [paging, isEntityThreadLoading, isInView]); const handleFeedFilterChange = useCallback((feedType, threadType) => { diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataModels/DataModelDetails.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataModels/DataModelDetails.component.tsx index c1b124e020a..e38f625e676 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataModels/DataModelDetails.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataModels/DataModelDetails.component.tsx @@ -29,7 +29,7 @@ import { EntityInfo, EntityType } from 'enums/entity.enum'; import { ServiceCategory } from 'enums/service.enum'; import { OwnerType } from 'enums/user.enum'; import { Paging } from 'generated/type/paging'; -import { useInfiniteScroll } from 'hooks/useInfiniteScroll'; +import { useElementInView } from 'hooks/useElementInView'; import { toString } from 'lodash'; import { ExtraInfo } from 'Models'; import { DATA_MODELS_DETAILS_TABS } from 'pages/DataModelPage/DataModelsInterface'; @@ -76,7 +76,7 @@ const DataModelDetails = ({ }: DataModelDetailsProps) => { const { t } = useTranslation(); const history = useHistory(); - const [elementRef, isInView] = useInfiniteScroll(observerOptions); + const [elementRef, isInView] = useElementInView(observerOptions); const [isEditDescription, setIsEditDescription] = useState(false); const [threadLink, setThreadLink] = useState(''); @@ -212,7 +212,7 @@ const DataModelDetails = ({ }; useEffect(() => { - fetchMoreThread(isInView as boolean, paging, isEntityThreadLoading); + fetchMoreThread(isInView, paging, isEntityThreadLoading); }, [paging, isEntityThreadLoading, isInView]); return ( diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/DatasetDetails.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/DatasetDetails.component.tsx index e796b24a5d9..92e42e56f93 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/DatasetDetails.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/DatasetDetails.component.tsx @@ -52,7 +52,7 @@ import { import { ThreadType } from '../../generated/entity/feed/thread'; import { Paging } from '../../generated/type/paging'; import { LabelType, State } from '../../generated/type/tagLabel'; -import { useInfiniteScroll } from '../../hooks/useInfiniteScroll'; +import { useElementInView } from '../../hooks/useElementInView'; import { getCurrentUserId, getEntityPlaceHolder, @@ -133,7 +133,7 @@ const DatasetDetails: React.FC = ({ ); const [queryCount, setQueryCount] = useState(0); - const [elementRef, isInView] = useInfiniteScroll(observerOptions); + const [elementRef, isInView] = useElementInView(observerOptions); const [tablePermissions, setTablePermissions] = useState( DEFAULT_ENTITY_PERMISSION @@ -624,7 +624,7 @@ const DatasetDetails: React.FC = ({ }, [usageSummary]); useEffect(() => { - fetchMoreThread(isInView as boolean, paging, isEntityThreadLoading); + fetchMoreThread(isInView, paging, isEntityThreadLoading); }, [paging, isEntityThreadLoading, isInView]); const handleFeedFilterChange = useCallback((feedType, threadType) => { diff --git a/openmetadata-ui/src/main/resources/ui/src/components/MlModelDetail/MlModelDetail.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/MlModelDetail/MlModelDetail.component.tsx index 73b2d28c1a5..7b78ca35c2e 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/MlModelDetail/MlModelDetail.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/MlModelDetail/MlModelDetail.component.tsx @@ -48,7 +48,7 @@ import { ThreadType } from '../../generated/entity/feed/thread'; import { EntityReference } from '../../generated/type/entityReference'; import { Paging } from '../../generated/type/paging'; import { LabelType, State, TagLabel } from '../../generated/type/tagLabel'; -import { useInfiniteScroll } from '../../hooks/useInfiniteScroll'; +import { useElementInView } from '../../hooks/useElementInView'; import { getEmptyPlaceholder, getEntityPlaceHolder, @@ -138,7 +138,7 @@ const MlModelDetail: FC = ({ } }, [mlModelDetail.id, getEntityPermission, setPipelinePermissions]); - const [elementRef, isInView] = useInfiniteScroll(observerOptions); + const [elementRef, isInView] = useElementInView(observerOptions); useEffect(() => { if (mlModelDetail.id) { @@ -514,7 +514,7 @@ const MlModelDetail: FC = ({ }, []); useEffect(() => { - fetchMoreThread(isInView as boolean, paging, isEntityThreadLoading); + fetchMoreThread(isInView, paging, isEntityThreadLoading); }, [paging, isEntityThreadLoading, isInView]); useEffect(() => { diff --git a/openmetadata-ui/src/main/resources/ui/src/components/MyData/MyData.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/MyData/MyData.component.tsx index 1d3fe98db95..14ab9b787e9 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/MyData/MyData.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/MyData/MyData.component.tsx @@ -34,7 +34,7 @@ import { observerOptions } from '../../constants/Mydata.constants'; import { FeedFilter } from '../../enums/mydata.enum'; import { ThreadType } from '../../generated/entity/feed/thread'; import { Paging } from '../../generated/type/paging'; -import { useInfiniteScroll } from '../../hooks/useInfiniteScroll'; +import { useElementInView } from '../../hooks/useElementInView'; import SVGIcons, { Icons } from '../../utils/SvgUtils'; import ActivityFeedList from '../ActivityFeed/ActivityFeedList/ActivityFeedList'; import ErrorPlaceHolderES from '../common/error-with-placeholder/ErrorPlaceHolderES'; @@ -67,7 +67,7 @@ const MyData: React.FC = ({ }: MyDataProps): React.ReactElement => { const { t } = useTranslation(); const isMounted = useRef(false); - const [elementRef, isInView] = useInfiniteScroll(observerOptions); + const [elementRef, isInView] = useElementInView(observerOptions); const [feedFilter, setFeedFilter] = useState(FeedFilter.OWNER); const [threadType, setThreadType] = useState(); const [showWelcomeScreen, setShowWelcomeScreen] = useState(false); @@ -235,7 +235,7 @@ const MyData: React.FC = ({ ); useEffect(() => { - fetchMoreFeed(Boolean(isInView), paging); + fetchMoreFeed(isInView, paging); }, [isInView, paging]); useEffect(() => { diff --git a/openmetadata-ui/src/main/resources/ui/src/components/PipelineDetails/PipelineDetails.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/PipelineDetails/PipelineDetails.component.tsx index bc7c627b0d2..a38415377f5 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/PipelineDetails/PipelineDetails.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/PipelineDetails/PipelineDetails.component.tsx @@ -68,7 +68,7 @@ import { Post, Thread, ThreadType } from '../../generated/entity/feed/thread'; import { EntityReference } from '../../generated/type/entityReference'; import { Paging } from '../../generated/type/paging'; import { LabelType, State } from '../../generated/type/tagLabel'; -import { useInfiniteScroll } from '../../hooks/useInfiniteScroll'; +import { useElementInView } from '../../hooks/useElementInView'; import { EntityFieldThreadCount } from '../../interface/feed.interface'; import { getCountBadge, @@ -178,7 +178,7 @@ const PipelineDetails = ({ const [threadLink, setThreadLink] = useState(''); - const [elementRef, isInView] = useInfiniteScroll(observerOptions); + const [elementRef, isInView] = useElementInView(observerOptions); const [selectedExecution] = useState( pipelineStatus ); @@ -477,11 +477,7 @@ const PipelineDetails = ({ }, [followers]); useEffect(() => { - fetchMoreThread( - isInView as boolean, - entityThreadPaging, - entityThreadLoading - ); + fetchMoreThread(isInView, entityThreadPaging, entityThreadLoading); }, [entityThreadPaging, entityThreadLoading, isInView]); const handleFeedFilterChange = useCallback((feedFilter, threadType) => { diff --git a/openmetadata-ui/src/main/resources/ui/src/components/TopicDetails/TopicDetails.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/TopicDetails/TopicDetails.component.tsx index 7899887a9e2..b2caf41221f 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/TopicDetails/TopicDetails.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/TopicDetails/TopicDetails.component.tsx @@ -35,7 +35,7 @@ import { Topic } from '../../generated/entity/data/topic'; import { ThreadType } from '../../generated/entity/feed/thread'; import { Paging } from '../../generated/type/paging'; import { LabelType, State } from '../../generated/type/tagLabel'; -import { useInfiniteScroll } from '../../hooks/useInfiniteScroll'; +import { useElementInView } from '../../hooks/useElementInView'; import { getCurrentUserId, getEntityPlaceHolder, @@ -95,7 +95,7 @@ const TopicDetails: React.FC = ({ const { t } = useTranslation(); const [isEdit, setIsEdit] = useState(false); const [threadLink, setThreadLink] = useState(''); - const [elementRef, isInView] = useInfiniteScroll(observerOptions); + const [elementRef, isInView] = useElementInView(observerOptions); const [threadType, setThreadType] = useState( ThreadType.Conversation ); @@ -418,7 +418,7 @@ const TopicDetails: React.FC = ({ }; useEffect(() => { - fetchMoreThread(isInView as boolean, paging, isEntityThreadLoading); + fetchMoreThread(isInView, paging, isEntityThreadLoading); }, [paging, isEntityThreadLoading, isInView]); const handleFeedFilterChange = useCallback((feedFilter, threadType) => { diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Users/Users.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Users/Users.component.tsx index e077781beea..6f671482ea7 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Users/Users.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Users/Users.component.tsx @@ -63,7 +63,7 @@ import { ThreadType } from '../../generated/entity/feed/thread'; import { Role } from '../../generated/entity/teams/role'; import { EntityReference } from '../../generated/entity/teams/user'; import { Paging } from '../../generated/type/paging'; -import { useInfiniteScroll } from '../../hooks/useInfiniteScroll'; +import { useElementInView } from '../../hooks/useElementInView'; import { getNonDeletedTeams } from '../../utils/CommonUtils'; import { getImageWithResolutionAndFallback, @@ -118,7 +118,7 @@ const Users = ({ onSwitchChange, }: Props) => { const [activeTab, setActiveTab] = useState(getUserCurrentTab(tab)); - const [elementRef, isInView] = useInfiniteScroll(observerOptions); + const [elementRef, isInView] = useElementInView(observerOptions); const [displayName, setDisplayName] = useState(userData.displayName); const [isDisplayNameEdit, setIsDisplayNameEdit] = useState(false); const [isDescriptionEdit, setIsDescriptionEdit] = useState(false); @@ -801,7 +801,7 @@ const Users = ({ }; useEffect(() => { - fetchMoreFeed(isInView as boolean, paging, isFeedLoading); + fetchMoreFeed(isInView, paging, isFeedLoading); }, [isInView, paging, isFeedLoading]); useEffect(() => { diff --git a/openmetadata-ui/src/main/resources/ui/src/hooks/useElementInView.test.ts b/openmetadata-ui/src/main/resources/ui/src/hooks/useElementInView.test.ts new file mode 100644 index 00000000000..9fd9ee60288 --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/hooks/useElementInView.test.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2023 Collate. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { renderHook } from '@testing-library/react-hooks'; +import { useElementInView } from './useElementInView'; + +describe('useElementInView', () => { + it('should return an array with a ref object and a boolean', () => { + const { result } = renderHook(() => useElementInView({})); + + expect(result.current).toEqual([expect.any(Object), expect.any(Boolean)]); + }); +}); diff --git a/openmetadata-ui/src/main/resources/ui/src/hooks/useInfiniteScroll.ts b/openmetadata-ui/src/main/resources/ui/src/hooks/useElementInView.ts similarity index 87% rename from openmetadata-ui/src/main/resources/ui/src/hooks/useInfiniteScroll.ts rename to openmetadata-ui/src/main/resources/ui/src/hooks/useElementInView.ts index 34b6bb0392e..212b9691a96 100644 --- a/openmetadata-ui/src/main/resources/ui/src/hooks/useInfiniteScroll.ts +++ b/openmetadata-ui/src/main/resources/ui/src/hooks/useElementInView.ts @@ -11,9 +11,11 @@ * limitations under the License. */ -import { useEffect, useRef, useState } from 'react'; +import { RefObject, useEffect, useRef, useState } from 'react'; -export const useInfiniteScroll = (options: IntersectionObserverInit) => { +export const useElementInView = ( + options: IntersectionObserverInit +): [RefObject, boolean] => { const elementRef = useRef(null); const [isInView, setIsInView] = useState(false); diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/DatabaseSchemaPage/DatabaseSchemaPage.component.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/DatabaseSchemaPage/DatabaseSchemaPage.component.tsx index c9ebcdbdc36..c174e41cb65 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/DatabaseSchemaPage/DatabaseSchemaPage.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/DatabaseSchemaPage/DatabaseSchemaPage.component.tsx @@ -95,7 +95,7 @@ import { DatabaseSchema } from '../../generated/entity/data/databaseSchema'; import { Table } from '../../generated/entity/data/table'; import { Post, Thread } from '../../generated/entity/feed/thread'; import { Paging } from '../../generated/type/paging'; -import { useInfiniteScroll } from '../../hooks/useInfiniteScroll'; +import { useElementInView } from '../../hooks/useElementInView'; import { EntityFieldThreadCount } from '../../interface/feed.interface'; import { getPartialNameFromTableFQN } from '../../utils/CommonUtils'; import { @@ -161,7 +161,7 @@ const DatabaseSchemaPage: FunctionComponent = () => { const [paging, setPaging] = useState({} as Paging); const [currentTablesPage, setCurrentTablesPage] = useState(INITIAL_PAGING_VALUE); - const [elementRef, isInView] = useInfiniteScroll(observerOptions); + const [elementRef, isInView] = useElementInView(observerOptions); const history = useHistory(); const isMounting = useRef(true); @@ -750,7 +750,7 @@ const DatabaseSchemaPage: FunctionComponent = () => { }, [tab]); useEffect(() => { - fetchMoreFeed(isInView as boolean, paging, isentityThreadLoading); + fetchMoreFeed(isInView, paging, isentityThreadLoading); }, [isInView, paging, isentityThreadLoading]); useEffect(() => { diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/database-details/index.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/database-details/index.tsx index 70a7d0d34a1..3513b14ccab 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/database-details/index.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/database-details/index.tsx @@ -92,7 +92,7 @@ import { Post, Thread } from '../../generated/entity/feed/thread'; import { EntityReference } from '../../generated/entity/teams/user'; import { UsageDetails } from '../../generated/type/entityUsage'; import { Paging } from '../../generated/type/paging'; -import { useInfiniteScroll } from '../../hooks/useInfiniteScroll'; +import { useElementInView } from '../../hooks/useElementInView'; import { EntityFieldThreadCount } from '../../interface/feed.interface'; import { databaseDetailsTabs, @@ -160,7 +160,7 @@ const DatabaseDetails: FunctionComponent = () => { const [threadLink, setThreadLink] = useState(''); const [paging, setPaging] = useState({} as Paging); - const [elementRef, isInView] = useInfiniteScroll(observerOptions); + const [elementRef, isInView] = useElementInView(observerOptions); const [currentPage, setCurrentPage] = useState(1); const [isEditable, setIsEditable] = useState(false); const [tagList, setTagList] = useState>([]); @@ -606,7 +606,7 @@ const DatabaseDetails: FunctionComponent = () => { }, [tab]); useEffect(() => { - fetchMoreFeed(isInView as boolean, paging, isentityThreadLoading); + fetchMoreFeed(isInView, paging, isentityThreadLoading); }, [isInView, paging, isentityThreadLoading]); useEffect(() => {