diff --git a/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/dashboardAPI.ts b/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/dashboardAPI.ts index aeb6e8bf42a..492b8447f8d 100644 --- a/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/dashboardAPI.ts +++ b/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/dashboardAPI.ts @@ -13,7 +13,6 @@ import { AxiosResponse } from 'axios'; import { Operation } from 'fast-json-patch'; -import { isNil } from 'lodash'; import { EntityReference } from 'Models'; import { Dashboard } from '../generated/entity/data/dashboard'; import { EntityHistory } from '../generated/type/entityHistory'; @@ -55,30 +54,6 @@ export const getDashboards = async ( return response.data; }; -export const getAllDashboards = async ( - paging: string, - arrQueryFields: string, - limit?: number -) => { - const searchParams = new URLSearchParams(); - - if (!isNil(limit)) { - searchParams.set('limit', `${limit}`); - } - - const url = getURLWithQueryFields( - `/dashboards`, - arrQueryFields, - `${searchParams.toString()}${paging ? `&${paging}` : ''}` - ); - - const response = await APIClient.get<{ data: Dashboard[]; paging: Paging }>( - url - ); - - return response.data; -}; - export const getDashboardDetails: Function = ( id: string, arrQueryFields: string diff --git a/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/miscAPI.ts b/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/miscAPI.ts index 5a1d2500b8e..e17ec755209 100644 --- a/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/miscAPI.ts +++ b/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/miscAPI.ts @@ -19,6 +19,7 @@ import { SearchIndex } from '../enums/search.enum'; import { AirflowConfiguration } from '../generated/configuration/airflowConfiguration'; import { AuthenticationConfiguration } from '../generated/configuration/authenticationConfiguration'; import { ResourcePermission } from '../generated/entity/policies/accessControl/resourcePermission'; +import { EntitiesCount } from '../generated/entity/utils/entitiesCount'; import { Paging } from '../generated/type/paging'; import { getURLWithQueryFields } from '../utils/APIUtils'; import { getCurrentUserId } from '../utils/CommonUtils'; @@ -275,3 +276,9 @@ export const getEntityCount = async ( return response.data; }; + +export const getAllEntityCount = async () => { + const response = await APIClient.get('/util/entities/count'); + + return response.data; +}; diff --git a/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/mlModelAPI.ts b/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/mlModelAPI.ts index 11e269b1cf7..9894fdc8fb7 100644 --- a/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/mlModelAPI.ts +++ b/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/mlModelAPI.ts @@ -13,7 +13,6 @@ import { AxiosResponse } from 'axios'; import { Operation } from 'fast-json-patch'; -import { isNil } from 'lodash'; import { Mlmodel } from '../generated/entity/data/mlmodel'; import { EntityReference } from '../generated/type/entityReference'; import { Paging } from '../generated/type/paging'; @@ -47,28 +46,6 @@ export const getMlmodels = async ( return response.data; }; -export const getAllMlModal = async ( - paging: string, - arrQueryFields: string, - limit?: number -) => { - const searchParams = new URLSearchParams(); - - if (!isNil(limit)) { - searchParams.set('limit', `${limit}`); - } - - const url = getURLWithQueryFields( - `/mlmodels`, - arrQueryFields, - `${searchParams.toString()}${paging ? `&${paging}` : ''}` - ); - - const response = await APIClient.get<{ data: Mlmodel; paging: Paging }>(url); - - return response.data; -}; - export const patchMlModelDetails = async (id: string, data: Operation[]) => { const configOptions = { headers: { 'Content-type': 'application/json-patch+json' }, diff --git a/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/pipelineAPI.ts b/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/pipelineAPI.ts index ac75c08e9a6..b517394f970 100644 --- a/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/pipelineAPI.ts +++ b/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/pipelineAPI.ts @@ -13,7 +13,6 @@ import { AxiosResponse } from 'axios'; import { Operation } from 'fast-json-patch'; -import { isNil } from 'lodash'; import { Pipeline } from '../generated/entity/data/pipeline'; import { EntityHistory } from '../generated/type/entityHistory'; import { EntityReference } from '../generated/type/entityReference'; @@ -55,30 +54,6 @@ export const getPipelines = async ( return response.data; }; -export const getAllPipelines = async ( - paging: string, - arrQueryFields: string, - limit?: number -) => { - const searchParams = new URLSearchParams(); - - if (!isNil(limit)) { - searchParams.set('limit', `${limit}`); - } - - const url = getURLWithQueryFields( - `/pipelines`, - arrQueryFields, - `${searchParams.toString()}${paging ? `&${paging}` : ''}` - ); - - const response = await APIClient.get<{ data: Pipeline[]; paging: Paging }>( - url - ); - - return response.data; -}; - export const getPipelineDetails: Function = ( id: string, arrQueryFields: string diff --git a/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/tableAPI.ts b/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/tableAPI.ts index 1139ed6d996..449ec9025ab 100644 --- a/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/tableAPI.ts +++ b/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/tableAPI.ts @@ -13,14 +13,12 @@ import { AxiosResponse } from 'axios'; import { Operation } from 'fast-json-patch'; -import { isNil, isUndefined } from 'lodash'; import { CreateColumnTest } from '../generated/api/tests/createColumnTest'; import { CreateTableTest } from '../generated/api/tests/createTableTest'; import { ColumnTestType, Table } from '../generated/entity/data/table'; import { TableTestType } from '../generated/tests/tableTest'; import { EntityHistory } from '../generated/type/entityHistory'; import { EntityReference } from '../generated/type/entityReference'; -import { Paging } from '../generated/type/paging'; import { getURLWithQueryFields } from '../utils/APIUtils'; import APIClient from './index'; @@ -67,32 +65,6 @@ export const getTableDetailsByFQN = async ( return response.data; }; -export const getAllTables = async ( - arrQueryFields?: string, - limit?: number, - database?: string -) => { - const searchParams = new URLSearchParams(); - - if (!isNil(limit)) { - searchParams.set('limit', `${limit}`); - } - - if (!isUndefined(database)) { - searchParams.set('database', database); - } - - const url = getURLWithQueryFields( - '/tables', - arrQueryFields, - searchParams.toString() - ); - - const response = await APIClient.get<{ data: Table[]; paging: Paging }>(url); - - return response.data; -}; - export const getDatabaseTables: Function = ( databaseName: string, paging: string, diff --git a/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/topicsAPI.ts b/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/topicsAPI.ts index e030f5b6201..5e5c3357af3 100644 --- a/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/topicsAPI.ts +++ b/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/topicsAPI.ts @@ -13,7 +13,6 @@ import { AxiosResponse } from 'axios'; import { Operation } from 'fast-json-patch'; -import { isNil } from 'lodash'; import { TabSpecificField } from '../enums/entity.enum'; import { Topic } from '../generated/entity/data/topic'; import { EntityHistory } from '../generated/type/entityHistory'; @@ -56,28 +55,6 @@ export const getTopics = async ( return response.data; }; -export const getAllTopics = async ( - paging: string, - arrQueryFields: string, - limit?: number -) => { - const searchParams = new URLSearchParams(); - - if (!isNil(limit)) { - searchParams.set('limit', `${limit}`); - } - - const url = getURLWithQueryFields( - `/topics`, - arrQueryFields, - `${searchParams.toString()}${paging ? `&${paging}` : ''}` - ); - - const response = await APIClient.get<{ data: Topic[]; paging: Paging }>(url); - - return response.data; -}; - export const getTopicDetails: Function = ( id: string, arrQueryFields: string diff --git a/openmetadata-ui/src/main/resources/ui/src/components/MyAssetStats/MyAssetStats.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/MyAssetStats/MyAssetStats.component.tsx index cd6940f6f62..e9fe9338ffa 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/MyAssetStats/MyAssetStats.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/MyAssetStats/MyAssetStats.component.tsx @@ -26,36 +26,11 @@ import { getCountBadge } from '../../utils/CommonUtils'; import SVGIcons, { Icons } from '../../utils/SvgUtils'; import NonAdminAction from '../common/non-admin-action/NonAdminAction'; import { leftPanelAntCardStyle } from '../containers/PageLayout'; +import { MyAssetStatsProps, Summary } from './MyAssetStats.interface'; -type Props = { - countDashboards: number; - countPipelines: number; - countServices: number; - countMlModal: number; - countTables: number; - countTopics: number; - countTeams: number; - countUsers: number; -}; -type Summary = { - icon: string; - data: string; - count?: number; - link?: string; - dataTestId?: string; - adminOnly?: boolean; -}; - -const MyAssetStats: FunctionComponent = ({ - countDashboards, - countPipelines, - countMlModal, - countServices, - countTables, - countTopics, - countTeams, - countUsers, -}: Props) => { +const MyAssetStats: FunctionComponent = ({ + entityCounts, +}: MyAssetStatsProps) => { const [dataSummary, setdataSummary] = useState>({}); const getSummarydata = () => { @@ -63,49 +38,49 @@ const MyAssetStats: FunctionComponent = ({ tables: { icon: Icons.TABLE_GREY, data: 'Tables', - count: countTables, + count: entityCounts.tableCount, link: getExplorePathWithSearch(undefined, 'tables'), dataTestId: 'tables', }, topics: { icon: Icons.TOPIC_GREY, data: 'Topics', - count: countTopics, + count: entityCounts.topicCount, link: getExplorePathWithSearch(undefined, 'topics'), dataTestId: 'topics', }, dashboards: { icon: Icons.DASHBOARD_GREY, data: 'Dashboards', - count: countDashboards, + count: entityCounts.dashboardCount, link: getExplorePathWithSearch(undefined, 'dashboards'), dataTestId: 'dashboards', }, pipelines: { icon: Icons.PIPELINE_GREY, data: 'Pipelines', - count: countPipelines, + count: entityCounts.pipelineCount, link: getExplorePathWithSearch(undefined, 'pipelines'), dataTestId: 'pipelines', }, mlModal: { icon: Icons.MLMODAL, data: 'ML Models', - count: countMlModal, + count: entityCounts.mlmodelCount, link: getExplorePathWithSearch(undefined, 'mlmodels'), dataTestId: 'mlmodels', }, service: { icon: Icons.SERVICE, data: 'Services', - count: countServices, + count: entityCounts.servicesCount, link: ROUTES.SERVICES, dataTestId: 'service', }, user: { icon: Icons.USERS, data: 'Users', - count: countUsers, + count: entityCounts.userCount, link: getTeamAndUserDetailsPath(UserType.USERS), dataTestId: 'user', adminOnly: true, @@ -113,7 +88,7 @@ const MyAssetStats: FunctionComponent = ({ teams: { icon: Icons.TEAMS_GREY, data: 'Teams', - count: countTeams, + count: entityCounts.teamCount, link: getTeamAndUserDetailsPath(), dataTestId: 'terms', }, diff --git a/openmetadata-ui/src/main/resources/ui/src/components/MyAssetStats/MyAssetStats.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/MyAssetStats/MyAssetStats.interface.ts new file mode 100644 index 00000000000..ae3ea40c664 --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/components/MyAssetStats/MyAssetStats.interface.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2022 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 { EntitiesCount } from '../../generated/entity/utils/entitiesCount'; + +export interface MyAssetStatsProps { + entityCounts: EntitiesCount; +} + +export interface Summary { + icon: string; + data: string; + count?: number; + link?: string; + dataTestId?: string; + adminOnly?: boolean; +} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/MyAssetStats/MyAssetStats.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/MyAssetStats/MyAssetStats.test.tsx index a13cefcd47d..847185351fe 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/MyAssetStats/MyAssetStats.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/MyAssetStats/MyAssetStats.test.tsx @@ -16,6 +16,7 @@ import React from 'react'; import { MemoryRouter } from 'react-router'; import { getTeamAndUserDetailsPath } from '../../constants/constants'; import { UserType } from '../../enums/user.enum'; +import { EntitiesCount } from '../../generated/entity/utils/entitiesCount'; import MyAssetStats from './MyAssetStats.component'; jest.mock('../../authentication/auth-provider/AuthProvider', () => { @@ -31,14 +32,16 @@ jest.mock('../../authentication/auth-provider/AuthProvider', () => { }); const mockProp = { - countDashboards: 10, - countPipelines: 3, - countServices: 193, - countTables: 40, - countTeams: 7, - countTopics: 13, - countUsers: 100, - countMlModal: 2, + entityCounts: { + tableCount: 40, + topicCount: 13, + dashboardCount: 10, + pipelineCount: 3, + mlmodelCount: 2, + servicesCount: 193, + userCount: 100, + teamCount: 7, + } as EntitiesCount, }; describe('Test MyDataHeader Component', () => { @@ -63,12 +66,9 @@ describe('Test MyDataHeader Component', () => { }); it('OnClick it should redirect to respective page', () => { - const { container } = render( - , - { - wrapper: MemoryRouter, - } - ); + const { container } = render(, { + wrapper: MemoryRouter, + }); const tables = getByTestId(container, 'tables'); const topics = getByTestId(container, 'topics'); const dashboards = getByTestId(container, 'dashboards'); 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 4a9766d6662..ee371b658e9 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 @@ -46,16 +46,9 @@ const MyData: React.FC = ({ activityFeeds, onRefreshFeeds, error, - countDashboards, - countPipelines, - countServices, - countTables, - countTopics, - countTeams, - countUsers, + entityCounts, ownedData, pendingTaskCount, - countMlModal, followedData, feedData, ownedDataCount, @@ -75,16 +68,7 @@ const MyData: React.FC = ({ const getLeftPanel = () => { return (
- +
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/MyData/MyData.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/MyData/MyData.interface.ts index a2a1160f824..23dfe986314 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/MyData/MyData.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/MyData/MyData.interface.ts @@ -15,6 +15,7 @@ import { EntityReference, SearchDataFunctionType } from 'Models'; import { FeedFilter } from '../../enums/mydata.enum'; import { Thread, ThreadType } from '../../generated/entity/feed/thread'; import { User } from '../../generated/entity/teams/user'; +import { EntitiesCount } from '../../generated/entity/utils/entitiesCount'; import { Paging } from '../../generated/type/paging'; import { ThreadUpdatedFunc } from '../../interface/feed.interface'; @@ -22,17 +23,10 @@ export interface MyDataProps { activityFeeds?: Thread[] | undefined; onRefreshFeeds?: () => void; error: string; - countServices: number; - countTables: number; - countTopics: number; - countTeams: number; - countUsers: number; - countMlModal: number; - countDashboards: number; + entityCounts: EntitiesCount; followedDataCount: number; pendingTaskCount: number; ownedDataCount: number; - countPipelines: number; userDetails?: User; ownedData: Array; followedData: Array; diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/MyDataPage/MyDataPage.component.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/MyDataPage/MyDataPage.component.tsx index 28635174127..80b418b6a4f 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/MyDataPage/MyDataPage.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/MyDataPage/MyDataPage.component.tsx @@ -25,15 +25,9 @@ import React, { } from 'react'; import { useLocation } from 'react-router-dom'; import AppState from '../../AppState'; -import { getAllDashboards } from '../../axiosAPIs/dashboardAPI'; import { getFeedsWithFilter, postFeedById } from '../../axiosAPIs/feedsAPI'; -import { fetchSandboxConfig } from '../../axiosAPIs/miscAPI'; -import { getAllMlModal } from '../../axiosAPIs/mlModelAPI'; -import { getAllPipelines } from '../../axiosAPIs/pipelineAPI'; -import { getAllTables } from '../../axiosAPIs/tableAPI'; -import { getTeams } from '../../axiosAPIs/teamsAPI'; -import { getAllTopics } from '../../axiosAPIs/topicsAPI'; -import { getUserById, getUsers } from '../../axiosAPIs/userAPI'; +import { fetchSandboxConfig, getAllEntityCount } from '../../axiosAPIs/miscAPI'; +import { getUserById } from '../../axiosAPIs/userAPI'; import PageContainerV1 from '../../components/containers/PageContainerV1'; import GithubStarButton from '../../components/GithubStarButton/GithubStarButton'; import Loader from '../../components/Loader/Loader'; @@ -47,6 +41,7 @@ import { import { AssetsType } from '../../enums/entity.enum'; import { FeedFilter } from '../../enums/mydata.enum'; import { Post, Thread, ThreadType } from '../../generated/entity/feed/thread'; +import { EntitiesCount } from '../../generated/entity/utils/entitiesCount'; import { Paging } from '../../generated/type/paging'; import { useAuth } from '../../hooks/authHooks'; import jsonData from '../../jsons/en'; @@ -55,21 +50,15 @@ import { getUpdatedThread, updateThreadData, } from '../../utils/FeedUtils'; -import { getAllServices } from '../../utils/ServiceUtils'; import { showErrorToast } from '../../utils/ToastUtils'; const MyDataPage = () => { const location = useLocation(); const { isAuthDisabled } = useAuth(location.pathname); const [error, setError] = useState(''); - const [countServices, setCountServices] = useState(); - const [countTables, setCountTables] = useState(); - const [countTopics, setCountTopics] = useState(); - const [countDashboards, setCountDashboards] = useState(); - const [countPipelines, setCountPipelines] = useState(); - const [countMlModal, setCountMlModal] = useState(); - const [countUsers, setCountUsers] = useState(); - const [countTeams, setCountTeams] = useState(); + const [entityCounts, setEntityCounts] = useState( + {} as EntitiesCount + ); const [ownedData, setOwnedData] = useState>(); const [followedData, setFollowedData] = useState>(); @@ -86,179 +75,37 @@ const MyDataPage = () => { const [paging, setPaging] = useState({} as Paging); const { socket } = useWebSocketConnector(); - const setTableCount = (count = 0) => { - setCountTables(count); - }; - const setTopicCount = (count = 0) => { - setCountTopics(count); - }; - const setPipelineCount = (count = 0) => { - setCountPipelines(count); - }; - const setDashboardCount = (count = 0) => { - setCountDashboards(count); - }; - const setUserCount = (count = 0) => { - setCountUsers(count); - }; - const setTeamCount = (count = 0) => { - setCountTeams(count); - }; - const currentUser = useMemo( () => AppState.getCurrentUserDetails(), [AppState.userDetails, AppState.nonSecureUserDetails] ); const fetchEntityCount = () => { - // limit=0 will fetch empty data list with total count - getAllTables('', 0) + getAllEntityCount() .then((res) => { - if (res.paging) { - setTableCount(res.paging.total); - } else { - throw jsonData['api-error-messages']['unexpected-server-response']; - } + setEntityCounts(res); }) .catch((err: AxiosError) => { showErrorToast( err, - jsonData['api-error-messages']['unexpected-server-response'] + jsonData['api-error-messages']['fetch-entity-count-error'] ); - setCountTables(0); - }); - - // limit=0 will fetch empty data list with total count - getAllTopics('', '', 0) - .then((res) => { - if (res.paging) { - setTopicCount(res.paging.total); - } else { - throw jsonData['api-error-messages']['unexpected-server-response']; - } - }) - .catch((err: AxiosError) => { - showErrorToast( - err, - jsonData['api-error-messages']['unexpected-server-response'] - ); - setCountTopics(0); - }); - - // limit=0 will fetch empty data list with total count - getAllPipelines('', '', 0) - .then((res) => { - if (res.paging) { - setPipelineCount(res.paging.total); - } else { - throw jsonData['api-error-messages']['unexpected-server-response']; - } - }) - .catch((err: AxiosError) => { - showErrorToast( - err, - jsonData['api-error-messages']['unexpected-server-response'] - ); - setCountPipelines(0); - }); - - // limit=0 will fetch empty data list with total count - getAllDashboards('', '', 0) - .then((res) => { - if (res.paging) { - setDashboardCount(res.paging.total); - } else { - throw jsonData['api-error-messages']['unexpected-server-response']; - } - }) - .catch((err: AxiosError) => { - showErrorToast( - err, - jsonData['api-error-messages']['unexpected-server-response'] - ); - setCountDashboards(0); - }); - - // limit=0 will fetch empty data list with total count - getAllMlModal('', '', 0) - .then((res) => { - if (res.paging) { - setCountMlModal(res.paging.total); - } else { - throw jsonData['api-error-messages']['unexpected-server-response']; - } - }) - .catch((err: AxiosError) => { - showErrorToast( - err, - jsonData['api-error-messages']['unexpected-server-response'] - ); - setCountMlModal(0); + setEntityCounts({ + tableCount: 0, + topicCount: 0, + dashboardCount: 0, + pipelineCount: 0, + mlmodelCount: 0, + servicesCount: 0, + userCount: 0, + teamCount: 0, + }); }); }; - const fetchTeamsAndUsersCount = () => { - getUsers('', 0, undefined, undefined, false) - .then((res) => { - if (res.paging) { - setUserCount(res.paging.total); - } else { - throw jsonData['api-error-messages']['unexpected-server-response']; - } - }) - .catch((err: AxiosError) => { - showErrorToast( - err, - jsonData['api-error-messages']['unexpected-server-response'] - ); - setUserCount(0); - }); - - getTeams('', 0) - .then((res) => { - if (res.paging) { - setTeamCount(res.paging.total); - } else { - throw jsonData['api-error-messages']['unexpected-server-response']; - } - }) - .catch((err: AxiosError) => { - showErrorToast( - err, - jsonData['api-error-messages']['unexpected-server-response'] - ); - setTeamCount(0); - }); - }; - - const fetchServiceCount = () => { - // limit=0 will fetch empty data list with total count - getAllServices(true, 0) - .then((res) => { - const total = res.reduce((prev, curr) => { - return prev + (curr?.paging?.total || 0); - }, 0); - setCountServices(total); - }) - .catch((err: AxiosError) => { - showErrorToast( - err, - jsonData['api-error-messages']['unexpected-server-response'] - ); - setCountServices(0); - }); - }; - - const fetchData = (fetchService = false) => { + const fetchData = () => { setError(''); - fetchEntityCount(); - - fetchTeamsAndUsersCount(); - - if (fetchService) { - fetchServiceCount(); - } }; const fetchMyData = async () => { @@ -428,7 +275,7 @@ const MyDataPage = () => { useEffect(() => { fetchSandboxMode(); - fetchData(true); + fetchData(); fetchMyTaskData(); }, []); @@ -479,26 +326,12 @@ const MyDataPage = () => { return ( - {!isUndefined(countServices) && - !isUndefined(countTables) && - !isUndefined(countTopics) && - !isUndefined(countDashboards) && - !isUndefined(countPipelines) && - !isUndefined(countTeams) && - !isUndefined(countMlModal) && - !isUndefined(countUsers) ? ( + {!isEmpty(entityCounts) ? ( { }); jest.mock('../../axiosAPIs/miscAPI', () => ({ - searchData: jest.fn().mockImplementation(() => - Promise.resolve({ - data: { - aggregations: { - 'sterms#Service': { - buckets: [], - }, - }, - hits: [], - }, - }) - ), fetchSandboxConfig: jest.fn().mockImplementation(() => Promise.resolve({ data: { @@ -57,94 +38,17 @@ jest.mock('../../axiosAPIs/miscAPI', () => ({ }, }) ), - fetchSlackConfig: jest.fn().mockImplementation(() => + getAllEntityCount: jest.fn().mockImplementation(() => Promise.resolve({ data: { - apiToken: '', - botName: '', - channels: [], - }, - }) - ), -})); - -jest.mock('../../axiosAPIs/tableAPI', () => ({ - getAllTables: jest.fn().mockImplementation(() => - Promise.resolve({ - data: { - data: [], - paging: { - total: 3, - }, - }, - }) - ), -})); - -jest.mock('../../axiosAPIs/topicsAPI', () => ({ - getAllTopics: jest.fn().mockImplementation(() => - Promise.resolve({ - data: { - data: [], - paging: { - total: 3, - }, - }, - }) - ), -})); - -jest.mock('../../axiosAPIs/dashboardAPI', () => ({ - getAllDashboards: jest.fn().mockImplementation(() => - Promise.resolve({ - data: { - data: [], - paging: { - total: 3, - }, - }, - }) - ), -})); - -jest.mock('../../axiosAPIs/pipelineAPI', () => ({ - getAllPipelines: jest.fn().mockImplementation(() => - Promise.resolve({ - data: { - data: [], - paging: { - total: 3, - }, - }, - }) - ), -})); - -jest.mock('../../axiosAPIs/mlModelAPI', () => ({ - getAllMlModal: jest.fn().mockImplementation(() => - Promise.resolve({ - data: { - data: [], - }, - }) - ), -})); - -jest.mock('../../axiosAPIs/userAPI', () => ({ - getUsers: jest.fn().mockImplementation(() => - Promise.resolve({ - data: { - data: [], - }, - }) - ), -})); - -jest.mock('../../axiosAPIs/teamsAPI', () => ({ - getTeams: jest.fn().mockImplementation(() => - Promise.resolve({ - data: { - data: [], + tableCount: 40, + topicCount: 13, + dashboardCount: 10, + pipelineCount: 3, + mlmodelCount: 2, + servicesCount: 193, + userCount: 100, + teamCount: 7, }, }) ), @@ -160,16 +64,6 @@ jest.mock('../../axiosAPIs/feedsAPI', () => ({ ), })); -jest.mock('../../utils/ServiceUtils', () => ({ - getAllServices: jest.fn().mockImplementation(() => Promise.resolve(['test'])), - getEntityCountByService: jest.fn().mockReturnValue({ - tableCount: 0, - topicCount: 0, - dashboardCount: 0, - pipelineCount: 0, - }), -})); - jest.mock('../../utils/CommonUtils', () => ({ isSandboxOMD: jest.fn().mockReturnValue(true), })); @@ -278,7 +172,7 @@ describe('Test MyData page component', () => { }); it('should render component if table count api fails', async () => { - (getAllTables as jest.Mock).mockImplementationOnce(() => + (getAllEntityCount as jest.Mock).mockImplementationOnce(() => Promise.reject({ response: { data: { message: 'Error!' } }, }) @@ -289,263 +183,5 @@ describe('Test MyData page component', () => { expect(myData).toBeInTheDocument(); }); - - it('should render component if table count api has no data', async () => { - (getAllTables as jest.Mock).mockImplementationOnce(() => - Promise.resolve({}) - ); - - const { container } = render(); - const myData = await findByText(container, /MyData.component/i); - - expect(myData).toBeInTheDocument(); - }); - - it('should render component if table count api has no paging', async () => { - (getAllTables as jest.Mock).mockImplementationOnce(() => - Promise.resolve({ - data: { - data: [], - }, - }) - ); - - const { container } = render(); - const myData = await findByText(container, /MyData.component/i); - - expect(myData).toBeInTheDocument(); - }); - - it('should render component if topic count api fails', async () => { - (getAllTopics as jest.Mock).mockImplementationOnce(() => - Promise.reject({ - response: { data: { message: 'Error!' } }, - }) - ); - - const { container } = render(); - const myData = await findByText(container, /MyData.component/i); - - expect(myData).toBeInTheDocument(); - }); - - it('should render component if topic count api has no data', async () => { - (getAllTopics as jest.Mock).mockImplementationOnce(() => - Promise.resolve({}) - ); - - const { container } = render(); - const myData = await findByText(container, /MyData.component/i); - - expect(myData).toBeInTheDocument(); - }); - - it('should render component if topic count api has no paging', async () => { - (getAllTopics as jest.Mock).mockImplementationOnce(() => - Promise.resolve({ - data: { - data: [], - }, - }) - ); - - const { container } = render(); - const myData = await findByText(container, /MyData.component/i); - - expect(myData).toBeInTheDocument(); - }); - - it('should render component if dashboard count api fails', async () => { - (getAllDashboards as jest.Mock).mockImplementationOnce(() => - Promise.reject({ - response: { data: { message: 'Error!' } }, - }) - ); - - const { container } = render(); - const myData = await findByText(container, /MyData.component/i); - - expect(myData).toBeInTheDocument(); - }); - - it('should render component if dashboard count api has no data', async () => { - (getAllDashboards as jest.Mock).mockImplementationOnce(() => - Promise.resolve({}) - ); - - const { container } = render(); - const myData = await findByText(container, /MyData.component/i); - - expect(myData).toBeInTheDocument(); - }); - - it('should render component if dashboard count api has no paging', async () => { - (getAllDashboards as jest.Mock).mockImplementationOnce(() => - Promise.resolve({ - data: { - data: [], - }, - }) - ); - - const { container } = render(); - const myData = await findByText(container, /MyData.component/i); - - expect(myData).toBeInTheDocument(); - }); - - it('should render component if pipeline count api fails', async () => { - (getAllPipelines as jest.Mock).mockImplementationOnce(() => - Promise.reject({ - response: { data: { message: 'Error!' } }, - }) - ); - - const { container } = render(); - const myData = await findByText(container, /MyData.component/i); - - expect(myData).toBeInTheDocument(); - }); - - it('should render component if pipeline count api has no data', async () => { - (getAllPipelines as jest.Mock).mockImplementationOnce(() => - Promise.resolve({}) - ); - - const { container } = render(); - const myData = await findByText(container, /MyData.component/i); - - expect(myData).toBeInTheDocument(); - }); - - it('should render component if pipeline count api has no paging', async () => { - (getAllPipelines as jest.Mock).mockImplementationOnce(() => - Promise.resolve({ - data: { - data: [], - }, - }) - ); - - const { container } = render(); - const myData = await findByText(container, /MyData.component/i); - - expect(myData).toBeInTheDocument(); - }); - - it('should render component if service util fails', async () => { - (getAllServices as jest.Mock).mockImplementationOnce(() => - Promise.reject({ - response: { data: { message: 'Error!' } }, - }) - ); - - const { container } = render(); - const myData = await findByText(container, /MyData.component/i); - - expect(myData).toBeInTheDocument(); - }); - - it('should render component if service util has no data', async () => { - (getAllServices as jest.Mock).mockImplementationOnce(() => - Promise.resolve([{}]) - ); - - const { container } = render(); - const myData = await findByText(container, /MyData.component/i); - - expect(myData).toBeInTheDocument(); - }); - - it('should render component if service util has no paging', async () => { - (getAllServices as jest.Mock).mockImplementationOnce(() => - Promise.resolve([ - { - data: { - data: [], - }, - }, - ]) - ); - - const { container } = render(); - const myData = await findByText(container, /MyData.component/i); - - expect(myData).toBeInTheDocument(); - }); - - it('should render component if user count api fails', async () => { - (getUsers as jest.Mock).mockImplementationOnce(() => - Promise.reject({ - response: { data: { message: 'Error!' } }, - }) - ); - - const { container } = render(); - const myData = await findByText(container, /MyData.component/i); - - expect(myData).toBeInTheDocument(); - }); - - it('should render component if user count api has no data', async () => { - (getUsers as jest.Mock).mockImplementationOnce(() => Promise.resolve({})); - - const { container } = render(); - const myData = await findByText(container, /MyData.component/i); - - expect(myData).toBeInTheDocument(); - }); - - it('should render component if user count api has no paging', async () => { - (getUsers as jest.Mock).mockImplementationOnce(() => - Promise.resolve({ - data: { - data: [], - }, - }) - ); - - const { container } = render(); - const myData = await findByText(container, /MyData.component/i); - - expect(myData).toBeInTheDocument(); - }); - - it('should render component if team count api fails', async () => { - (getTeams as jest.Mock).mockImplementationOnce(() => - Promise.reject({ - response: { data: { message: 'Error!' } }, - }) - ); - - const { container } = render(); - const myData = await findByText(container, /MyData.component/i); - - expect(myData).toBeInTheDocument(); - }); - - it('should render component if team count api has no data', async () => { - (getTeams as jest.Mock).mockImplementationOnce(() => Promise.resolve({})); - - const { container } = render(); - const myData = await findByText(container, /MyData.component/i); - - expect(myData).toBeInTheDocument(); - }); - - it('should render component if team count api has no paging', async () => { - (getTeams as jest.Mock).mockImplementationOnce(() => - Promise.resolve({ - data: { - data: [], - }, - }) - ); - - const { container } = render(); - const myData = await findByText(container, /MyData.component/i); - - expect(myData).toBeInTheDocument(); - }); }); }); diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/tour-page/TourPage.component.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/tour-page/TourPage.component.tsx index 3e65acb0d43..1cdb44aef1b 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/tour-page/TourPage.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/tour-page/TourPage.component.tsx @@ -125,14 +125,16 @@ const TourPage = () => { case CurrentTourPageType.MY_DATA_PAGE: return ( { diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/ServiceUtils.tsx b/openmetadata-ui/src/main/resources/ui/src/utils/ServiceUtils.tsx index dd7c66bf5e7..9619d2c20d7 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/ServiceUtils.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/utils/ServiceUtils.tsx @@ -17,13 +17,11 @@ import { Bucket, DynamicFormFieldType, DynamicObj, - ServiceCollection, ServicesData, ServiceTypes, } from 'Models'; import React from 'react'; import { getEntityCount } from '../axiosAPIs/miscAPI'; -import { getServiceDetails, getServices } from '../axiosAPIs/serviceAPI'; import { addMetadataIngestionGuide, addProfilerIngestionGuide, @@ -34,7 +32,6 @@ import { import { AIRBYTE, AIRFLOW, - arrServiceTypes, ATHENA, AZURESQL, BIGQUERY, @@ -95,8 +92,7 @@ import { PipelineService, PipelineServiceType, } from '../generated/entity/services/pipelineService'; -import { Paging } from '../generated/type/paging'; -import { ServiceResponse, ServicesType } from '../interface/service.interface'; +import { ServicesType } from '../interface/service.interface'; import { getEntityDeleteMessage, pluralize } from './CommonUtils'; import { getDashboardURL } from './DashboardServiceUtils'; import { getBrokers } from './MessagingServiceUtils'; @@ -254,73 +250,6 @@ export const getFrequencyTime = (isoDate: string): string => { return `${day}D-${hour}H-${minute}M`; }; -const getAllServiceList = ( - allServiceCollectionArr: Array, - limit?: number -): Promise> => { - // fetch services of all individual collection - return new Promise>((resolve, reject) => { - if (allServiceCollectionArr.length) { - let promiseArr = []; - promiseArr = allServiceCollectionArr.map((obj) => { - return getServices(obj.value, limit); - }); - Promise.allSettled(promiseArr) - .then((result) => { - if (result.length) { - let serviceArr = []; - serviceArr = result.map((service) => - service.status === 'fulfilled' - ? service.value - : ({ - data: [], - paging: { total: 0 } as Paging, - } as ServiceResponse) - ); - resolve(serviceArr); - } else { - resolve([]); - } - }) - .catch((err) => reject(err)); - } else { - resolve([]); - } - }); -}; - -export const getAllServices = ( - onlyVisibleServices = true, - limit?: number -): Promise> => { - return new Promise>((resolve, reject) => { - getServiceDetails().then((res) => { - let allServiceCollectionArr: Array = []; - if (res.data?.length) { - const arrServiceCat: Array = res.data.map( - (service) => { - return { - name: service.collection.name, - value: service.collection.name, - }; - } - ); - - if (onlyVisibleServices) { - allServiceCollectionArr = arrServiceCat.filter((service) => - arrServiceTypes.includes(service.name as ServiceTypes) - ); - } else { - allServiceCollectionArr = arrServiceCat; - } - } - getAllServiceList(allServiceCollectionArr, limit) - .then((resAll) => resolve(resAll)) - .catch((err) => reject(err)); - }); - }); -}; - export const getServiceCategoryFromType = (type: string): ServiceTypes => { let serviceCategory: ServiceTypes = 'databaseServices'; for (const category in serviceTypes) {