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:
Shailesh Parmar 2021-08-23 10:33:26 +05:30 committed by GitHub
parent 95f650268b
commit f028c1d395
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 241 additions and 175 deletions

View File

@ -17,6 +17,7 @@
import classNames from 'classnames'; import classNames from 'classnames';
import React, { FunctionComponent, useRef, useState } from 'react'; import React, { FunctionComponent, useRef, useState } from 'react';
import { fromISOString } from '../../../utils/ServiceUtils';
import { Button } from '../../buttons/Button/Button'; import { Button } from '../../buttons/Button/Button';
import MarkdownWithPreview from '../../common/editor/MarkdownWithPreview'; import MarkdownWithPreview from '../../common/editor/MarkdownWithPreview';
// import { serviceType } from '../../../constants/services.const'; // import { serviceType } from '../../../constants/services.const';
@ -119,24 +120,6 @@ const seprateUrl = (url?: string) => {
return {}; 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) => { const errorMsg = (value: string) => {
return ( return (
<div className="tw-mt-1"> <div className="tw-mt-1">

View File

@ -93,7 +93,7 @@ const SearchedData: React.FC<SearchedDataProp> = ({
</div> </div>
))} ))}
{totalValue > 0 && data.length > 0 && ( {totalValue > PAGE_SIZE && data.length > 0 && (
<Pagination <Pagination
currentPage={currentPage} currentPage={currentPage}
paginate={paginate} paginate={paginate}

View File

@ -54,6 +54,10 @@ declare module 'Models' {
export type ServiceOption = { export type ServiceOption = {
id: string; id: string;
description: string; description: string;
ingestionSchedule?: {
repeatFrequency: string;
startDate: string;
};
jdbc: { connectionUrl: string; driverClass: string }; jdbc: { connectionUrl: string; driverClass: string };
name: string; name: string;
serviceType: string; serviceType: string;

View File

@ -18,6 +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 { 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';
@ -265,8 +266,6 @@ const DatabaseDetails: FunctionComponent = () => {
</div> </div>
</div> </div>
</div> </div>
{data.length ? (
<>
<table <table
className="tw-bg-white tw-w-full tw-mb-4" className="tw-bg-white tw-w-full tw-mb-4"
data-testid="database-tables"> data-testid="database-tables">
@ -280,7 +279,8 @@ const DatabaseDetails: FunctionComponent = () => {
</tr> </tr>
</thead> </thead>
<tbody className="tableBody"> <tbody className="tableBody">
{data.map((table, index) => ( {data.length > 0 ? (
data.map((table, index) => (
<tr <tr
className={classNames( className={classNames(
'tableBody-row', 'tableBody-row',
@ -290,9 +290,7 @@ const DatabaseDetails: FunctionComponent = () => {
key={index}> key={index}>
<td className="tableBody-cell"> <td className="tableBody-cell">
<Link <Link
to={getDatasetDetailsPath( to={getDatasetDetailsPath(table.fullyQualifiedName)}>
table.fullyQualifiedName
)}>
{table.name} {table.name}
</Link> </Link>
</td> </td>
@ -308,9 +306,7 @@ const DatabaseDetails: FunctionComponent = () => {
)} )}
</td> </td>
<td className="tableBody-cell"> <td className="tableBody-cell">
<p> <p>{getOwnerFromId(table?.owner?.id)?.name || '--'}</p>
{getOwnerFromId(table?.owner?.id)?.name || '--'}
</p>
</td> </td>
<td className="tableBody-cell"> <td className="tableBody-cell">
<p> <p>
@ -352,15 +348,18 @@ const DatabaseDetails: FunctionComponent = () => {
))} ))}
</td> </td>
</tr> </tr>
))} ))
) : (
<tr className="tableBody-row">
<td className="tableBody-cell tw-text-center" colSpan={5}>
No records found.
</td>
</tr>
)}
</tbody> </tbody>
</table> </table>
{Boolean(!isNull(paging.after) || !isNull(paging.before)) && (
<NextPrevious paging={paging} pagingHandler={pagingHandler} /> <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>
)} )}
</div> </div>
</PageContainer> </PageContainer>

View File

@ -17,7 +17,7 @@
import { AxiosError, AxiosResponse } from 'axios'; import { AxiosError, AxiosResponse } from 'axios';
import classNames from 'classnames'; import classNames from 'classnames';
import { isUndefined } from 'lodash'; import { isNull, isUndefined } from 'lodash';
import { Database, Paging, ServiceOption } from 'Models'; import { Database, Paging, ServiceOption } from 'Models';
import React, { FunctionComponent, useEffect, useState } from 'react'; import React, { FunctionComponent, useEffect, useState } from 'react';
import { Link, useParams } from 'react-router-dom'; import { Link, useParams } from 'react-router-dom';
@ -33,7 +33,7 @@ import { ModalWithMarkdownEditor } from '../../components/Modals/ModalWithMarkdo
import { pagingObject } from '../../constants/constants'; import { pagingObject } from '../../constants/constants';
import useToastContext from '../../hooks/useToastContext'; import useToastContext from '../../hooks/useToastContext';
import { isEven } from '../../utils/CommonUtils'; import { isEven } from '../../utils/CommonUtils';
import { serviceTypeLogo } from '../../utils/ServiceUtils'; import { getFrequencyTime, serviceTypeLogo } from '../../utils/ServiceUtils';
import SVGIcons from '../../utils/SvgUtils'; import SVGIcons from '../../utils/SvgUtils';
import { getUsagePercentile } from '../../utils/TableUtils'; import { getUsagePercentile } from '../../utils/TableUtils';
@ -141,6 +141,44 @@ const ServicePage: FunctionComponent = () => {
<div className="tw-px-4"> <div className="tw-px-4">
<TitleBreadcrumb titleLinks={slashedTableName} /> <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-bg-white tw-my-4">
<div className="tw-col-span-3"> <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"> <div className="schema-description tw-flex tw-flex-col tw-h-full tw-relative tw-border tw-border-main tw-rounded-md">
@ -179,8 +217,7 @@ const ServicePage: FunctionComponent = () => {
</div> </div>
</div> </div>
</div> </div>
{data.length > 0 ? (
<>
<div className="tw-mt-4"> <div className="tw-mt-4">
<table <table
className="tw-bg-white tw-w-full tw-mb-4" className="tw-bg-white tw-w-full tw-mb-4"
@ -194,7 +231,8 @@ const ServicePage: FunctionComponent = () => {
</tr> </tr>
</thead> </thead>
<tbody className="tableBody"> <tbody className="tableBody">
{data.map((database, index) => ( {data.length > 0 ? (
data.map((database, index) => (
<tr <tr
className={classNames( className={classNames(
'tableBody-row', 'tableBody-row',
@ -203,8 +241,7 @@ const ServicePage: FunctionComponent = () => {
data-testid="column" data-testid="column"
key={index}> key={index}>
<td className="tableBody-cell"> <td className="tableBody-cell">
<Link <Link to={`/database/${database.fullyQualifiedName}`}>
to={`/database/${database.fullyQualifiedName}`}>
{database.name} {database.name}
</Link> </Link>
</td> </td>
@ -230,16 +267,19 @@ const ServicePage: FunctionComponent = () => {
</p> </p>
</td> </td>
</tr> </tr>
))} ))
) : (
<tr className="tableBody-row">
<td className="tableBody-cell tw-text-center" colSpan={4}>
No records found.
</td>
</tr>
)}
</tbody> </tbody>
</table> </table>
</div> </div>
{Boolean(!isNull(paging.after) || !isNull(paging.before)) && (
<NextPrevious paging={paging} pagingHandler={pagingHandler} /> <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>
)} )}
</div> </div>
</PageContainer> </PageContainer>

View File

@ -38,7 +38,7 @@ import {
} from '../../components/Modals/AddServiceModal/AddServiceModal'; } from '../../components/Modals/AddServiceModal/AddServiceModal';
import { getServiceDetailsPath } from '../../constants/constants'; import { getServiceDetailsPath } from '../../constants/constants';
import { NOSERVICE, PLUS } from '../../constants/services.const'; import { NOSERVICE, PLUS } from '../../constants/services.const';
import { serviceTypeLogo } from '../../utils/ServiceUtils'; import { getFrequencyTime, serviceTypeLogo } from '../../utils/ServiceUtils';
import SVGIcons from '../../utils/SvgUtils'; import SVGIcons from '../../utils/SvgUtils';
export type ApiData = { export type ApiData = {
@ -218,6 +218,22 @@ const ServicesPage = () => {
<span className="tw-tag tw-ml-3">mysql</span> <span className="tw-tag tw-ml-3">mysql</span>
<span className="tw-tag tw-ml-2">sales</span> <span className="tw-tag tw-ml-2">sales</span>
</div> */} </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=""> <div className="">
<label className="tw-mb-0">Type:</label> <label className="tw-mb-0">Type:</label>
<span className=" tw-ml-1 tw-font-normal tw-text-grey-body"> <span className=" tw-ml-1 tw-font-normal tw-text-grey-body">

View File

@ -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 = ( const getAllServiceList = (
allServiceCollectionArr: Array<ServiceCollection> allServiceCollectionArr: Array<ServiceCollection>
): Promise<Array<ServiceDataObj>> => { ): Promise<Array<ServiceDataObj>> => {