From f48e34be9ee7fde4ea295f0e3478b11c933570ea Mon Sep 17 00:00:00 2001 From: darth-coder00 <86726556+darth-coder00@users.noreply.github.com> Date: Tue, 7 Sep 2021 20:14:58 +0530 Subject: [PATCH] Added Dashboard services UI and api integration (#422) Co-authored-by: aashitk --- .../src/assets/img/service-icon-superset.png | Bin 0 -> 27867 bytes .../AddServiceModal/AddServiceModal.tsx | 165 ++++++++++++------ .../ui/src/constants/services.const.ts | 5 + .../resources/ui/src/enums/service.enum.ts | 5 + .../resources/ui/src/interface/types.d.ts | 7 +- .../ui/src/pages/database-details/index.tsx | 4 +- .../resources/ui/src/pages/service/index.tsx | 118 +++++++++++-- .../resources/ui/src/pages/services/index.tsx | 13 ++ .../resources/ui/src/utils/ServiceUtils.ts | 5 + 9 files changed, 251 insertions(+), 71 deletions(-) create mode 100644 catalog-rest-service/src/main/resources/ui/src/assets/img/service-icon-superset.png diff --git a/catalog-rest-service/src/main/resources/ui/src/assets/img/service-icon-superset.png b/catalog-rest-service/src/main/resources/ui/src/assets/img/service-icon-superset.png new file mode 100644 index 0000000000000000000000000000000000000000..b0d768b2b0f378c22a3de1a190cf513e6c458ed6 GIT binary patch literal 27867 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 literal 0 HcmV?d00001 diff --git a/catalog-rest-service/src/main/resources/ui/src/components/Modals/AddServiceModal/AddServiceModal.tsx b/catalog-rest-service/src/main/resources/ui/src/components/Modals/AddServiceModal/AddServiceModal.tsx index c7f894e0263..64dd6ade39b 100644 --- a/catalog-rest-service/src/main/resources/ui/src/components/Modals/AddServiceModal/AddServiceModal.tsx +++ b/catalog-rest-service/src/main/resources/ui/src/components/Modals/AddServiceModal/AddServiceModal.tsx @@ -44,6 +44,9 @@ export type DataObj = { }; brokers?: Array; schemaRegistry?: string; + dashboardUrl?: string; + username?: string; + password?: string; }; type DatabaseService = { @@ -57,6 +60,12 @@ type MessagingService = { schemaRegistry: string; }; +type DashboardService = { + dashboardUrl: string; + username: string; + password: string; +}; + export type ServiceDataObj = { description: string; href: string; @@ -65,7 +74,8 @@ export type ServiceDataObj = { serviceType: string; ingestionSchedule?: { repeatFrequency: string; startDate: string }; } & Partial & - Partial; + Partial & + Partial; export type EditObj = { edit: boolean; @@ -86,10 +96,11 @@ type ErrorMsg = { name: boolean; url?: boolean; // port: boolean; - // userName: boolean; - // password: boolean; driverClass?: boolean; broker?: boolean; + dashboardUrl?: boolean; + username?: boolean; + password?: boolean; }; type EditorContentRef = { getEditorContent: () => string; @@ -176,6 +187,9 @@ export const AddServiceModal: FunctionComponent = ({ const [schemaRegistry, setSchemaRegistry] = useState( data?.schemaRegistry || '' ); + const [dashboardUrl, setDashboardUrl] = useState(data?.dashboardUrl || ''); + const [username, setUsername] = useState(data?.username || ''); + const [password, setPassword] = useState(data?.password || ''); const [frequency, setFrequency] = useState( fromISOString(data?.ingestionSchedule?.repeatFrequency) ); @@ -261,18 +275,27 @@ export const AddServiceModal: FunctionComponent = ({ }; const onSaveHelper = (value: ErrorMsg) => { - const { selectService, name, url, driverClass, broker } = value; + const { + selectService, + name, + url, + driverClass, + broker, + dashboardUrl, + username, + password, + } = value; return ( !sameNameError && !selectService && !name && !url && - // !port && - // !userName && - // !password && !driverClass && - !broker + !broker && + !dashboardUrl && + !username && + !password ); }; @@ -287,9 +310,6 @@ export const AddServiceModal: FunctionComponent = ({ setMsg = { ...setMsg, url: !url, - // port: !port, - // userName: !userName, - // password: !password, driverClass: !driverClass, }; } @@ -303,6 +323,17 @@ export const AddServiceModal: FunctionComponent = ({ }; } + break; + case ServiceCategory.DASHBOARD_SERVICES: + { + setMsg = { + ...setMsg, + dashboardUrl: !dashboardUrl, + username: !username, + password: !password, + }; + } + break; default: break; @@ -347,6 +378,17 @@ export const AddServiceModal: FunctionComponent = ({ }; } + break; + case ServiceCategory.DASHBOARD_SERVICES: + { + dataObj = { + ...dataObj, + dashboardUrl: dashboardUrl, + username: username, + password: password, + }; + } + break; default: break; @@ -374,54 +416,7 @@ export const AddServiceModal: FunctionComponent = ({ /> {showErrorMsg.url && errorMsg('Connection url is required')} - - {/* didn't removed below code as it will be need in future relase */} - - {/*
- - - {showErrorMsg.port && errorMsg('Port is required')} -
*/} - {/*
-
- - - {showErrorMsg.userName && errorMsg('Username is required')} -
-
- - - {showErrorMsg.password && errorMsg('Password is required')} -
-
*/}
diff --git a/catalog-rest-service/src/main/resources/ui/src/pages/service/index.tsx b/catalog-rest-service/src/main/resources/ui/src/pages/service/index.tsx index 2834a27126e..556678eb4dc 100644 --- a/catalog-rest-service/src/main/resources/ui/src/pages/service/index.tsx +++ b/catalog-rest-service/src/main/resources/ui/src/pages/service/index.tsx @@ -17,10 +17,11 @@ import { AxiosError, AxiosResponse } from 'axios'; import classNames from 'classnames'; -import { isNull, isUndefined } from 'lodash'; +import { isNil, isUndefined } from 'lodash'; import { Database, Paging, ServiceOption } from 'Models'; import React, { Fragment, FunctionComponent, useEffect, useState } from 'react'; import { Link, useParams } from 'react-router-dom'; +import { getDashboards } from '../../axiosAPIs/dashboardAPI'; import { getDatabases } from '../../axiosAPIs/databaseAPI'; import { getServiceByFQN, updateService } from '../../axiosAPIs/serviceAPI'; import { getTopics } from '../../axiosAPIs/topicsAPI'; @@ -36,6 +37,7 @@ import Tags from '../../components/tags/tags'; import { pagingObject } from '../../constants/constants'; import { SearchIndex } from '../../enums/search.enum'; import { ServiceCategory } from '../../enums/service.enum'; +import { Dashboard } from '../../generated/entity/data/dashboard'; import { Topic } from '../../generated/entity/data/topic'; import useToastContext from '../../hooks/useToastContext'; import { isEven } from '../../utils/CommonUtils'; @@ -101,6 +103,30 @@ const ServicePage: FunctionComponent = () => { }); }; + const fetchDashboards = (paging?: string) => { + setIsloading(true); + getDashboards(serviceFQN, paging, [ + 'owner', + 'service', + 'usageSummary', + 'tags', + ]) + .then((res: AxiosResponse) => { + if (res.data.data) { + setData(res.data.data); + setPaging(res.data.paging); + setIsloading(false); + } else { + setData([]); + setPaging(pagingObject); + setIsloading(false); + } + }) + .catch(() => { + setIsloading(false); + }); + }; + const getOtherDetails = (paging?: string) => { switch (serviceName) { case ServiceCategory.DATABASE_SERVICES: { @@ -113,6 +139,11 @@ const ServicePage: FunctionComponent = () => { break; } + case ServiceCategory.DASHBOARD_SERVICES: { + fetchDashboards(paging); + + break; + } default: break; } @@ -123,9 +154,12 @@ const ServicePage: FunctionComponent = () => { case ServiceCategory.MESSAGING_SERVICES: return getEntityLink(SearchIndex.TOPIC, fqn); + case ServiceCategory.DASHBOARD_SERVICES: + return getEntityLink(SearchIndex.DASHBOARD, fqn); + case ServiceCategory.DATABASE_SERVICES: default: - return `/database/${fqn}`; + return getEntityLink(SearchIndex.TABLE, fqn); } }; @@ -205,6 +239,29 @@ const ServicePage: FunctionComponent = () => { ); } + case ServiceCategory.DASHBOARD_SERVICES: { + return ( + + + Dashboard Url : + {' '} + + {serviceDetails?.dashboardUrl ? ( + + {serviceDetails.dashboardUrl} + + ) : ( + '--' + )} + + + + ); + } default: { return <>; } @@ -233,6 +290,16 @@ const ServicePage: FunctionComponent = () => { ); } + case ServiceCategory.DASHBOARD_SERVICES: { + return ( + <> + Dashboard Name + Description + Owner + Tags + + ); + } default: return <>; } @@ -280,6 +347,33 @@ const ServicePage: FunctionComponent = () => { ); } + case ServiceCategory.DASHBOARD_SERVICES: { + const dashboard = data as Dashboard; + + return ( + + {dashboard.tags && dashboard.tags?.length > 0 + ? dashboard.tags.map((tag, tagIndex) => ( + + + + )) + : '--'} + + ); + } default: return <>; } @@ -427,7 +521,7 @@ const ServicePage: FunctionComponent = () => { {data.length > 0 ? ( - data.map((database, index) => ( + data.map((dataObj, index) => ( { data-testid="column" key={index}> - - {database.name} + + {serviceName === + ServiceCategory.DASHBOARD_SERVICES && + dataObj.displayName + ? dataObj.displayName + : dataObj.name} - {database.description ? ( + {dataObj.description ? ( ) : ( @@ -452,9 +550,9 @@ const ServicePage: FunctionComponent = () => { )} -

{database?.owner?.name || '--'}

+

{dataObj?.owner?.name || '--'}

- {getOptionalTableCells(database)} + {getOptionalTableCells(dataObj)} )) ) : ( @@ -467,7 +565,7 @@ const ServicePage: FunctionComponent = () => { - {Boolean(!isNull(paging.after) || !isNull(paging.before)) && ( + {Boolean(!isNil(paging.after) || !isNil(paging.before)) && ( )} diff --git a/catalog-rest-service/src/main/resources/ui/src/pages/services/index.tsx b/catalog-rest-service/src/main/resources/ui/src/pages/services/index.tsx index b85d480ae1d..fa388f9efe5 100644 --- a/catalog-rest-service/src/main/resources/ui/src/pages/services/index.tsx +++ b/catalog-rest-service/src/main/resources/ui/src/pages/services/index.tsx @@ -70,6 +70,7 @@ const ServicesPage = () => { const [services, setServices] = useState({ databaseServices: [], messagingServices: [], + dashboardServices: [], }); const [serviceList, setServiceList] = useState>([]); const [editData, setEditData] = useState(); @@ -238,6 +239,18 @@ const ServicesPage = () => { ); } + case ServiceCategory.DASHBOARD_SERVICES: { + return ( + <> +
+ + + {service.dashboardUrl} + +
+ + ); + } default: { return <>; } diff --git a/catalog-rest-service/src/main/resources/ui/src/utils/ServiceUtils.ts b/catalog-rest-service/src/main/resources/ui/src/utils/ServiceUtils.ts index f2e63c2461d..85860dba940 100644 --- a/catalog-rest-service/src/main/resources/ui/src/utils/ServiceUtils.ts +++ b/catalog-rest-service/src/main/resources/ui/src/utils/ServiceUtils.ts @@ -17,8 +17,10 @@ import { serviceTypes, SERVICE_DEFAULT, SNOWFLAKE, + SUPERSET, } from '../constants/services.const'; import { + DashboardServiceType, DatabaseServiceType, MessagingServiceType, } from '../enums/service.enum'; @@ -62,6 +64,9 @@ export const serviceTypeLogo = (type: string) => { case MessagingServiceType.PULSAR: return PULSAR; + case DashboardServiceType.SUPERSET: + return SUPERSET; + default: return SERVICE_DEFAULT; }