Fix(UI): Explore page bugs (#8607)

* - Made  changes to show more information about tables in data card on explore page
- Fixed bugs related to entity summary panel

* Replaced Space components for vertical flex with Row and Col for ColumnSummary
This commit is contained in:
Aniket Katkar 2022-11-10 18:02:37 +05:30 committed by GitHub
parent 3e3cf971c2
commit a6822aa094
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 187 additions and 147 deletions

View File

@ -11,10 +11,11 @@
* limitations under the License.
*/
import { Divider, Space, Typography } from 'antd';
import { Col, Divider, Row, Space, Typography } from 'antd';
import { toLower } from 'lodash';
import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { MAX_CHAR_LIMIT_ENTITY_SUMMARY } from '../../../constants/constants';
import { getTagValue } from '../../../utils/CommonUtils';
import SVGIcons from '../../../utils/SvgUtils';
import RichTextEditorPreviewer from '../../common/rich-text-editor/RichTextEditorPreviewer';
@ -38,50 +39,59 @@ export default function ColumnSummary({ columns }: ColumnSummaryProps) {
}, [columns]);
return (
<Space direction="vertical">
<Row>
{columns &&
formattedColumnsData.map((column) => (
<React.Fragment key={column.name}>
<Space direction="vertical" size={0}>
<Text className="column-name">{column.name}</Text>
<Space className="text-xs" size={4}>
<Space size={4}>
<Text className="text-gray">{`${t('label.type')}:`}</Text>
<Text className="text-semi-bold">{toLower(column.type)}</Text>
</Space>
{column.tags?.length !== 0 && (
<>
<Divider type="vertical" />
<Space size={4}>
<SVGIcons
alt="icon-tag"
icon="icon-tag-grey"
width="12"
/>
<Col key={column.name} span={24}>
<Row>
<Col span={24}>
<Text className="column-name">{column.name}</Text>
</Col>
<Col span={24}>
<Space className="text-xs" size={4}>
<Space size={4}>
<Text className="text-gray">{`${t('label.type')}:`}</Text>
<Text className="text-semi-bold">
{toLower(column.type)}
</Text>
</Space>
{column.tags?.length !== 0 && (
<>
<Divider type="vertical" />
<Space size={4}>
<SVGIcons
alt="icon-tag"
icon="icon-tag-grey"
width="12"
/>
<TagsViewer
sizeCap={-1}
tags={(column.tags || []).map((tag) =>
getTagValue(tag)
)}
/>
</Space>
</>
)}
</Space>
<Paragraph className="text-gray">
{column.description ? (
<RichTextEditorPreviewer
markdown={column.description || ''}
/>
) : (
t('label.no-description')
)}
</Paragraph>
</Space>
<TagsViewer
sizeCap={-1}
tags={(column.tags || []).map((tag) =>
getTagValue(tag)
)}
/>
</Space>
</>
)}
</Space>
</Col>
<Col span={24}>
<Paragraph className="text-gray">
{column.description ? (
<RichTextEditorPreviewer
markdown={column.description || ''}
maxLength={MAX_CHAR_LIMIT_ENTITY_SUMMARY}
/>
) : (
t('label.no-description')
)}
</Paragraph>
</Col>
</Row>
<Divider />
</React.Fragment>
</Col>
))}
</Space>
</Row>
);
}

View File

@ -12,7 +12,7 @@
*/
import { CloseOutlined } from '@ant-design/icons';
import { Col, Divider, Row, Space, Typography } from 'antd';
import { Col, Divider, Row, Typography } from 'antd';
import classNames from 'classnames';
import React from 'react';
import { useTranslation } from 'react-i18next';
@ -46,54 +46,70 @@ export default function EntitySummaryPanel({
'summary-panel-container',
showPanel ? 'show-panel' : ''
)}>
<Space
className={classNames('basic-info-container m-md')}
direction="vertical">
<Typography.Title level={5}>{entityDetails.name}</Typography.Title>
<Space className={classNames('w-full')} direction="vertical">
{Object.keys(basicTableInfo).map((fieldName) => (
<Row gutter={16} key={fieldName}>
<Col className="text-gray" span={10}>
{fieldName}
<Row className={classNames('m-md')}>
<Col span={24}>
<Typography.Title level={5}>{entityDetails.name}</Typography.Title>
</Col>
<Col span={24}>
<Row>
{Object.keys(basicTableInfo).map((fieldName) => (
<Col key={fieldName} span={24}>
<Row gutter={16}>
<Col className="text-gray" span={10}>
{fieldName}
</Col>
<Col span={12}>
{basicTableInfo[fieldName as keyof BasicTableInfo]}
</Col>
</Row>
</Col>
<Col span={12}>
{basicTableInfo[fieldName as keyof BasicTableInfo]}
))}
</Row>
</Col>
</Row>
<Divider className="m-0" />
<Row className={classNames('m-md')} gutter={[0, 16]}>
<Col span={24}>
<Typography.Text className="section-header">
{t('label.profiler-amp-data-quality')}
</Typography.Text>
</Col>
<Col span={24}>
<Row gutter={[16, 16]}>
{overallSummery.map((field) => (
<Col key={field.title} span={10}>
<Row>
<Col span={24}>
<Typography.Text className="text-gray">
{field.title}
</Typography.Text>
</Col>
<Col span={24}>
<Typography.Text
className={classNames(
'tw-text-2xl tw-font-semibold',
field.className
)}>
{field.value}
</Typography.Text>
</Col>
</Row>
</Col>
</Row>
))}
</Space>
</Space>
))}
</Row>
</Col>
</Row>
<Divider className="m-0" />
<Space className={classNames('m-md')} direction="vertical">
<Typography.Text className="section-header">
{t('label.profiler-amp-data-quality')}
</Typography.Text>
<Row gutter={[16, 16]}>
{overallSummery.map((field) => (
<Col key={field.title} span={10}>
<Space direction="vertical" size={6}>
<Typography.Text className="text-gray">
{field.title}
</Typography.Text>
<Typography.Text
className={classNames(
'tw-text-2xl tw-font-semibold',
field.className
)}>
{field.value}
</Typography.Text>
</Space>
</Col>
))}
</Row>
</Space>
<Divider className="m-0" />
<Space className={classNames('m-md')} direction="vertical">
<Typography.Text className="section-header">
{t('label.schema')}
</Typography.Text>
<ColumnSummary columns={columns} />
</Space>
<Row className={classNames('m-md')} gutter={[0, 16]}>
<Col span={24}>
<Typography.Text className="section-header">
{t('label.schema')}
</Typography.Text>
</Col>
<Col span={24}>
<ColumnSummary columns={columns} />
</Col>
</Row>
<CloseOutlined className="close-icon" onClick={handleClosePanel} />
</div>
);

