feat: update explore entity summary panel design (#11851)

* feat: explore page new design

* fix: update explore data card

* fix: jest and cypress test

* fix: revert lineage changes

* fix: remove unused component

* fix: minor css fix

* fix: cypress tests

* fix: code smells

* fix: css issues

* fix: update summary panel styling

* fix: submenu highlight issue

* fix: update quick filters padding

* fix: sonar fixes

* fix: sonar fixes

* fix: update navbar style

* fix: css issues

* fix: jest test

* fix: header styling
This commit is contained in:
karanh37 2023-06-02 00:56:34 +05:30 committed by GitHub
parent 25370156c1
commit ca93d96cb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 233 additions and 277 deletions

View File

@ -56,7 +56,7 @@ function ContainerSummary({
<> <>
<Row className="m-md" gutter={[0, 4]}> <Row className="m-md" gutter={[0, 4]}>
<Col span={24}> <Col span={24}>
<Row> <Row gutter={[0, 4]}>
{entityInfo.map((info) => { {entityInfo.map((info) => {
const isOwner = info.name === t('label.owner'); const isOwner = info.name === t('label.owner');
@ -107,10 +107,10 @@ function ContainerSummary({
</Row> </Row>
<Divider className="m-y-xs" /> <Divider className="m-y-xs" />
<Row className="m-md" gutter={[0, 16]}> <Row className="m-md" gutter={[0, 8]}>
<Col span={24}> <Col span={24}>
<Typography.Text <Typography.Text
className="text-base text-grey-muted" className="text-grey-muted"
data-testid="schema-header"> data-testid="schema-header">
{t('label.schema')} {t('label.schema')}
</Typography.Text> </Typography.Text>

View File

@ -172,10 +172,10 @@ function DashboardSummary({
</> </>
) : null} ) : null}
<Row className="m-md" gutter={[0, 16]}> <Row className="m-md" gutter={[0, 8]}>
<Col span={24}> <Col span={24}>
<Typography.Text <Typography.Text
className="text-base text-grey-muted" className="text-grey-muted"
data-testid="charts-header"> data-testid="charts-header">
{t('label.chart-plural')} {t('label.chart-plural')}
</Typography.Text> </Typography.Text>
@ -187,10 +187,10 @@ function DashboardSummary({
<Divider className="m-y-xs" /> <Divider className="m-y-xs" />
<Row className="m-md" gutter={[0, 16]}> <Row className="m-md" gutter={[0, 8]}>
<Col span={24}> <Col span={24}>
<Typography.Text <Typography.Text
className="text-base text-grey-muted" className="text-grey-muted"
data-testid="data-model-header"> data-testid="data-model-header">
{t('label.data-model-plural')} {t('label.data-model-plural')}
</Typography.Text> </Typography.Text>

View File

@ -70,7 +70,7 @@ const DataModelSummary = ({
<> <>
<Row className="m-md" gutter={[0, 4]}> <Row className="m-md" gutter={[0, 4]}>
<Col span={24}> <Col span={24}>
<Row> <Row gutter={[0, 4]}>
{entityInfo.map((info) => { {entityInfo.map((info) => {
const isOwner = info.name === t('label.owner'); const isOwner = info.name === t('label.owner');
@ -135,7 +135,7 @@ const DataModelSummary = ({
<Divider className="m-y-xs" /> <Divider className="m-y-xs" />
<Row className="m-md" gutter={[0, 16]}> <Row className="m-md" gutter={[0, 8]}>
<Col span={24}> <Col span={24}>
<Typography.Text <Typography.Text
className="text-base text-grey-muted" className="text-base text-grey-muted"

View File

@ -23,7 +23,7 @@ import { get } from 'lodash';
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { Link, useParams } from 'react-router-dom'; import { Link, useParams } from 'react-router-dom';
import { getEntityLinkFromType, getEntityName } from 'utils/EntityUtils'; import { getEntityLinkFromType, getEntityName } from 'utils/EntityUtils';
import { getEncodedFqn } from 'utils/StringsUtils'; import { getEncodedFqn, stringToHTML } from 'utils/StringsUtils';
import { Mlmodel } from '../../../generated/entity/data/mlmodel'; import { Mlmodel } from '../../../generated/entity/data/mlmodel';
import { Pipeline } from '../../../generated/entity/data/pipeline'; import { Pipeline } from '../../../generated/entity/data/pipeline';
import { Topic } from '../../../generated/entity/data/topic'; import { Topic } from '../../../generated/entity/data/topic';
@ -110,7 +110,7 @@ export default function EntitySummaryPanel({
data-testid="entity-link" data-testid="entity-link"
to={entityLink}> to={entityLink}>
<Typography.Text className="m-b-0 d-block entity-header-display-name"> <Typography.Text className="m-b-0 d-block entity-header-display-name">
{getEntityName(entityDetails.details)} {stringToHTML(getEntityName(entityDetails.details))}
</Typography.Text> </Typography.Text>
</Link> </Link>
} }

View File

@ -13,19 +13,13 @@
@import url('../../../styles/variables.less'); @import url('../../../styles/variables.less');
@summary-panel-offset: 80px; // (topnav height) 64px + page padding top and bottom 16px @summary-panel-offset: 80px; // (topnav height) 64px + page padding top and bottom 16px
@label-color: #6b7280;
@successColor: #28a745;
@failedColor: #cb2431;
@abortedColor: #efae2f;
@section-header-color: #6b7280;
.summary-panel-container { .summary-panel-container {
margin-right: -8px; margin-right: -8px;
position: sticky; position: sticky;
height: calc(100vh - @summary-panel-offset); height: calc(100vh - @summary-panel-offset);
top: 2px; // To show the border properly
z-index: 9; z-index: 9;
box-shadow: @panels-shadow-color; box-shadow: none;
border: @global-border; border: @global-border;
border-top: none; border-top: none;
font-size: 14px; font-size: 14px;
@ -35,7 +29,7 @@
scrollbar-width: none; scrollbar-width: none;
.ant-drawer-content-wrapper { .ant-drawer-content-wrapper {
box-shadow: -2px 2px 4px rgba(0, 0, 0, 0.12); box-shadow: none;
} }
.ant-drawer-body { .ant-drawer-body {
padding: unset; padding: unset;
@ -48,16 +42,6 @@
font-weight: 700; font-weight: 700;
} }
.success {
color: @successColor;
}
.failed {
color: @failed-color;
}
.aborted {
color: @abortedColor;
}
.entity-title { .entity-title {
font-weight: 500; font-weight: 500;
} }
@ -66,11 +50,6 @@
margin: 16px 0px; margin: 16px 0px;
} }
div.ant-typography {
margin-top: 16px;
margin-bottom: 0px;
}
.close-icon { .close-icon {
position: absolute; position: absolute;
top: 12px; top: 12px;

View File

@ -54,6 +54,7 @@ jest.mock('utils/EntityUtils', () => ({
})); }));
jest.mock('utils/StringsUtils', () => ({ jest.mock('utils/StringsUtils', () => ({
getEncodedFqn: jest.fn().mockImplementation((fqn) => fqn), getEncodedFqn: jest.fn().mockImplementation((fqn) => fqn),
stringToHTML: jest.fn(),
})); }));
jest.mock('./PipelineSummary/PipelineSummary.component', () => jest.mock('./PipelineSummary/PipelineSummary.component', () =>

View File

@ -77,7 +77,7 @@ function GlossaryTermSummary({
<Row className="m-md" gutter={[0, 16]}> <Row className="m-md" gutter={[0, 16]}>
<Col span={24}> <Col span={24}>
<Typography.Text <Typography.Text
className="text-base text-grey-muted" className="text-grey-muted"
data-testid="reviewer-header"> data-testid="reviewer-header">
{t('label.reviewer-plural')} {t('label.reviewer-plural')}
</Typography.Text> </Typography.Text>
@ -117,7 +117,7 @@ function GlossaryTermSummary({
<Row className="m-md" gutter={[0, 8]}> <Row className="m-md" gutter={[0, 8]}>
<Col span={24}> <Col span={24}>
<Typography.Text <Typography.Text
className="text-base text-grey-muted" className="text-grey-muted"
data-testid="synonyms-header"> data-testid="synonyms-header">
{t('label.synonym-plural')} {t('label.synonym-plural')}
</Typography.Text> </Typography.Text>
@ -145,10 +145,10 @@ function GlossaryTermSummary({
<Divider className="m-y-xs" /> <Divider className="m-y-xs" />
<Row className="m-md" gutter={[0, 16]}> <Row className="m-md" gutter={[0, 8]}>
<Col span={24}> <Col span={24}>
<Typography.Text <Typography.Text
className="text-base text-grey-muted" className="text-grey-muted"
data-testid="children-header"> data-testid="children-header">
{t('label.children')} {t('label.children')}
</Typography.Text> </Typography.Text>

View File

@ -70,7 +70,7 @@ function MlModelSummary({
<> <>
<Row className="m-md" gutter={[0, 4]}> <Row className="m-md" gutter={[0, 4]}>
<Col span={24}> <Col span={24}>
<Row> <Row gutter={[0, 4]}>
{entityInfo.map((info) => { {entityInfo.map((info) => {
const isOwner = info.name === t('label.owner'); const isOwner = info.name === t('label.owner');
@ -133,10 +133,10 @@ function MlModelSummary({
</> </>
) : null} ) : null}
<Row className="m-md" gutter={[0, 16]}> <Row className="m-md" gutter={[0, 8]}>
<Col span={24}> <Col span={24}>
<Typography.Text <Typography.Text
className="text-base text-grey-muted" className="text-grey-muted"
data-testid="features-header"> data-testid="features-header">
{t('label.feature-plural')} {t('label.feature-plural')}
</Typography.Text> </Typography.Text>

View File

@ -65,7 +65,7 @@ function PipelineSummary({
<> <>
<Row className="m-md" gutter={[0, 4]}> <Row className="m-md" gutter={[0, 4]}>
<Col span={24}> <Col span={24}>
<Row> <Row gutter={[0, 4]}>
{entityInfo.map((info) => { {entityInfo.map((info) => {
const isOwner = info.name === t('label.owner'); const isOwner = info.name === t('label.owner');
@ -137,10 +137,10 @@ function PipelineSummary({
</> </>
) : null} ) : null}
<Row className="m-md" gutter={[0, 16]}> <Row className="m-md" gutter={[0, 8]}>
<Col span={24}> <Col span={24}>
<Typography.Text <Typography.Text
className="text-base text-grey-muted" className="text-grey-muted"
data-testid="tasks-header"> data-testid="tasks-header">
{t('label.task-plural')} {t('label.task-plural')}
</Typography.Text> </Typography.Text>

View File

@ -12,19 +12,31 @@
*/ */
.summary-list-collapse { .summary-list-collapse {
&.ant-collapse {
background-color: rgba(0, 0, 0, 0.02);
margin-bottom: 16px;
padding: 16px;
.ant-collapse-item { .ant-collapse-item {
.ant-collapse-header { .ant-collapse-header {
padding: 0px; padding: 0;
.summary-list-item-container {
padding: 0;
margin-bottom: 0;
}
}
.summary-list-item-container {
background-color: inherit;
margin-bottom: 0;
}
}
}
.summary-list-collapse {
margin-bottom: 0;
}
}
.ant-collapse-arrow { .summary-list-item-container {
margin-right: 8px; background-color: rgba(0, 0, 0, 0.02);
} margin-bottom: 16px;
} padding: 16px;
.ant-collapse-content {
.ant-collapse-content-box {
padding: 0px;
padding-left: 20px;
}
}
}
} }

View File

@ -11,7 +11,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { Col, Divider, Row, Space, Typography } from 'antd'; import { Col, Row, Space, Typography } from 'antd';
import TagsViewer from 'components/Tag/TagsViewer/tags-viewer'; import TagsViewer from 'components/Tag/TagsViewer/tags-viewer';
import React from 'react'; import React from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -31,8 +31,12 @@ function SummaryListItem({
return ( return (
<Col key={entityDetails.name} span={24}> <Col key={entityDetails.name} span={24}>
<Row gutter={[0, 4]}> <div className="summary-list-item-container">
<Col data-testid="title-container" span={24}> <Row gutter={[0, 8]}>
<Col
className="d-flex items-center"
data-testid="title-container"
span={24}>
{isColumnsData && {isColumnsData &&
prepareConstraintIcon( prepareConstraintIcon(
entityDetails.name, entityDetails.name,
@ -42,30 +46,16 @@ function SummaryListItem({
'14px' '14px'
)} )}
{entityDetails.title} {entityDetails.title}
</Col>
<Col span={24}>
<Row className="text-xs font-thin" gutter={[4, 4]}>
<Col className="self-center">
{entityDetails.type && ( {entityDetails.type && (
<Space className="h-6" size={4}> <Typography.Text
<Text className="text-grey-muted">{`${t( className="text-grey-muted text-xs p-l-xs"
'label.type' data-testid="entity-type">{`(${entityDetails.type})`}</Typography.Text>
)}:`}</Text>
<Text
className="font-medium text-grey-body"
data-testid="entity-type">
{entityDetails.type}
</Text>
</Space>
)} )}
</Col> </Col>
{entityDetails.algorithm && ( {entityDetails.algorithm && (
<> <Col span={24}>
<Col className="self-center">
<Divider type="vertical" />
</Col>
<Col className="self-center">
<Space className="h-6" size={4}> <Space className="h-6" size={4}>
<Text className="text-grey-muted">{`${t( <Text className="text-grey-muted">{`${t(
'label.algorithm' 'label.algorithm'
@ -77,27 +67,10 @@ function SummaryListItem({
</Text> </Text>
</Space> </Space>
</Col> </Col>
</>
)} )}
{entityDetails.tags && entityDetails.tags.length !== 0 && (
<>
<Col className="self-center">
<Divider type="vertical" />
</Col>
<Col className="flex-grow">
<TagsViewer
sizeCap={-1}
tags={(entityDetails.tags || []).map((tag) =>
getTagValue(tag)
)}
/>
</Col>
</>
)}
</Row>
</Col>
<Col span={24}> <Col span={24}>
<Paragraph className="text-grey-body"> <Paragraph className="text-grey-body m-y-0">
{entityDetails.description ? ( {entityDetails.description ? (
<RichTextEditorPreviewer <RichTextEditorPreviewer
markdown={entityDetails.description || ''} markdown={entityDetails.description || ''}
@ -108,8 +81,17 @@ function SummaryListItem({
)} )}
</Paragraph> </Paragraph>
</Col> </Col>
{entityDetails.tags && entityDetails.tags.length !== 0 && (
<Col className="flex-grow" span={24}>
<TagsViewer
sizeCap={2}
tags={(entityDetails.tags || []).map((tag) => getTagValue(tag))}
type="border"
/>
</Col>
)}
</Row> </Row>
<Divider className="m-y-xs" /> </div>
</Col> </Col>
); );
} }

View File

@ -47,20 +47,15 @@ import { INITIAL_TEST_RESULT_SUMMARY } from '../../../../constants/profiler.cons
import { SummaryEntityType } from '../../../../enums/EntitySummary.enum'; import { SummaryEntityType } from '../../../../enums/EntitySummary.enum';
import { Table } from '../../../../generated/entity/data/table'; import { Table } from '../../../../generated/entity/data/table';
import { Include } from '../../../../generated/type/include'; import { Include } from '../../../../generated/type/include';
import { import { formTwoDigitNmber as formTwoDigitNumber } from '../../../../utils/CommonUtils';
formatNumberWithComma,
formTwoDigitNmber as formTwoDigitNumber,
} from '../../../../utils/CommonUtils';
import { updateTestResults } from '../../../../utils/DataQualityAndProfilerUtils'; import { updateTestResults } from '../../../../utils/DataQualityAndProfilerUtils';
import { getFormattedEntityData } from '../../../../utils/EntitySummaryPanelUtils'; import { getFormattedEntityData } from '../../../../utils/EntitySummaryPanelUtils';
import { generateEntityLink } from '../../../../utils/TableUtils'; import { generateEntityLink } from '../../../../utils/TableUtils';
import { showErrorToast } from '../../../../utils/ToastUtils'; import { showErrorToast } from '../../../../utils/ToastUtils';
import { import { TableTestsType } from '../../../TableProfiler/TableProfiler.interface';
OverallTableSummeryType,
TableTestsType,
} from '../../../TableProfiler/TableProfiler.interface';
import SummaryList from '../SummaryList/SummaryList.component'; import SummaryList from '../SummaryList/SummaryList.component';
import { BasicEntityInfo } from '../SummaryList/SummaryList.interface'; import { BasicEntityInfo } from '../SummaryList/SummaryList.interface';
import './table-summary.less';
import { TableSummaryProps } from './TableSummary.interface'; import { TableSummaryProps } from './TableSummary.interface';
function TableSummary({ function TableSummary({
@ -101,7 +96,9 @@ function TableSummary({
useEffect(() => { useEffect(() => {
if (tableDetails.id && !isTourPage) { if (tableDetails.id && !isTourPage) {
fetchResourcePermission(); fetchResourcePermission().catch(() => {
// error handled in parent
});
} }
if (isTourPage) { if (isTourPage) {
@ -178,49 +175,6 @@ function TableSummary({
} }
}, [entityDetails]); }, [entityDetails]);
const overallSummary: OverallTableSummeryType[] | undefined = useMemo(() => {
if (isUndefined(tableDetails.profile)) {
return undefined;
}
return [
{
title: t('label.entity-count', {
entity: t('label.row'),
}),
value: formatNumberWithComma(tableDetails?.profile?.rowCount ?? 0),
},
{
title: t('label.column-entity', {
entity: t('label.count'),
}),
value:
tableDetails?.profile?.columnCount ?? entityDetails.columns.length,
},
{
title: `${t('label.table-entity-text', {
entityText: t('label.sample'),
})} %`,
value: `${tableDetails?.profile?.profileSample ?? 100}%`,
},
{
title: `${t('label.test-plural')} ${t('label.passed')}`,
value: formTwoDigitNumber(tableTests.results.success),
className: 'success',
},
{
title: `${t('label.test-plural')} ${t('label.aborted')}`,
value: formTwoDigitNumber(tableTests.results.aborted),
className: 'aborted',
},
{
title: `${t('label.test-plural')} ${t('label.failed')}`,
value: formTwoDigitNumber(tableTests.results.failed),
className: 'failed',
},
];
}, [tableDetails, tableTests, viewProfilerPermission]);
const profilerSummary = useMemo(() => { const profilerSummary = useMemo(() => {
if (!viewProfilerPermission) { if (!viewProfilerPermission) {
return ( return (
@ -232,40 +186,47 @@ function TableSummary({
); );
} }
return isUndefined(overallSummary) ? ( return isUndefined(tableDetails.profile) ? (
<Typography.Text <Typography.Text
className="text-grey-body" className="text-grey-body"
data-testid="no-profiler-enabled-message"> data-testid="no-profiler-enabled-message">
{t('message.no-profiler-enabled-summary-message')} {t('message.no-profiler-enabled-summary-message')}
</Typography.Text> </Typography.Text>
) : ( ) : (
<Row gutter={[0, 16]}> <div className="d-flex justify-between">
{overallSummary.map((field) => ( <div className="profiler-item green" data-testid="test-passed">
<Col key={field.title} span={10}> <div
<Row> className="font-semibold text-lg"
<Col span={24}> data-testid="test-passed-value">
<Typography.Text {formTwoDigitNumber(tableTests.results.success)}
className="text-grey-muted" </div>
data-testid={`${field.title}-label`}> <div className="text-xs text-grey-muted">{`${t(
{field.title} 'label.test-plural'
</Typography.Text> )} ${t('label.passed')}`}</div>
</Col> </div>
<Col span={24}> <div className="profiler-item amber" data-testid="test-aborted">
<Typography.Text <div
className={classNames( className="font-semibold text-lg"
'summary-panel-statistics-count', data-testid="test-aborted-value">
field.className {formTwoDigitNumber(tableTests.results.aborted)}
)} </div>
data-testid={`${field.title}-value`}> <div className="text-xs text-grey-muted">{`${t(
{field.value} 'label.test-plural'
</Typography.Text> )} ${t('label.aborted')}`}</div>
</Col> </div>
</Row> <div className="profiler-item red" data-testid="test-failed">
</Col> <div
))} className="font-semibold text-lg"
</Row> data-testid="test-failed-value">
{formTwoDigitNumber(tableTests.results.failed)}
</div>
<div className="text-xs text-grey-muted">{`${t(
'label.test-plural'
)} ${t('label.failed')}`}</div>
</div>
</div>
); );
}, [overallSummary, viewProfilerPermission]); }, [tableDetails, tableTests, viewProfilerPermission]);
const { columns } = tableDetails; const { columns } = tableDetails;
@ -307,7 +268,7 @@ function TableSummary({
<> <>
<Row className="m-md" gutter={[0, 4]}> <Row className="m-md" gutter={[0, 4]}>
<Col span={24}> <Col span={24}>
<Row> <Row gutter={[0, 4]}>
{entityInfo.map((info) => { {entityInfo.map((info) => {
const isOwner = info.name === t('label.owner'); const isOwner = info.name === t('label.owner');
@ -320,7 +281,7 @@ function TableSummary({
gutter={[16, 32]}> gutter={[16, 32]}>
{!isOwner ? ( {!isOwner ? (
<Col data-testid={`${info.name}-label`} span={8}> <Col data-testid={`${info.name}-label`} span={8}>
<Typography.Text className="text-grey-muted"> <Typography.Text className="summary-item-key text-grey-muted">
{info.name} {info.name}
</Typography.Text> </Typography.Text>
</Col> </Col>
@ -343,9 +304,12 @@ function TableSummary({
</Link> </Link>
) : ( ) : (
<Typography.Text <Typography.Text
className={classNames('text-grey-muted', { className={classNames(
'summary-item-value text-grey-muted',
{
'text-grey-body': !isOwner, 'text-grey-body': !isOwner,
})}> }
)}>
{info.value} {info.value}
</Typography.Text> </Typography.Text>
)} )}
@ -373,7 +337,7 @@ function TableSummary({
<Row className="m-md" gutter={[0, 16]}> <Row className="m-md" gutter={[0, 16]}>
<Col span={24}> <Col span={24}>
<Typography.Text <Typography.Text
className="text-base text-grey-muted" className="text-grey-muted"
data-testid="profiler-header"> data-testid="profiler-header">
{t('label.profiler-amp-data-quality')} {t('label.profiler-amp-data-quality')}
</Typography.Text> </Typography.Text>
@ -383,10 +347,10 @@ function TableSummary({
<Divider className="m-y-xs" /> <Divider className="m-y-xs" />
<Row className="m-md" gutter={[0, 16]}> <Row className="m-md" gutter={[0, 8]}>
<Col span={24}> <Col span={24}>
<Typography.Text <Typography.Text
className="text-base text-grey-muted" className="text-grey-muted"
data-testid="schema-header"> data-testid="schema-header">
{t('label.schema')} {t('label.schema')}
</Typography.Text> </Typography.Text>

View File

@ -162,44 +162,16 @@ describe('TableSummary component tests', () => {
render(<TableSummary entityDetails={mockTableEntityDetails} />); render(<TableSummary entityDetails={mockTableEntityDetails} />);
}); });
const rowCountLabel = screen.getByTestId('label.entity-count-label'); const testsPassedLabel = screen.getByTestId('test-passed');
const colCountLabel = screen.getByTestId('label.column-entity-label'); const testsAbortedLabel = screen.getByTestId('test-aborted');
const tableSampleLabel = screen.getByTestId( const testsFailedLabel = screen.getByTestId('test-failed');
'label.table-entity-text %-label' const testsPassedValue = screen.getByTestId('test-passed-value');
); const testsAbortedValue = screen.getByTestId('test-aborted-value');
const testsPassedLabel = screen.getByTestId( const testsFailedValue = screen.getByTestId('test-failed-value');
'label.test-plural label.passed-label'
);
const testsAbortedLabel = screen.getByTestId(
'label.test-plural label.aborted-label'
);
const testsFailedLabel = screen.getByTestId(
'label.test-plural label.failed-label'
);
const rowCountValue = screen.getByTestId('label.entity-count-value');
const colCountValue = screen.getByTestId('label.column-entity-value');
const tableSampleValue = screen.getByTestId(
'label.table-entity-text %-value'
);
const testsPassedValue = screen.getByTestId(
'label.test-plural label.passed-value'
);
const testsAbortedValue = screen.getByTestId(
'label.test-plural label.aborted-value'
);
const testsFailedValue = screen.getByTestId(
'label.test-plural label.failed-value'
);
expect(rowCountLabel).toBeInTheDocument();
expect(colCountLabel).toBeInTheDocument();
expect(tableSampleLabel).toBeInTheDocument();
expect(testsPassedLabel).toBeInTheDocument(); expect(testsPassedLabel).toBeInTheDocument();
expect(testsAbortedLabel).toBeInTheDocument(); expect(testsAbortedLabel).toBeInTheDocument();
expect(testsFailedLabel).toBeInTheDocument(); expect(testsFailedLabel).toBeInTheDocument();
expect(rowCountValue).toContainHTML('30');
expect(colCountValue).toContainHTML('2');
expect(tableSampleValue).toContainHTML('100%');
expect(testsPassedValue).toContainHTML('00'); expect(testsPassedValue).toContainHTML('00');
expect(testsAbortedValue).toContainHTML('00'); expect(testsAbortedValue).toContainHTML('00');
expect(testsFailedValue).toContainHTML('00'); expect(testsFailedValue).toContainHTML('00');

View File

@ -0,0 +1,36 @@
/*
* 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');
@green: #ebf9f4;
@amber: #fbf2db;
@red: #faf1f8;
.profiler-item {
width: 100px;
height: 80px;
text-align: center;
border: 1px solid @border-color;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
border-radius: 10px;
&.green {
background: @green;
}
&.amber {
background: @amber;
}
&.red {
background: @red;
}
}

View File

@ -71,7 +71,7 @@ function TagsSummary({ entityDetails, isLoading }: TagsSummaryProps) {
<Row className="m-md" gutter={[0, 16]}> <Row className="m-md" gutter={[0, 16]}>
<Col span={24}> <Col span={24}>
<Typography.Text <Typography.Text
className="text-base text-grey-muted" className="text-grey-muted"
data-testid="usage-header"> data-testid="usage-header">
{t('label.usage')} {t('label.usage')}
</Typography.Text> </Typography.Text>

View File

@ -140,7 +140,7 @@ function TopicSummary({
</Col> </Col>
) : null} ) : null}
<Col span={24}> <Col span={24}>
<Row> <Row gutter={[0, 4]}>
{Object.keys(topicConfig).map((fieldName) => { {Object.keys(topicConfig).map((fieldName) => {
const value = const value =
topicConfig[fieldName as keyof TopicConfigObjectInterface]; topicConfig[fieldName as keyof TopicConfigObjectInterface];
@ -177,23 +177,21 @@ function TopicSummary({
</> </>
) : null} ) : null}
<Row className="m-md" gutter={[0, 16]}> <Row className="m-md" gutter={[0, 8]}>
<Col span={24}> <Col span={24}>
<Typography.Text <Typography.Text
className="text-base text-grey-muted" className="text-grey-muted"
data-testid="schema-header"> data-testid="schema-header">
{t('label.schema')} {t('label.schema')}
</Typography.Text> </Typography.Text>
</Col> </Col>
<Col span={24}> <Col span={24}>
{isEmpty(topicDetails?.messageSchema?.schemaFields) ? ( {isEmpty(topicDetails?.messageSchema?.schemaFields) ? (
<div className="m-y-md">
<Typography.Text data-testid="no-data-message"> <Typography.Text data-testid="no-data-message">
<Typography.Text className="text-grey-body"> <Typography.Text className="text-grey-body">
{t('message.no-data-available')} {t('message.no-data-available')}
</Typography.Text> </Typography.Text>
</Typography.Text> </Typography.Text>
</div>
) : ( ) : (
<SummaryList formattedEntityData={formattedSchemaFieldsData} /> <SummaryList formattedEntityData={formattedSchemaFieldsData} />
)} )}

View File

@ -151,7 +151,7 @@ const ExploreQuickFilters: FC<ExploreQuickFiltersProps> = ({
}; };
return ( return (
<Space wrap className="explore-quick-filters-container" size={[16, 16]}> <Space wrap className="explore-quick-filters-container" size={[4, 16]}>
{fields.map((field) => ( {fields.map((field) => (
<SearchDropdown <SearchDropdown
highlight highlight
@ -175,12 +175,12 @@ const ExploreQuickFilters: FC<ExploreQuickFiltersProps> = ({
data-testid="show-deleted" data-testid="show-deleted"
onChange={onChangeShowDeleted} onChange={onChangeShowDeleted}
/> />
<Typography.Text className="p-l-xss"> <Typography.Text className="p-l-xs">
{t('label.show-deleted')} {t('label.show-deleted')}
</Typography.Text> </Typography.Text>
</span> </span>
<span <span
className="tw-text-primary tw-self-center tw-cursor-pointer" className="text-primary self-center cursor-pointer p-l-xs"
data-testid="advance-search-button" data-testid="advance-search-button"
onClick={onAdvanceSearch}> onClick={onAdvanceSearch}>
{t('label.advanced-entity', { {t('label.advanced-entity', {

View File

@ -21,7 +21,7 @@ import { ReactComponent as InsightsIcon } from 'assets/svg/lampcharge.svg';
import { ReactComponent as LogoutIcon } from 'assets/svg/logout.svg'; import { ReactComponent as LogoutIcon } from 'assets/svg/logout.svg';
import { useAuthContext } from 'components/authentication/auth-provider/AuthProvider'; import { useAuthContext } from 'components/authentication/auth-provider/AuthProvider';
import { ROUTES } from 'constants/constants'; import { ROUTES } from 'constants/constants';
import React from 'react'; import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { NavLink } from 'react-router-dom'; import { NavLink } from 'react-router-dom';
import './left-sidebar.less'; import './left-sidebar.less';
@ -30,6 +30,16 @@ const LeftSidebar = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const { onLogoutHandler } = useAuthContext(); const { onLogoutHandler } = useAuthContext();
const subMenuItemSelected = useMemo(() => {
if (location.pathname.startsWith('/glossary')) {
return ['glossary'];
} else if (location.pathname.startsWith('/tags')) {
return ['tags'];
}
return [];
}, [location.pathname]);
return ( return (
<div className="d-flex flex-col justify-between h-full"> <div className="d-flex flex-col justify-between h-full">
<Row className="p-y-sm"> <Row className="p-y-sm">
@ -90,7 +100,10 @@ const LeftSidebar = () => {
</div> </div>
</NavLink> </NavLink>
</Col> </Col>
<Menu className="left-panel-item" mode="vertical"> <Menu
className="left-panel-item"
mode="vertical"
selectedKeys={subMenuItemSelected}>
<Menu.SubMenu <Menu.SubMenu
data-testid="governance" data-testid="governance"
key="governance" key="governance"

View File

@ -408,7 +408,7 @@ const NavBar = ({
))} ))}
</div> </div>
<Dropdown <Dropdown
className="cursor-pointer m-r-sm" className="cursor-pointer m-r-lg"
menu={{ items: supportDropdown }} menu={{ items: supportDropdown }}
overlayStyle={{ width: 175 }} overlayStyle={{ width: 175 }}
placement="bottomRight" placement="bottomRight"
@ -420,7 +420,7 @@ const NavBar = ({
</Dropdown> </Dropdown>
<Dropdown <Dropdown
className="cursor-pointer m-r-sm" className="cursor-pointer m-r-lg"
menu={{ menu={{
items: languageSelectOptions, items: languageSelectOptions,
onClick: handleLanguageChange, onClick: handleLanguageChange,
@ -433,7 +433,7 @@ const NavBar = ({
</Space> </Space>
</Dropdown> </Dropdown>
<button className="focus:tw-no-underline hover:tw-underline flex-shrink m-r-sm"> <button className="focus:tw-no-underline hover:tw-underline flex-shrink m-r-lg">
<Dropdown <Dropdown
destroyPopupOnHide destroyPopupOnHide
dropdownRender={() => ( dropdownRender={() => (

View File

@ -390,6 +390,7 @@ a[href].link-text-grey,
font-size: 12px; font-size: 12px;
.link-title { .link-title {
font-size: inherit !important; font-size: inherit !important;
color: @text-grey-muted !important;
} }
} }

View File

@ -181,10 +181,6 @@ pre {
.appbar-search .rc-virtual-list-holder { .appbar-search .rc-virtual-list-holder {
max-height: max-content; max-height: max-content;
} }
.suggestions-menu {
left: 0;
top: 37px;
}
/* Breadcrumb */ /* Breadcrumb */
.breadcrumb { .breadcrumb {

View File

@ -65,7 +65,7 @@ export const getFormattedEntityData = (
name: chart.name, name: chart.name,
title: ( title: (
<Link target="_blank" to={{ pathname: chart.chartUrl }}> <Link target="_blank" to={{ pathname: chart.chartUrl }}>
<div className="d-flex items-center m-b-xs"> <div className="d-flex items-center">
<Text className="entity-title text-primary font-medium m-r-xss"> <Text className="entity-title text-primary font-medium m-r-xss">
{getTitleName(chart)} {getTitleName(chart)}
</Text> </Text>
@ -88,8 +88,10 @@ export const getFormattedEntityData = (
name: task.name, name: task.name,
title: ( title: (
<Link target="_blank" to={{ pathname: task.taskUrl }}> <Link target="_blank" to={{ pathname: task.taskUrl }}>
<div className="d-flex items-center m-b-xs"> <div className="d-flex items-center">
<Text className="entity-title text-primary font-medium m-r-xss"> <Text
className="entity-title text-primary font-medium m-r-xss"
ellipsis={{ tooltip: true }}>
{getTitleName(task)} {getTitleName(task)}
</Text> </Text>
<SVGIcons <SVGIcons