mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-11-02 11:39:12 +00:00
issue-211: added addtional inforamtion related to driver class, frequ… (#235)
* issue-211: added addtional inforamtion related to driver class, frequency and service type * added addtional info in services page, ui change for service page when there is no table data * added same ui changes for all the pagination, if there is no info related to next prev page, pagination will be hidden * added page count constant instead of fix value
This commit is contained in:
parent
95f650268b
commit
f028c1d395
@ -17,6 +17,7 @@
|
||||
|
||||
import classNames from 'classnames';
|
||||
import React, { FunctionComponent, useRef, useState } from 'react';
|
||||
import { fromISOString } from '../../../utils/ServiceUtils';
|
||||
import { Button } from '../../buttons/Button/Button';
|
||||
import MarkdownWithPreview from '../../common/editor/MarkdownWithPreview';
|
||||
// import { serviceType } from '../../../constants/services.const';
|
||||
@ -119,24 +120,6 @@ const seprateUrl = (url?: string) => {
|
||||
return {};
|
||||
};
|
||||
|
||||
const fromISOString = (isoValue = '') => {
|
||||
if (isoValue) {
|
||||
// 'P1DT 0H 0M'
|
||||
const [d, hm] = isoValue.split('T');
|
||||
const day = +d.replace('D', '').replace('P', '');
|
||||
const [h, time] = hm.split('H');
|
||||
const minute = +time.replace('M', '');
|
||||
|
||||
return { day, hour: +h, minute };
|
||||
} else {
|
||||
return {
|
||||
day: 1,
|
||||
hour: 0,
|
||||
minute: 0,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const errorMsg = (value: string) => {
|
||||
return (
|
||||
<div className="tw-mt-1">
|
||||
|
||||
@ -93,7 +93,7 @@ const SearchedData: React.FC<SearchedDataProp> = ({
|
||||
</div>
|
||||
))}
|
||||
|
||||
{totalValue > 0 && data.length > 0 && (
|
||||
{totalValue > PAGE_SIZE && data.length > 0 && (
|
||||
<Pagination
|
||||
currentPage={currentPage}
|
||||
paginate={paginate}
|
||||
|
||||
@ -54,6 +54,10 @@ declare module 'Models' {
|
||||
export type ServiceOption = {
|
||||
id: string;
|
||||
description: string;
|
||||
ingestionSchedule?: {
|
||||
repeatFrequency: string;
|
||||
startDate: string;
|
||||
};
|
||||
jdbc: { connectionUrl: string; driverClass: string };
|
||||
name: string;
|
||||
serviceType: string;
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
import { AxiosResponse } from 'axios';
|
||||
import classNames from 'classnames';
|
||||
import { compare } from 'fast-json-patch';
|
||||
import { isNull } from 'lodash';
|
||||
import { observer } from 'mobx-react';
|
||||
import { Database, Paging, TableDetail } from 'Models';
|
||||
import React, { FunctionComponent, useEffect, useRef, useState } from 'react';
|
||||
@ -265,102 +266,100 @@ const DatabaseDetails: FunctionComponent = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{data.length ? (
|
||||
<>
|
||||
<table
|
||||
className="tw-bg-white tw-w-full tw-mb-4"
|
||||
data-testid="database-tables">
|
||||
<thead>
|
||||
<tr className="tableHead-row">
|
||||
<th className="tableHead-cell">Table Name</th>
|
||||
<th className="tableHead-cell">Description</th>
|
||||
<th className="tableHead-cell">Owner</th>
|
||||
<th className="tableHead-cell">Usage</th>
|
||||
<th className="tableHead-cell tw-w-60">Tags</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="tableBody">
|
||||
{data.map((table, index) => (
|
||||
<tr
|
||||
className={classNames(
|
||||
'tableBody-row',
|
||||
!isEven(index + 1) ? 'odd-row' : null
|
||||
<table
|
||||
className="tw-bg-white tw-w-full tw-mb-4"
|
||||
data-testid="database-tables">
|
||||
<thead>
|
||||
<tr className="tableHead-row">
|
||||
<th className="tableHead-cell">Table Name</th>
|
||||
<th className="tableHead-cell">Description</th>
|
||||
<th className="tableHead-cell">Owner</th>
|
||||
<th className="tableHead-cell">Usage</th>
|
||||
<th className="tableHead-cell tw-w-60">Tags</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="tableBody">
|
||||
{data.length > 0 ? (
|
||||
data.map((table, index) => (
|
||||
<tr
|
||||
className={classNames(
|
||||
'tableBody-row',
|
||||
!isEven(index + 1) ? 'odd-row' : null
|
||||
)}
|
||||
data-testid="column"
|
||||
key={index}>
|
||||
<td className="tableBody-cell">
|
||||
<Link
|
||||
to={getDatasetDetailsPath(table.fullyQualifiedName)}>
|
||||
{table.name}
|
||||
</Link>
|
||||
</td>
|
||||
<td className="tableBody-cell">
|
||||
{table.description ? (
|
||||
<RichTextEditorPreviewer
|
||||
markdown={table.description}
|
||||
/>
|
||||
) : (
|
||||
<span className="tw-no-description">
|
||||
No description added
|
||||
</span>
|
||||
)}
|
||||
data-testid="column"
|
||||
key={index}>
|
||||
<td className="tableBody-cell">
|
||||
<Link
|
||||
to={getDatasetDetailsPath(
|
||||
table.fullyQualifiedName
|
||||
)}>
|
||||
{table.name}
|
||||
</Link>
|
||||
</td>
|
||||
<td className="tableBody-cell">
|
||||
{table.description ? (
|
||||
<RichTextEditorPreviewer
|
||||
markdown={table.description}
|
||||
/>
|
||||
) : (
|
||||
<span className="tw-no-description">
|
||||
No description added
|
||||
</span>
|
||||
</td>
|
||||
<td className="tableBody-cell">
|
||||
<p>{getOwnerFromId(table?.owner?.id)?.name || '--'}</p>
|
||||
</td>
|
||||
<td className="tableBody-cell">
|
||||
<p>
|
||||
{getUsagePercentile(
|
||||
table.usageSummary.weeklyStats.percentileRank || 0
|
||||
)}
|
||||
</td>
|
||||
<td className="tableBody-cell">
|
||||
<p>
|
||||
{getOwnerFromId(table?.owner?.id)?.name || '--'}
|
||||
</p>
|
||||
</td>
|
||||
<td className="tableBody-cell">
|
||||
<p>
|
||||
{getUsagePercentile(
|
||||
table.usageSummary.weeklyStats.percentileRank || 0
|
||||
)}
|
||||
</p>
|
||||
</td>
|
||||
<td className="tableBody-cell">
|
||||
{table.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>
|
||||
))}
|
||||
{getTableTags(table.columns).map((tag, tagIdx) => (
|
||||
<PopOver
|
||||
key={tagIdx}
|
||||
position="top"
|
||||
size="small"
|
||||
title={tag.labelType}
|
||||
trigger="mouseenter">
|
||||
<Tags
|
||||
className="tw-bg-gray-200"
|
||||
tag={`#${tag.tagFQN}`}
|
||||
/>
|
||||
</PopOver>
|
||||
))}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
<NextPrevious paging={paging} pagingHandler={pagingHandler} />
|
||||
</>
|
||||
) : (
|
||||
<h1 className="tw-text-center tw-mt-60 tw-text-grey-body tw-font-normal">
|
||||
{databaseName} does not have any tables
|
||||
</h1>
|
||||
</p>
|
||||
</td>
|
||||
<td className="tableBody-cell">
|
||||
{table.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>
|
||||
))}
|
||||
{getTableTags(table.columns).map((tag, tagIdx) => (
|
||||
<PopOver
|
||||
key={tagIdx}
|
||||
position="top"
|
||||
size="small"
|
||||
title={tag.labelType}
|
||||
trigger="mouseenter">
|
||||
<Tags
|
||||
className="tw-bg-gray-200"
|
||||
tag={`#${tag.tagFQN}`}
|
||||
/>
|
||||
</PopOver>
|
||||
))}
|
||||
</td>
|
||||
</tr>
|
||||
))
|
||||
) : (
|
||||
<tr className="tableBody-row">
|
||||
<td className="tableBody-cell tw-text-center" colSpan={5}>
|
||||
No records found.
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
{Boolean(!isNull(paging.after) || !isNull(paging.before)) && (
|
||||
<NextPrevious paging={paging} pagingHandler={pagingHandler} />
|
||||
)}
|
||||
</div>
|
||||
</PageContainer>
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
|
||||
import { AxiosError, AxiosResponse } from 'axios';
|
||||
import classNames from 'classnames';
|
||||
import { isUndefined } from 'lodash';
|
||||
import { isNull, isUndefined } from 'lodash';
|
||||
import { Database, Paging, ServiceOption } from 'Models';
|
||||
import React, { FunctionComponent, useEffect, useState } from 'react';
|
||||
import { Link, useParams } from 'react-router-dom';
|
||||
@ -33,7 +33,7 @@ import { ModalWithMarkdownEditor } from '../../components/Modals/ModalWithMarkdo
|
||||
import { pagingObject } from '../../constants/constants';
|
||||
import useToastContext from '../../hooks/useToastContext';
|
||||
import { isEven } from '../../utils/CommonUtils';
|
||||
import { serviceTypeLogo } from '../../utils/ServiceUtils';
|
||||
import { getFrequencyTime, serviceTypeLogo } from '../../utils/ServiceUtils';
|
||||
import SVGIcons from '../../utils/SvgUtils';
|
||||
import { getUsagePercentile } from '../../utils/TableUtils';
|
||||
|
||||
@ -141,6 +141,44 @@ const ServicePage: FunctionComponent = () => {
|
||||
<div className="tw-px-4">
|
||||
<TitleBreadcrumb titleLinks={slashedTableName} />
|
||||
|
||||
<div className="tw-flex tw-gap-1 tw-mb-2 tw-mt-1">
|
||||
<span>
|
||||
<span className="tw-text-grey-muted tw-font-normal">
|
||||
Driver Class :
|
||||
</span>{' '}
|
||||
<span className="tw-pl-1tw-font-normal ">
|
||||
{serviceDetails?.jdbc.driverClass || '--'}
|
||||
</span>
|
||||
<span className="tw-mx-3 tw-inline-block tw-text-gray-400">
|
||||
•
|
||||
</span>
|
||||
</span>
|
||||
<span>
|
||||
<span className="tw-text-grey-muted tw-font-normal">
|
||||
Frequency :
|
||||
</span>{' '}
|
||||
<span className="tw-pl-1 tw-font-normal">
|
||||
{' '}
|
||||
{serviceDetails?.ingestionSchedule
|
||||
? getFrequencyTime(
|
||||
serviceDetails.ingestionSchedule.repeatFrequency
|
||||
)
|
||||
: 'N/A'}
|
||||
</span>
|
||||
<span className="tw-mx-3 tw-inline-block tw-text-gray-400">
|
||||
•
|
||||
</span>
|
||||
</span>
|
||||
<span>
|
||||
<span className="tw-text-grey-muted tw-font-normal">
|
||||
Service Type :
|
||||
</span>{' '}
|
||||
<span className="tw-pl-1 tw-font-normal">
|
||||
{serviceDetails?.serviceType}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="tw-bg-white tw-my-4">
|
||||
<div className="tw-col-span-3">
|
||||
<div className="schema-description tw-flex tw-flex-col tw-h-full tw-relative tw-border tw-border-main tw-rounded-md">
|
||||
@ -179,67 +217,69 @@ const ServicePage: FunctionComponent = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{data.length > 0 ? (
|
||||
<>
|
||||
<div className="tw-mt-4">
|
||||
<table
|
||||
className="tw-bg-white tw-w-full tw-mb-4"
|
||||
data-testid="database-tables">
|
||||
<thead>
|
||||
<tr className="tableHead-row">
|
||||
<th className="tableHead-cell">Database Name</th>
|
||||
<th className="tableHead-cell">Description</th>
|
||||
<th className="tableHead-cell">Owner</th>
|
||||
<th className="tableHead-cell">Usage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="tableBody">
|
||||
{data.map((database, index) => (
|
||||
<tr
|
||||
className={classNames(
|
||||
'tableBody-row',
|
||||
!isEven(index + 1) ? 'odd-row' : null
|
||||
|
||||
<div className="tw-mt-4">
|
||||
<table
|
||||
className="tw-bg-white tw-w-full tw-mb-4"
|
||||
data-testid="database-tables">
|
||||
<thead>
|
||||
<tr className="tableHead-row">
|
||||
<th className="tableHead-cell">Database Name</th>
|
||||
<th className="tableHead-cell">Description</th>
|
||||
<th className="tableHead-cell">Owner</th>
|
||||
<th className="tableHead-cell">Usage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="tableBody">
|
||||
{data.length > 0 ? (
|
||||
data.map((database, index) => (
|
||||
<tr
|
||||
className={classNames(
|
||||
'tableBody-row',
|
||||
!isEven(index + 1) ? 'odd-row' : null
|
||||
)}
|
||||
data-testid="column"
|
||||
key={index}>
|
||||
<td className="tableBody-cell">
|
||||
<Link to={`/database/${database.fullyQualifiedName}`}>
|
||||
{database.name}
|
||||
</Link>
|
||||
</td>
|
||||
<td className="tableBody-cell">
|
||||
{database.description ? (
|
||||
<RichTextEditorPreviewer
|
||||
markdown={database.description}
|
||||
/>
|
||||
) : (
|
||||
<span className="tw-no-description">
|
||||
No description added
|
||||
</span>
|
||||
)}
|
||||
data-testid="column"
|
||||
key={index}>
|
||||
<td className="tableBody-cell">
|
||||
<Link
|
||||
to={`/database/${database.fullyQualifiedName}`}>
|
||||
{database.name}
|
||||
</Link>
|
||||
</td>
|
||||
<td className="tableBody-cell">
|
||||
{database.description ? (
|
||||
<RichTextEditorPreviewer
|
||||
markdown={database.description}
|
||||
/>
|
||||
) : (
|
||||
<span className="tw-no-description">
|
||||
No description added
|
||||
</span>
|
||||
</td>
|
||||
<td className="tableBody-cell">
|
||||
<p>{database?.owner?.name || '--'}</p>
|
||||
</td>
|
||||
<td className="tableBody-cell">
|
||||
<p>
|
||||
{getUsagePercentile(
|
||||
database.usageSummary.weeklyStats.percentileRank
|
||||
)}
|
||||
</td>
|
||||
<td className="tableBody-cell">
|
||||
<p>{database?.owner?.name || '--'}</p>
|
||||
</td>
|
||||
<td className="tableBody-cell">
|
||||
<p>
|
||||
{getUsagePercentile(
|
||||
database.usageSummary.weeklyStats.percentileRank
|
||||
)}
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<NextPrevious paging={paging} pagingHandler={pagingHandler} />
|
||||
</>
|
||||
) : (
|
||||
<h1 className="tw-text-center tw-mt-60 tw-text-grey-body tw-font-normal">
|
||||
{serviceFQN} does not have any databases
|
||||
</h1>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
))
|
||||
) : (
|
||||
<tr className="tableBody-row">
|
||||
<td className="tableBody-cell tw-text-center" colSpan={4}>
|
||||
No records found.
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{Boolean(!isNull(paging.after) || !isNull(paging.before)) && (
|
||||
<NextPrevious paging={paging} pagingHandler={pagingHandler} />
|
||||
)}
|
||||
</div>
|
||||
</PageContainer>
|
||||
|
||||
@ -38,7 +38,7 @@ import {
|
||||
} from '../../components/Modals/AddServiceModal/AddServiceModal';
|
||||
import { getServiceDetailsPath } from '../../constants/constants';
|
||||
import { NOSERVICE, PLUS } from '../../constants/services.const';
|
||||
import { serviceTypeLogo } from '../../utils/ServiceUtils';
|
||||
import { getFrequencyTime, serviceTypeLogo } from '../../utils/ServiceUtils';
|
||||
import SVGIcons from '../../utils/SvgUtils';
|
||||
|
||||
export type ApiData = {
|
||||
@ -218,6 +218,22 @@ const ServicesPage = () => {
|
||||
<span className="tw-tag tw-ml-3">mysql</span>
|
||||
<span className="tw-tag tw-ml-2">sales</span>
|
||||
</div> */}
|
||||
<div className="tw-mb-1">
|
||||
<label className="tw-mb-0">Driver Class:</label>
|
||||
<span className=" tw-ml-1 tw-font-normal tw-text-grey-body">
|
||||
{service.driverClass}
|
||||
</span>
|
||||
</div>
|
||||
<div className="tw-mb-1">
|
||||
<label className="tw-mb-0">Frequency:</label>
|
||||
<span className=" tw-ml-1 tw-font-normal tw-text-grey-body">
|
||||
{service.ingestionSchedule
|
||||
? getFrequencyTime(
|
||||
service.ingestionSchedule.repeatFrequency
|
||||
)
|
||||
: 'N/A'}
|
||||
</span>
|
||||
</div>
|
||||
<div className="">
|
||||
<label className="tw-mb-0">Type:</label>
|
||||
<span className=" tw-ml-1 tw-font-normal tw-text-grey-body">
|
||||
|
||||
@ -47,6 +47,30 @@ export const serviceTypeLogo = (type: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const fromISOString = (isoValue = '') => {
|
||||
if (isoValue) {
|
||||
// 'P1DT 0H 0M'
|
||||
const [d, hm] = isoValue.split('T');
|
||||
const day = +d.replace('D', '').replace('P', '');
|
||||
const [h, time] = hm.split('H');
|
||||
const minute = +time.replace('M', '');
|
||||
|
||||
return { day, hour: +h, minute };
|
||||
} else {
|
||||
return {
|
||||
day: 1,
|
||||
hour: 0,
|
||||
minute: 0,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export const getFrequencyTime = (isoDate: string): string => {
|
||||
const { day, hour, minute } = fromISOString(isoDate);
|
||||
|
||||
return `${day}D-${hour}H-${minute}M`;
|
||||
};
|
||||
|
||||
const getAllServiceList = (
|
||||
allServiceCollectionArr: Array<ServiceCollection>
|
||||
): Promise<Array<ServiceDataObj>> => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user