View File

@ -37,10 +37,6 @@
-ms-overflow-style: none;
scrollbar-width: none;
.basic-info-container {
width: calc(100% - 32px);
}
.text-gray {
color: @label-color;
}
@ -64,7 +60,7 @@
}
.ant-divider-horizontal {
margin: 8px 0px;
margin: 16px 0px;
}
div.ant-typography {

View File

@ -16,10 +16,18 @@ import {
faSortAmountUpAlt,
} from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Card, Space, Tabs } from 'antd';
import { Card, Tabs } from 'antd';
import { AxiosError } from 'axios';
import unique from 'fork-ts-checker-webpack-plugin/lib/utils/array/unique';
import { isNil, isNumber, lowerCase, noop, omit, toUpper } from 'lodash';
import {
isNil,
isNumber,
lowerCase,
noop,
omit,
toLower,
toUpper,
} from 'lodash';
import { EntityType } from 'Models';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
@ -43,6 +51,7 @@ import {
import { updateTestResults } from '../../utils/DataQualityAndProfilerUtils';
import { generateEntityLink } from '../../utils/TableUtils';
import { showErrorToast } from '../../utils/ToastUtils';
import { Entities } from '../AddWebhook/WebhookConstants';
import AdvancedSearch from '../AdvancedSearch/AdvancedSearch.component';
import { FacetFilterProps } from '../common/facetfilter/facetFilter.interface';
import PageLayoutV1 from '../containers/PageLayoutV1';
@ -293,6 +302,7 @@ const Explore: React.FC<ExploreProps> = ({
}
onChange={(tab) => {
tab && onChangeSearchIndex(tab as ExploreSearchIndex);
setShowSummaryPanel(false);
}}>
{Object.entries(tabsInfo).map(([tabSearchIndex, tabDetail]) => (
<Tabs.TabPane
@ -314,46 +324,50 @@ const Explore: React.FC<ExploreProps> = ({
/>
))}
</Tabs>
<Space>
<div
style={{
marginRight: showSummaryPanel ? '380px' : '',
}}>
<AdvancedSearch
jsonTree={advancedSearchJsonTree}
searchIndex={searchIndex}
onChangeJsonTree={(nTree) => onChangeAdvancedSearchJsonTree(nTree)}
onChangeQueryFilter={(nQueryFilter) =>
onChangeAdvancedSearchQueryFilter(nQueryFilter)
<div
style={{
marginRight: showSummaryPanel ? '390px' : '',
}}>
<AdvancedSearch
jsonTree={advancedSearchJsonTree}
searchIndex={searchIndex}
onChangeJsonTree={(nTree) => onChangeAdvancedSearchJsonTree(nTree)}
onChangeQueryFilter={(nQueryFilter) =>
onChangeAdvancedSearchQueryFilter(nQueryFilter)
}
/>
{!loading ? (
<SearchedData
isFilterSelected
showResultCount
currentPage={page}
data={searchResults?.hits.hits ?? []}
handleSummaryPanelDisplay={
tab === toLower(Entities.table)
? handleSummaryPanelDisplay
: undefined
}
paginate={(value) => {
if (isNumber(value)) {
onChangePage(value);
} else if (!isNaN(Number.parseInt(value))) {
onChangePage(Number.parseInt(value));
}
}}
totalValue={searchResults?.hits.total.value ?? 0}
/>
{!loading ? (
<SearchedData
isFilterSelected
showResultCount
currentPage={page}
data={searchResults?.hits.hits ?? []}
handleSummaryPanelDisplay={handleSummaryPanelDisplay}
paginate={(value) => {
if (isNumber(value)) {
onChangePage(value);
} else if (!isNaN(Number.parseInt(value))) {
onChangePage(Number.parseInt(value));
}
}}
totalValue={searchResults?.hits.total.value ?? 0}
/>
) : (
<Loader />
)}
</div>
) : (
<Loader />
)}
</div>
{tab === toLower(Entities.table) && (
<EntitySummaryPanel
entityDetails={entityDetails || ({} as Table)}
handleClosePanel={handleClosePanel}
overallSummery={overallSummery}
showPanel={showSummaryPanel}
/>
</Space>
)}
</PageLayoutV1>
);
};

View File

@ -219,7 +219,10 @@ const EntitySummaryDetails = ({
data-testid="owner-link"
href={data.value as string}
rel="noopener noreferrer"
target={data.openInNewTab ? '_blank' : '_self'}>
target={data.openInNewTab ? '_blank' : '_self'}
onClick={(e) => {
e.stopPropagation();
}}>
{displayVal}
{data.openInNewTab && (
<>

View File

@ -13,7 +13,7 @@
import { faExclamationCircle } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { isNil, isString, startCase, uniqueId } from 'lodash';
import { isString, startCase, uniqueId } from 'lodash';
import { ExtraInfo } from 'Models';
import React, { useMemo } from 'react';
import { Link, useLocation } from 'react-router-dom';
@ -49,7 +49,7 @@ export interface TableDataCardPropsV2 {
value: number;
}[];
searchIndex: SearchIndex | EntityType;
handleSummaryPanelDisplay: (source: Table) => void;
handleSummaryPanelDisplay?: (source: Table) => void;
}
const TableDataCardV2: React.FC<TableDataCardPropsV2> = ({
@ -62,19 +62,8 @@ const TableDataCardV2: React.FC<TableDataCardPropsV2> = ({
const location = useLocation();
const otherDetails = useMemo(() => {
const _otherDetails: ExtraInfo[] = [];
if ('tier' in source && !isNil(source.tier)) {
_otherDetails.push({
key: 'Tier',
value: isString(source.tier)
? source.tier
: source.tier.tagFQN.split(FQN_SEPARATOR_CHAR)[1],
});
}
if ('owner' in source && !isNil(source.owner)) {
_otherDetails.push({
const _otherDetails: ExtraInfo[] = [
{
key: 'Owner',
value: getOwnerValue(source.owner as EntityReference),
placeholderText: getEntityPlaceHolder(
@ -89,8 +78,16 @@ const TableDataCardV2: React.FC<TableDataCardPropsV2> = ({
source.owner?.type === OwnerType.USER
? source.owner?.name
: undefined,
});
}
},
{
key: 'Tier',
value: source.tier
? isString(source.tier)
? source.tier
: source.tier?.tagFQN.split(FQN_SEPARATOR_CHAR)[1]
: '',
},
];
if ('usageSummary' in source) {
_otherDetails.push({
@ -110,7 +107,8 @@ const TableDataCardV2: React.FC<TableDataCardPropsV2> = ({
return _otherDetails;
}, [source]);
const handleLinkClick = () => {
const handleLinkClick = (e: React.MouseEvent) => {
e.stopPropagation();
if (location.pathname.includes(ROUTES.TOUR)) {
AppState.currentTourPage = CurrentTourPageType.DATASET_PAGE;
}
@ -145,7 +143,9 @@ const TableDataCardV2: React.FC<TableDataCardPropsV2> = ({
<div
className="tw-bg-white tw-p-3 tw-border tw-border-main tw-rounded-md"
data-testid="table-data-card"
onClick={() => handleSummaryPanelDisplay(source as Table)}>
onClick={() => {
handleSummaryPanelDisplay && handleSummaryPanelDisplay(source as Table);
}}>
<div>
{'databaseSchema' in source && 'database' in source && (
<span

View File

@ -68,5 +68,5 @@ export interface SearchedDataProps {
showOnboardingTemplate?: boolean;
showOnlyChildren?: boolean;
isFilterSelected: boolean;
handleSummaryPanelDisplay: (source: Table) => void;
handleSummaryPanelDisplay?: (source: Table) => void;
}

View File

@ -45,6 +45,7 @@ export const ADD_USER_CONTAINER_HEIGHT = 250;
export const INGESTION_PROGRESS_START_VAL = 20;
export const INGESTION_PROGRESS_END_VAL = 80;
export const DEPLOYED_PROGRESS_VAL = 100;
export const MAX_CHAR_LIMIT_ENTITY_SUMMARY = 130;
export const LOCALSTORAGE_RECENTLY_VIEWED = `recentlyViewedData_${COOKIE_VERSION}`;
export const LOCALSTORAGE_RECENTLY_SEARCHED = `recentlySearchedData_${COOKIE_VERSION}`;
export const LOCALSTORAGE_USER_PROFILES = 'userProfiles';