mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-07-21 08:21:40 +00:00
Added Dashboard services UI and api integration (#422)
Co-authored-by: aashitk <aashit.kothari@deuexsolutions.com>
This commit is contained in:
parent
5c01546daf
commit
f48e34be9e
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
@ -44,6 +44,9 @@ export type DataObj = {
|
|||||||
};
|
};
|
||||||
brokers?: Array<string>;
|
brokers?: Array<string>;
|
||||||
schemaRegistry?: string;
|
schemaRegistry?: string;
|
||||||
|
dashboardUrl?: string;
|
||||||
|
username?: string;
|
||||||
|
password?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DatabaseService = {
|
type DatabaseService = {
|
||||||
@ -57,6 +60,12 @@ type MessagingService = {
|
|||||||
schemaRegistry: string;
|
schemaRegistry: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type DashboardService = {
|
||||||
|
dashboardUrl: string;
|
||||||
|
username: string;
|
||||||
|
password: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type ServiceDataObj = {
|
export type ServiceDataObj = {
|
||||||
description: string;
|
description: string;
|
||||||
href: string;
|
href: string;
|
||||||
@ -65,7 +74,8 @@ export type ServiceDataObj = {
|
|||||||
serviceType: string;
|
serviceType: string;
|
||||||
ingestionSchedule?: { repeatFrequency: string; startDate: string };
|
ingestionSchedule?: { repeatFrequency: string; startDate: string };
|
||||||
} & Partial<DatabaseService> &
|
} & Partial<DatabaseService> &
|
||||||
Partial<MessagingService>;
|
Partial<MessagingService> &
|
||||||
|
Partial<DashboardService>;
|
||||||
|
|
||||||
export type EditObj = {
|
export type EditObj = {
|
||||||
edit: boolean;
|
edit: boolean;
|
||||||
@ -86,10 +96,11 @@ type ErrorMsg = {
|
|||||||
name: boolean;
|
name: boolean;
|
||||||
url?: boolean;
|
url?: boolean;
|
||||||
// port: boolean;
|
// port: boolean;
|
||||||
// userName: boolean;
|
|
||||||
// password: boolean;
|
|
||||||
driverClass?: boolean;
|
driverClass?: boolean;
|
||||||
broker?: boolean;
|
broker?: boolean;
|
||||||
|
dashboardUrl?: boolean;
|
||||||
|
username?: boolean;
|
||||||
|
password?: boolean;
|
||||||
};
|
};
|
||||||
type EditorContentRef = {
|
type EditorContentRef = {
|
||||||
getEditorContent: () => string;
|
getEditorContent: () => string;
|
||||||
@ -176,6 +187,9 @@ export const AddServiceModal: FunctionComponent<Props> = ({
|
|||||||
const [schemaRegistry, setSchemaRegistry] = useState(
|
const [schemaRegistry, setSchemaRegistry] = useState(
|
||||||
data?.schemaRegistry || ''
|
data?.schemaRegistry || ''
|
||||||
);
|
);
|
||||||
|
const [dashboardUrl, setDashboardUrl] = useState(data?.dashboardUrl || '');
|
||||||
|
const [username, setUsername] = useState(data?.username || '');
|
||||||
|
const [password, setPassword] = useState(data?.password || '');
|
||||||
const [frequency, setFrequency] = useState(
|
const [frequency, setFrequency] = useState(
|
||||||
fromISOString(data?.ingestionSchedule?.repeatFrequency)
|
fromISOString(data?.ingestionSchedule?.repeatFrequency)
|
||||||
);
|
);
|
||||||
@ -261,18 +275,27 @@ export const AddServiceModal: FunctionComponent<Props> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onSaveHelper = (value: ErrorMsg) => {
|
const onSaveHelper = (value: ErrorMsg) => {
|
||||||
const { selectService, name, url, driverClass, broker } = value;
|
const {
|
||||||
|
selectService,
|
||||||
|
name,
|
||||||
|
url,
|
||||||
|
driverClass,
|
||||||
|
broker,
|
||||||
|
dashboardUrl,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
} = value;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
!sameNameError &&
|
!sameNameError &&
|
||||||
!selectService &&
|
!selectService &&
|
||||||
!name &&
|
!name &&
|
||||||
!url &&
|
!url &&
|
||||||
// !port &&
|
|
||||||
// !userName &&
|
|
||||||
// !password &&
|
|
||||||
!driverClass &&
|
!driverClass &&
|
||||||
!broker
|
!broker &&
|
||||||
|
!dashboardUrl &&
|
||||||
|
!username &&
|
||||||
|
!password
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -287,9 +310,6 @@ export const AddServiceModal: FunctionComponent<Props> = ({
|
|||||||
setMsg = {
|
setMsg = {
|
||||||
...setMsg,
|
...setMsg,
|
||||||
url: !url,
|
url: !url,
|
||||||
// port: !port,
|
|
||||||
// userName: !userName,
|
|
||||||
// password: !password,
|
|
||||||
driverClass: !driverClass,
|
driverClass: !driverClass,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -303,6 +323,17 @@ export const AddServiceModal: FunctionComponent<Props> = ({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case ServiceCategory.DASHBOARD_SERVICES:
|
||||||
|
{
|
||||||
|
setMsg = {
|
||||||
|
...setMsg,
|
||||||
|
dashboardUrl: !dashboardUrl,
|
||||||
|
username: !username,
|
||||||
|
password: !password,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -347,6 +378,17 @@ export const AddServiceModal: FunctionComponent<Props> = ({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case ServiceCategory.DASHBOARD_SERVICES:
|
||||||
|
{
|
||||||
|
dataObj = {
|
||||||
|
...dataObj,
|
||||||
|
dashboardUrl: dashboardUrl,
|
||||||
|
username: username,
|
||||||
|
password: password,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -374,54 +416,7 @@ export const AddServiceModal: FunctionComponent<Props> = ({
|
|||||||
/>
|
/>
|
||||||
{showErrorMsg.url && errorMsg('Connection url is required')}
|
{showErrorMsg.url && errorMsg('Connection url is required')}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* didn't removed below code as it will be need in future relase */}
|
|
||||||
|
|
||||||
{/* <div>
|
|
||||||
<label className="tw-block tw-form-label" htmlFor="port">
|
|
||||||
{requiredField('Connection Port:')}
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
className="tw-form-inputs tw-px-3 tw-py-1"
|
|
||||||
id="port"
|
|
||||||
name="port"
|
|
||||||
type="number"
|
|
||||||
value={port}
|
|
||||||
onChange={handleValidation}
|
|
||||||
/>
|
|
||||||
{showErrorMsg.port && errorMsg('Port is required')}
|
|
||||||
</div> */}
|
|
||||||
</div>
|
</div>
|
||||||
{/* <div className="tw-mt-4 tw-grid tw-grid-cols-2 tw-gap-2 ">
|
|
||||||
<div>
|
|
||||||
<label className="tw-block tw-form-label" htmlFor="userName">
|
|
||||||
{requiredField('Username:')}
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
className="tw-form-inputs tw-px-3 tw-py-1"
|
|
||||||
id="userName"
|
|
||||||
name="userName"
|
|
||||||
type="text"
|
|
||||||
value={userName}
|
|
||||||
onChange={handleValidation}
|
|
||||||
/>
|
|
||||||
{showErrorMsg.userName && errorMsg('Username is required')}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label className="tw-block tw-form-label" htmlFor="password">
|
|
||||||
{requiredField('Password:')}
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
className="tw-form-inputs tw-px-3 tw-py-1"
|
|
||||||
id="password"
|
|
||||||
name="password"
|
|
||||||
type="password"
|
|
||||||
value={password}
|
|
||||||
onChange={handleValidation}
|
|
||||||
/>
|
|
||||||
{showErrorMsg.password && errorMsg('Password is required')}
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
<div className="tw-mt-4">
|
<div className="tw-mt-4">
|
||||||
<label className="tw-block tw-form-label" htmlFor="database">
|
<label className="tw-block tw-form-label" htmlFor="database">
|
||||||
Database:
|
Database:
|
||||||
@ -500,12 +495,66 @@ export const AddServiceModal: FunctionComponent<Props> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getDashboardFields = (): JSX.Element => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="tw-mt-4">
|
||||||
|
<label className="tw-block tw-form-label" htmlFor="dashboard-url">
|
||||||
|
{requiredField('Dashboard Url:')}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
className="tw-form-inputs tw-px-3 tw-py-1"
|
||||||
|
id="dashboard-url"
|
||||||
|
name="dashboard-url"
|
||||||
|
placeholder="http(s)://hostname:port"
|
||||||
|
type="text"
|
||||||
|
value={dashboardUrl}
|
||||||
|
onChange={(e) => setDashboardUrl(e.target.value)}
|
||||||
|
/>
|
||||||
|
{showErrorMsg.dashboardUrl && errorMsg('Dashboard url is required')}
|
||||||
|
</div>
|
||||||
|
<div className="tw-mt-4">
|
||||||
|
<label className="tw-block tw-form-label" htmlFor="username">
|
||||||
|
{requiredField('Username:')}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
className="tw-form-inputs tw-px-3 tw-py-1"
|
||||||
|
id="username"
|
||||||
|
name="username"
|
||||||
|
placeholder="username"
|
||||||
|
type="text"
|
||||||
|
value={username}
|
||||||
|
onChange={(e) => setUsername(e.target.value)}
|
||||||
|
/>
|
||||||
|
{showErrorMsg.username && errorMsg('Username is required')}
|
||||||
|
</div>
|
||||||
|
<div className="tw-mt-4">
|
||||||
|
<label className="tw-block tw-form-label" htmlFor="password">
|
||||||
|
{requiredField('Password:')}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
className="tw-form-inputs tw-px-3 tw-py-1"
|
||||||
|
id="password"
|
||||||
|
name="password"
|
||||||
|
placeholder="password"
|
||||||
|
type="password"
|
||||||
|
value={password}
|
||||||
|
onChange={(e) => setPassword(e.target.value)}
|
||||||
|
/>
|
||||||
|
{showErrorMsg.password && errorMsg('Password is required')}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const getOptionalFields = (): JSX.Element => {
|
const getOptionalFields = (): JSX.Element => {
|
||||||
switch (serviceName) {
|
switch (serviceName) {
|
||||||
case ServiceCategory.DATABASE_SERVICES:
|
case ServiceCategory.DATABASE_SERVICES:
|
||||||
return getDatabaseFields();
|
return getDatabaseFields();
|
||||||
case ServiceCategory.MESSAGING_SERVICES:
|
case ServiceCategory.MESSAGING_SERVICES:
|
||||||
return getMessagingFields();
|
return getMessagingFields();
|
||||||
|
case ServiceCategory.DASHBOARD_SERVICES:
|
||||||
|
return getDashboardFields();
|
||||||
default:
|
default:
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import query from '../assets/img/service-icon-query.png';
|
|||||||
import redshift from '../assets/img/service-icon-redshift.png';
|
import redshift from '../assets/img/service-icon-redshift.png';
|
||||||
import snowflakes from '../assets/img/service-icon-snowflakes.png';
|
import snowflakes from '../assets/img/service-icon-snowflakes.png';
|
||||||
import mysql from '../assets/img/service-icon-sql.png';
|
import mysql from '../assets/img/service-icon-sql.png';
|
||||||
|
import superset from '../assets/img/service-icon-superset.png';
|
||||||
import plus from '../assets/svg/plus.svg';
|
import plus from '../assets/svg/plus.svg';
|
||||||
import { ServiceCategory } from '../enums/service.enum';
|
import { ServiceCategory } from '../enums/service.enum';
|
||||||
|
|
||||||
@ -45,6 +46,7 @@ export const ATHENA = athena;
|
|||||||
export const PRESTO = presto;
|
export const PRESTO = presto;
|
||||||
export const KAFKA = kafka;
|
export const KAFKA = kafka;
|
||||||
export const PULSAR = pulsar;
|
export const PULSAR = pulsar;
|
||||||
|
export const SUPERSET = superset;
|
||||||
export const SERVICE_DEFAULT = serviceDefault;
|
export const SERVICE_DEFAULT = serviceDefault;
|
||||||
|
|
||||||
export const PLUS = plus;
|
export const PLUS = plus;
|
||||||
@ -64,16 +66,19 @@ export const serviceTypes: Record<ServiceTypes, Array<string>> = {
|
|||||||
'Presto',
|
'Presto',
|
||||||
],
|
],
|
||||||
messagingServices: ['Kafka', 'Pulsar'],
|
messagingServices: ['Kafka', 'Pulsar'],
|
||||||
|
dashboardServices: ['Superset'],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const arrServiceTypes: Array<ServiceTypes> = [
|
export const arrServiceTypes: Array<ServiceTypes> = [
|
||||||
'databaseServices',
|
'databaseServices',
|
||||||
'messagingServices',
|
'messagingServices',
|
||||||
|
'dashboardServices',
|
||||||
];
|
];
|
||||||
|
|
||||||
export const servicesDisplayName = {
|
export const servicesDisplayName = {
|
||||||
databaseServices: 'Database Service',
|
databaseServices: 'Database Service',
|
||||||
messagingServices: 'Messaging Service',
|
messagingServices: 'Messaging Service',
|
||||||
|
dashboardServices: 'Dashboard Service',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const routeServiceTypes = [
|
export const routeServiceTypes = [
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
export enum ServiceCategory {
|
export enum ServiceCategory {
|
||||||
DATABASE_SERVICES = 'databaseServices',
|
DATABASE_SERVICES = 'databaseServices',
|
||||||
MESSAGING_SERVICES = 'messagingServices',
|
MESSAGING_SERVICES = 'messagingServices',
|
||||||
|
DASHBOARD_SERVICES = 'dashboardServices',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum DatabaseServiceType {
|
export enum DatabaseServiceType {
|
||||||
@ -37,3 +38,7 @@ export enum MessagingServiceType {
|
|||||||
KAFKA = 'Kafka',
|
KAFKA = 'Kafka',
|
||||||
PULSAR = 'Pulsar',
|
PULSAR = 'Pulsar',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum DashboardServiceType {
|
||||||
|
SUPERSET = 'Superset',
|
||||||
|
}
|
||||||
|
@ -52,6 +52,7 @@ declare module 'Models' {
|
|||||||
id: string;
|
id: string;
|
||||||
brokers?: Array<string>;
|
brokers?: Array<string>;
|
||||||
description: string;
|
description: string;
|
||||||
|
dashboardUrl?: string;
|
||||||
ingestionSchedule?: {
|
ingestionSchedule?: {
|
||||||
repeatFrequency: string;
|
repeatFrequency: string;
|
||||||
startDate: string;
|
startDate: string;
|
||||||
@ -253,6 +254,7 @@ declare module 'Models' {
|
|||||||
|
|
||||||
export type Database = {
|
export type Database = {
|
||||||
description: string;
|
description: string;
|
||||||
|
displayName?: string;
|
||||||
fullyQualifiedName: string;
|
fullyQualifiedName: string;
|
||||||
href: string;
|
href: string;
|
||||||
id: string;
|
id: string;
|
||||||
@ -317,7 +319,10 @@ declare module 'Models' {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ServiceTypes = 'databaseServices' | 'messagingServices';
|
export type ServiceTypes =
|
||||||
|
| 'databaseServices'
|
||||||
|
| 'messagingServices'
|
||||||
|
| 'dashboardServices';
|
||||||
|
|
||||||
export type ServiceRecord = Record<ServiceTypes, Array<ServiceDataObj>>;
|
export type ServiceRecord = Record<ServiceTypes, Array<ServiceDataObj>>;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
import { AxiosResponse } from 'axios';
|
import { AxiosResponse } from 'axios';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { compare } from 'fast-json-patch';
|
import { compare } from 'fast-json-patch';
|
||||||
import { isNull } from 'lodash';
|
import { isNil } from 'lodash';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Database, Paging, TableDetail } from 'Models';
|
import { Database, Paging, TableDetail } from 'Models';
|
||||||
import React, { FunctionComponent, useEffect, useRef, useState } from 'react';
|
import React, { FunctionComponent, useEffect, useRef, useState } from 'react';
|
||||||
@ -366,7 +366,7 @@ const DatabaseDetails: FunctionComponent = () => {
|
|||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{Boolean(!isNull(paging.after) || !isNull(paging.before)) && (
|
{Boolean(!isNil(paging.after) || !isNil(paging.before)) && (
|
||||||
<NextPrevious paging={paging} pagingHandler={pagingHandler} />
|
<NextPrevious paging={paging} pagingHandler={pagingHandler} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -17,10 +17,11 @@
|
|||||||
|
|
||||||
import { AxiosError, AxiosResponse } from 'axios';
|
import { AxiosError, AxiosResponse } from 'axios';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { isNull, isUndefined } from 'lodash';
|
import { isNil, isUndefined } from 'lodash';
|
||||||
import { Database, Paging, ServiceOption } from 'Models';
|
import { Database, Paging, ServiceOption } from 'Models';
|
||||||
import React, { Fragment, FunctionComponent, useEffect, useState } from 'react';
|
import React, { Fragment, FunctionComponent, useEffect, useState } from 'react';
|
||||||
import { Link, useParams } from 'react-router-dom';
|
import { Link, useParams } from 'react-router-dom';
|
||||||
|
import { getDashboards } from '../../axiosAPIs/dashboardAPI';
|
||||||
import { getDatabases } from '../../axiosAPIs/databaseAPI';
|
import { getDatabases } from '../../axiosAPIs/databaseAPI';
|
||||||
import { getServiceByFQN, updateService } from '../../axiosAPIs/serviceAPI';
|
import { getServiceByFQN, updateService } from '../../axiosAPIs/serviceAPI';
|
||||||
import { getTopics } from '../../axiosAPIs/topicsAPI';
|
import { getTopics } from '../../axiosAPIs/topicsAPI';
|
||||||
@ -36,6 +37,7 @@ import Tags from '../../components/tags/tags';
|
|||||||
import { pagingObject } from '../../constants/constants';
|
import { pagingObject } from '../../constants/constants';
|
||||||
import { SearchIndex } from '../../enums/search.enum';
|
import { SearchIndex } from '../../enums/search.enum';
|
||||||
import { ServiceCategory } from '../../enums/service.enum';
|
import { ServiceCategory } from '../../enums/service.enum';
|
||||||
|
import { Dashboard } from '../../generated/entity/data/dashboard';
|
||||||
import { Topic } from '../../generated/entity/data/topic';
|
import { Topic } from '../../generated/entity/data/topic';
|
||||||
import useToastContext from '../../hooks/useToastContext';
|
import useToastContext from '../../hooks/useToastContext';
|
||||||
import { isEven } from '../../utils/CommonUtils';
|
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) => {
|
const getOtherDetails = (paging?: string) => {
|
||||||
switch (serviceName) {
|
switch (serviceName) {
|
||||||
case ServiceCategory.DATABASE_SERVICES: {
|
case ServiceCategory.DATABASE_SERVICES: {
|
||||||
@ -113,6 +139,11 @@ const ServicePage: FunctionComponent = () => {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ServiceCategory.DASHBOARD_SERVICES: {
|
||||||
|
fetchDashboards(paging);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -123,9 +154,12 @@ const ServicePage: FunctionComponent = () => {
|
|||||||
case ServiceCategory.MESSAGING_SERVICES:
|
case ServiceCategory.MESSAGING_SERVICES:
|
||||||
return getEntityLink(SearchIndex.TOPIC, fqn);
|
return getEntityLink(SearchIndex.TOPIC, fqn);
|
||||||
|
|
||||||
|
case ServiceCategory.DASHBOARD_SERVICES:
|
||||||
|
return getEntityLink(SearchIndex.DASHBOARD, fqn);
|
||||||
|
|
||||||
case ServiceCategory.DATABASE_SERVICES:
|
case ServiceCategory.DATABASE_SERVICES:
|
||||||
default:
|
default:
|
||||||
return `/database/${fqn}`;
|
return getEntityLink(SearchIndex.TABLE, fqn);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -205,6 +239,29 @@ const ServicePage: FunctionComponent = () => {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
case ServiceCategory.DASHBOARD_SERVICES: {
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
<span className="tw-text-grey-muted tw-font-normal">
|
||||||
|
Dashboard Url :
|
||||||
|
</span>{' '}
|
||||||
|
<span className="tw-pl-1tw-font-normal ">
|
||||||
|
{serviceDetails?.dashboardUrl ? (
|
||||||
|
<a
|
||||||
|
className="link-text"
|
||||||
|
href={serviceDetails.dashboardUrl}
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
target="_blank">
|
||||||
|
{serviceDetails.dashboardUrl}
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
'--'
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
<span className="tw-mx-3 tw-text-grey-muted">•</span>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
@ -233,6 +290,16 @@ const ServicePage: FunctionComponent = () => {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
case ServiceCategory.DASHBOARD_SERVICES: {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<th className="tableHead-cell">Dashboard Name</th>
|
||||||
|
<th className="tableHead-cell">Description</th>
|
||||||
|
<th className="tableHead-cell">Owner</th>
|
||||||
|
<th className="tableHead-cell">Tags</th>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
@ -280,6 +347,33 @@ const ServicePage: FunctionComponent = () => {
|
|||||||
</td>
|
</td>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
case ServiceCategory.DASHBOARD_SERVICES: {
|
||||||
|
const dashboard = data as Dashboard;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<td className="tableBody-cell">
|
||||||
|
{dashboard.tags && dashboard.tags?.length > 0
|
||||||
|
? dashboard.tags.map((tag, tagIndex) => (
|
||||||
|
<PopOver
|
||||||
|
key={tagIndex}
|
||||||
|
position="top"
|
||||||
|
size="small"
|
||||||
|
title={tag.labelType}
|
||||||
|
trigger="mouseenter">
|
||||||
|
<Tags
|
||||||
|
className="tw-bg-gray-200"
|
||||||
|
tag={`#${
|
||||||
|
tag.tagFQN?.startsWith('Tier.Tier')
|
||||||
|
? tag.tagFQN.split('.')[1]
|
||||||
|
: tag.tagFQN
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
|
</PopOver>
|
||||||
|
))
|
||||||
|
: '--'}
|
||||||
|
</td>
|
||||||
|
);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
@ -427,7 +521,7 @@ const ServicePage: FunctionComponent = () => {
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody className="tableBody">
|
<tbody className="tableBody">
|
||||||
{data.length > 0 ? (
|
{data.length > 0 ? (
|
||||||
data.map((database, index) => (
|
data.map((dataObj, index) => (
|
||||||
<tr
|
<tr
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'tableBody-row',
|
'tableBody-row',
|
||||||
@ -436,14 +530,18 @@ const ServicePage: FunctionComponent = () => {
|
|||||||
data-testid="column"
|
data-testid="column"
|
||||||
key={index}>
|
key={index}>
|
||||||
<td className="tableBody-cell">
|
<td className="tableBody-cell">
|
||||||
<Link to={getLinkForFqn(database.fullyQualifiedName)}>
|
<Link to={getLinkForFqn(dataObj.fullyQualifiedName)}>
|
||||||
{database.name}
|
{serviceName ===
|
||||||
|
ServiceCategory.DASHBOARD_SERVICES &&
|
||||||
|
dataObj.displayName
|
||||||
|
? dataObj.displayName
|
||||||
|
: dataObj.name}
|
||||||
</Link>
|
</Link>
|
||||||
</td>
|
</td>
|
||||||
<td className="tableBody-cell">
|
<td className="tableBody-cell">
|
||||||
{database.description ? (
|
{dataObj.description ? (
|
||||||
<RichTextEditorPreviewer
|
<RichTextEditorPreviewer
|
||||||
markdown={database.description}
|
markdown={dataObj.description}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<span className="tw-no-description">
|
<span className="tw-no-description">
|
||||||
@ -452,9 +550,9 @@ const ServicePage: FunctionComponent = () => {
|
|||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
<td className="tableBody-cell">
|
<td className="tableBody-cell">
|
||||||
<p>{database?.owner?.name || '--'}</p>
|
<p>{dataObj?.owner?.name || '--'}</p>
|
||||||
</td>
|
</td>
|
||||||
{getOptionalTableCells(database)}
|
{getOptionalTableCells(dataObj)}
|
||||||
</tr>
|
</tr>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
@ -467,7 +565,7 @@ const ServicePage: FunctionComponent = () => {
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
{Boolean(!isNull(paging.after) || !isNull(paging.before)) && (
|
{Boolean(!isNil(paging.after) || !isNil(paging.before)) && (
|
||||||
<NextPrevious paging={paging} pagingHandler={pagingHandler} />
|
<NextPrevious paging={paging} pagingHandler={pagingHandler} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -70,6 +70,7 @@ const ServicesPage = () => {
|
|||||||
const [services, setServices] = useState<ServiceRecord>({
|
const [services, setServices] = useState<ServiceRecord>({
|
||||||
databaseServices: [],
|
databaseServices: [],
|
||||||
messagingServices: [],
|
messagingServices: [],
|
||||||
|
dashboardServices: [],
|
||||||
});
|
});
|
||||||
const [serviceList, setServiceList] = useState<Array<ServiceDataObj>>([]);
|
const [serviceList, setServiceList] = useState<Array<ServiceDataObj>>([]);
|
||||||
const [editData, setEditData] = useState<ServiceDataObj>();
|
const [editData, setEditData] = useState<ServiceDataObj>();
|
||||||
@ -238,6 +239,18 @@ const ServicesPage = () => {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
case ServiceCategory.DASHBOARD_SERVICES: {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="tw-mb-1">
|
||||||
|
<label className="tw-mb-0">Dashboard URL:</label>
|
||||||
|
<span className=" tw-ml-1 tw-font-normal tw-text-grey-body">
|
||||||
|
{service.dashboardUrl}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,10 @@ import {
|
|||||||
serviceTypes,
|
serviceTypes,
|
||||||
SERVICE_DEFAULT,
|
SERVICE_DEFAULT,
|
||||||
SNOWFLAKE,
|
SNOWFLAKE,
|
||||||
|
SUPERSET,
|
||||||
} from '../constants/services.const';
|
} from '../constants/services.const';
|
||||||
import {
|
import {
|
||||||
|
DashboardServiceType,
|
||||||
DatabaseServiceType,
|
DatabaseServiceType,
|
||||||
MessagingServiceType,
|
MessagingServiceType,
|
||||||
} from '../enums/service.enum';
|
} from '../enums/service.enum';
|
||||||
@ -62,6 +64,9 @@ export const serviceTypeLogo = (type: string) => {
|
|||||||
case MessagingServiceType.PULSAR:
|
case MessagingServiceType.PULSAR:
|
||||||
return PULSAR;
|
return PULSAR;
|
||||||
|
|
||||||
|
case DashboardServiceType.SUPERSET:
|
||||||
|
return SUPERSET;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return SERVICE_DEFAULT;
|
return SERVICE_DEFAULT;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user