diff --git a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/BulkImport.spec.ts b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/BulkImport.spec.ts index d876de68534..e24f240346d 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/BulkImport.spec.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/BulkImport.spec.ts @@ -1024,13 +1024,11 @@ test.describe('Bulk Import Export', () => { page.getByTestId('glossary-container').getByTestId('add-tag') ).toBeVisible(); - await expect(page.getByTestId('Tier')).toContainText('No Tier'); + await expect(page.getByTestId('Tier')).toContainText('--'); - await expect(page.getByTestId('certification-label')).toContainText( - 'No Certification' - ); + await expect(page.getByTestId('certification-label')).toContainText('--'); - await expect(page.getByTestId('owner-label')).toContainText('No Owners'); + await expect(page.getByTestId('owner-label')).toContainText('--'); await expect(page.getByTestId('no-domain-text')).toBeVisible(); }); diff --git a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/TestSuite.spec.ts b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/TestSuite.spec.ts index 5a7fcd71268..24ed847740e 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/TestSuite.spec.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/TestSuite.spec.ts @@ -107,7 +107,7 @@ test('Logical TestSuite', async ({ page }) => { await assignDomain(page, domain1.responseData); // TODO: Add domain update // await updateDomain(page, domain2.responseData); - await removeDomain(page, domain1.responseData); + await removeDomain(page, domain1.responseData, false); }); await test.step( diff --git a/openmetadata-ui/src/main/resources/ui/playwright/utils/common.ts b/openmetadata-ui/src/main/resources/ui/playwright/utils/common.ts index 002107daef9..a0d3514c480 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/utils/common.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/utils/common.ts @@ -262,7 +262,8 @@ export const updateDomain = async ( export const removeDomain = async ( page: Page, - domain: { name: string; displayName: string; fullyQualifiedName?: string } + domain: { name: string; displayName: string; fullyQualifiedName?: string }, + showDashPlaceholder = true ) => { await page.getByTestId('add-domain').click(); await page.waitForSelector('[data-testid="loader"]', { state: 'detached' }); @@ -280,7 +281,9 @@ export const removeDomain = async ( await patchReq; await page.waitForSelector('[data-testid="loader"]', { state: 'detached' }); - await expect(page.getByTestId('no-domain-text')).toContainText('No Domains'); + await expect(page.getByTestId('no-domain-text')).toContainText( + showDashPlaceholder ? '--' : 'No Domains' + ); }; export const assignDataProduct = async ( diff --git a/openmetadata-ui/src/main/resources/ui/playwright/utils/entity.ts b/openmetadata-ui/src/main/resources/ui/playwright/utils/entity.ts index 66978403460..287a7e84bee 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/utils/entity.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/utils/entity.ts @@ -478,7 +478,7 @@ export const removeTier = async (page: Page, endpoint: string) => { await patchRequest; await clickOutside(page); - await expect(page.getByTestId('Tier')).toContainText('No Tier'); + await expect(page.getByTestId('Tier')).toContainText('--'); }; export const assignCertification = async ( @@ -509,9 +509,7 @@ export const removeCertification = async (page: Page, endpoint: string) => { await patchRequest; await clickOutside(page); - await expect(page.getByTestId('certification-label')).toContainText( - 'No Certification' - ); + await expect(page.getByTestId('certification-label')).toContainText('--'); }; export const updateDescription = async ( diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataAssets/DataAssetsHeader/DataAssetsHeader.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataAssets/DataAssetsHeader/DataAssetsHeader.component.tsx index 91c9a918166..0fe05219d3c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataAssets/DataAssetsHeader/DataAssetsHeader.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataAssets/DataAssetsHeader/DataAssetsHeader.component.tsx @@ -32,6 +32,7 @@ import { OwnerLabel } from '../../../components/common/OwnerLabel/OwnerLabel.com import TierCard from '../../../components/common/TierCard/TierCard'; import EntityHeaderTitle from '../../../components/Entity/EntityHeaderTitle/EntityHeaderTitle.component'; import { AUTO_PILOT_APP_NAME } from '../../../constants/Applications.constant'; +import { NO_DATA_PLACEHOLDER } from '../../../constants/constants'; import { EXCLUDE_AUTO_PILOT_SERVICE_TYPES, SERVICE_TYPES, @@ -59,7 +60,6 @@ import { getDataQualityLineage } from '../../../rest/lineageAPI'; import { getContainerByName } from '../../../rest/storageAPI'; import { getDataAssetsHeaderInfo, - getEntityExtraInfoLength, isDataAssetsWithServiceField, } from '../../../utils/DataAssetsHeader.utils'; import { getDataContractStatusIcon } from '../../../utils/DataContract/DataContractUtils'; @@ -324,14 +324,6 @@ export const DataAssetsHeader = ({ [entityType, dataAsset, entityName, parentContainers] ); - const showCompressedExtraInfoItems = useMemo( - () => - entityType === EntityType.METRIC - ? false - : getEntityExtraInfoLength(extraInfo) <= 1, - [extraInfo, entityType] - ); - const handleOpenTaskClick = () => { if (!dataAsset.fullyQualifiedName) { return; @@ -663,15 +655,14 @@ export const DataAssetsHeader = ({
{showDomain && ( <> )} {tier ? (
@@ -719,6 +712,7 @@ export const DataAssetsHeader = ({
- {t('label.no-entity', { - entity: t('label.tier'), - })} + {NO_DATA_PLACEHOLDER}
)} @@ -819,9 +811,7 @@ export const DataAssetsHeader = ({ certification={(dataAsset as Table).certification!} /> ) : ( - t('label.no-entity', { - entity: t('label.certification'), - }) + NO_DATA_PLACEHOLDER )} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataAssets/DataAssetsHeader/DataAssetsHeader.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataAssets/DataAssetsHeader/DataAssetsHeader.test.tsx index 1eefa0fb096..f4b64808d8f 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataAssets/DataAssetsHeader/DataAssetsHeader.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataAssets/DataAssetsHeader/DataAssetsHeader.test.tsx @@ -269,7 +269,7 @@ describe('DataAssetsHeader component', () => { it('should not render the Tier data if not present', () => { render(); - expect(screen.getByTestId('Tier')).toContainHTML('label.no-entity'); + expect(screen.getByTestId('Tier')).toContainHTML('--'); }); it('should not call getDataQualityLineage, if isDqAlertSupported and alert supported is false', () => { @@ -389,9 +389,7 @@ describe('DataAssetsHeader component', () => { // Test without certification when serviceCategory is undefined render(); - expect(screen.getByTestId('certification-label')).toContainHTML( - 'label.no-entity' - ); + expect(screen.getByTestId('certification-label')).toContainHTML('--'); // Reset the mock to original value useRequiredParamsMock.mockReturnValue({ diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataAssets/DataAssetsHeader/data-asset-header.less b/openmetadata-ui/src/main/resources/ui/src/components/DataAssets/DataAssetsHeader/data-asset-header.less index d0e2a928778..08850e62345 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataAssets/DataAssetsHeader/data-asset-header.less +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataAssets/DataAssetsHeader/data-asset-header.less @@ -20,18 +20,9 @@ gap: 16px; display: flex; background-color: @background-color; - justify-content: space-evenly; flex-wrap: wrap; } - .data-asset-header-less-items { - justify-content: initial; - - .ant-divider { - margin: 0 20px 0 100px; - } - } - .ant-space-item { .entity-no-tier { color: @primary-heading-color; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsV1/TagsV1.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsV1/TagsV1.component.tsx index b66929b9ec2..2554bc60ca8 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsV1/TagsV1.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsV1/TagsV1.component.tsx @@ -33,6 +33,7 @@ import { TagsV1Props } from './TagsV1.interface'; import './tagsV1.less'; const TagsV1 = ({ + hideIcon, tag, startWith, className, @@ -131,34 +132,43 @@ const TagsV1 = ({ return ''; }, [newLook, tag.style?.color]); + const renderIcon = useMemo(() => { + if (hideIcon) { + return null; + } + + if (tag.style?.iconURL) { + return ( + + ); + } + + return startIcon; + }, [hideIcon, tag.style?.iconURL, startIcon]); + const tagContent = useMemo( () => ( -
+
{tagColorBar}
- {tag.style?.iconURL ? ( - - ) : ( - startIcon - )} - - {tagName} - +
), @@ -205,11 +215,12 @@ const TagsV1 = ({ }> - + {getTagDisplay(tagName)} - + ), [tagName] diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsV1/TagsV1.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsV1/TagsV1.interface.ts index 72fa5a41f50..b1f8114eb63 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsV1/TagsV1.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsV1/TagsV1.interface.ts @@ -21,6 +21,7 @@ export interface DataTestId { } export type TagsV1Props = { + hideIcon?: boolean; tag: TagLabel | HighlightedTagLabel; startWith: TAG_START_WITH; showOnlyName?: boolean; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsV1/tagsV1.less b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsV1/tagsV1.less index 0e18dc92ff6..4b61ded24b1 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsV1/tagsV1.less +++ b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsV1/tagsV1.less @@ -37,11 +37,12 @@ .ant-tag.tag-chip-content { width: max-content; - height: 30px; + max-width: 200px; margin: 0px; border: none; - padding: 0; + padding: 2px 0; background: @tag-background-color; + border-radius: @border-rad-xs; &.diff-added { background: @success-background-color; @@ -90,8 +91,15 @@ } .tags-label { - display: inline-block; + display: block; font-size: 12px; font-weight: 500; color: inherit; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.tag-content-container { + min-width: 0; } diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/CertificationTag/CertificationTag.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/CertificationTag/CertificationTag.tsx index b1138305086..c6b9847553d 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/CertificationTag/CertificationTag.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/CertificationTag/CertificationTag.tsx @@ -57,6 +57,7 @@ const CertificationTag = ({ backgroundColor: certification.tagLabel.style?.color ? certification.tagLabel.style?.color + '33' : '#f8f8f8', + padding: '2px 6px', } : {}; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/DomainLabel/DomainLabel.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/DomainLabel/DomainLabel.component.tsx index 143d19da069..d1a0e0afe11 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/DomainLabel/DomainLabel.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/DomainLabel/DomainLabel.component.tsx @@ -19,7 +19,10 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { ReactComponent as DomainIcon } from '../../../assets/svg/ic-domain.svg'; import { ReactComponent as InheritIcon } from '../../../assets/svg/ic-inherit.svg'; -import { DE_ACTIVE_COLOR } from '../../../constants/constants'; +import { + DE_ACTIVE_COLOR, + NO_DATA_PLACEHOLDER, +} from '../../../constants/constants'; import { EntityReference } from '../../../generated/entity/type'; import { getAPIfromSource, @@ -34,6 +37,7 @@ import './domain-label.less'; import { DomainLabelProps } from './DomainLabel.interface'; export const DomainLabel = ({ + showDashPlaceholder, afterDomainUpdateAction, hasPermission, domains, @@ -50,6 +54,12 @@ export const DomainLabel = ({ const { t } = useTranslation(); const [activeDomain, setActiveDomain] = useState([]); + const defaultDomainText = useMemo(() => { + return showDashPlaceholder + ? NO_DATA_PLACEHOLDER + : t('label.no-entity', { entity: t('label.domain-plural') }); + }, [showDashPlaceholder]); + const handleDomainSave = useCallback( async (selectedDomain: EntityReference | EntityReference[]) => { const entityDetails = getEntityAPIfromSource(entityType as AssetsUnion)( @@ -166,8 +176,12 @@ export const DomainLabel = ({ })), className: 'domain-tooltip-list', }}> - - +{remainingCount} + + {`+${remainingCount}`}
@@ -185,7 +199,7 @@ export const DomainLabel = ({ textClassName )} data-testid="no-domain-text"> - {t('label.no-entity', { entity: t('label.domain-plural') })} + {defaultDomainText} ); }, [ @@ -226,7 +240,7 @@ export const DomainLabel = ({ {activeDomain.length > 0 ? t('label.domain-plural') - : t('label.no-entity', { entity: t('label.domain-plural') })} + : defaultDomainText} )} {selectableList} @@ -240,7 +254,7 @@ export const DomainLabel = ({ } return ( -
+
{headerLayout && (
void; hasPermission?: boolean; domains: EntityReference[] | undefined; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/DomainLabel/DomainLabel.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/DomainLabel/DomainLabel.test.tsx new file mode 100644 index 00000000000..3074a17007e --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/DomainLabel/DomainLabel.test.tsx @@ -0,0 +1,273 @@ +/* + * Copyright 2025 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 '@testing-library/jest-dom'; +import { render, screen } from '@testing-library/react'; +import { MemoryRouter } from 'react-router-dom'; +import { EntityType } from '../../../enums/entity.enum'; +import { EntityReference } from '../../../generated/entity/type'; +import { DomainLabel } from './DomainLabel.component'; + +jest.mock('../../../utils/EntityUtils', () => ({ + getEntityName: jest + .fn() + .mockImplementation((entity) => entity?.name || 'Unknown'), +})); + +jest.mock('../../../utils/RouterUtils', () => ({ + getDomainPath: jest + .fn() + .mockImplementation((fqn: string) => `/domain/${fqn}`), +})); + +jest.mock('../../../utils/Assets/AssetsUtils', () => ({ + getAPIfromSource: jest.fn().mockReturnValue(jest.fn()), + getEntityAPifromSource: jest.fn().mockReturnValue(jest.fn()), +})); + +jest.mock('../../../utils/DomainUtils', () => ({ + renderDomainLink: jest + .fn() + .mockImplementation((domain, displayName, className) => ( + + {displayName || domain.name} + + )), +})); + +jest.mock('../../../utils/ToastUtils', () => ({ + showErrorToast: jest.fn(), +})); + +jest.mock('../../../assets/svg/ic-domain.svg', () => ({ + ReactComponent: () =>
Domain Icon
, +})); + +jest.mock('../../../assets/svg/ic-inherit.svg', () => ({ + ReactComponent: () =>
Inherit Icon
, +})); + +jest.mock('../DomainSelectableList/DomainSelectableList.component', () => ({ + __esModule: true, + default: ({ onUpdate, selectedDomain }: any) => ( + + ), +})); + +// Mock data +const mockDomain1: EntityReference = { + id: 'domain-1', + fullyQualifiedName: 'domain.one', + name: 'Domain One', + type: 'domain', +}; + +const mockDomain2: EntityReference = { + id: 'domain-2', + fullyQualifiedName: 'domain.two', + name: 'Domain Two', + type: 'domain', +}; + +const mockInheritedDomain: EntityReference = { + id: 'domain-inherited', + fullyQualifiedName: 'domain.inherited', + name: 'Inherited Domain', + type: 'domain', + inherited: true, +}; + +const defaultProps = { + domains: [mockDomain1], + entityType: EntityType.TABLE, + entityFqn: 'test.table', + entityId: 'test-id', +}; + +const renderDomainLabel = (props: any = {}) => + render( + + + + ); + +describe('DomainLabel Component', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should render single domain correctly', () => { + renderDomainLabel({ domains: [mockDomain1] }); + + expect(screen.getByTestId('domain-link')).toBeInTheDocument(); + expect(screen.getByText('Domain One')).toBeInTheDocument(); + }); + + it('should render multiple domains with dropdown when multiple and headerLayout are true', () => { + renderDomainLabel({ + domains: [mockDomain1, mockDomain2], + multiple: true, + headerLayout: true, + }); + + expect(screen.getByText('Domain One')).toBeInTheDocument(); + expect(screen.getByTestId('domain-count-button')).toBeInTheDocument(); + expect(screen.getByText('+1')).toBeInTheDocument(); + }); + + it('should render all domains when multiple is true but headerLayout is false', () => { + renderDomainLabel({ + domains: [mockDomain1, mockDomain2], + multiple: true, + headerLayout: false, + }); + + expect(screen.getByText('Domain One')).toBeInTheDocument(); + expect(screen.getByText('Domain Two')).toBeInTheDocument(); + expect(screen.queryByTestId('domain-count-button')).not.toBeInTheDocument(); + }); + + it('should render "No Domains" text when domains array is empty', () => { + renderDomainLabel({ domains: [] }); + + expect(screen.getByTestId('no-domain-text')).toBeInTheDocument(); + expect(screen.getByText('label.no-entity')).toBeInTheDocument(); + }); + + it('should render "No Domains" text when domains is undefined', () => { + renderDomainLabel({ domains: undefined }); + + expect(screen.getByTestId('no-domain-text')).toBeInTheDocument(); + expect(screen.getByText('label.no-entity')).toBeInTheDocument(); + }); + + it('should render inherited domain with inherit icon', () => { + renderDomainLabel({ domains: [mockInheritedDomain] }); + + expect(screen.getByText('Inherited Domain')).toBeInTheDocument(); + }); + + it('should handle domain with missing name', () => { + const domainWithoutName = { + ...mockDomain1, + name: undefined, + }; + + renderDomainLabel({ domains: [domainWithoutName] }); + + expect(screen.getByTestId('domain-link')).toBeInTheDocument(); + }); + + it('should render domain heading when showDomainHeading is true', () => { + renderDomainLabel({ showDomainHeading: true }); + + expect(screen.getByTestId('header-domain-container')).toBeInTheDocument(); + expect(screen.getByText('label.domain-plural')).toBeInTheDocument(); + }); + + it('should not render domain heading when showDomainHeading is false', () => { + renderDomainLabel({ showDomainHeading: false }); + + expect(screen.queryByText('Domains')).not.toBeInTheDocument(); + }); + + it('should not show domain icon for single domain in header layout', () => { + renderDomainLabel({ + headerLayout: true, + multiple: false, + domains: [mockDomain1], + }); + + expect(screen.queryByTestId('domain-icon')).not.toBeInTheDocument(); + }); + + it('should render DomainSelectableList when hasPermission is true', () => { + renderDomainLabel({ hasPermission: true }); + + expect(screen.getByTestId('domain-selectable-list')).toBeInTheDocument(); + }); + + it('should not render DomainSelectableList when hasPermission is false', () => { + renderDomainLabel({ hasPermission: false }); + + expect( + screen.queryByTestId('domain-selectable-list') + ).not.toBeInTheDocument(); + }); + + it('should not render DomainSelectableList when hasPermission is undefined', () => { + renderDomainLabel({ hasPermission: undefined }); + + expect( + screen.queryByTestId('domain-selectable-list') + ).not.toBeInTheDocument(); + }); + + it('should handle domains as single object instead of array', () => { + renderDomainLabel({ domains: mockDomain1 }); + + expect(screen.getByText('Domain One')).toBeInTheDocument(); + }); + + it('should handle empty domain object', () => { + const emptyDomain = {} as EntityReference; + + renderDomainLabel({ domains: [emptyDomain] }); + + expect(screen.getByTestId('domain-link')).toBeInTheDocument(); + }); + + it('should handle domain with empty fullyQualifiedName', () => { + const domainWithEmptyFQN = { + ...mockDomain1, + fullyQualifiedName: '', + }; + + renderDomainLabel({ domains: [domainWithEmptyFQN] }); + + expect(screen.getByTestId('domain-link')).toBeInTheDocument(); + }); + + it('should handle mixed domain types (inherited and non-inherited)', () => { + renderDomainLabel({ + domains: [mockDomain1, mockInheritedDomain], + multiple: true, + headerLayout: true, + }); + + expect(screen.getByText('Domain One')).toBeInTheDocument(); + expect(screen.getByTestId('domain-count-button')).toBeInTheDocument(); + }); + + it('should have proper test ID for domain count button', () => { + renderDomainLabel({ + domains: [mockDomain1, mockDomain2], + multiple: true, + headerLayout: true, + }); + + expect(screen.getByTestId('domain-count-button')).toBeInTheDocument(); + }); + + it('should have proper test ID for no domain text', () => { + renderDomainLabel({ domains: [] }); + + expect(screen.getByTestId('no-domain-text')).toBeInTheDocument(); + }); +}); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/NoOwner/NoOwnerFound.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/common/NoOwner/NoOwnerFound.interface.ts index 53da2ac3d48..86799ee5148 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/NoOwner/NoOwnerFound.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/NoOwner/NoOwnerFound.interface.ts @@ -13,6 +13,7 @@ import { EntityReference } from '../../../generated/tests/testCase'; export interface NoOwnerFoundProps { + showDashPlaceholder?: boolean; isCompactView: boolean; placeHolder?: string; showLabel?: boolean; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/NoOwner/NoOwnerFound.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/NoOwner/NoOwnerFound.tsx index 98ccb755914..1c9abefd91f 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/NoOwner/NoOwnerFound.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/NoOwner/NoOwnerFound.tsx @@ -13,13 +13,15 @@ import Icon from '@ant-design/icons'; import { Typography } from 'antd'; import classNames from 'classnames'; -import React from 'react'; +import React, { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { ReactComponent as IconUser } from '../../../assets/svg/user.svg'; +import { NO_DATA_PLACEHOLDER } from '../../../constants/constants'; import { UserTeamSelectableList } from '../UserTeamSelectableList/UserTeamSelectableList.component'; import { NoOwnerFoundProps } from './NoOwnerFound.interface'; export const NoOwnerFound: React.FC = ({ + showDashPlaceholder, isCompactView, showLabel = true, placeHolder, @@ -32,6 +34,22 @@ export const NoOwnerFound: React.FC = ({ }) => { const { t } = useTranslation(); + const ownerPlaceholder = useMemo(() => { + const defaultPlaceholder = showDashPlaceholder + ? NO_DATA_PLACEHOLDER + : t('label.no-entity', { entity: t('label.owner-plural') }); + + if (placeHolder) { + if (showLabel) { + return defaultPlaceholder; + } + + return placeHolder; + } + + return defaultPlaceholder; + }, [placeHolder, showLabel, showDashPlaceholder]); + return (
= ({ {!isCompactView && (
- {placeHolder - ? showLabel - ? t('label.no-entity', { entity: placeHolder }) - : placeHolder - : t('label.no-entity', { entity: t('label.owner-plural') })} + {ownerPlaceholder}
)}
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/OwnerLabel/OwnerLabel.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/OwnerLabel/OwnerLabel.component.tsx index 897489a3361..dfcdd0dd303 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/OwnerLabel/OwnerLabel.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/OwnerLabel/OwnerLabel.component.tsx @@ -27,6 +27,7 @@ import './owner-label.less'; import { OwnerLabelProps } from './OwnerLabel.interface'; export const OwnerLabel = ({ + showDashPlaceholder, owners = [], showLabel = true, className, @@ -102,8 +103,8 @@ export const OwnerLabel = ({ .slice(maxVisibleOwners); const renderMultipleType = useMemo(() => { return ( -
-
+
+
{showMultipleTypeTeam.map((owner, index) => (
{showMoreButton && !isCompactView && ( -
- -
+ )}
{isCompactView && onUpdate && ( diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/OwnerLabel/OwnerLabel.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/common/OwnerLabel/OwnerLabel.interface.ts index 6e0df139af6..54949814357 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/OwnerLabel/OwnerLabel.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/OwnerLabel/OwnerLabel.interface.ts @@ -14,6 +14,7 @@ import { ReactNode } from 'react'; import { EntityReference } from '../../../generated/tests/testCase'; export interface OwnerLabelProps { + showDashPlaceholder?: boolean; owners?: EntityReference[]; showLabel?: boolean; className?: string; diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/DataAssetsHeader.utils.tsx b/openmetadata-ui/src/main/resources/ui/src/utils/DataAssetsHeader.utils.tsx index 4522b366758..1dad9b33a57 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/DataAssetsHeader.utils.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/utils/DataAssetsHeader.utils.tsx @@ -104,7 +104,7 @@ export const ExtraInfoLabel = ({ {label} )}
- {value} + {value ?? NO_DATA_PLACEHOLDER}