mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-09-01 05:03:10 +00:00
fix lineage playwright (#17889)
* fix lineage playwright * remove in operator usage and use lodash get utility * fix metric playwright * fix lineage pw * update drag and drop * fix flakiness * minor sonar fix --------- Co-authored-by: Sachin Chaurasiya <sachinchaurasiyachotey87@gmail.com>
This commit is contained in:
parent
41d94ac068
commit
58ed12cf47
@ -34,6 +34,7 @@ import {
|
|||||||
connectEdgeBetweenNodes,
|
connectEdgeBetweenNodes,
|
||||||
deleteEdge,
|
deleteEdge,
|
||||||
deleteNode,
|
deleteNode,
|
||||||
|
editLineage,
|
||||||
performZoomOut,
|
performZoomOut,
|
||||||
removeColumnLineage,
|
removeColumnLineage,
|
||||||
setupEntitiesForLineage,
|
setupEntitiesForLineage,
|
||||||
@ -52,6 +53,7 @@ const entities = [
|
|||||||
MlModelClass,
|
MlModelClass,
|
||||||
ContainerClass,
|
ContainerClass,
|
||||||
SearchIndexClass,
|
SearchIndexClass,
|
||||||
|
ApiEndpointClass,
|
||||||
MetricClass,
|
MetricClass,
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
@ -72,68 +74,66 @@ test.afterAll('Cleanup', async ({ browser }) => {
|
|||||||
for (const EntityClass of entities) {
|
for (const EntityClass of entities) {
|
||||||
const defaultEntity = new EntityClass();
|
const defaultEntity = new EntityClass();
|
||||||
|
|
||||||
test.fixme(
|
test(`Lineage creation from ${defaultEntity.getType()} entity`, async ({
|
||||||
`Lineage creation from ${defaultEntity.getType()} entity`,
|
browser,
|
||||||
async ({ browser }) => {
|
}) => {
|
||||||
test.slow(true);
|
test.slow(true);
|
||||||
|
|
||||||
const { page } = await createNewPage(browser);
|
const { page } = await createNewPage(browser);
|
||||||
const { currentEntity, entities, cleanup } =
|
const { currentEntity, entities, cleanup } = await setupEntitiesForLineage(
|
||||||
await setupEntitiesForLineage(page, defaultEntity);
|
page,
|
||||||
|
defaultEntity
|
||||||
|
);
|
||||||
|
|
||||||
await test.step('Should create lineage for the entity', async () => {
|
await test.step('Should create lineage for the entity', async () => {
|
||||||
await redirectToHomePage(page);
|
await redirectToHomePage(page);
|
||||||
await currentEntity.visitEntityPage(page);
|
await currentEntity.visitEntityPage(page);
|
||||||
await visitLineageTab(page);
|
await visitLineageTab(page);
|
||||||
await verifyColumnLayerInactive(page);
|
await verifyColumnLayerInactive(page);
|
||||||
await page.click('[data-testid="edit-lineage"]');
|
await editLineage(page);
|
||||||
await performZoomOut(page);
|
await performZoomOut(page);
|
||||||
for (const entity of entities) {
|
for (const entity of entities) {
|
||||||
await connectEdgeBetweenNodes(page, currentEntity, entity);
|
await connectEdgeBetweenNodes(page, currentEntity, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
await redirectToHomePage(page);
|
await redirectToHomePage(page);
|
||||||
await currentEntity.visitEntityPage(page);
|
await currentEntity.visitEntityPage(page);
|
||||||
await visitLineageTab(page);
|
await visitLineageTab(page);
|
||||||
await page
|
await page
|
||||||
.locator('.react-flow__controls-fitview')
|
.locator('.react-flow__controls-fitview')
|
||||||
.dispatchEvent('click');
|
.dispatchEvent('click');
|
||||||
|
|
||||||
for (const entity of entities) {
|
for (const entity of entities) {
|
||||||
await verifyNodePresent(page, entity);
|
await verifyNodePresent(page, entity);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('Should create pipeline between entities', async () => {
|
await test.step('Should create pipeline between entities', async () => {
|
||||||
await page.click('[data-testid="edit-lineage"]');
|
await editLineage(page);
|
||||||
await performZoomOut(page);
|
await performZoomOut(page);
|
||||||
|
|
||||||
for (const entity of entities) {
|
for (const entity of entities) {
|
||||||
await applyPipelineFromModal(page, currentEntity, entity, pipeline);
|
await applyPipelineFromModal(page, currentEntity, entity, pipeline);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step(
|
await test.step('Remove lineage between nodes for the entity', async () => {
|
||||||
'Remove lineage between nodes for the entity',
|
await redirectToHomePage(page);
|
||||||
async () => {
|
await currentEntity.visitEntityPage(page);
|
||||||
await redirectToHomePage(page);
|
await visitLineageTab(page);
|
||||||
await currentEntity.visitEntityPage(page);
|
await editLineage(page);
|
||||||
await visitLineageTab(page);
|
await performZoomOut(page);
|
||||||
await page.click('[data-testid="edit-lineage"]');
|
|
||||||
await performZoomOut(page);
|
|
||||||
|
|
||||||
for (const entity of entities) {
|
for (const entity of entities) {
|
||||||
await deleteEdge(page, currentEntity, entity);
|
await deleteEdge(page, currentEntity, entity);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
await cleanup();
|
await cleanup();
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test.fixme('Verify column lineage between tables', async ({ browser }) => {
|
test('Verify column lineage between tables', async ({ browser }) => {
|
||||||
const { page } = await createNewPage(browser);
|
const { page } = await createNewPage(browser);
|
||||||
const { apiContext, afterAction } = await getApiContext(page);
|
const { apiContext, afterAction } = await getApiContext(page);
|
||||||
const table1 = new TableClass();
|
const table1 = new TableClass();
|
||||||
@ -171,117 +171,112 @@ test.fixme('Verify column lineage between tables', async ({ browser }) => {
|
|||||||
await afterAction();
|
await afterAction();
|
||||||
});
|
});
|
||||||
|
|
||||||
test.fixme(
|
test('Verify column lineage between table and topic', async ({ browser }) => {
|
||||||
'Verify column lineage between table and topic',
|
const { page } = await createNewPage(browser);
|
||||||
async ({ browser }) => {
|
const { apiContext, afterAction } = await getApiContext(page);
|
||||||
const { page } = await createNewPage(browser);
|
const table = new TableClass();
|
||||||
const { apiContext, afterAction } = await getApiContext(page);
|
const topic = new TopicClass();
|
||||||
const table = new TableClass();
|
await table.create(apiContext);
|
||||||
const topic = new TopicClass();
|
await topic.create(apiContext);
|
||||||
await table.create(apiContext);
|
|
||||||
await topic.create(apiContext);
|
|
||||||
|
|
||||||
const sourceTableFqn = get(table, 'entityResponseData.fullyQualifiedName');
|
const sourceTableFqn = get(table, 'entityResponseData.fullyQualifiedName');
|
||||||
const sourceCol = `${sourceTableFqn}.${get(
|
const sourceCol = `${sourceTableFqn}.${get(
|
||||||
table,
|
table,
|
||||||
'entityResponseData.columns[0].name'
|
'entityResponseData.columns[0].name'
|
||||||
)}`;
|
)}`;
|
||||||
const targetCol = get(
|
const targetCol = get(
|
||||||
topic,
|
topic,
|
||||||
'entityResponseData.messageSchema.schemaFields[0].children[0].fullyQualifiedName'
|
'entityResponseData.messageSchema.schemaFields[0].children[0].fullyQualifiedName'
|
||||||
);
|
);
|
||||||
|
|
||||||
await addPipelineBetweenNodes(page, table, topic);
|
await addPipelineBetweenNodes(page, table, topic);
|
||||||
await activateColumnLayer(page);
|
await activateColumnLayer(page);
|
||||||
|
|
||||||
// Add column lineage
|
// Add column lineage
|
||||||
await addColumnLineage(page, sourceCol, targetCol);
|
await addColumnLineage(page, sourceCol, targetCol);
|
||||||
await page.click('[data-testid="edit-lineage"]');
|
await page.click('[data-testid="edit-lineage"]');
|
||||||
|
|
||||||
await removeColumnLineage(page, sourceCol, targetCol);
|
await removeColumnLineage(page, sourceCol, targetCol);
|
||||||
await page.click('[data-testid="edit-lineage"]');
|
await page.click('[data-testid="edit-lineage"]');
|
||||||
|
|
||||||
await deleteNode(page, topic);
|
await deleteNode(page, topic);
|
||||||
await table.delete(apiContext);
|
await table.delete(apiContext);
|
||||||
await topic.delete(apiContext);
|
await topic.delete(apiContext);
|
||||||
|
|
||||||
await afterAction();
|
await afterAction();
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
test.fixme(
|
test('Verify column lineage between topic and api endpoint', async ({
|
||||||
'Verify column lineage between topic and api endpoint',
|
browser,
|
||||||
async ({ browser }) => {
|
}) => {
|
||||||
const { page } = await createNewPage(browser);
|
const { page } = await createNewPage(browser);
|
||||||
const { apiContext, afterAction } = await getApiContext(page);
|
const { apiContext, afterAction } = await getApiContext(page);
|
||||||
const topic = new TopicClass();
|
const topic = new TopicClass();
|
||||||
const apiEndpoint = new ApiEndpointClass();
|
const apiEndpoint = new ApiEndpointClass();
|
||||||
|
|
||||||
await topic.create(apiContext);
|
await topic.create(apiContext);
|
||||||
await apiEndpoint.create(apiContext);
|
await apiEndpoint.create(apiContext);
|
||||||
|
|
||||||
const sourceCol = get(
|
const sourceCol = get(
|
||||||
topic,
|
topic,
|
||||||
'entityResponseData.messageSchema.schemaFields[0].children[0].fullyQualifiedName'
|
'entityResponseData.messageSchema.schemaFields[0].children[0].fullyQualifiedName'
|
||||||
);
|
);
|
||||||
|
|
||||||
const targetCol = get(
|
const targetCol = get(
|
||||||
apiEndpoint,
|
apiEndpoint,
|
||||||
'entityResponseData.responseSchema.schemaFields[0].children[1].fullyQualifiedName'
|
'entityResponseData.responseSchema.schemaFields[0].children[1].fullyQualifiedName'
|
||||||
);
|
);
|
||||||
|
|
||||||
await addPipelineBetweenNodes(page, topic, apiEndpoint);
|
await addPipelineBetweenNodes(page, topic, apiEndpoint);
|
||||||
await activateColumnLayer(page);
|
await activateColumnLayer(page);
|
||||||
|
|
||||||
// Add column lineage
|
// Add column lineage
|
||||||
await addColumnLineage(page, sourceCol, targetCol);
|
await addColumnLineage(page, sourceCol, targetCol);
|
||||||
await page.click('[data-testid="edit-lineage"]');
|
await page.click('[data-testid="edit-lineage"]');
|
||||||
|
|
||||||
await removeColumnLineage(page, sourceCol, targetCol);
|
await removeColumnLineage(page, sourceCol, targetCol);
|
||||||
await page.click('[data-testid="edit-lineage"]');
|
await page.click('[data-testid="edit-lineage"]');
|
||||||
|
|
||||||
await deleteNode(page, apiEndpoint);
|
await deleteNode(page, apiEndpoint);
|
||||||
await topic.delete(apiContext);
|
await topic.delete(apiContext);
|
||||||
await apiEndpoint.delete(apiContext);
|
await apiEndpoint.delete(apiContext);
|
||||||
|
|
||||||
await afterAction();
|
await afterAction();
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
test.fixme(
|
test('Verify column lineage between table and api endpoint', async ({
|
||||||
'Verify column lineage between table and api endpoint',
|
browser,
|
||||||
async ({ browser }) => {
|
}) => {
|
||||||
const { page } = await createNewPage(browser);
|
const { page } = await createNewPage(browser);
|
||||||
const { apiContext, afterAction } = await getApiContext(page);
|
const { apiContext, afterAction } = await getApiContext(page);
|
||||||
const table = new TableClass();
|
const table = new TableClass();
|
||||||
const apiEndpoint = new ApiEndpointClass();
|
const apiEndpoint = new ApiEndpointClass();
|
||||||
await table.create(apiContext);
|
await table.create(apiContext);
|
||||||
await apiEndpoint.create(apiContext);
|
await apiEndpoint.create(apiContext);
|
||||||
|
|
||||||
const sourceTableFqn = get(table, 'entityResponseData.fullyQualifiedName');
|
const sourceTableFqn = get(table, 'entityResponseData.fullyQualifiedName');
|
||||||
const sourceCol = `${sourceTableFqn}.${get(
|
const sourceCol = `${sourceTableFqn}.${get(
|
||||||
table,
|
table,
|
||||||
'entityResponseData.columns[0].name'
|
'entityResponseData.columns[0].name'
|
||||||
)}`;
|
)}`;
|
||||||
const targetCol = get(
|
const targetCol = get(
|
||||||
apiEndpoint,
|
apiEndpoint,
|
||||||
'entityResponseData.responseSchema.schemaFields[0].children[0].fullyQualifiedName'
|
'entityResponseData.responseSchema.schemaFields[0].children[0].fullyQualifiedName'
|
||||||
);
|
);
|
||||||
|
|
||||||
await addPipelineBetweenNodes(page, table, apiEndpoint);
|
await addPipelineBetweenNodes(page, table, apiEndpoint);
|
||||||
await activateColumnLayer(page);
|
await activateColumnLayer(page);
|
||||||
|
|
||||||
// Add column lineage
|
// Add column lineage
|
||||||
await addColumnLineage(page, sourceCol, targetCol);
|
await addColumnLineage(page, sourceCol, targetCol);
|
||||||
await page.click('[data-testid="edit-lineage"]');
|
await page.click('[data-testid="edit-lineage"]');
|
||||||
|
|
||||||
await removeColumnLineage(page, sourceCol, targetCol);
|
await removeColumnLineage(page, sourceCol, targetCol);
|
||||||
await page.click('[data-testid="edit-lineage"]');
|
await page.click('[data-testid="edit-lineage"]');
|
||||||
|
|
||||||
await deleteNode(page, apiEndpoint);
|
await deleteNode(page, apiEndpoint);
|
||||||
await table.delete(apiContext);
|
await table.delete(apiContext);
|
||||||
await apiEndpoint.delete(apiContext);
|
await apiEndpoint.delete(apiContext);
|
||||||
|
|
||||||
await afterAction();
|
await afterAction();
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
@ -37,12 +37,20 @@ export const activateColumnLayer = async (page: Page) => {
|
|||||||
await page.click('[data-testid="lineage-layer-column-btn"]');
|
await page.click('[data-testid="lineage-layer-column-btn"]');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const editLineage = async (page: Page) => {
|
||||||
|
await page.click('[data-testid="edit-lineage"]');
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
page.getByTestId('table_search_index-draggable-icon')
|
||||||
|
).toBeVisible();
|
||||||
|
};
|
||||||
|
|
||||||
export const performZoomOut = async (page: Page) => {
|
export const performZoomOut = async (page: Page) => {
|
||||||
for (let i = 0; i < 5; i++) {
|
const zoomOutBtn = page.locator('.react-flow__controls-zoomout');
|
||||||
const zoomOutBtn = page.locator('.react-flow__controls-zoomout');
|
const enabled = await zoomOutBtn.isEnabled();
|
||||||
const enabled = await zoomOutBtn.isEnabled();
|
if (enabled) {
|
||||||
if (enabled) {
|
for (const _ of Array.from({ length: 8 })) {
|
||||||
zoomOutBtn.dispatchEvent('click');
|
await zoomOutBtn.dispatchEvent('click');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -78,6 +86,20 @@ export const deleteEdge = async (
|
|||||||
await deleteRes;
|
await deleteRes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const dragAndDropNode = async (
|
||||||
|
page: Page,
|
||||||
|
originSelector: string,
|
||||||
|
destinationSelector: string
|
||||||
|
) => {
|
||||||
|
const destinationElement = await page.waitForSelector(destinationSelector);
|
||||||
|
await page.hover(originSelector);
|
||||||
|
await page.mouse.down();
|
||||||
|
const box = (await destinationElement.boundingBox())!;
|
||||||
|
await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
|
||||||
|
await destinationElement.hover();
|
||||||
|
await page.mouse.up();
|
||||||
|
};
|
||||||
|
|
||||||
export const dragConnection = async (
|
export const dragConnection = async (
|
||||||
page: Page,
|
page: Page,
|
||||||
sourceId: string,
|
sourceId: string,
|
||||||
@ -109,10 +131,10 @@ export const connectEdgeBetweenNodes = async (
|
|||||||
const toNodeName = get(toNode, 'entityResponseData.name');
|
const toNodeName = get(toNode, 'entityResponseData.name');
|
||||||
const toNodeFqn = get(toNode, 'entityResponseData.fullyQualifiedName');
|
const toNodeFqn = get(toNode, 'entityResponseData.fullyQualifiedName');
|
||||||
|
|
||||||
await page.locator(`[data-testid="${type}-draggable-icon"]`).hover();
|
const source = `[data-testid="${type}-draggable-icon"]`;
|
||||||
await page.mouse.down();
|
const target = '[data-testid="lineage-details"]';
|
||||||
await page.locator('[data-testid="lineage-details"]').hover();
|
|
||||||
await page.mouse.up();
|
await dragAndDropNode(page, source, target);
|
||||||
|
|
||||||
await page.locator('[data-testid="suggestion-node"]').dispatchEvent('click');
|
await page.locator('[data-testid="suggestion-node"]').dispatchEvent('click');
|
||||||
|
|
||||||
@ -370,7 +392,7 @@ export const addPipelineBetweenNodes = async (
|
|||||||
) => {
|
) => {
|
||||||
await sourceEntity.visitEntityPage(page);
|
await sourceEntity.visitEntityPage(page);
|
||||||
await page.click('[data-testid="lineage"]');
|
await page.click('[data-testid="lineage"]');
|
||||||
await page.click('[data-testid="edit-lineage"]');
|
await editLineage(page);
|
||||||
|
|
||||||
await performZoomOut(page);
|
await performZoomOut(page);
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ import Icon from '@ant-design/icons';
|
|||||||
import { Button, Col, Divider, Row, Space, Tooltip, Typography } from 'antd';
|
import { Button, Col, Divider, Row, Space, Tooltip, Typography } from 'antd';
|
||||||
import ButtonGroup from 'antd/lib/button/button-group';
|
import ButtonGroup from 'antd/lib/button/button-group';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import { capitalize, isEmpty } from 'lodash';
|
import { capitalize, get, isEmpty } from 'lodash';
|
||||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
@ -161,18 +161,18 @@ export const DataAssetsHeader = ({
|
|||||||
const [isBreadcrumbLoading, setIsBreadcrumbLoading] = useState(false);
|
const [isBreadcrumbLoading, setIsBreadcrumbLoading] = useState(false);
|
||||||
const [isFollowingLoading, setIsFollowingLoading] = useState(false);
|
const [isFollowingLoading, setIsFollowingLoading] = useState(false);
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const icon = useMemo(
|
const icon = useMemo(() => {
|
||||||
() =>
|
const serviceType = get(dataAsset, 'serviceType', '');
|
||||||
'serviceType' in dataAsset ? (
|
|
||||||
<img
|
return serviceType ? (
|
||||||
className="h-9"
|
<img
|
||||||
src={serviceUtilClassBase.getServiceTypeLogo(
|
className="h-9"
|
||||||
dataAsset as SearchSourceAlias
|
src={serviceUtilClassBase.getServiceTypeLogo(
|
||||||
)}
|
dataAsset as SearchSourceAlias
|
||||||
/>
|
)}
|
||||||
) : null,
|
/>
|
||||||
[dataAsset]
|
) : null;
|
||||||
);
|
}, [dataAsset]);
|
||||||
const [copyTooltip, setCopyTooltip] = useState<string>();
|
const [copyTooltip, setCopyTooltip] = useState<string>();
|
||||||
|
|
||||||
const excludeEntityService = useMemo(
|
const excludeEntityService = useMemo(
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
import Icon from '@ant-design/icons/lib/components/Icon';
|
import Icon from '@ant-design/icons/lib/components/Icon';
|
||||||
import { Button, Col, Divider, Row, Space, Tooltip, Typography } from 'antd';
|
import { Button, Col, Divider, Row, Space, Tooltip, Typography } from 'antd';
|
||||||
import { isEmpty } from 'lodash';
|
import { get, isEmpty } from 'lodash';
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ReactComponent as VersionIcon } from '../../../assets/svg/ic-version.svg';
|
import { ReactComponent as VersionIcon } from '../../../assets/svg/ic-version.svg';
|
||||||
@ -89,13 +89,20 @@ function DataAssetsVersionHeader({
|
|||||||
() => getDataAssetsVersionHeaderInfo(entityType, currentVersionData),
|
() => getDataAssetsVersionHeaderInfo(entityType, currentVersionData),
|
||||||
[entityType, currentVersionData]
|
[entityType, currentVersionData]
|
||||||
);
|
);
|
||||||
const logo = useMemo(
|
|
||||||
() =>
|
const icon = useMemo(() => {
|
||||||
serviceUtilClassBase.getServiceTypeLogo(
|
const serviceType = get(currentVersionData, 'serviceType', '');
|
||||||
currentVersionData as SearchSourceAlias
|
|
||||||
),
|
return serviceType ? (
|
||||||
[currentVersionData]
|
<img
|
||||||
);
|
alt="service-icon"
|
||||||
|
className="h-9"
|
||||||
|
src={serviceUtilClassBase.getServiceTypeLogo(
|
||||||
|
currentVersionData as SearchSourceAlias
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
) : null;
|
||||||
|
}, [currentVersionData]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row className="p-x-lg" gutter={[8, 12]} justify="space-between">
|
<Row className="p-x-lg" gutter={[8, 12]} justify="space-between">
|
||||||
@ -108,11 +115,7 @@ function DataAssetsVersionHeader({
|
|||||||
<EntityHeaderTitle
|
<EntityHeaderTitle
|
||||||
deleted={deleted}
|
deleted={deleted}
|
||||||
displayName={displayName}
|
displayName={displayName}
|
||||||
icon={
|
icon={icon}
|
||||||
'serviceType' in currentVersionData && (
|
|
||||||
<img className="h-9" src={logo} />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
name={currentVersionData?.name}
|
name={currentVersionData?.name}
|
||||||
serviceName={serviceName ?? ''}
|
serviceName={serviceName ?? ''}
|
||||||
/>
|
/>
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
import { CloseOutlined } from '@ant-design/icons';
|
import { CloseOutlined } from '@ant-design/icons';
|
||||||
import { Col, Drawer, Row } from 'antd';
|
import { Col, Drawer, Row } from 'antd';
|
||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep, get } from 'lodash';
|
||||||
import { EntityDetailUnion } from 'Models';
|
import { EntityDetailUnion } from 'Models';
|
||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import { EntityType } from '../../../enums/entity.enum';
|
import { EntityType } from '../../../enums/entity.enum';
|
||||||
@ -29,7 +29,6 @@ import { StoredProcedure } from '../../../generated/entity/data/storedProcedure'
|
|||||||
import { Table } from '../../../generated/entity/data/table';
|
import { Table } from '../../../generated/entity/data/table';
|
||||||
import { Topic } from '../../../generated/entity/data/topic';
|
import { Topic } from '../../../generated/entity/data/topic';
|
||||||
import { TagLabel } from '../../../generated/type/tagLabel';
|
import { TagLabel } from '../../../generated/type/tagLabel';
|
||||||
import { SearchSourceAlias } from '../../../interface/search.interface';
|
|
||||||
import entityUtilClassBase from '../../../utils/EntityUtilClassBase';
|
import entityUtilClassBase from '../../../utils/EntityUtilClassBase';
|
||||||
import {
|
import {
|
||||||
DRAWER_NAVIGATION_OPTIONS,
|
DRAWER_NAVIGATION_OPTIONS,
|
||||||
@ -72,18 +71,16 @@ const EntityInfoDrawer = ({
|
|||||||
[selectedNode]
|
[selectedNode]
|
||||||
);
|
);
|
||||||
|
|
||||||
const icon = useMemo(
|
const icon = useMemo(() => {
|
||||||
() =>
|
const serviceType = get(selectedNode, 'serviceType', '');
|
||||||
'serviceType' in selectedNode ? (
|
|
||||||
<img
|
return serviceType ? (
|
||||||
className="h-9"
|
<img
|
||||||
src={serviceUtilClassBase.getServiceTypeLogo(
|
className="h-9"
|
||||||
selectedNode as SearchSourceAlias
|
src={serviceUtilClassBase.getServiceTypeLogo(selectedNode)}
|
||||||
)}
|
/>
|
||||||
/>
|
) : null;
|
||||||
) : null,
|
}, [selectedNode]);
|
||||||
[selectedNode]
|
|
||||||
);
|
|
||||||
|
|
||||||
const tags = useMemo(
|
const tags = useMemo(
|
||||||
() =>
|
() =>
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
import { Button, Select } from 'antd';
|
import { Button, Select } from 'antd';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import { capitalize, debounce } from 'lodash';
|
import { capitalize, debounce, get } from 'lodash';
|
||||||
import React, {
|
import React, {
|
||||||
FC,
|
FC,
|
||||||
HTMLAttributes,
|
HTMLAttributes,
|
||||||
@ -125,9 +125,7 @@ const NodeSuggestions: FC<EntitySuggestionProps> = ({
|
|||||||
}}>
|
}}>
|
||||||
<div className="d-flex items-center w-full overflow-hidden">
|
<div className="d-flex items-center w-full overflow-hidden">
|
||||||
<img
|
<img
|
||||||
alt={
|
alt={get(entity, 'serviceType', '') || entity.name}
|
||||||
'serviceType' in entity ? entity.serviceType : entity.name
|
|
||||||
}
|
|
||||||
className="m-r-xs"
|
className="m-r-xs"
|
||||||
height="16px"
|
height="16px"
|
||||||
src={serviceUtilClassBase.getServiceTypeLogo(entity)}
|
src={serviceUtilClassBase.getServiceTypeLogo(entity)}
|
||||||
|
@ -75,7 +75,6 @@ import {
|
|||||||
} from '../../generated/type/entityLineage';
|
} from '../../generated/type/entityLineage';
|
||||||
import { useFqn } from '../../hooks/useFqn';
|
import { useFqn } from '../../hooks/useFqn';
|
||||||
import { getLineageDataByFQN, updateLineageEdge } from '../../rest/lineageAPI';
|
import { getLineageDataByFQN, updateLineageEdge } from '../../rest/lineageAPI';
|
||||||
import { isDeleted } from '../../utils/CommonUtils';
|
|
||||||
import {
|
import {
|
||||||
addLineageHandler,
|
addLineageHandler,
|
||||||
centerNodePosition,
|
centerNodePosition,
|
||||||
@ -650,12 +649,7 @@ const LineageProvider = ({ children }: LineageProviderProps) => {
|
|||||||
} else {
|
} else {
|
||||||
setSelectedEdge(undefined);
|
setSelectedEdge(undefined);
|
||||||
setActiveNode(node);
|
setActiveNode(node);
|
||||||
const sourceTypeNode = node.data.node as SourceType;
|
setSelectedNode(node.data.node as SourceType);
|
||||||
setSelectedNode({
|
|
||||||
...sourceTypeNode,
|
|
||||||
// we are getting deleted as a string instead of boolean from API so need to handle it like this
|
|
||||||
deleted: isDeleted(sourceTypeNode.deleted),
|
|
||||||
});
|
|
||||||
setIsDrawerOpen(true);
|
setIsDrawerOpen(true);
|
||||||
handleLineageTracing(node);
|
handleLineageTracing(node);
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ import { ColumnLineage, LineageDetails } from '../generated/type/entityLineage';
|
|||||||
import { EntityReference } from '../generated/type/entityReference';
|
import { EntityReference } from '../generated/type/entityReference';
|
||||||
import { TagSource } from '../generated/type/tagLabel';
|
import { TagSource } from '../generated/type/tagLabel';
|
||||||
import { addLineage, deleteLineageEdge } from '../rest/miscAPI';
|
import { addLineage, deleteLineageEdge } from '../rest/miscAPI';
|
||||||
import { getPartialNameFromTableFQN } from './CommonUtils';
|
import { getPartialNameFromTableFQN, isDeleted } from './CommonUtils';
|
||||||
import { getEntityName, getEntityReferenceFromEntity } from './EntityUtils';
|
import { getEntityName, getEntityReferenceFromEntity } from './EntityUtils';
|
||||||
import Fqn from './Fqn';
|
import Fqn from './Fqn';
|
||||||
import { jsonToCSV } from './StringsUtils';
|
import { jsonToCSV } from './StringsUtils';
|
||||||
@ -728,6 +728,9 @@ export const createNodes = (
|
|||||||
? node.type
|
? node.type
|
||||||
: getNodeType(edgesData, node.id);
|
: getNodeType(edgesData, node.id);
|
||||||
|
|
||||||
|
// we are getting deleted as a string instead of boolean from API so need to handle it like this
|
||||||
|
node.deleted = isDeleted(node.deleted);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: `${node.id}`,
|
id: `${node.id}`,
|
||||||
sourcePosition: Position.Right,
|
sourcePosition: Position.Right,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user