MINOR: added domain data in lineage side panel and fix relatedColumn search TableConstraints modal (#18671)

* added domain data in lineage side panel

* localization keys

* fix unit test

* fix unit test and minor improvement around permission in schema page utils

* added the encoding and escape method to query
This commit is contained in:
Ashish Gupta 2024-11-19 17:03:15 +05:30 committed by GitHub
parent ff261fb373
commit 484a9584ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 278 additions and 136 deletions

View File

@ -112,6 +112,7 @@ export class TableClass extends EntityClass {
testSuitePipelineResponseData: unknown[] = [];
testCasesResponseData: unknown[] = [];
queryResponseData: unknown[] = [];
additionalEntityTableResponseData: unknown[] = [];
constructor(name?: string) {
super(EntityTypeEndpoint.Table);
@ -157,6 +158,31 @@ export class TableClass extends EntityClass {
};
}
async createAdditionalTable(
tableData: {
name: string;
displayName: string;
description?: string;
columns?: any[];
databaseSchema?: string;
},
apiContext: APIRequestContext
) {
const entityResponse = await apiContext.post('/api/v1/tables', {
data: {
...this.entity,
...tableData,
},
});
const entity = await entityResponse.json();
this.additionalEntityTableResponseData = [
...this.additionalEntityTableResponseData,
entity,
];
return entity;
}
get() {
return {
service: this.serviceResponseData,

View File

@ -71,7 +71,7 @@ describe('SearchIndexSummary component tests', () => {
const ownerLabel = screen.queryByTestId('label.owner-label');
const tierLabel = screen.getByText('label.tier');
const serviceLabel = screen.getByText('label.service');
const tierValue = screen.getByText('-');
const tierValue = screen.getByTestId('label.tier-value');
const serviceValue = screen.getByText('testES');
const summaryList = screen.getByTestId('SummaryList');
@ -80,7 +80,7 @@ describe('SearchIndexSummary component tests', () => {
expect(fieldsHeader).toBeInTheDocument();
expect(tierLabel).toBeInTheDocument();
expect(serviceLabel).toBeInTheDocument();
expect(tierValue).toBeInTheDocument();
expect(tierValue).toContainHTML('-');
expect(serviceValue).toBeInTheDocument();
expect(summaryList).toBeInTheDocument();
});

View File

@ -12,31 +12,33 @@
*/
import { Col, Divider, Row, Typography } from 'antd';
import { get, isArray, isEmpty } from 'lodash';
import { get, isEmpty } from 'lodash';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { TabSpecificField } from '../../../../enums/entity.enum';
import { SummaryEntityType } from '../../../../enums/EntitySummary.enum';
import { ExplorePageTabs } from '../../../../enums/Explore.enum';
import { TagLabel, Topic } from '../../../../generated/entity/data/topic';
import { getTopicByFqn } from '../../../../rest/topicsAPI';
import {
getFormattedEntityData,
getSortedTagsWithHighlight,
} from '../../../../utils/EntitySummaryPanelUtils';
import { DRAWER_NAVIGATION_OPTIONS } from '../../../../utils/EntityUtils';
import { bytesToSize } from '../../../../utils/StringsUtils';
import { getConfigObject } from '../../../../utils/TopicDetailsUtils';
import {
DRAWER_NAVIGATION_OPTIONS,
getEntityOverview,
} from '../../../../utils/EntityUtils';
import { OwnerLabel } from '../../../common/OwnerLabel/OwnerLabel.component';
import SummaryPanelSkeleton from '../../../common/Skeleton/SummaryPanelSkeleton/SummaryPanelSkeleton.component';
import SummaryTagsDescription from '../../../common/SummaryTagsDescription/SummaryTagsDescription.component';
import { SearchedDataProps } from '../../../SearchedData/SearchedData.interface';
import { TopicConfigObjectInterface } from '../../../Topic/TopicDetails/TopicDetails.interface';
import CommonEntitySummaryInfo from '../CommonEntitySummaryInfo/CommonEntitySummaryInfo';
import SummaryList from '../SummaryList/SummaryList.component';
import { BasicEntityInfo } from '../SummaryList/SummaryList.interface';
interface TopicSummaryProps {
entityDetails: Topic;
componentType?: string;
componentType?: DRAWER_NAVIGATION_OPTIONS;
tags?: TagLabel[];
isLoading?: boolean;
highlights?: SearchedDataProps['data'][number]['highlight'];
@ -57,16 +59,15 @@ function TopicSummary({
() => componentType === DRAWER_NAVIGATION_OPTIONS.explore,
[componentType]
);
const topicConfig = useMemo(() => {
const combined = { ...topicDetails, ...entityDetails };
const configs = getConfigObject(combined);
return {
...configs,
'Retention Size': bytesToSize(configs['Retention Size'] ?? 0),
'Max Message Size': bytesToSize(configs['Max Message Size'] ?? 0),
};
}, [entityDetails, topicDetails]);
const entityInfo = useMemo(
() =>
getEntityOverview(ExplorePageTabs.TOPICS, {
...topicDetails,
...entityDetails,
}),
[topicDetails, entityDetails]
);
const ownerDetails = useMemo(() => {
const owners = entityDetails.owners;
@ -116,29 +117,10 @@ function TopicSummary({
</Col>
) : null}
<Col span={24}>
<Row gutter={[0, 4]}>
{Object.keys(topicConfig).map((fieldName) => {
const value =
topicConfig[fieldName as keyof TopicConfigObjectInterface];
const fieldValue = isArray(value) ? value.join(', ') : value;
return (
<Col key={fieldName} span={24}>
<Row gutter={[16, 32]}>
<Col data-testid={`${fieldName}-label`} span={10}>
<Typography.Text className="text-grey-muted">
{fieldName}
</Typography.Text>
</Col>
<Col data-testid={`${fieldName}-value`} span={14}>
{fieldValue ? fieldValue : '-'}
</Col>
</Row>
</Col>
);
})}
</Row>
<CommonEntitySummaryInfo
componentType={componentType}
entityInfo={entityInfo}
/>
</Col>
</Row>
<Divider className="m-y-xs" />

View File

@ -48,34 +48,31 @@ describe('TopicSummary component tests', () => {
render(<TopicSummary entityDetails={mockTopicEntityDetails} />);
});
const partitionsLabel = await screen.findByTestId('Partitions-label');
const replicationFactorLabel = await screen.findByTestId(
'Replication Factor-label'
const partitionsLabel = screen.getByTestId('label.partition-plural-label');
const replicationFactorLabel = screen.getByTestId(
'label.replication-factor-label'
);
const retentionSizeLabel = await screen.findByTestId(
'Retention Size-label'
const retentionSizeLabel = screen.getByTestId('label.retention-size-label');
const cleanUpPoliciesLabel = screen.getByTestId(
'label.clean-up-policy-plural-label'
);
const cleanUpPoliciesLabel = await screen.findByTestId(
'CleanUp Policies-label'
const maxMessageSizeLabel = screen.getByTestId(
'label.max-message-size-label'
);
const maxMessageSizeLabel = await screen.findByTestId(
'Max Message Size-label'
const partitionsValue = screen.getByTestId('label.partition-plural-value');
const replicationFactorValue = screen.getByTestId(
'label.replication-factor-value'
);
const partitionsValue = await screen.findByTestId('Partitions-value');
const replicationFactorValue = await screen.findByTestId(
'Replication Factor-value'
const retentionSizeValue = screen.getByTestId('label.retention-size-value');
const cleanUpPoliciesValue = screen.getByTestId(
'label.clean-up-policy-plural-value'
);
const retentionSizeValue = await screen.findByTestId(
'Retention Size-value'
const maxMessageSizeValue = screen.getByTestId(
'label.max-message-size-value'
);
const cleanUpPoliciesValue = await screen.findByTestId(
'CleanUp Policies-value'
);
const maxMessageSizeValue = await screen.findByTestId(
'Max Message Size-value'
);
const schemaHeader = await screen.findByTestId('schema-header');
const summaryList = await screen.findByTestId('SummaryList');
const schemaHeader = screen.getByTestId('schema-header');
const summaryList = screen.getByTestId('SummaryList');
expect(partitionsLabel).toBeInTheDocument();
expect(replicationFactorLabel).toBeInTheDocument();
@ -115,7 +112,7 @@ describe('TopicSummary component tests', () => {
render(<TopicSummary entityDetails={mockTopicEntityDetails} />);
});
const partitionsValue = screen.getByTestId('Partitions-value');
const partitionsValue = screen.getByTestId('label.partition-plural-value');
expect(partitionsValue).toContainHTML('-');
});

View File

@ -162,6 +162,7 @@
"classification-lowercase": "klassifizierung",
"classification-lowercase-plural": "klassifizierungen",
"classification-plural": "Klassifizierungen",
"clean-up-policy-plural": "CleanUp Policies",
"clean-up-policy-plural-lowercase": "Aufräumrichtlinien",
"clear": "Löschen",
"clear-entity": "{{entity}} löschen",
@ -719,6 +720,7 @@
"matrix": "Matrix",
"max": "Maximal",
"max-login-fail-attempt-plural": "Max login fail attampts",
"max-message-size": "Max Message Size",
"maximum-size-lowercase": "Maximale Größe",
"may": "Mai",
"mean": "Durchschnitt",
@ -1072,6 +1074,7 @@
"schema-name": "Schema-Name",
"schema-plural": "Schemata",
"schema-text": "Schema Text",
"schema-type": "Schema Type",
"scope-plural": "Umfänge",
"search": "Suchen",
"search-by-type": "Suchen nach {{type}}",

View File

@ -162,6 +162,7 @@
"classification-lowercase": "classification",
"classification-lowercase-plural": "classifications",
"classification-plural": "Classifications",
"clean-up-policy-plural": "CleanUp Policies",
"clean-up-policy-plural-lowercase": "clean-up policies",
"clear": "Clear",
"clear-entity": "Clear {{entity}}",
@ -719,6 +720,7 @@
"matrix": "Matrix",
"max": "Max",
"max-login-fail-attempt-plural": "Max login fail attempts",
"max-message-size": "Max Message Size",
"maximum-size-lowercase": "maximum size",
"may": "May",
"mean": "Mean",
@ -1022,7 +1024,7 @@
"result-plural": "Results",
"resume": "Resume",
"retention-period": "Retention Period",
"retention-size": "retention-size",
"retention-size": "Retention Size",
"retention-size-lowercase": "retention size",
"return": "Return",
"review-data-entity": "Review data {{entity}}",
@ -1072,6 +1074,7 @@
"schema-name": "Schema Name",
"schema-plural": "Schemas",
"schema-text": "Schema Text",
"schema-type": "Schema Type",
"scope-plural": "Scopes",
"search": "Search",
"search-by-type": "Search by {{type}}",

View File

@ -162,6 +162,7 @@
"classification-lowercase": "clasificación",
"classification-lowercase-plural": "clasificaciones",
"classification-plural": "Clasificaciones",
"clean-up-policy-plural": "CleanUp Policies",
"clean-up-policy-plural-lowercase": "políticas de limpieza",
"clear": "Limpiar",
"clear-entity": "Limpiar {{entity}}",
@ -719,6 +720,7 @@
"matrix": "Matrix",
"max": "Máximo",
"max-login-fail-attempt-plural": "Máximo de intentos de inicio de sesión fallidos",
"max-message-size": "Max Message Size",
"maximum-size-lowercase": "tamaño máximo",
"may": "Mayo",
"mean": "Media",
@ -1072,6 +1074,7 @@
"schema-name": "Nombre del Esquema",
"schema-plural": "Esquemas",
"schema-text": "Schema Text",
"schema-type": "Schema Type",
"scope-plural": "Ámbitos",
"search": "Buscar",
"search-by-type": "Buscar por {{type}}",

View File

@ -162,6 +162,7 @@
"classification-lowercase": "classification",
"classification-lowercase-plural": "classifications",
"classification-plural": "Classifications",
"clean-up-policy-plural": "CleanUp Policies",
"clean-up-policy-plural-lowercase": "Nettoyer les Stratégies",
"clear": "Effacer",
"clear-entity": "Effacer {{entity}}",
@ -719,6 +720,7 @@
"matrix": "Matrice",
"max": "Max",
"max-login-fail-attempt-plural": "Nombre maximum de tenatives de login infructueuses",
"max-message-size": "Max Message Size",
"maximum-size-lowercase": "taille maximum",
"may": "Mai",
"mean": "Moyenne",
@ -1072,6 +1074,7 @@
"schema-name": "Nom du Schéma",
"schema-plural": "Schémas",
"schema-text": "Texte du Schéma",
"schema-type": "Schema Type",
"scope-plural": "Périmètres",
"search": "Rechercher",
"search-by-type": "Rechercher par {{type}}",

View File

@ -162,6 +162,7 @@
"classification-lowercase": "clasificación",
"classification-lowercase-plural": "clasificacións",
"classification-plural": "Clasificacións",
"clean-up-policy-plural": "CleanUp Policies",
"clean-up-policy-plural-lowercase": "políticas de limpeza",
"clear": "Limpar",
"clear-entity": "Limpar {{entity}}",
@ -719,6 +720,7 @@
"matrix": "Matriz",
"max": "Máximo",
"max-login-fail-attempt-plural": "Número máximo de intentos fallidos de inicio de sesión",
"max-message-size": "Max Message Size",
"maximum-size-lowercase": "tamaño máximo",
"may": "Maio",
"mean": "Media",
@ -1072,6 +1074,7 @@
"schema-name": "Nome do esquema",
"schema-plural": "Esquemas",
"schema-text": "Texto do esquema",
"schema-type": "Schema Type",
"scope-plural": "Ámbitos",
"search": "Buscar",
"search-by-type": "Buscar por {{type}}",

View File

@ -162,6 +162,7 @@
"classification-lowercase": "סיווג",
"classification-lowercase-plural": "סיווגים",
"classification-plural": "סיווגים",
"clean-up-policy-plural": "CleanUp Policies",
"clean-up-policy-plural-lowercase": "מדיניות ניקיון",
"clear": "נקה",
"clear-entity": "נקה {{entity}}",
@ -719,6 +720,7 @@
"matrix": "Matrix",
"max": "מרבי",
"max-login-fail-attempt-plural": "מספר מרבי של ניסיונות כניסה נכשלים",
"max-message-size": "Max Message Size",
"maximum-size-lowercase": "גודל מרבי",
"may": "מאי",
"mean": "ממוצע",
@ -1072,6 +1074,7 @@
"schema-name": "שם סכימה",
"schema-plural": "סכמות",
"schema-text": "Schema Text",
"schema-type": "Schema Type",
"scope-plural": "היקף",
"search": "חיפוש",
"search-by-type": "חפש לפי {{type}}",

View File

@ -162,6 +162,7 @@
"classification-lowercase": "分類",
"classification-lowercase-plural": "classifications",
"classification-plural": "分類",
"clean-up-policy-plural": "CleanUp Policies",
"clean-up-policy-plural-lowercase": "ポリシーの削除",
"clear": "Clear",
"clear-entity": "{{entity}}を削除",
@ -719,6 +720,7 @@
"matrix": "Matrix",
"max": "最大",
"max-login-fail-attempt-plural": "Max login fail attampts",
"max-message-size": "Max Message Size",
"maximum-size-lowercase": "最大サイズ",
"may": "3月",
"mean": "Mean",
@ -1072,6 +1074,7 @@
"schema-name": "スキーマ名",
"schema-plural": "スキーマ",
"schema-text": "Schema Text",
"schema-type": "Schema Type",
"scope-plural": "スコープ",
"search": "検索",
"search-by-type": "{{type}}で検索",

View File

@ -162,6 +162,7 @@
"classification-lowercase": "classificatie",
"classification-lowercase-plural": "classificaties",
"classification-plural": "Classificaties",
"clean-up-policy-plural": "CleanUp Policies",
"clean-up-policy-plural-lowercase": "beleidsregels opschonen",
"clear": "Wissen",
"clear-entity": "Wissen {{entity}}",
@ -719,6 +720,7 @@
"matrix": "Matrix",
"max": "Max",
"max-login-fail-attempt-plural": "Max aantal mislukte loginpogingen",
"max-message-size": "Max Message Size",
"maximum-size-lowercase": "maximale grootte",
"may": "mei",
"mean": "Gemiddelde",
@ -1072,6 +1074,7 @@
"schema-name": "Schemanaam",
"schema-plural": "Schemas",
"schema-text": "Schema Text",
"schema-type": "Schema Type",
"scope-plural": "Bereik",
"search": "Zoeken",
"search-by-type": "Zoeken op {{type}}",

View File

@ -162,6 +162,7 @@
"classification-lowercase": "طبقه‌بندی",
"classification-lowercase-plural": "طبقه‌بندی‌ها",
"classification-plural": "طبقه‌بندی‌ها",
"clean-up-policy-plural": "CleanUp Policies",
"clean-up-policy-plural-lowercase": "سیاست‌های پاکسازی",
"clear": "پاک کردن",
"clear-entity": "پاک کردن {{entity}}",
@ -719,6 +720,7 @@
"matrix": "ماتریس",
"max": "حداکثر",
"max-login-fail-attempt-plural": "حداکثر تلاش‌های ناموفق برای ورود",
"max-message-size": "Max Message Size",
"maximum-size-lowercase": "حداکثر اندازه",
"may": "می",
"mean": "میانگین",
@ -1072,6 +1074,7 @@
"schema-name": "نام اسکیما",
"schema-plural": "اسکیماها",
"schema-text": "متن اسکیما",
"schema-type": "Schema Type",
"scope-plural": "دامنه‌ها",
"search": "جستجو",
"search-by-type": "جستجو بر اساس {{type}}",

View File

@ -162,6 +162,7 @@
"classification-lowercase": "classificação",
"classification-lowercase-plural": "classificações",
"classification-plural": "Classificações",
"clean-up-policy-plural": "CleanUp Policies",
"clean-up-policy-plural-lowercase": "políticas de limpeza",
"clear": "Limpar",
"clear-entity": "Limpar {{entity}}",
@ -719,6 +720,7 @@
"matrix": "Matrix",
"max": "Máx",
"max-login-fail-attempt-plural": "Máximas tentativas de falha de login",
"max-message-size": "Max Message Size",
"maximum-size-lowercase": "tamanho máximo",
"may": "Maio",
"mean": "Média",
@ -1072,6 +1074,7 @@
"schema-name": "Nome do Esquema",
"schema-plural": "Esquemas",
"schema-text": "Schema Text",
"schema-type": "Schema Type",
"scope-plural": "Escopos",
"search": "Pesquisar",
"search-by-type": "Pesquisar por {{type}}",

View File

@ -162,6 +162,7 @@
"classification-lowercase": "classificação",
"classification-lowercase-plural": "classificações",
"classification-plural": "Classificações",
"clean-up-policy-plural": "CleanUp Policies",
"clean-up-policy-plural-lowercase": "políticas de limpeza",
"clear": "Limpar",
"clear-entity": "Limpar {{entity}}",
@ -719,6 +720,7 @@
"matrix": "Matrix",
"max": "Máx",
"max-login-fail-attempt-plural": "Máximas tentativas de falha de login",
"max-message-size": "Max Message Size",
"maximum-size-lowercase": "tamanho máximo",
"may": "Maio",
"mean": "Média",
@ -1072,6 +1074,7 @@
"schema-name": "Nome do Esquema",
"schema-plural": "Esquemas",
"schema-text": "Schema Text",
"schema-type": "Schema Type",
"scope-plural": "Escopos",
"search": "Pesquisar",
"search-by-type": "Pesquisar por {{type}}",

View File

@ -162,6 +162,7 @@
"classification-lowercase": "классификация",
"classification-lowercase-plural": "классификации",
"classification-plural": "Классификации",
"clean-up-policy-plural": "CleanUp Policies",
"clean-up-policy-plural-lowercase": "политика очистки",
"clear": "Очистить",
"clear-entity": "Очистить {{entity}}",
@ -719,6 +720,7 @@
"matrix": "Matrix",
"max": "Максимум",
"max-login-fail-attempt-plural": "Max login fail attampts",
"max-message-size": "Max Message Size",
"maximum-size-lowercase": "максимальный размер",
"may": "Май",
"mean": "Среднее",
@ -1072,6 +1074,7 @@
"schema-name": "Наименование схемы",
"schema-plural": "Схемы",
"schema-text": "Schema Text",
"schema-type": "Schema Type",
"scope-plural": "Объемы",
"search": "Поиск",
"search-by-type": "Поиск {{type}}",

View File

@ -162,6 +162,7 @@
"classification-lowercase": "การจำแนกประเภท",
"classification-lowercase-plural": "การจำแนกประเภทหลายรายการ",
"classification-plural": "การจำแนกประเภทหลายรายการ",
"clean-up-policy-plural": "CleanUp Policies",
"clean-up-policy-plural-lowercase": "นโยบายการทำความสะอาด",
"clear": "ลบ",
"clear-entity": "ลบ {{entity}}",
@ -719,6 +720,7 @@
"matrix": "เมทริกซ์",
"max": "สูงสุด",
"max-login-fail-attempt-plural": "จำนวนความพยายามในการเข้าสู่ระบบสูงสุดที่ล้มเหลว",
"max-message-size": "Max Message Size",
"maximum-size-lowercase": "ขนาดสูงสุด",
"may": "พฤษภาคม",
"mean": "ค่าเฉลี่ย",
@ -1072,6 +1074,7 @@
"schema-name": "ชื่อสคีมา",
"schema-plural": "สคีมาหลายรายการ",
"schema-text": "ข้อความสคีมา",
"schema-type": "Schema Type",
"scope-plural": "ขอบเขต",
"search": "ค้นหา",
"search-by-type": "ค้นหาตาม {{type}}",

View File

@ -162,6 +162,7 @@
"classification-lowercase": "分类",
"classification-lowercase-plural": "分类",
"classification-plural": "分类",
"clean-up-policy-plural": "CleanUp Policies",
"clean-up-policy-plural-lowercase": "清理策略",
"clear": "清除",
"clear-entity": "清除{{entity}}",
@ -719,6 +720,7 @@
"matrix": "Matrix",
"max": "最大值",
"max-login-fail-attempt-plural": "最大登录失败次数",
"max-message-size": "Max Message Size",
"maximum-size-lowercase": "最大",
"may": "五月",
"mean": "平均值",
@ -1072,6 +1074,7 @@
"schema-name": "数据模式名称",
"schema-plural": "数据模式",
"schema-text": "数据模式文本",
"schema-type": "Schema Type",
"scope-plural": "范围",
"search": "搜索",
"search-by-type": "通过{{type}}搜索",

View File

@ -591,6 +591,7 @@ const DatabaseSchemaPage: FunctionComponent = () => {
decodedDatabaseSchemaFQN,
tags,
viewAllPermission,
databaseSchemaPermission,
storedProcedureCount,
onEditCancel,
handleExtensionUpdate,
@ -623,6 +624,7 @@ const DatabaseSchemaPage: FunctionComponent = () => {
tags,
viewAllPermission,
storedProcedureCount,
databaseSchemaPermission,
handleExtensionUpdate,
handleTagSelection,
onThreadLinkSelect,

View File

@ -24,6 +24,10 @@ import { SearchIndex } from '../../../../enums/search.enum';
import { ConstraintType, Table } from '../../../../generated/entity/data/table';
import { searchQuery } from '../../../../rest/searchAPI';
import { getServiceNameQueryFilter } from '../../../../utils/ServiceUtils';
import {
escapeESReservedCharacters,
getEncodedFqn,
} from '../../../../utils/StringsUtils';
import { showErrorToast } from '../../../../utils/ToastUtils';
import './table-constraint.style.less';
import {
@ -58,8 +62,11 @@ const TableConstraintsModal = ({
const getSearchResults = async (value: string) => {
setIsRelatedColumnLoading(true);
try {
const encodedValue = getEncodedFqn(escapeESReservedCharacters(value));
const data = await searchQuery({
query: value,
query:
value &&
`(columns.name.keyword:${encodedValue}) OR (columns.fullyQualifiedName:${encodedValue})`,
searchIndex: SearchIndex.TABLE,
queryFilter: getServiceNameQueryFilter(
tableDetails?.service?.name ?? ''
@ -250,6 +257,7 @@ const TableConstraintsModal = ({
},
]}>
<Select
allowClear
showSearch
data-testid={`${key}-related-column-select`}
loading={isRelatedColumnLoading}
@ -259,7 +267,10 @@ const TableConstraintsModal = ({
onClick={(e) => e.stopPropagation()}
onSearch={handleSearch}>
{relatedColumns.map((option) => (
<Select.Option key={option.value} value={option.value}>
<Select.Option
data-testid={`option-label-${option.label}`}
key={option.value}
value={option.value}>
<Tooltip placement="right" title={option.label}>
<Typography.Text>{option.label}</Typography.Text>
</Tooltip>

View File

@ -13,6 +13,7 @@
import { EntityTags } from 'Models';
import { PagingHandlerParams } from '../components/common/NextPrevious/NextPrevious.interface';
import { TabProps } from '../components/common/TabsLabel/TabsLabel.interface';
import { OperationPermission } from '../context/PermissionProvider/PermissionProvider.interface';
import { DetailPageWidgetKeys } from '../enums/CustomizeDetailPage.enum';
import { EntityTabs } from '../enums/entity.enum';
import { DatabaseSchema } from '../generated/entity/data/databaseSchema';
@ -40,6 +41,7 @@ export interface DatabaseSchemaPageTabProps {
tags: any[];
viewAllPermission: boolean;
storedProcedureCount: number;
databaseSchemaPermission: OperationPermission;
handleExtensionUpdate: (schema: DatabaseSchema) => Promise<void>;
handleTagSelection: (selectedTags: EntityTags[]) => Promise<void>;
onThreadLinkSelect: (link: string, threadType?: ThreadType) => void;

View File

@ -38,6 +38,7 @@ jest.mock('../constants/constants', () => ({
jest.mock('./RouterUtils', () => ({
getDataQualityPagePath: jest.fn(),
getDomainPath: jest.fn(),
}));
describe('EntityUtils unit tests', () => {

View File

@ -138,7 +138,7 @@ import {
getTeamsWithFqnPath,
} from './RouterUtils';
import { getServiceRouteFromServiceType } from './ServiceUtils';
import { stringToHTML } from './StringsUtils';
import { bytesToSize, stringToHTML } from './StringsUtils';
import {
getDataTypeString,
getTagsWithoutTier,
@ -221,6 +221,7 @@ const getTableFieldsFromTableDetails = (tableDetails: Table) => {
service,
database,
databaseSchema,
domain,
} = tableDetails;
const [serviceName, databaseName, schemaName] = getPartialNameFromTableFQN(
fullyQualifiedName ?? '',
@ -245,9 +246,40 @@ const getTableFieldsFromTableDetails = (tableDetails: Table) => {
profile,
columns,
tableType,
domain,
};
};
const getCommonOverview = (
{
owners,
domain,
}: {
owners?: EntityReference[];
domain?: EntityReference;
},
showOwner = true
) => {
return [
...(showOwner
? [
{
name: i18next.t('label.owner-plural'),
value: <OwnerLabel hasPermission={false} owners={owners} />,
visible: [DRAWER_NAVIGATION_OPTIONS.lineage],
},
]
: []),
{
name: i18next.t('label.domain'),
value: getEntityName(domain) || NO_DATA,
isLink: Boolean(domain),
url: getDomainPath(domain?.fullyQualifiedName),
visible: [DRAWER_NAVIGATION_OPTIONS.lineage],
},
];
};
const getTableOverview = (
tableDetails: Table,
additionalInfo?: Record<string, number | string>
@ -263,14 +295,11 @@ const getTableOverview = (
schema,
tier,
usage,
domain,
} = getTableFieldsFromTableDetails(tableDetails);
const overview = [
{
name: i18next.t('label.owner-plural'),
value: <OwnerLabel hasPermission={false} owners={owners} />,
visible: [DRAWER_NAVIGATION_OPTIONS.lineage],
},
...getCommonOverview({ owners, domain }),
{
name: i18next.t('label.type'),
value: tableType ?? TableType.Regular,
@ -371,17 +400,86 @@ const getTableOverview = (
return overview;
};
const getTopicOverview = (topicDetails: Topic) => {
const {
domain,
partitions,
replicationFactor,
retentionSize,
cleanupPolicies,
maximumMessageSize,
messageSchema,
} = topicDetails;
const overview = [
...getCommonOverview({ domain }, false),
{
name: i18next.t('label.partition-plural'),
value: partitions ?? NO_DATA,
isLink: false,
visible: [
DRAWER_NAVIGATION_OPTIONS.lineage,
DRAWER_NAVIGATION_OPTIONS.explore,
],
},
{
name: i18next.t('label.replication-factor'),
value: replicationFactor,
isLink: false,
visible: [
DRAWER_NAVIGATION_OPTIONS.lineage,
DRAWER_NAVIGATION_OPTIONS.explore,
],
},
{
name: i18next.t('label.retention-size'),
value: bytesToSize(retentionSize ?? 0),
isLink: false,
visible: [
DRAWER_NAVIGATION_OPTIONS.lineage,
DRAWER_NAVIGATION_OPTIONS.explore,
],
},
{
name: i18next.t('label.clean-up-policy-plural'),
value: cleanupPolicies ? cleanupPolicies.join(', ') : NO_DATA,
isLink: false,
visible: [
DRAWER_NAVIGATION_OPTIONS.lineage,
DRAWER_NAVIGATION_OPTIONS.explore,
],
},
{
name: i18next.t('label.max-message-size'),
value: bytesToSize(maximumMessageSize ?? 0),
isLink: false,
visible: [
DRAWER_NAVIGATION_OPTIONS.lineage,
DRAWER_NAVIGATION_OPTIONS.explore,
],
},
{
name: i18next.t('label.schema-type'),
value: messageSchema?.schemaType ?? NO_DATA,
isLink: false,
visible: [
DRAWER_NAVIGATION_OPTIONS.lineage,
DRAWER_NAVIGATION_OPTIONS.explore,
],
},
];
return overview;
};
const getPipelineOverview = (pipelineDetails: Pipeline) => {
const { owners, tags, sourceUrl, service, displayName } = pipelineDetails;
const { owners, tags, sourceUrl, service, displayName, domain } =
pipelineDetails;
const tier = getTierTags(tags ?? []);
const serviceDisplayName = getEntityName(service);
const overview = [
{
name: i18next.t('label.owner-plural'),
value: <OwnerLabel hasPermission={false} owners={owners} />,
visible: [DRAWER_NAVIGATION_OPTIONS.lineage],
},
...getCommonOverview({ owners, domain }),
{
name: `${i18next.t('label.pipeline')} ${i18next.t(
'label.url-uppercase'
@ -419,17 +517,13 @@ const getPipelineOverview = (pipelineDetails: Pipeline) => {
};
const getDashboardOverview = (dashboardDetails: Dashboard) => {
const { owners, tags, sourceUrl, service, displayName, project } =
const { owners, tags, sourceUrl, service, displayName, project, domain } =
dashboardDetails;
const tier = getTierTags(tags ?? []);
const serviceDisplayName = getEntityName(service);
const overview = [
{
name: i18next.t('label.owner-plural'),
value: <OwnerLabel hasPermission={false} owners={owners} />,
visible: [DRAWER_NAVIGATION_OPTIONS.lineage],
},
...getCommonOverview({ owners, domain }),
{
name: `${i18next.t('label.dashboard')} ${i18next.t(
'label.url-uppercase'
@ -478,15 +572,11 @@ const getDashboardOverview = (dashboardDetails: Dashboard) => {
export const getSearchIndexOverview = (
searchIndexDetails: SearchIndexEntity
) => {
const { owners, tags, service } = searchIndexDetails;
const { owners, tags, service, domain } = searchIndexDetails;
const tier = getTierTags(tags ?? []);
const overview = [
{
name: i18next.t('label.owner-plural'),
value: <OwnerLabel hasPermission={false} owners={owners} />,
visible: [DRAWER_NAVIGATION_OPTIONS.lineage],
},
...getCommonOverview({ owners, domain }),
{
name: i18next.t('label.tier'),
value: entityTierRenderer(tier),
@ -511,14 +601,11 @@ export const getSearchIndexOverview = (
};
const getMlModelOverview = (mlModelDetails: Mlmodel) => {
const { algorithm, target, server, dashboard, owners } = mlModelDetails;
const { algorithm, target, server, dashboard, owners, domain } =
mlModelDetails;
const overview = [
{
name: i18next.t('label.owner-plural'),
value: <OwnerLabel hasPermission={false} owners={owners} />,
visible: [DRAWER_NAVIGATION_OPTIONS.lineage],
},
...getCommonOverview({ owners, domain }),
{
name: i18next.t('label.algorithm'),
value: algorithm || NO_DATA,
@ -570,7 +657,8 @@ const getMlModelOverview = (mlModelDetails: Mlmodel) => {
};
const getContainerOverview = (containerDetails: Container) => {
const { numberOfObjects, serviceType, dataModel } = containerDetails;
const { numberOfObjects, serviceType, dataModel, owners, domain } =
containerDetails;
const visible = [
DRAWER_NAVIGATION_OPTIONS.lineage,
@ -578,6 +666,7 @@ const getContainerOverview = (containerDetails: Container) => {
];
const overview = [
...getCommonOverview({ owners, domain }),
{
name: i18next.t('label.object-plural'),
value: numberOfObjects,
@ -605,16 +694,19 @@ const getContainerOverview = (containerDetails: Container) => {
};
const getChartOverview = (chartDetails: Chart) => {
const { owners, sourceUrl, chartType, service, serviceType, displayName } =
chartDetails;
const {
owners,
sourceUrl,
chartType,
service,
serviceType,
displayName,
domain,
} = chartDetails;
const serviceDisplayName = getEntityName(service);
const overview = [
{
name: i18next.t('label.owner-plural'),
value: <OwnerLabel hasPermission={false} owners={owners} />,
visible: [DRAWER_NAVIGATION_OPTIONS.lineage],
},
...getCommonOverview({ owners, domain }),
{
name: `${i18next.t('label.chart')} ${i18next.t('label.url-uppercase')}`,
value: stringToHTML(displayName ?? '') || NO_DATA,
@ -668,6 +760,7 @@ const getDataModelOverview = (dataModelDetails: DashboardDataModel) => {
owners,
tags,
service,
domain,
displayName,
dataModelType,
fullyQualifiedName,
@ -675,11 +768,7 @@ const getDataModelOverview = (dataModelDetails: DashboardDataModel) => {
const tier = getTierTags(tags ?? []);
const overview = [
{
name: i18next.t('label.owner-plural'),
value: <OwnerLabel hasPermission={false} owners={owners} />,
visible: [DRAWER_NAVIGATION_OPTIONS.lineage],
},
...getCommonOverview({ owners, domain }),
{
name: `${i18next.t('label.data-model')} ${i18next.t(
'label.url-uppercase'
@ -738,7 +827,7 @@ const getDataModelOverview = (dataModelDetails: DashboardDataModel) => {
const getStoredProcedureOverview = (
storedProcedureDetails: StoredProcedure
) => {
const { fullyQualifiedName, owners, tags, storedProcedureCode } =
const { fullyQualifiedName, owners, tags, domain, storedProcedureCode } =
storedProcedureDetails;
const [service, database, schema] = getPartialNameFromTableFQN(
fullyQualifiedName ?? '',
@ -749,11 +838,7 @@ const getStoredProcedureOverview = (
const tier = getTierTags(tags ?? []);
const overview = [
{
name: i18next.t('label.owner-plural'),
value: <OwnerLabel hasPermission={false} owners={owners} />,
visible: [DRAWER_NAVIGATION_OPTIONS.lineage],
},
...getCommonOverview({ owners, domain }),
{
name: i18next.t('label.service'),
value: service || NO_DATA,
@ -822,7 +907,7 @@ const getStoredProcedureOverview = (
};
const getDatabaseOverview = (databaseDetails: Database) => {
const { owners, service, tags, usageSummary } = databaseDetails;
const { owners, service, domain, tags, usageSummary } = databaseDetails;
const tier = getTierTags(tags ?? []);
@ -832,6 +917,7 @@ const getDatabaseOverview = (databaseDetails: Database) => {
value: <OwnerLabel hasPermission={false} owners={owners} />,
visible: [DRAWER_NAVIGATION_OPTIONS.explore],
},
...getCommonOverview({ domain }, false),
{
name: i18next.t('label.tier'),
value: entityTierRenderer(tier),
@ -861,7 +947,7 @@ const getDatabaseOverview = (databaseDetails: Database) => {
};
const getDatabaseSchemaOverview = (databaseSchemaDetails: DatabaseSchema) => {
const { owners, service, tags, usageSummary, database } =
const { owners, service, tags, domain, usageSummary, database } =
databaseSchemaDetails;
const tier = getTierTags(tags ?? []);
@ -872,7 +958,7 @@ const getDatabaseSchemaOverview = (databaseSchemaDetails: DatabaseSchema) => {
value: <OwnerLabel hasPermission={false} owners={owners} />,
visible: [DRAWER_NAVIGATION_OPTIONS.explore],
},
...getCommonOverview({ domain }, false),
{
name: i18next.t('label.tier'),
value: entityTierRenderer(tier),
@ -911,7 +997,7 @@ const getDatabaseSchemaOverview = (databaseSchemaDetails: DatabaseSchema) => {
};
const getEntityServiceOverview = (serviceDetails: EntityServiceUnion) => {
const { owners, tags, serviceType } = serviceDetails;
const { owners, domain, tags, serviceType } = serviceDetails;
const tier = getTierTags(tags ?? []);
@ -921,6 +1007,7 @@ const getEntityServiceOverview = (serviceDetails: EntityServiceUnion) => {
value: <OwnerLabel hasPermission={false} owners={owners} />,
visible: [DRAWER_NAVIGATION_OPTIONS.explore],
},
...getCommonOverview({ domain }, false),
{
name: i18next.t('label.tier'),
value: entityTierRenderer(tier),
@ -943,9 +1030,10 @@ const getApiCollectionOverview = (apiCollection: APICollection) => {
return [];
}
const { service } = apiCollection;
const { service, domain } = apiCollection;
const overview = [
...getCommonOverview({ domain }, false),
{
name: i18next.t('label.endpoint-url'),
value: apiCollection.endpointURL || NO_DATA,
@ -972,9 +1060,10 @@ const getApiEndpointOverview = (apiEndpoint: APIEndpoint) => {
if (isNil(apiEndpoint) || isEmpty(apiEndpoint)) {
return [];
}
const { service, apiCollection } = apiEndpoint;
const { domain, service, apiCollection } = apiEndpoint;
const overview = [
...getCommonOverview({ domain }, false),
{
name: i18next.t('label.endpoint-url'),
value: apiEndpoint.endpointURL || NO_DATA,
@ -1031,6 +1120,7 @@ const getMetricOverview = (metric: Metric) => {
}
const overview = [
...getCommonOverview({ domain: metric.domain }, false),
{
name: i18next.t('label.metric-type'),
value: metric.metricType || NO_DATA,
@ -1073,6 +1163,10 @@ export const getEntityOverview = (
return getTableOverview(entityDetail as Table, additionalInfo);
}
case ExplorePageTabs.TOPICS: {
return getTopicOverview(entityDetail as Topic);
}
case ExplorePageTabs.PIPELINES: {
return getPipelineOverview(entityDetail as Pipeline);
}

View File

@ -11,23 +11,8 @@
* limitations under the License.
*/
import { TopicConfigObjectInterface } from '../components/Topic/TopicDetails/TopicDetails.interface';
import { DetailPageWidgetKeys } from '../enums/CustomizeDetailPage.enum';
import { EntityTabs } from '../enums/entity.enum';
import { Topic } from '../generated/entity/data/topic';
export const getConfigObject = (
topicDetails: Topic
): TopicConfigObjectInterface => {
return {
Partitions: topicDetails.partitions,
'Replication Factor': topicDetails.replicationFactor,
'Retention Size': topicDetails.retentionSize,
'CleanUp Policies': topicDetails.cleanupPolicies,
'Max Message Size': topicDetails.maximumMessageSize,
'Schema Type': topicDetails.messageSchema?.schemaType,
};
};
export const getTopicDetailsPageDefaultLayout = (tab: EntityTabs) => {
switch (tab) {