Improvement(UI): Optimised the API calls on homepage. (#6675)

* Removed unnecessary API calls on homepage for fetching different entity counts and replaced it with one util api

Removed unused API functions

Fixed failing unit tests caused by above changes

* Used async await pattern for API call function

* Rename MyAssetStats.Interface.ts to MyAssetStats.interface.ts
This commit is contained in:
Aniket Katkar 2022-08-10 09:26:42 +05:30 committed by GitHub
parent cbcc00bc78
commit 9eff5f1ed3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 109 additions and 846 deletions

View File

@ -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

View File

@ -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<EntitiesCount>('/util/entities/count');
return response.data;
};

View File

@ -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' },

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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<Props> = ({
countDashboards,
countPipelines,
countMlModal,
countServices,
countTables,
countTopics,
countTeams,
countUsers,
}: Props) => {
const MyAssetStats: FunctionComponent<MyAssetStatsProps> = ({
entityCounts,
}: MyAssetStatsProps) => {
const [dataSummary, setdataSummary] = useState<Record<string, Summary>>({});
const getSummarydata = () => {
@ -63,49 +38,49 @@ const MyAssetStats: FunctionComponent<Props> = ({
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<Props> = ({
teams: {
icon: Icons.TEAMS_GREY,
data: 'Teams',
count: countTeams,
count: entityCounts.teamCount,
link: getTeamAndUserDetailsPath(),
dataTestId: 'terms',
},

View File

@ -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;
}

View File

@ -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(
<MyAssetStats {...mockProp} countServices={4} />,
{
wrapper: MemoryRouter,
}
);
const { container } = render(<MyAssetStats {...mockProp} />, {
wrapper: MemoryRouter,
});
const tables = getByTestId(container, 'tables');
const topics = getByTestId(container, 'topics');
const dashboards = getByTestId(container, 'dashboards');

View File

@ -46,16 +46,9 @@ const MyData: React.FC<MyDataProps> = ({
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<MyDataProps> = ({
const getLeftPanel = () => {
return (
<div className="tw-mt-4">
<MyAssetStats
countDashboards={countDashboards}
countMlModal={countMlModal}
countPipelines={countPipelines}
countServices={countServices}
countTables={countTables}
countTeams={countTeams}
countTopics={countTopics}
countUsers={countUsers}
/>
<MyAssetStats entityCounts={entityCounts} />
<div className="tw-mb-5" />
<RecentlyViewed />
<div className="tw-mb-5" />

View File

@ -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<EntityReference>;
followedData: Array<EntityReference>;

View File

@ -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<string>('');
const [countServices, setCountServices] = useState<number>();
const [countTables, setCountTables] = useState<number>();
const [countTopics, setCountTopics] = useState<number>();
const [countDashboards, setCountDashboards] = useState<number>();
const [countPipelines, setCountPipelines] = useState<number>();
const [countMlModal, setCountMlModal] = useState<number>();
const [countUsers, setCountUsers] = useState<number>();
const [countTeams, setCountTeams] = useState<number>();
const [entityCounts, setEntityCounts] = useState<EntitiesCount>(
{} as EntitiesCount
);
const [ownedData, setOwnedData] = useState<Array<EntityReference>>();
const [followedData, setFollowedData] = useState<Array<EntityReference>>();
@ -86,179 +75,37 @@ const MyDataPage = () => {
const [paging, setPaging] = useState<Paging>({} 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 (
<PageContainerV1>
{!isUndefined(countServices) &&
!isUndefined(countTables) &&
!isUndefined(countTopics) &&
!isUndefined(countDashboards) &&
!isUndefined(countPipelines) &&
!isUndefined(countTeams) &&
!isUndefined(countMlModal) &&
!isUndefined(countUsers) ? (
{!isEmpty(entityCounts) ? (
<Fragment>
<MyData
activityFeeds={activityFeeds}
countDashboards={countDashboards}
countMlModal={countMlModal}
countPipelines={countPipelines}
countServices={countServices}
countTables={countTables}
countTeams={countTeams}
countTopics={countTopics}
countUsers={countUsers}
deletePostHandler={deletePostHandler}
entityCounts={entityCounts}
error={error}
feedData={entityThread || []}
fetchFeedHandler={handleFeedFetchFromFeedList}

View File

@ -13,14 +13,7 @@
import { findByText, queryByText, render } from '@testing-library/react';
import React, { ReactNode } from 'react';
import { getAllDashboards } from '../../axiosAPIs/dashboardAPI';
import { fetchSandboxConfig } from '../../axiosAPIs/miscAPI';
import { getAllPipelines } from '../../axiosAPIs/pipelineAPI';
import { getAllTables } from '../../axiosAPIs/tableAPI';
import { getTeams } from '../../axiosAPIs/teamsAPI';
import { getAllTopics } from '../../axiosAPIs/topicsAPI';
import { getUsers } from '../../axiosAPIs/userAPI';
import { getAllServices } from '../../utils/ServiceUtils';
import { fetchSandboxConfig, getAllEntityCount } from '../../axiosAPIs/miscAPI';
import MyDataPageComponent from './MyDataPage.component';
const mockAuth = {
@ -38,18 +31,6 @@ jest.mock('../../components/MyData/MyData.component', () => {
});
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(<MyDataPageComponent />);
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(<MyDataPageComponent />);
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(<MyDataPageComponent />);
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(<MyDataPageComponent />);
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(<MyDataPageComponent />);
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(<MyDataPageComponent />);
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(<MyDataPageComponent />);
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(<MyDataPageComponent />);
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(<MyDataPageComponent />);
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(<MyDataPageComponent />);
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(<MyDataPageComponent />);
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(<MyDataPageComponent />);
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(<MyDataPageComponent />);
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(<MyDataPageComponent />);
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(<MyDataPageComponent />);
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(<MyDataPageComponent />);
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(<MyDataPageComponent />);
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(<MyDataPageComponent />);
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(<MyDataPageComponent />);
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(<MyDataPageComponent />);
const myData = await findByText(container, /MyData.component/i);
expect(myData).toBeInTheDocument();
});
});
});

View File

@ -125,14 +125,16 @@ const TourPage = () => {
case CurrentTourPageType.MY_DATA_PAGE:
return (
<MyData
countDashboards={10}
countMlModal={2}
countPipelines={8}
countServices={4}
countTables={21}
countTeams={7}
countTopics={20}
countUsers={100}
entityCounts={{
tableCount: 21,
topicCount: 20,
dashboardCount: 10,
pipelineCount: 8,
mlmodelCount: 2,
servicesCount: 4,
userCount: 100,
teamCount: 7,
}}
error=""
feedData={myDataSearchResult as MyDataProps['feedData']}
fetchData={() => {

View File

@ -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<ServiceCollection>,
limit?: number
): Promise<Array<ServiceResponse>> => {
// fetch services of all individual collection
return new Promise<Array<ServiceResponse>>((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<Array<ServiceResponse>> => {
return new Promise<Array<ServiceResponse>>((resolve, reject) => {
getServiceDetails().then((res) => {
let allServiceCollectionArr: Array<ServiceCollection> = [];
if (res.data?.length) {
const arrServiceCat: Array<ServiceCollection> = 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) {