feat(ui): show table constraint on table details page (#12163)

* feat(ui): show table constraint on table details page

* chore: sync locale

---------

Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
This commit is contained in:
Sachin Chaurasiya 2023-06-28 14:18:24 +05:30 committed by GitHub
parent d91a01a666
commit df7f5a7309
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 225 additions and 0 deletions

View File

@ -0,0 +1,3 @@
<svg width="19" height="72" viewBox="0 0 19 72" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18.2703 0.775635H0.847656V70.7756H18.2703" stroke="black" stroke-width="0.8" stroke-dasharray="1.6 1.6"/>
</svg>

After

Width:  |  Height:  |  Size: 219 B

View File

@ -0,0 +1,3 @@
<svg width="19" height="40" viewBox="0 0 19 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18.5197 0.775635H0.937744V38.7756H18.5197" stroke="black" stroke-width="0.8" stroke-dasharray="1.6 1.6"/>
</svg>

After

Width:  |  Height:  |  Size: 219 B

View File

@ -0,0 +1,3 @@
<svg width="125" height="2" viewBox="0 0 125 2" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M124.5 1.27565L0.5 1.27563" stroke="black" stroke-width="0.8" stroke-dasharray="1.6 1.6"/>
</svg>

After

Width:  |  Height:  |  Size: 203 B

View File

@ -876,6 +876,7 @@
"synonym-lowercase-plural": "synonyms",
"synonym-plural": "Synonyms",
"table": "Table",
"table-constraint": "Table Constraint",
"table-entity-text": "Table {{entityText}}",
"table-lowercase": "table",
"table-lowercase-plural": "tables",

View File

@ -876,6 +876,7 @@
"synonym-lowercase-plural": "sinónimos",
"synonym-plural": "Sinónimos",
"table": "Tabla",
"table-constraint": "Table Constraint",
"table-entity-text": "Tabla {{entityText}}",
"table-lowercase": "tabla",
"table-lowercase-plural": "tablas",

View File

@ -876,6 +876,7 @@
"synonym-lowercase-plural": "synonymes",
"synonym-plural": "Synonymes",
"table": "Table",
"table-constraint": "Table Constraint",
"table-entity-text": "Table {{entityText}}",
"table-lowercase": "table",
"table-lowercase-plural": "tables",

View File

@ -876,6 +876,7 @@
"synonym-lowercase-plural": "シノニム",
"synonym-plural": "シノニム",
"table": "テーブル",
"table-constraint": "Table Constraint",
"table-entity-text": "テーブル {{entityText}}",
"table-lowercase": "テーブル",
"table-lowercase-plural": "tables",

View File

@ -876,6 +876,7 @@
"synonym-lowercase-plural": "sinônimos",
"synonym-plural": "Sinônimos",
"table": "Tabela",
"table-constraint": "Table Constraint",
"table-entity-text": "Tabela {{entityText}}",
"table-lowercase": "tabela",
"table-lowercase-plural": "tables",

View File

@ -876,6 +876,7 @@
"synonym-lowercase-plural": "同义词",
"synonym-plural": "同义词",
"table": "数据表",
"table-constraint": "Table Constraint",
"table-entity-text": "数据表{{entityText}}",
"table-lowercase": "数据表",
"table-lowercase-plural": "数据表",

View File

@ -0,0 +1,44 @@
/*
* Copyright 2023 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Icon from '@ant-design/icons/lib/components/Icon';
import { Tooltip } from 'antd';
import { ReactComponent as IconForeignKey } from 'assets/svg/foriegnKey.svg';
import SectionLine from 'assets/svg/section-line-medium.svg';
import React from 'react';
import { useTranslation } from 'react-i18next';
const ForeignKeyConstraint = () => {
const { t } = useTranslation();
return (
<div className="constraint-foreign-key">
<img
className="foreign-key-section-line"
src={SectionLine}
width="100%"
/>
<Tooltip
placement="bottom"
title={t('label.foreign-key')}
trigger="hover">
<Icon
alt="foreign-key"
className="foreign-key-icon"
component={IconForeignKey}
/>
</Tooltip>
</div>
);
};
export default ForeignKeyConstraint;

View File

@ -0,0 +1,31 @@
/*
* Copyright 2023 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Icon from '@ant-design/icons/lib/components/Icon';
import { ReactComponent as IconKey } from 'assets/svg/icon-key.svg';
import StraightLine from 'assets/svg/straight-line.svg';
import React from 'react';
const PrimaryKeyConstraint = () => {
return (
<div className="constraint-primary-key">
<img src={StraightLine} />
<Icon
alt="primary-key"
className="primary-key-icon"
component={IconKey}
/>
</div>
);
};
export default PrimaryKeyConstraint;

View File

@ -0,0 +1,77 @@
/*
* Copyright 2023 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Space, Typography } from 'antd';
import { ConstraintType, Table } from 'generated/entity/data/table';
import { isUndefined, map } from 'lodash';
import React, { FC, Fragment } from 'react';
import { useTranslation } from 'react-i18next';
import ForeignKeyConstraint from './ForeignKeyConstraint';
import PrimaryKeyConstraint from './PrimaryKeyConstraint';
import './table-constraints.less';
interface TableConstraintsProps {
constraints: Table['tableConstraints'];
}
const TableConstraints: FC<TableConstraintsProps> = ({ constraints }) => {
const { t } = useTranslation();
if (isUndefined(constraints)) {
return null;
}
return (
<Space className="p-b-sm" direction="vertical">
<Typography.Text className="right-panel-label">
{t('label.table-constraint')}
</Typography.Text>
{constraints.map(({ constraintType, columns, referredColumns }) => {
if (constraintType === ConstraintType.PrimaryKey) {
const columnsLength = (columns?.length ?? 0) - 1;
return (
<Space className="constraint-columns">
{columns?.map((column, index) => (
<Fragment key={column}>
<Typography.Text>{column}</Typography.Text>
{index < columnsLength ? <PrimaryKeyConstraint /> : null}
</Fragment>
))}
</Space>
);
}
if (constraintType === ConstraintType.ForeignKey) {
return (
<Space className="constraint-columns">
<ForeignKeyConstraint />
<Space direction="vertical" size={16}>
<Typography.Text>{columns?.join(', ')}</Typography.Text>
<div data-testid="referred-column-name">
{map(referredColumns, (referredColumn) => (
<Typography.Text className="truncate referred-column-name">
{referredColumn}
</Typography.Text>
))}
</div>
</Space>
</Space>
);
}
return null;
})}
</Space>
);
};
export default TableConstraints;

View File

@ -0,0 +1,54 @@
/*
* Copyright 2023 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import url('../../../styles/variables.less');
.constraint-columns {
border-radius: 5px;
background: @grey-1;
padding: 16px;
max-width: 300px;
}
.referred-column-name {
display: block;
max-width: 250px;
}
.constraint-primary-key {
position: relative;
.primary-key-icon {
position: absolute;
transform: translate(36px, -8px);
background: white;
height: 20px;
width: 20px;
border-radius: 50%;
border: @global-border;
padding: 2px;
}
}
.constraint-foreign-key {
position: relative;
.foreign-key-section-line {
margin-top: 20px;
}
.foreign-key-icon {
background: white;
height: 20px;
width: 20px;
border-radius: 50%;
border: @global-border;
padding: 2px;
transform: translate(-7px, -31px);
}
}

View File

@ -87,6 +87,7 @@ import { getTagsWithoutTier, getTierTags } from 'utils/TableUtils';
import { showErrorToast, showSuccessToast } from 'utils/ToastUtils';
import { FrequentlyJoinedTables } from './FrequentlyJoinedTables/FrequentlyJoinedTables.component';
import './table-details-page-v1.less';
import TableConstraints from './TableConstraints/TableConstraints';
const TableDetailsPageV1 = () => {
const { isTourOpen, activeTabForTourDatasetPage, isTourPage } =
@ -519,6 +520,7 @@ const TableDetailsPageV1 = () => {
onSelectionChange={handleTagSelection}
onThreadLinkSelect={onThreadLinkSelect}
/>
<TableConstraints constraints={tableDetails?.tableConstraints} />
</Space>
</Col>
</Row>

View File

@ -434,6 +434,8 @@ a[href].link-text-grey,
}
}
.entity-tag-right-panel-container {
height: calc(100vh - 236px);
overflow-y: scroll;
border-left: @global-border;
margin-left: 20px;
padding: 12px 8px 0 8px;