UI :- Converted html table to Antd table for Dashboard and PipelinesVersion (#8019)

* Converted html table to Antd table for Dashboard and Pipline Version

* remove dummy text

* change dashboardDetails and DatabaseSchema table to Antd

* remove tailwind css

* changes as per comments
This commit is contained in:
Ashish Gupta 2022-10-13 11:01:10 +05:30 committed by GitHub
parent 0e44f7d35d
commit 1f1943d2f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 294 additions and 311 deletions

View File

@ -11,13 +11,19 @@
* limitations under the License.
*/
import { Tooltip } from 'antd';
import { Space, Table, Tooltip } from 'antd';
import { ColumnsType } from 'antd/lib/table';
import { AxiosError } from 'axios';
import classNames from 'classnames';
import { compare } from 'fast-json-patch';
import { isUndefined } from 'lodash';
import { EntityTags, ExtraInfo, TagOption } from 'Models';
import React, { RefObject, useCallback, useEffect, useState } from 'react';
import React, {
RefObject,
useCallback,
useEffect,
useMemo,
useState,
} from 'react';
import { Link } from 'react-router-dom';
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
import { EntityField } from '../../constants/feed.constants';
@ -38,7 +44,6 @@ import {
getEntityName,
getEntityPlaceHolder,
getOwnerValue,
isEven,
} from '../../utils/CommonUtils';
import { getEntityFeedLink } from '../../utils/EntityUtils';
import { getDefaultValue } from '../../utils/FeedElementUtils';
@ -481,6 +486,121 @@ const DashboardDetails = ({
[paging]
);
const tableColumn: ColumnsType<ChartType> = useMemo(
() => [
{
title: 'Chart Name',
dataIndex: 'chartName',
key: 'chartName',
width: 200,
render: (_, record) => (
<Link target="_blank" to={{ pathname: record.chartUrl }}>
<Space>
<span>{getEntityName(record as unknown as EntityReference)}</span>
<SVGIcons
alt="external-link"
className="tw-align-middle"
icon="external-link"
width="16px"
/>
</Space>
</Link>
),
},
{
title: 'Chart Type',
dataIndex: 'chartType',
key: 'chartType',
width: 100,
},
{
title: 'Description',
dataIndex: 'description',
key: 'description',
width: 300,
render: (text, record, index) => (
<Space
className="w-full tw-group cursor-pointer"
data-testid="description">
<div>
{text ? (
<RichTextEditorPreviewer markdown={text} />
) : (
<span className="tw-no-description">No description</span>
)}
</div>
{!deleted && (
<Tooltip
title={
dashboardPermissions.EditAll
? 'Edit Description'
: NO_PERMISSION_FOR_ACTION
}>
<button
className="tw-self-start tw-w-8 tw-h-auto tw-opacity-0 tw-ml-1 group-hover:tw-opacity-100 focus:tw-outline-none"
disabled={!dashboardPermissions.EditAll}
onClick={() => handleUpdateChart(record, index)}>
<SVGIcons
alt="edit"
icon="icon-edit"
title="Edit"
width="16px"
/>
</button>
</Tooltip>
)}
</Space>
),
},
{
title: 'Tags',
dataIndex: 'tags',
key: 'tags',
width: 300,
render: (text, record, index) => (
<div
className="relative tableBody-cell"
data-testid="tags-wrapper"
onClick={() => handleTagContainerClick(record, index)}>
{deleted ? (
<div className="tw-flex tw-flex-wrap">
<TagsViewer sizeCap={-1} tags={text || []} />
</div>
) : (
<TagsContainer
editable={editChartTags?.index === index}
isLoading={isTagLoading && editChartTags?.index === index}
selectedTags={text as EntityTags[]}
showAddTagButton={
dashboardPermissions.EditAll || dashboardPermissions.EditTags
}
size="small"
tagList={tagList}
type="label"
onCancel={() => {
handleChartTagSelection();
}}
onSelectionChange={(tags) => {
handleChartTagSelection(tags, {
chart: record,
index,
});
}}
/>
)}
</div>
),
},
],
[
dashboardPermissions.EditAll,
dashboardPermissions.EditTags,
editChartTags,
tagList,
deleted,
]
);
return (
<PageContainer>
<div className="tw-px-6 tw-w-full tw-h-full tw-flex tw-flex-col">
@ -567,132 +687,14 @@ const DashboardDetails = ({
/>
</div>
</div>
<div className="tw-table-responsive tw-table-container">
<table className="tw-w-full" data-testid="charts-table">
<thead>
<tr className="tableHead-row">
<th className="tableHead-cell">Chart Name</th>
<th className="tableHead-cell">Chart Type</th>
<th className="tableHead-cell">Description</th>
<th className="tableHead-cell tw-w-60">Tags</th>
</tr>
</thead>
<tbody className="tableBody">
{charts.map((chart, index) => (
<tr
className={classNames(
'tableBody-row',
!isEven(index + 1) ? 'odd-row' : null
)}
key={index}>
<td className="tableBody-cell">
<Link
target="_blank"
to={{ pathname: chart.chartUrl }}>
<span className="tw-flex">
<span className="tw-mr-1">
{getEntityName(
chart as unknown as EntityReference
)}
</span>
<SVGIcons
alt="external-link"
className="tw-align-middle"
icon="external-link"
width="16px"
/>
</span>
</Link>
</td>
<td className="tableBody-cell">
{chart.chartType}
</td>
<td className="tw-group tableBody-cell tw-relative">
<div className="tw-inline-block">
<div
className="tw-cursor-pointer tw-flex"
data-testid="description">
<div>
{chart.description ? (
<RichTextEditorPreviewer
markdown={chart.description}
/>
) : (
<span className="tw-no-description">
No description
</span>
)}
</div>
{!deleted && (
<Tooltip
title={
dashboardPermissions.EditAll
? 'Edit Description'
: NO_PERMISSION_FOR_ACTION
}>
<button
className="tw-self-start tw-w-8 tw-h-auto tw-opacity-0 tw-ml-1 group-hover:tw-opacity-100 focus:tw-outline-none"
disabled={!dashboardPermissions.EditAll}
onClick={() =>
handleUpdateChart(chart, index)
}>
<SVGIcons
alt="edit"
icon="icon-edit"
title="Edit"
width="16px"
/>
</button>
</Tooltip>
)}
</div>
</div>
</td>
<td
className="tw-group tw-relative tableBody-cell"
data-testid="tags-wrapper"
onClick={() =>
handleTagContainerClick(chart, index)
}>
{deleted ? (
<div className="tw-flex tw-flex-wrap">
<TagsViewer
sizeCap={-1}
tags={chart.tags || []}
/>
</div>
) : (
<TagsContainer
editable={editChartTags?.index === index}
isLoading={
isTagLoading &&
editChartTags?.index === index
}
selectedTags={chart.tags as EntityTags[]}
showAddTagButton={
dashboardPermissions.EditAll ||
dashboardPermissions.EditTags
}
size="small"
tagList={tagList}
type="label"
onCancel={() => {
handleChartTagSelection();
}}
onSelectionChange={(tags) => {
handleChartTagSelection(tags, {
chart,
index,
});
}}
/>
)}
</td>
</tr>
))}
</tbody>
</table>
</div>
<Table
columns={tableColumn}
data-testid="charts-table"
dataSource={charts}
pagination={false}
rowKey="id"
size="small"
/>
</>
)}
{activeTab === 2 && (

View File

@ -11,10 +11,12 @@
* limitations under the License.
*/
import { Space, Table } from 'antd';
import { ColumnsType } from 'antd/lib/table';
import classNames from 'classnames';
import { isUndefined } from 'lodash';
import { ExtraInfo } from 'Models';
import React, { FC, useEffect, useState } from 'react';
import React, { FC, useEffect, useMemo, useState } from 'react';
import { Link } from 'react-router-dom';
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
import { EntityField } from '../../constants/feed.constants';
@ -22,9 +24,9 @@ import { OwnerType } from '../../enums/user.enum';
import {
ChangeDescription,
Dashboard,
EntityReference,
} from '../../generated/entity/data/dashboard';
import { TagLabel } from '../../generated/type/tagLabel';
import { isEven } from '../../utils/CommonUtils';
import {
getDescriptionDiff,
getDiffByFieldName,
@ -212,6 +214,51 @@ const DashboardVersion: FC<DashboardVersionProp> = ({
);
}, [currentVersionData]);
const tableColumn: ColumnsType<EntityReference> = useMemo(
() => [
{
title: 'Chart Name',
dataIndex: 'name',
key: 'name',
render: (text, record) => (
<Link target="_blank" to={{ pathname: text }}>
<Space>
<span>{record.displayName}</span>
<SVGIcons
alt="external-link"
className="tw-align-middle"
icon="external-link"
width="16px"
/>
</Space>
</Link>
),
},
{
title: 'Chart Type',
dataIndex: 'type',
key: 'type',
},
{
title: 'Description',
dataIndex: 'description',
key: 'description',
render: (text) =>
text ? (
<RichTextEditorPreviewer markdown={text} />
) : (
<span className="tw-no-description">No description</span>
),
},
{
title: 'Tags',
dataIndex: 'tags',
key: 'tags',
},
],
[]
);
return (
<PageContainer>
<div
@ -249,60 +296,15 @@ const DashboardVersion: FC<DashboardVersionProp> = ({
description={getDashboardDescription()}
/>
</div>
<div className="tw-table-responsive tw-my-6 tw-col-span-full tw-table-container">
<table className="tw-w-full" data-testid="schema-table">
<thead>
<tr className="tableHead-row">
<th className="tableHead-cell">Chart Name</th>
<th className="tableHead-cell">Chart Type</th>
<th className="tableHead-cell">Description</th>
<th className="tableHead-cell tw-w-60">Tags</th>
</tr>
</thead>
<tbody className="tableBody">
{(currentVersionData as Dashboard)?.charts?.map(
(chart, index) => (
<tr
className={classNames(
'tableBody-row',
!isEven(index + 1) ? 'odd-row' : null
)}
key={index}>
<td className="tableBody-cell">
<Link
target="_blank"
to={{ pathname: chart.name }}>
<span className="tw-flex">
<span className="tw-mr-1">
{chart.displayName}
</span>
<SVGIcons
alt="external-link"
className="tw-align-middle"
icon="external-link"
width="16px"
/>
</span>
</Link>
</td>
<td className="tableBody-cell">{chart.type}</td>
<td className="tw-group tableBody-cell tw-relative">
{chart.description ? (
<RichTextEditorPreviewer
markdown={chart.description}
/>
) : (
<span className="tw-no-description">
No description
</span>
)}
</td>
<td className="tw-group tw-relative tableBody-cell" />
</tr>
)
)}
</tbody>
</table>
<div className="m-y-md tw-col-span-full">
<Table
columns={tableColumn}
data-testid="schema-table"
dataSource={(currentVersionData as Dashboard)?.charts}
pagination={false}
rowKey="id"
size="small"
/>
</div>
</div>
</div>

View File

@ -11,10 +11,12 @@
* limitations under the License.
*/
import { Space, Table } from 'antd';
import { ColumnsType } from 'antd/lib/table';
import classNames from 'classnames';
import { isUndefined } from 'lodash';
import { ExtraInfo } from 'Models';
import React, { FC, useEffect, useState } from 'react';
import React, { FC, useEffect, useMemo, useState } from 'react';
import { Link } from 'react-router-dom';
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
import { EntityField } from '../../constants/feed.constants';
@ -22,9 +24,9 @@ import { OwnerType } from '../../enums/user.enum';
import {
ChangeDescription,
Pipeline,
Task,
} from '../../generated/entity/data/pipeline';
import { TagLabel } from '../../generated/type/tagLabel';
import { isEven } from '../../utils/CommonUtils';
import {
getDescriptionDiff,
getDiffByFieldName,
@ -212,6 +214,46 @@ const PipelineVersion: FC<PipelineVersionProp> = ({
);
}, [currentVersionData]);
const tableColumn: ColumnsType<Task> = useMemo(
() => [
{
title: 'Task Name',
dataIndex: 'displayName',
key: 'displayName',
render: (text, record) => (
<Link target="_blank" to={{ pathname: record.taskUrl }}>
<Space>
<span>{text}</span>
<SVGIcons
alt="external-link"
className="tw-align-middle"
icon="external-link"
width="16px"
/>
</Space>
</Link>
),
},
{
title: 'Description',
dataIndex: 'description',
key: 'description',
render: (text) =>
text ? (
<RichTextEditorPreviewer markdown={text} />
) : (
<span className="tw-no-description">No description</span>
),
},
{
title: 'Task Type',
dataIndex: 'taskType',
key: 'taskType',
},
],
[]
);
return (
<PageContainer>
<div
@ -246,74 +288,15 @@ const PipelineVersion: FC<PipelineVersionProp> = ({
description={getPipelineDescription()}
/>
</div>
<div className="tw-table-responsive tw-my-6 tw-col-span-full tw-table-container">
<table className="tw-w-full" data-testid="schema-table">
<thead>
<tr className="tableHead-row">
<th className="tableHead-cell">Task Name</th>
<th className="tableHead-cell">Description</th>
<th className="tableHead-cell">Task Type</th>
</tr>
</thead>
<tbody className="tableBody">
{(currentVersionData as Pipeline)?.tasks?.map(
(task, index) => (
<tr
className={classNames(
'tableBody-row',
!isEven(index + 1) ? 'odd-row' : null
)}
key={index}>
<td className="tableBody-cell">
<Link
target="_blank"
to={{ pathname: task.taskUrl }}>
<span className="tw-flex">
<span className="tw-mr-1">
{task.displayName}
</span>
<SVGIcons
alt="external-link"
className="tw-align-middle"
icon="external-link"
width="16px"
/>
</span>
</Link>
</td>
<td className="tw-group tableBody-cell tw-relative">
<div
className="tw-cursor-pointer hover:tw-underline tw-flex"
data-testid="description">
<div>
{task.description ? (
<RichTextEditorPreviewer
markdown={task.description}
/>
) : (
<span className="tw-no-description">
No description
</span>
)}
</div>
<button className="tw-self-start tw-w-8 tw-h-auto tw-opacity-0 tw-ml-1 group-hover:tw-opacity-100 focus:tw-outline-none">
<SVGIcons
alt="edit"
icon="icon-edit"
title="Edit"
width="16px"
/>
</button>
</div>
</td>
<td className="tableBody-cell">
{task.taskType}
</td>
</tr>
)
)}
</tbody>
</table>
<div className="m-y-md tw-col-span-full">
<Table
columns={tableColumn}
data-testid="schema-table"
dataSource={(currentVersionData as Pipeline)?.tasks}
pagination={false}
rowKey="name"
size="small"
/>
</div>
</div>
</div>

View File

@ -11,9 +11,9 @@
* limitations under the License.
*/
import { Col, Row, Space } from 'antd';
import { Col, Row, Space, Table as TableAntd } from 'antd';
import { ColumnsType } from 'antd/lib/table';
import { AxiosError } from 'axios';
import classNames from 'classnames';
import { compare, Operation } from 'fast-json-patch';
import { startCase } from 'lodash';
import { observer } from 'mobx-react';
@ -23,6 +23,7 @@ import React, {
FunctionComponent,
RefObject,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
@ -81,7 +82,6 @@ import jsonData from '../../jsons/en';
import {
getEntityName,
getPartialNameFromTableFQN,
isEven,
} from '../../utils/CommonUtils';
import {
databaseSchemaDetailsTabs,
@ -516,60 +516,49 @@ const DatabaseSchemaPage: FunctionComponent = () => {
}
};
const tableColumn: ColumnsType<Table> = useMemo(
() => [
{
title: 'Table Name',
dataIndex: 'name',
key: 'name',
render: (text: string, record: Table) => {
return (
<Link
to={getEntityLink(
EntityType.TABLE,
record.fullyQualifiedName as string
)}>
{text}
</Link>
);
},
},
{
title: 'Description',
dataIndex: 'description',
key: 'description',
render: (text: string) =>
text?.trim() ? (
<RichTextEditorPreviewer markdown={text} />
) : (
<span className="tw-no-description">No description</span>
),
},
],
[]
);
const getSchemaTableList = () => {
return (
<div className="tw-table-container tw-mb-4">
<table
className="tw-bg-white tw-w-full"
data-testid="databaseSchema-tables">
<thead data-testid="table-header">
<tr className="tableHead-row">
<th className="tableHead-cell" data-testid="header-name">
Table Name
</th>
<th className="tableHead-cell" data-testid="header-description">
Description
</th>
</tr>
</thead>
<tbody className="tableBody">
{tableData.length > 0 ? (
tableData.map((table, index) => (
<tr
className={classNames(
'tableBody-row',
!isEven(index + 1) ? 'odd-row' : null
)}
data-testid="table-column"
key={index}>
<td className="tableBody-cell">
<Link
to={getEntityLink(
EntityType.TABLE,
table.fullyQualifiedName as string
)}>
{table.name}
</Link>
</td>
<td className="tableBody-cell">
{table.description?.trim() ? (
<RichTextEditorPreviewer markdown={table.description} />
) : (
<span className="tw-no-description">No description</span>
)}
</td>
</tr>
))
) : (
<tr className="tableBody-row">
<td className="tableBody-cell tw-text-center" colSpan={5}>
No records found.
</td>
</tr>
)}
</tbody>
</table>
</div>
<TableAntd
columns={tableColumn}
data-testid="databaseSchema-tables"
dataSource={tableData}
pagination={false}
rowKey="id"
size="small"
/>
);
};

View File

@ -11,6 +11,13 @@
* limitations under the License.
*/
.relative {
position: relative;
}
.absolute {
position: absolute;
}
.align-start {
align-items: start;
}