diff --git a/datahub-web-react/src/Mocks.tsx b/datahub-web-react/src/Mocks.tsx
index 160174a04a..f606356e10 100644
--- a/datahub-web-react/src/Mocks.tsx
+++ b/datahub-web-react/src/Mocks.tsx
@@ -4352,3 +4352,25 @@ export const mockFineGrainedLineages1: GenericEntityProperties = {
},
],
};
+
+export const useEntityDataFunc = () => {
+ const value = {
+ entityData: {
+ parentContainers: {
+ containers: [
+ {
+ properties: {
+ name: 'name1',
+ },
+ },
+ {
+ properties: {
+ name: 'name2',
+ },
+ },
+ ],
+ },
+ },
+ };
+ return value;
+};
diff --git a/datahub-web-react/src/app/lineage/__tests__/LineageEntityView.empty.test.tsx b/datahub-web-react/src/app/lineage/__tests__/LineageEntityView.empty.test.tsx
new file mode 100644
index 0000000000..1121bbc6da
--- /dev/null
+++ b/datahub-web-react/src/app/lineage/__tests__/LineageEntityView.empty.test.tsx
@@ -0,0 +1,27 @@
+import { render } from '@testing-library/react';
+import React from 'react';
+
+import LineageEntityView from '@app/lineage/manage/LineageEntityView';
+import { dataset1 } from '@src/Mocks';
+import { getTestEntityRegistry } from '@utils/test-utils/TestPageContainer';
+
+const mockEntityRegistry = getTestEntityRegistry();
+vi.mock('../../useEntityRegistry', () => ({
+ useEntityRegistry: () => mockEntityRegistry,
+}));
+vi.mock('@app/entity/shared/EntityContext', () => ({
+ useEntityData: () => {
+ return {};
+ },
+}));
+describe('LineageEntityViewEmpty', () => {
+ it('should render an entity properly in LineageEntityView if no containers', () => {
+ const { getByTestId, getByText } = render();
+ // expect platform logo, platform name, divider, entity type, and display name
+ expect(getByTestId('platform-logo')).toBeInTheDocument();
+ expect(getByText(dataset1.platform.name)).toBeInTheDocument();
+ expect(getByTestId('divider')).toBeInTheDocument();
+ expect(getByText('Dataset')).toBeInTheDocument();
+ expect(getByText(dataset1.properties.name)).toBeInTheDocument();
+ });
+});
diff --git a/datahub-web-react/src/app/lineage/__tests__/LineageEntityView.test.tsx b/datahub-web-react/src/app/lineage/__tests__/LineageEntityView.test.tsx
index 51e1ef121d..0d9d5c4dc4 100644
--- a/datahub-web-react/src/app/lineage/__tests__/LineageEntityView.test.tsx
+++ b/datahub-web-react/src/app/lineage/__tests__/LineageEntityView.test.tsx
@@ -2,7 +2,7 @@ import { render } from '@testing-library/react';
import React from 'react';
import LineageEntityView from '@app/lineage/manage/LineageEntityView';
-import { dataset1 } from '@src/Mocks';
+import { dataset1, useEntityDataFunc } from '@src/Mocks';
import { getTestEntityRegistry } from '@utils/test-utils/TestPageContainer';
const mockEntityRegistry = getTestEntityRegistry();
@@ -10,10 +10,15 @@ vi.mock('../../useEntityRegistry', () => ({
useEntityRegistry: () => mockEntityRegistry,
}));
+vi.mock('@app/entity/shared/EntityContext', () => ({
+ useEntityData: () => {
+ return useEntityDataFunc();
+ },
+}));
+
describe('LineageEntityView', () => {
it('should render an entity properly in LineageEntityView', () => {
const { getByTestId, getByText } = render();
-
// expect platform logo, platform name, divider, entity type, and display name
expect(getByTestId('platform-logo')).toBeInTheDocument();
expect(getByText(dataset1.platform.name)).toBeInTheDocument();
@@ -25,18 +30,26 @@ describe('LineageEntityView', () => {
it('should render the subtype name if it exists and not the type name', () => {
const datasetWithSubtype = { ...dataset1, subTypes: { typeNames: ['view'] } };
const { getByText, queryByText } = render();
-
expect(queryByText('Dataset')).not.toBeInTheDocument();
expect(getByText('View')).toBeInTheDocument();
});
it('should not render a divider if there is no platform name', () => {
+ vi.mock('@app/entity/shared/EntityContext', () => ({
+ useEntityData: () => {
+ return useEntityDataFunc();
+ },
+ }));
+
const datasetNoPlatformName = {
...dataset1,
platform: { ...dataset1.platform, name: '', properties: { displayName: '' } },
};
const { queryByTestId } = render();
-
expect(queryByTestId('divider')).not.toBeInTheDocument();
});
+
+ afterAll(() => {
+ vi.resetAllMocks();
+ });
});
diff --git a/datahub-web-react/src/app/lineage/manage/ContainerView.tsx b/datahub-web-react/src/app/lineage/manage/ContainerView.tsx
new file mode 100644
index 0000000000..046de602ee
--- /dev/null
+++ b/datahub-web-react/src/app/lineage/manage/ContainerView.tsx
@@ -0,0 +1,30 @@
+import React from 'react';
+
+import { StyledRightOutlined } from '@app/entity/shared/containers/profile/header/PlatformContent/ParentNodesView';
+
+import { Container } from '@types';
+
+export interface ContainerViewProps {
+ directContainer: Container | undefined | null;
+ remainingContainers: Container[] | undefined | null;
+}
+
+export function ContainerView({ directContainer, remainingContainers }: ContainerViewProps) {
+ return (
+ <>
+ {remainingContainers &&
+ remainingContainers.map((c) => (
+ <>
+
+ {c?.properties?.name}
+ >
+ ))}
+ {directContainer && (
+ <>
+
+ {directContainer?.properties?.name}
+ >
+ )}
+ >
+ );
+}
diff --git a/datahub-web-react/src/app/lineage/manage/EntityEdge.tsx b/datahub-web-react/src/app/lineage/manage/EntityEdge.tsx
index 609ccb7a29..41afef5ede 100644
--- a/datahub-web-react/src/app/lineage/manage/EntityEdge.tsx
+++ b/datahub-web-react/src/app/lineage/manage/EntityEdge.tsx
@@ -3,14 +3,36 @@ import Text from 'antd/lib/typography/Text';
import React from 'react';
import styled from 'styled-components/macro';
+import { useEntityData } from '@app/entity/shared/EntityContext';
import { ANTD_GRAY, DEFAULT_SYSTEM_ACTOR_URNS } from '@app/entity/shared/constants';
+import { getPlatformName } from '@app/entity/shared/utils';
+import { ContainerView } from '@app/lineage/manage/ContainerView';
import UserAvatar from '@app/lineage/manage/UserAvatar';
import { useEntityRegistry } from '@app/useEntityRegistry';
import { CorpUser, Entity } from '@types';
-const EntityItem = styled.div`
+const PlatformContent = styled.div<{ removeMargin?: boolean }>`
+ display: flex;
+ align-items: center;
+ font-size: 10px;
+ margin-left: 5px;
+ color: ${ANTD_GRAY[7]};
+`;
+
+const PlatformName = styled.span`
+ margin-left: 0px;
+`;
+
+const EntityItemOuter = styled.div`
border-bottom: 1px solid ${ANTD_GRAY[4]};
+ display: block;
+ align-items: center;
+ padding: 12px 0;
+ justify-content: space-between;
+`;
+
+const EntityItem = styled.div`
display: flex;
align-items: center;
padding: 12px 0;
@@ -45,23 +67,33 @@ interface Props {
export default function EntityEdge({ entity, removeEntity, createdActor, createdOn }: Props) {
const entityRegistry = useEntityRegistry();
+ const { entityData } = useEntityData();
const genericProps = entityRegistry.getGenericEntityProperties(entity.type, entity);
const platformLogoUrl = genericProps?.platform?.properties?.logoUrl;
const shouldDisplayAvatar =
createdActor && !DEFAULT_SYSTEM_ACTOR_URNS.includes(createdActor.urn) && createdActor.properties !== null;
-
+ const containers = entityData?.parentContainers?.containers;
+ const remainingContainers = containers?.slice(1);
+ const directContainer = containers ? containers[0] : null;
+ const platformName = getPlatformName(genericProps);
return (
-
-
- {platformLogoUrl && }{' '}
-
- {entityRegistry.getDisplayName(entity.type, entity)}
-
-
-
- {shouldDisplayAvatar && }
- removeEntity(entity)} />
-
-
+
+
+ {platformName}
+
+
+
+
+ {platformLogoUrl && }{' '}
+
+ {entityRegistry.getDisplayName(entity.type, entity)}
+
+
+
+ {shouldDisplayAvatar && }
+ removeEntity(entity)} />
+
+
+
);
}
diff --git a/datahub-web-react/src/app/lineage/manage/LineageEntityView.tsx b/datahub-web-react/src/app/lineage/manage/LineageEntityView.tsx
index 99fbd7310d..b84f37c438 100644
--- a/datahub-web-react/src/app/lineage/manage/LineageEntityView.tsx
+++ b/datahub-web-react/src/app/lineage/manage/LineageEntityView.tsx
@@ -2,8 +2,10 @@ import { Divider } from 'antd';
import React from 'react';
import styled from 'styled-components/macro';
+import { useEntityData } from '@app/entity/shared/EntityContext';
import { ANTD_GRAY } from '@app/entity/shared/constants';
import { getPlatformName } from '@app/entity/shared/utils';
+import { ContainerView } from '@app/lineage/manage/ContainerView';
import { capitalizeFirstLetterOnly } from '@app/shared/textUtil';
import { useEntityRegistry } from '@app/useEntityRegistry';
@@ -44,22 +46,27 @@ interface Props {
export default function LineageEntityView({ entity, displaySearchResult }: Props) {
const entityRegistry = useEntityRegistry();
const genericProps = entityRegistry.getGenericEntityProperties(entity.type, entity);
+ const { entityData } = useEntityData();
const platformLogoUrl = genericProps?.platform?.properties?.logoUrl;
const platformName = getPlatformName(genericProps);
+ const containers = entityData?.parentContainers?.containers;
+ const remainingContainers = containers?.slice(1);
+ const directContainer = containers ? containers[0] : null;
return (
- {platformLogoUrl && (
-
- )}
- {platformName}
- {platformName && }
{capitalizeFirstLetterOnly(genericProps?.subTypes?.typeNames?.[0]) ||
entityRegistry.getEntityName(entity.type)}
+ {platformName && }
+ {platformLogoUrl && (
+
+ )}
+ {platformName}
+
{entityRegistry.getDisplayName(entity.type, entity)}