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

View File

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

View File

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

View File

@ -16,10 +16,18 @@ import {
faSortAmountUpAlt, faSortAmountUpAlt,
} from '@fortawesome/free-solid-svg-icons'; } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Card, Space, Tabs } from 'antd'; import { Card, Tabs } from 'antd';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import unique from 'fork-ts-checker-webpack-plugin/lib/utils/array/unique'; 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 { EntityType } from 'Models';
import React, { useEffect, useMemo, useRef, useState } from 'react'; import React, { useEffect, useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -43,6 +51,7 @@ import {
import { updateTestResults } from '../../utils/DataQualityAndProfilerUtils'; import { updateTestResults } from '../../utils/DataQualityAndProfilerUtils';
import { generateEntityLink } from '../../utils/TableUtils'; import { generateEntityLink } from '../../utils/TableUtils';
import { showErrorToast } from '../../utils/ToastUtils'; import { showErrorToast } from '../../utils/ToastUtils';
import { Entities } from '../AddWebhook/WebhookConstants';
import AdvancedSearch from '../AdvancedSearch/AdvancedSearch.component'; import AdvancedSearch from '../AdvancedSearch/AdvancedSearch.component';
import { FacetFilterProps } from '../common/facetfilter/facetFilter.interface'; import { FacetFilterProps } from '../common/facetfilter/facetFilter.interface';
import PageLayoutV1 from '../containers/PageLayoutV1'; import PageLayoutV1 from '../containers/PageLayoutV1';
@ -293,6 +302,7 @@ const Explore: React.FC<ExploreProps> = ({
} }
onChange={(tab) => { onChange={(tab) => {
tab && onChangeSearchIndex(tab as ExploreSearchIndex); tab && onChangeSearchIndex(tab as ExploreSearchIndex);
setShowSummaryPanel(false);
}}> }}>
{Object.entries(tabsInfo).map(([tabSearchIndex, tabDetail]) => ( {Object.entries(tabsInfo).map(([tabSearchIndex, tabDetail]) => (
<Tabs.TabPane <Tabs.TabPane
@ -314,10 +324,9 @@ const Explore: React.FC<ExploreProps> = ({
/> />
))} ))}
</Tabs> </Tabs>
<Space>
<div <div
style={{ style={{
marginRight: showSummaryPanel ? '380px' : '', marginRight: showSummaryPanel ? '390px' : '',
}}> }}>
<AdvancedSearch <AdvancedSearch
jsonTree={advancedSearchJsonTree} jsonTree={advancedSearchJsonTree}
@ -333,7 +342,11 @@ const Explore: React.FC<ExploreProps> = ({
showResultCount showResultCount
currentPage={page} currentPage={page}
data={searchResults?.hits.hits ?? []} data={searchResults?.hits.hits ?? []}
handleSummaryPanelDisplay={handleSummaryPanelDisplay} handleSummaryPanelDisplay={
tab === toLower(Entities.table)
? handleSummaryPanelDisplay
: undefined
}
paginate={(value) => { paginate={(value) => {
if (isNumber(value)) { if (isNumber(value)) {
onChangePage(value); onChangePage(value);
@ -347,13 +360,14 @@ const Explore: React.FC<ExploreProps> = ({
<Loader /> <Loader />
)} )}
</div> </div>
{tab === toLower(Entities.table) && (
<EntitySummaryPanel <EntitySummaryPanel
entityDetails={entityDetails || ({} as Table)} entityDetails={entityDetails || ({} as Table)}
handleClosePanel={handleClosePanel} handleClosePanel={handleClosePanel}
overallSummery={overallSummery} overallSummery={overallSummery}
showPanel={showSummaryPanel} showPanel={showSummaryPanel}
/> />
</Space> )}
</PageLayoutV1> </PageLayoutV1>
); );
}; };

View File

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

View File

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

View File

@ -68,5 +68,5 @@ export interface SearchedDataProps {
showOnboardingTemplate?: boolean; showOnboardingTemplate?: boolean;
showOnlyChildren?: boolean; showOnlyChildren?: boolean;
isFilterSelected: 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_START_VAL = 20;
export const INGESTION_PROGRESS_END_VAL = 80; export const INGESTION_PROGRESS_END_VAL = 80;
export const DEPLOYED_PROGRESS_VAL = 100; 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_VIEWED = `recentlyViewedData_${COOKIE_VERSION}`;
export const LOCALSTORAGE_RECENTLY_SEARCHED = `recentlySearchedData_${COOKIE_VERSION}`; export const LOCALSTORAGE_RECENTLY_SEARCHED = `recentlySearchedData_${COOKIE_VERSION}`;
export const LOCALSTORAGE_USER_PROFILES = 'userProfiles'; export const LOCALSTORAGE_USER_PROFILES = 'userProfiles';