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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -162,44 +162,16 @@ describe('TableSummary component tests', () => {
render(<TableSummary entityDetails={mockTableEntityDetails} />);
});
const rowCountLabel = screen.getByTestId('label.entity-count-label');
const colCountLabel = screen.getByTestId('label.column-entity-label');
const tableSampleLabel = screen.getByTestId(
'label.table-entity-text %-label'
);
const testsPassedLabel = screen.getByTestId(
'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'
);
const testsPassedLabel = screen.getByTestId('test-passed');
const testsAbortedLabel = screen.getByTestId('test-aborted');
const testsFailedLabel = screen.getByTestId('test-failed');
const testsPassedValue = screen.getByTestId('test-passed-value');
const testsAbortedValue = screen.getByTestId('test-aborted-value');
const testsFailedValue = screen.getByTestId('test-failed-value');
expect(rowCountLabel).toBeInTheDocument();
expect(colCountLabel).toBeInTheDocument();
expect(tableSampleLabel).toBeInTheDocument();
expect(testsPassedLabel).toBeInTheDocument();
expect(testsAbortedLabel).toBeInTheDocument();
expect(testsFailedLabel).toBeInTheDocument();
expect(rowCountValue).toContainHTML('30');
expect(colCountValue).toContainHTML('2');
expect(tableSampleValue).toContainHTML('100%');
expect(testsPassedValue).toContainHTML('00');
expect(testsAbortedValue).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]}>
<Col span={24}>
<Typography.Text
className="text-base text-grey-muted"
className="text-grey-muted"
data-testid="usage-header">
{t('label.usage')}
</Typography.Text>

View File

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

View File

@ -151,7 +151,7 @@ const ExploreQuickFilters: FC<ExploreQuickFiltersProps> = ({
};
return (
<Space wrap className="explore-quick-filters-container" size={[16, 16]}>
<Space wrap className="explore-quick-filters-container" size={[4, 16]}>
{fields.map((field) => (
<SearchDropdown
highlight
@ -175,12 +175,12 @@ const ExploreQuickFilters: FC<ExploreQuickFiltersProps> = ({
data-testid="show-deleted"
onChange={onChangeShowDeleted}
/>
<Typography.Text className="p-l-xss">
<Typography.Text className="p-l-xs">
{t('label.show-deleted')}
</Typography.Text>
</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"
onClick={onAdvanceSearch}>
{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 { useAuthContext } from 'components/authentication/auth-provider/AuthProvider';
import { ROUTES } from 'constants/constants';
import React from 'react';
import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { NavLink } from 'react-router-dom';
import './left-sidebar.less';
@ -30,6 +30,16 @@ const LeftSidebar = () => {
const { t } = useTranslation();
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 (
<div className="d-flex flex-col justify-between h-full">
<Row className="p-y-sm">
@ -90,7 +100,10 @@ const LeftSidebar = () => {
</div>
</NavLink>
</Col>
<Menu className="left-panel-item" mode="vertical">
<Menu
className="left-panel-item"
mode="vertical"
selectedKeys={subMenuItemSelected}>
<Menu.SubMenu
data-testid="governance"
key="governance"

View File

@ -408,7 +408,7 @@ const NavBar = ({
))}
</div>
<Dropdown
className="cursor-pointer m-r-sm"
className="cursor-pointer m-r-lg"
menu={{ items: supportDropdown }}
overlayStyle={{ width: 175 }}
placement="bottomRight"
@ -420,7 +420,7 @@ const NavBar = ({
</Dropdown>
<Dropdown
className="cursor-pointer m-r-sm"
className="cursor-pointer m-r-lg"
menu={{
items: languageSelectOptions,
onClick: handleLanguageChange,
@ -433,7 +433,7 @@ const NavBar = ({
</Space>
</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
destroyPopupOnHide
dropdownRender={() => (

View File

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

View File

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

View File

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