From 6f46ebbfeff6b09e87a9a62aceb9c65660fe82c2 Mon Sep 17 00:00:00 2001 From: Shailesh Parmar Date: Tue, 26 Oct 2021 13:19:57 +0530 Subject: [PATCH] UI: Refector explore page (#925) * UI: refactor explore page * rename index to exlore.component for mock file and test file --- .../Explore/Explore.component.test.tsx} | 57 +++- .../Explore/Explore.component.tsx} | 320 ++++++------------ .../Explore/exlore.mock.js} | 77 ++++- .../Explore}/explore.constants.ts | 0 .../components/Explore/explore.interface.ts | 76 +++++ ...face.ts => ExplorePage.component.test.tsx} | 38 ++- .../pages/explore/ExplorePage.component.tsx | 228 +++++++++++++ .../ui/src/router/AuthenticatedAppRouter.tsx | 2 +- 8 files changed, 545 insertions(+), 253 deletions(-) rename catalog-rest-service/src/main/resources/ui/src/{pages/explore/index.test.tsx => components/Explore/Explore.component.test.tsx} (60%) rename catalog-rest-service/src/main/resources/ui/src/{pages/explore/index.tsx => components/Explore/Explore.component.tsx} (68%) rename catalog-rest-service/src/main/resources/ui/src/{pages/explore/index.mock.js => components/Explore/exlore.mock.js} (69%) rename catalog-rest-service/src/main/resources/ui/src/{pages/explore => components/Explore}/explore.constants.ts (100%) create mode 100644 catalog-rest-service/src/main/resources/ui/src/components/Explore/explore.interface.ts rename catalog-rest-service/src/main/resources/ui/src/pages/explore/{explore.interface.ts => ExplorePage.component.test.tsx} (55%) create mode 100644 catalog-rest-service/src/main/resources/ui/src/pages/explore/ExplorePage.component.tsx diff --git a/catalog-rest-service/src/main/resources/ui/src/pages/explore/index.test.tsx b/catalog-rest-service/src/main/resources/ui/src/components/Explore/Explore.component.test.tsx similarity index 60% rename from catalog-rest-service/src/main/resources/ui/src/pages/explore/index.test.tsx rename to catalog-rest-service/src/main/resources/ui/src/components/Explore/Explore.component.test.tsx index ee47cd68a5a..e5af0bfaa42 100644 --- a/catalog-rest-service/src/main/resources/ui/src/pages/explore/index.test.tsx +++ b/catalog-rest-service/src/main/resources/ui/src/components/Explore/Explore.component.test.tsx @@ -16,21 +16,16 @@ */ import { findAllByTestId, findByTestId, render } from '@testing-library/react'; +import { SearchResponse } from 'Models'; import React from 'react'; import { MemoryRouter } from 'react-router'; -import ExplorePage from './index'; -import { mockResponse } from './index.mock'; +import { mockResponse } from './exlore.mock'; +import Explore from './Explore.component'; jest.mock('react-router-dom', () => ({ useHistory: jest.fn(), - useParams: jest.fn().mockImplementation(() => ({ searchQuery: '' })), useLocation: jest.fn().mockImplementation(() => ({ search: '' })), })); -jest.mock('../../axiosAPIs/miscAPI', () => ({ - searchData: jest - .fn() - .mockImplementation(() => Promise.resolve({ data: mockResponse })), -})); jest.mock('../../utils/FilterUtils', () => ({ getFilterString: jest.fn().mockImplementation(() => 'user.address'), })); @@ -45,15 +40,47 @@ jest.mock('../../components/searched-data/SearchedData', () => { )); }); -jest.mock('../../hooks/useToastContext', () => { - return () => jest.fn(); -}); +const handleSearchText = jest.fn(); +const updateTableCount = jest.fn(); +const updateTopicCount = jest.fn(); +const updateDashboardCount = jest.fn(); +const updatePipelineCount = jest.fn(); +const fetchData = jest.fn(); -describe('Test Explore page', () => { +const mockSearchResult = { + resSearchResults: mockResponse as unknown as SearchResponse, + resAggServiceType: mockResponse as unknown as SearchResponse, + resAggTier: mockResponse as unknown as SearchResponse, + resAggTag: mockResponse as unknown as SearchResponse, +}; + +describe('Test Explore component', () => { it('Component should render', async () => { - const { container } = render(, { - wrapper: MemoryRouter, - }); + const { container } = render( + , + { + wrapper: MemoryRouter, + } + ); const pageContainer = await findByTestId(container, 'fluid-container'); const searchData = await findByTestId(container, 'search-data'); const wrappedContent = await findByTestId(container, 'wrapped-content'); diff --git a/catalog-rest-service/src/main/resources/ui/src/pages/explore/index.tsx b/catalog-rest-service/src/main/resources/ui/src/components/Explore/Explore.component.tsx similarity index 68% rename from catalog-rest-service/src/main/resources/ui/src/pages/explore/index.tsx rename to catalog-rest-service/src/main/resources/ui/src/components/Explore/Explore.component.tsx index a9e8f43f132..1addd8321b3 100644 --- a/catalog-rest-service/src/main/resources/ui/src/pages/explore/index.tsx +++ b/catalog-rest-service/src/main/resources/ui/src/components/Explore/Explore.component.tsx @@ -15,20 +15,17 @@ * limitations under the License. */ -import { AxiosError } from 'axios'; import classNames from 'classnames'; import { cloneDeep } from 'lodash'; import { AggregationType, - Bucket, FilterObject, FormatedTableData, SearchResponse, } from 'Models'; import React, { useCallback, useEffect, useRef, useState } from 'react'; -import { useHistory, useLocation, useParams } from 'react-router-dom'; +import { useHistory, useLocation } from 'react-router-dom'; import AppState from '../../AppState'; -import { searchData } from '../../axiosAPIs/miscAPI'; import { Button } from '../../components/buttons/Button/Button'; import ErrorPlaceHolderES from '../../components/common/error-with-placeholder/ErrorPlaceHolderES'; import FacetFilter from '../../components/common/facetfilter/FacetFilter'; @@ -36,7 +33,6 @@ import PageContainer from '../../components/containers/PageContainer'; import DropDownList from '../../components/dropdown/DropDownList'; import SearchedData from '../../components/searched-data/SearchedData'; import { - ERROR500, getExplorePathWithSearch, PAGE_SIZE, tableSortingFields, @@ -44,16 +40,14 @@ import { } from '../../constants/constants'; import { SearchIndex } from '../../enums/search.enum'; import { usePrevious } from '../../hooks/usePrevious'; -import useToastContext from '../../hooks/useToastContext'; import { getAggregationList } from '../../utils/AggregationUtils'; import { formatDataResponse } from '../../utils/APIUtils'; import { getCountBadge } from '../../utils/CommonUtils'; import { getFilterString } from '../../utils/FilterUtils'; -import { getTotalEntityCountByService } from '../../utils/ServiceUtils'; import { dropdownIcon as DropDownIcon } from '../../utils/svgconstant'; import SVGIcons from '../../utils/SvgUtils'; import { getAggrWithDefaultValue, tabsInfo } from './explore.constants'; -import { Params } from './explore.interface'; +import { ExploreProps } from './explore.interface'; const getQueryParam = (urlSearchQuery = ''): FilterObject => { const arrSearchQuery = urlSearchQuery @@ -125,36 +119,43 @@ const getCurrentIndex = (tab: string) => { return currentIndex; }; -const ExplorePage: React.FC = (): React.ReactElement => { +const Explore: React.FC = ({ + tabCounts, + searchText, + tab, + searchQuery, + searchResult, + error, + isLoading, + handleSearchText, + fetchData, + updateTableCount, + updateTopicCount, + updateDashboardCount, + updatePipelineCount, +}: ExploreProps) => { const location = useLocation(); const history = useHistory(); const filterObject: FilterObject = { ...{ tags: [], service: [], tier: [] }, ...getQueryParam(location.search), }; - const showToast = useToastContext(); - const { searchQuery, tab } = useParams(); - const [searchText, setSearchText] = useState(searchQuery || ''); const [data, setData] = useState>([]); const [filters, setFilters] = useState(filterObject); const [currentPage, setCurrentPage] = useState(1); const [totalNumberOfValue, setTotalNumberOfValues] = useState(0); const [aggregations, setAggregations] = useState>([]); - const [isLoading, setIsLoading] = useState(true); const [searchTag, setSearchTag] = useState(location.search); - const [error, setError] = useState(''); + const [fieldListVisible, setFieldListVisible] = useState(false); const [sortField, setSortField] = useState(''); const [sortOrder, setSortOrder] = useState('desc'); const [searchIndex, setSearchIndex] = useState(getCurrentIndex(tab)); const [currentTab, setCurrentTab] = useState(getCurrentTab(tab)); - const [tableCount, setTableCount] = useState(0); - const [topicCount, setTopicCount] = useState(0); - const [dashboardCount, setDashboardCount] = useState(0); - const [pipelineCount, setPipelineCount] = useState(0); const [fieldList, setFieldList] = useState>(tableSortingFields); const isMounting = useRef(true); + const forceSetAgg = useRef(false); const previsouIndex = usePrevious(searchIndex); const handleSelectedFilter = ( @@ -238,19 +239,19 @@ const ExplorePage: React.FC = (): React.ReactElement => { const setCount = (count = 0) => { switch (searchIndex) { case SearchIndex.TABLE: - setTableCount(count); + updateTableCount(count); break; case SearchIndex.DASHBOARD: - setDashboardCount(count); + updateDashboardCount(count); break; case SearchIndex.TOPIC: - setTopicCount(count); + updateTopicCount(count); break; case SearchIndex.PIPELINE: - setPipelineCount(count); + updatePipelineCount(count); break; default: @@ -258,176 +259,47 @@ const ExplorePage: React.FC = (): React.ReactElement => { } }; - const fetchCounts = () => { - const emptyValue = ''; - const tableCount = searchData( - searchText, - 0, - 0, - emptyValue, - emptyValue, - emptyValue, - SearchIndex.TABLE - ); - const topicCount = searchData( - searchText, - 0, - 0, - emptyValue, - emptyValue, - emptyValue, - SearchIndex.TOPIC - ); - const dashboardCount = searchData( - searchText, - 0, - 0, - emptyValue, - emptyValue, - emptyValue, - SearchIndex.DASHBOARD - ); - const pipelineCount = searchData( - searchText, - 0, - 0, - emptyValue, - emptyValue, - emptyValue, - SearchIndex.PIPELINE - ); - Promise.allSettled([ - tableCount, - topicCount, - dashboardCount, - pipelineCount, - ]).then( - ([ - table, - topic, - dashboard, - pipeline, - ]: PromiseSettledResult[]) => { - setTableCount( - table.status === 'fulfilled' - ? getTotalEntityCountByService( - table.value.data.aggregations?.['sterms#Service'] - ?.buckets as Bucket[] - ) - : 0 - ); - setTopicCount( - topic.status === 'fulfilled' - ? getTotalEntityCountByService( - topic.value.data.aggregations?.['sterms#Service'] - ?.buckets as Bucket[] - ) - : 0 - ); - setDashboardCount( - dashboard.status === 'fulfilled' - ? getTotalEntityCountByService( - dashboard.value.data.aggregations?.['sterms#Service'] - ?.buckets as Bucket[] - ) - : 0 - ); - setPipelineCount( - pipeline.status === 'fulfilled' - ? getTotalEntityCountByService( - pipeline.value.data.aggregations?.['sterms#Service'] - ?.buckets as Bucket[] - ) - : 0 - ); - } - ); - }; + const fetchTableData = () => { + const fetchParams = [ + { + queryString: searchText, + from: currentPage, + size: PAGE_SIZE, + filters: getFilterString(filters), + sortField: sortField, + sortOrder: sortOrder, + searchIndex: searchIndex, + }, + { + queryString: searchText, + from: currentPage, + size: 0, + filters: getFilterString(filters, ['service']), + sortField: sortField, + sortOrder: sortOrder, + searchIndex: searchIndex, + }, + { + queryString: searchText, + from: currentPage, + size: 0, + filters: getFilterString(filters, ['tier']), + sortField: sortField, + sortOrder: sortOrder, + searchIndex: searchIndex, + }, + { + queryString: searchText, + from: currentPage, + size: 0, + filters: getFilterString(filters, ['tags']), + sortField: sortField, + sortOrder: sortOrder, + searchIndex: searchIndex, + }, + ]; - const fetchTableData = (forceSetAgg: boolean) => { - setIsLoading(true); - - const searchResults = searchData( - searchText, - currentPage, - PAGE_SIZE, - getFilterString(filters), - sortField, - sortOrder, - searchIndex - ); - const serviceTypeAgg = searchData( - searchText, - currentPage, - 0, - getFilterString(filters, ['service']), - sortField, - sortOrder, - searchIndex - ); - const tierAgg = searchData( - searchText, - currentPage, - 0, - getFilterString(filters, ['tier']), - sortField, - sortOrder, - searchIndex - ); - const tagAgg = searchData( - searchText, - currentPage, - 0, - getFilterString(filters, ['tags']), - sortField, - sortOrder, - searchIndex - ); - - Promise.all([searchResults, serviceTypeAgg, tierAgg, tagAgg]) - .then( - ([ - resSearchResults, - resAggServiceType, - resAggTier, - resAggTag, - ]: Array) => { - updateSearchResults(resSearchResults); - setCount(resSearchResults.data.hits.total.value); - if (forceSetAgg) { - setAggregations( - resSearchResults.data.hits.hits.length > 0 - ? getAggregationList(resSearchResults.data.aggregations) - : [] - ); - } else { - const aggServiceType = getAggregationList( - resAggServiceType.data.aggregations, - 'service' - ); - const aggTier = getAggregationList( - resAggTier.data.aggregations, - 'tier' - ); - const aggTag = getAggregationList( - resAggTag.data.aggregations, - 'tags' - ); - - updateAggregationCount([...aggServiceType, ...aggTier, ...aggTag]); - } - setIsLoading(false); - } - ) - .catch((err: AxiosError) => { - setError(err.response?.data?.responseMessage); - showToast({ - variant: 'error', - body: err.response?.data?.responseMessage ?? ERROR500, - }); - - setIsLoading(false); - }); + fetchData(fetchParams); }; const getFacetedFilter = () => { @@ -515,13 +387,13 @@ const ExplorePage: React.FC = (): React.ReactElement => { const getTabCount = (index: string) => { switch (index) { case SearchIndex.TABLE: - return getCountBadge(tableCount); + return getCountBadge(tabCounts.table); case SearchIndex.TOPIC: - return getCountBadge(topicCount); + return getCountBadge(tabCounts.topic); case SearchIndex.DASHBOARD: - return getCountBadge(dashboardCount); + return getCountBadge(tabCounts.dashboard); case SearchIndex.PIPELINE: - return getCountBadge(pipelineCount); + return getCountBadge(tabCounts.pipeline); default: return getCountBadge(); } @@ -543,23 +415,23 @@ const ExplorePage: React.FC = (): React.ReactElement => {