mirror of
https://github.com/datahub-project/datahub.git
synced 2025-09-26 01:23:16 +00:00
Issue-13594: Show database and schema. (#13856)
Co-authored-by: Maciek Rakowski <maciekrakowski@Macieks-MacBook-Pro.local> Co-authored-by: Andrew Sikowitz <andrew.sikowitz@acryl.io>
This commit is contained in:
parent
f04244fd69
commit
0242777c4b
@ -4352,3 +4352,25 @@ export const mockFineGrainedLineages1: GenericEntityProperties = {
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const useEntityDataFunc = () => {
|
||||
const value = {
|
||||
entityData: {
|
||||
parentContainers: {
|
||||
containers: [
|
||||
{
|
||||
properties: {
|
||||
name: 'name1',
|
||||
},
|
||||
},
|
||||
{
|
||||
properties: {
|
||||
name: 'name2',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
return value;
|
||||
};
|
||||
|
@ -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(<LineageEntityView entity={dataset1} />);
|
||||
// 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();
|
||||
});
|
||||
});
|
@ -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(<LineageEntityView entity={dataset1} />);
|
||||
|
||||
// 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(<LineageEntityView entity={datasetWithSubtype} />);
|
||||
|
||||
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(<LineageEntityView entity={datasetNoPlatformName} />);
|
||||
|
||||
expect(queryByTestId('divider')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
vi.resetAllMocks();
|
||||
});
|
||||
});
|
||||
|
30
datahub-web-react/src/app/lineage/manage/ContainerView.tsx
Normal file
30
datahub-web-react/src/app/lineage/manage/ContainerView.tsx
Normal file
@ -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) => (
|
||||
<>
|
||||
<StyledRightOutlined data-testid="right-arrow" />
|
||||
<span>{c?.properties?.name}</span>
|
||||
</>
|
||||
))}
|
||||
{directContainer && (
|
||||
<>
|
||||
<StyledRightOutlined data-testid="right-arrow" />
|
||||
<span>{directContainer?.properties?.name}</span>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
@ -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 (
|
||||
<EntityItem data-testid="lineage-entity-item">
|
||||
<NameAndLogoWrapper>
|
||||
{platformLogoUrl && <PlatformLogo src={platformLogoUrl} alt="platform logo" />}{' '}
|
||||
<EntityName ellipsis={{ tooltip: entityRegistry.getDisplayName(entity.type, entity) }}>
|
||||
{entityRegistry.getDisplayName(entity.type, entity)}
|
||||
</EntityName>
|
||||
</NameAndLogoWrapper>
|
||||
<span>
|
||||
{shouldDisplayAvatar && <UserAvatar createdActor={createdActor} createdOn={createdOn} />}
|
||||
<StyledClose onClick={() => removeEntity(entity)} />
|
||||
</span>
|
||||
</EntityItem>
|
||||
<EntityItemOuter>
|
||||
<PlatformContent>
|
||||
<PlatformName>{platformName}</PlatformName>
|
||||
<ContainerView remainingContainers={remainingContainers} directContainer={directContainer} />
|
||||
</PlatformContent>
|
||||
<EntityItem data-testid="lineage-entity-item">
|
||||
<NameAndLogoWrapper>
|
||||
{platformLogoUrl && <PlatformLogo src={platformLogoUrl} alt="platform logo" />}{' '}
|
||||
<EntityName ellipsis={{ tooltip: entityRegistry.getDisplayName(entity.type, entity) }}>
|
||||
{entityRegistry.getDisplayName(entity.type, entity)}
|
||||
</EntityName>
|
||||
</NameAndLogoWrapper>
|
||||
<span>
|
||||
{shouldDisplayAvatar && <UserAvatar createdActor={createdActor} createdOn={createdOn} />}
|
||||
<StyledClose onClick={() => removeEntity(entity)} />
|
||||
</span>
|
||||
</EntityItem>
|
||||
</EntityItemOuter>
|
||||
);
|
||||
}
|
||||
|
@ -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 (
|
||||
<EntityWrapper shrinkPadding={displaySearchResult}>
|
||||
<PlatformContent removeMargin={displaySearchResult}>
|
||||
{platformLogoUrl && (
|
||||
<PlatformLogo src={platformLogoUrl} alt="platform logo" data-testid="platform-logo" />
|
||||
)}
|
||||
<span>{platformName}</span>
|
||||
{platformName && <StyledDivider type="vertical" data-testid="divider" />}
|
||||
<span>
|
||||
{capitalizeFirstLetterOnly(genericProps?.subTypes?.typeNames?.[0]) ||
|
||||
entityRegistry.getEntityName(entity.type)}
|
||||
</span>
|
||||
{platformName && <StyledDivider type="vertical" data-testid="divider" />}
|
||||
{platformLogoUrl && (
|
||||
<PlatformLogo src={platformLogoUrl} alt="platform logo" data-testid="platform-logo" />
|
||||
)}
|
||||
<span>{platformName}</span>
|
||||
<ContainerView remainingContainers={remainingContainers} directContainer={directContainer} />
|
||||
</PlatformContent>
|
||||
<EntityName shrinkSize={displaySearchResult}>
|
||||
{entityRegistry.getDisplayName(entity.type, entity)}
|
||||
|
Loading…
x
Reference in New Issue
Block a user