Show collapse for record type of topic entity (#16063)

* fix minor lineage issues

* fix cypress

* fix lineage cypress
This commit is contained in:
Karan Hotchandani 2024-04-29 19:16:40 +05:30 committed by GitHub
parent eac0466b4d
commit 876a02bcdb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 146 additions and 39 deletions

View File

@ -17,6 +17,7 @@
- "openmetadata-ui/**/*[sS]earch*"
- "openmetadata-ui/**/*[mM]y[dD]ata*"
- "openmetadata-ui/**/*[eE]xplore*"
- "openmetadata-ui/**/*[eE]ntity*"
"e2e:Governance":
- "openmetadata-ui/**/*[gG]lossary*"

View File

@ -38,7 +38,7 @@ const dragConnection = (sourceId, targetId, isColumnLineage = false) => {
};
const performZoomOut = () => {
for (let i = 0; i < 7; i++) {
for (let i = 0; i < 12; i++) {
cy.get('.react-flow__controls-zoomout').click({ force: true });
}
};
@ -227,6 +227,7 @@ describe('Lineage verification', { tags: 'DataAssets' }, () => {
LINEAGE_ITEMS.forEach((entity, index) => {
it(`Lineage Add Node for entity ${entity.entityType}`, () => {
interceptURL('GET', '/api/v1/lineage', 'lineageApi');
visitEntityDetailsPage({
term: entity.term,
serviceName: entity.serviceName,
@ -248,6 +249,8 @@ describe('Lineage verification', { tags: 'DataAssets' }, () => {
cy.get('[data-testid="edit-lineage"]').click();
cy.reload();
verifyResponseStatusCode('@lineageApi', 200);
performZoomOut();
// Verify Added Nodes

View File

@ -72,6 +72,7 @@
"@tiptap/suggestion": "^2.3.0",
"@toast-ui/react-editor": "^3.1.8",
"@types/turndown": "^5.0.4",
"@dagrejs/dagre": "^1.1.2",
"analytics": "^0.8.1",
"antd": "4.24.0",
"antlr4": "4.9.2",
@ -82,7 +83,6 @@
"cookie-storage": "^6.1.0",
"cronstrue": "^1.122.0",
"crypto-random-string-with-promisify-polyfill": "^5.0.0",
"dagre": "^0.8.5",
"diff": "^5.0.0",
"eventemitter3": "^5.0.1",
"fast-json-patch": "^3.1.1",
@ -240,4 +240,4 @@
"prosemirror-view": "1.28.2",
"axios": "1.6.4"
}
}
}

View File

@ -75,16 +75,23 @@ const EdgeInfoDrawer = ({
}
});
const {
entityType: sourceEntityType = '',
fullyQualifiedName: sourceFqn = '',
} = sourceData?.data?.node ?? {};
const {
entityType: targetEntityType = '',
fullyQualifiedName: targetFqn = '',
} = targetData?.data?.node ?? {};
setEdgeData({
sourceData: {
key: t('label.source'),
value: sourceData && getEntityName(sourceData?.data?.node),
link:
sourceData &&
entityUtilClassBase.getEntityLink(
data.sourceType,
sourceData.data.node.fullyQualifiedName
),
entityUtilClassBase.getEntityLink(sourceEntityType, sourceFqn),
},
sourceColumn: {
key: t('label.source-column'),
@ -95,10 +102,7 @@ const EdgeInfoDrawer = ({
value: targetData ? getEntityName(targetData?.data?.node) : undefined,
link:
targetData &&
entityUtilClassBase.getEntityLink(
data.targetData,
targetData.data.node.fullyQualifiedName
),
entityUtilClassBase.getEntityLink(targetEntityType, targetFqn),
},
targetColumn: {
key: t('label.target-column'),

View File

@ -67,7 +67,6 @@ export const POSITION_Y = 60;
export const NODE_WIDTH = 400;
export const NODE_HEIGHT = 90;
export const EXPANDED_NODE_HEIGHT = 350;
export const ELEMENT_DELETE_STATE = {
loading: false,

View File

@ -1183,6 +1183,20 @@ const LineageProvider = ({ children }: LineageProviderProps) => {
}
}, [isEditMode, deletePressed, backspacePressed, activeNode, selectedEdge]);
useEffect(() => {
const { node, edge } = getLayoutedElements(
{
node: nodes,
edge: edges,
},
EntityLineageDirection.LEFT_RIGHT,
activeLayer.includes(LineageLayerView.COLUMN)
);
setNodes(node);
setEdges(edge);
}, [activeLayer]);
const activityFeedContextValues = useMemo(() => {
return {
isDrawerOpen,

View File

@ -12,8 +12,8 @@
*/
import { CheckOutlined, SearchOutlined } from '@ant-design/icons';
import { graphlib, layout } from '@dagrejs/dagre';
import { AxiosError } from 'axios';
import dagre from 'dagre';
import { t } from 'i18next';
import {
cloneDeep,
@ -142,7 +142,8 @@ export const getLayoutedElements = (
direction = EntityLineageDirection.LEFT_RIGHT,
isExpanded = true
) => {
const dagreGraph = new dagre.graphlib.Graph();
const Graph = graphlib.Graph;
const dagreGraph = new Graph();
dagreGraph.setDefaultEdgeLabel(() => ({}));
dagreGraph.setGraph({ rankdir: direction });
@ -170,7 +171,7 @@ export const getLayoutedElements = (
);
edgesRequired.forEach((el) => dagreGraph.setEdge(el.source, el.target));
dagre.layout(dagreGraph);
layout(dagreGraph);
const uNode = nodeData.map((el) => {
const nodeWithPosition = dagreGraph.node(el.id);
@ -613,18 +614,22 @@ export const createNodes = (
getEntityName(a).localeCompare(getEntityName(b))
);
// Create a new dagre graph
const graph = new dagre.graphlib.Graph();
const GraphInstance = graphlib.Graph;
const graph = new GraphInstance();
// Set an object for the graph label
graph.setGraph({ rankdir: EntityLineageDirection.LEFT_RIGHT });
graph.setGraph({
rankdir: EntityLineageDirection.LEFT_RIGHT,
});
// Default to assigning a new object as a label for each new edge.
graph.setDefaultEdgeLabel(() => ({}));
// Add nodes to the graph
uniqueNodesData.forEach((node) => {
graph.setNode(node.id, { width: NODE_WIDTH, height: NODE_HEIGHT });
const { childrenHeight } = getEntityChildrenAndLabel(node as SourceType);
const nodeHeight = childrenHeight + 220;
graph.setNode(node.id, { width: NODE_WIDTH, height: nodeHeight });
});
// Add edges to the graph (if you have edge information)
@ -633,7 +638,7 @@ export const createNodes = (
});
// Perform the layout
dagre.layout(graph);
layout(graph);
// Get the layout positions
const layoutPositions = graph.nodes().map((nodeId) => graph.node(nodeId));
@ -656,8 +661,8 @@ export const createNodes = (
isRootNode: entityFqn === node.fullyQualifiedName,
},
position: {
x: position.x,
y: position.y,
x: position.x - NODE_WIDTH / 2,
y: position.y - position.height / 2,
},
};
});

View File

@ -85,6 +85,16 @@ describe('EntitySummaryPanelUtils tests', () => {
expect(resultFormattedData).toEqual(mockInvalidDataResponse);
});
it('getFormattedEntityData should render nesting for schema fields', () => {
const resultFormattedData = getFormattedEntityData(
SummaryEntityType.SCHEMAFIELD,
mockEntityDataWithNesting,
mockHighlights
);
expect(resultFormattedData).toEqual(mockEntityDataWithNestingResponse);
});
});
describe('getSortedTagsWithHighlight', () => {

View File

@ -272,6 +272,12 @@ export const getFormattedEntityData = (
const { listHighlights, listHighlightsMap } =
getMapOfListHighlights(highlights);
const entityHasChildren = [
SummaryEntityType.COLUMN,
SummaryEntityType.FIELD,
SummaryEntityType.SCHEMAFIELD,
].includes(entityType);
const { highlightedListItem, remainingListItem } = entityInfo.reduce(
(acc, listItem) => {
// return the highlight of listItem
@ -297,8 +303,7 @@ export const getFormattedEntityData = (
...(entityType === SummaryEntityType.MLFEATURE && {
algorithm: (listItem as MlFeature).featureAlgorithm,
}),
...((entityType === SummaryEntityType.COLUMN ||
entityType === SummaryEntityType.FIELD) && {
...(entityHasChildren && {
children: getFormattedEntityData(
entityType,
(listItem as Column | Field).children,

View File

@ -241,6 +241,75 @@ export const mockEntityDataWithNesting: Column[] = [
},
];
export const mockTopicDataHavingNesting = [
{
children: [
{
dataType: 'STRING',
name: 'id',
fullyQualifiedName: 'sample_kafka.customer_events.Customer.id',
dataTypeDisplay: 'string',
tags: [],
},
{
dataType: 'STRING',
name: 'first_name',
fullyQualifiedName: 'sample_kafka.customer_events.Customer.first_name',
dataTypeDisplay: 'string',
tags: [],
},
{
dataType: 'STRING',
name: 'last_name',
fullyQualifiedName: 'sample_kafka.customer_events.Customer.last_name',
dataTypeDisplay: 'string',
tags: [],
},
{
dataType: 'STRING',
name: 'email',
fullyQualifiedName: 'sample_kafka.customer_events.Customer.email',
dataTypeDisplay: 'string',
tags: [],
},
{
dataType: 'STRING',
name: 'address_line_1',
fullyQualifiedName:
'sample_kafka.customer_events.Customer.address_line_1',
dataTypeDisplay: 'string',
tags: [],
},
{
dataType: 'STRING',
name: 'address_line_2',
fullyQualifiedName:
'sample_kafka.customer_events.Customer.address_line_2',
dataTypeDisplay: 'string',
tags: [],
},
{
dataType: 'STRING',
name: 'post_code',
fullyQualifiedName: 'sample_kafka.customer_events.Customer.post_code',
dataTypeDisplay: 'string',
tags: [],
},
{
dataType: 'STRING',
name: 'country',
fullyQualifiedName: 'sample_kafka.customer_events.Customer.country',
dataTypeDisplay: 'string',
tags: [],
},
],
dataType: 'RECORD',
name: 'Customer',
fullyQualifiedName: 'sample_kafka.customer_events.Customer',
tags: [],
},
];
export const mockEntityDataWithNestingResponse: BasicEntityInfo[] = [
{
name: 'title2',

View File

@ -2321,6 +2321,18 @@
debug "^3.1.0"
lodash.once "^4.1.1"
"@dagrejs/dagre@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@dagrejs/dagre/-/dagre-1.1.2.tgz#5ec339979447091f48d2144deed8c70dfadae374"
integrity sha512-F09dphqvHsbe/6C2t2unbmpr5q41BNPEfJCdn8Z7aEBpVSy/zFQ/b4SWsweQjWNsYMDvE2ffNUN8X0CeFsEGNw==
dependencies:
"@dagrejs/graphlib" "2.2.2"
"@dagrejs/graphlib@2.2.2":
version "2.2.2"
resolved "https://registry.yarnpkg.com/@dagrejs/graphlib/-/graphlib-2.2.2.tgz#74154d5cb880a23b4fae71034a09b4b5aef06feb"
integrity sha512-CbyGpCDKsiTg/wuk79S7Muoj8mghDGAESWGxcSyhHX5jD35vYMBZochYVFzlHxynpE9unpu6O+4ZuhrLxASsOg==
"@date-io/core@^1.3.13":
version "1.3.13"
resolved "https://registry.yarnpkg.com/@date-io/core/-/core-1.3.13.tgz#90c71da493f20204b7a972929cc5c482d078b3fa"
@ -6759,14 +6771,6 @@ d3-zoom@^3.0.0:
d3-selection "2 - 3"
d3-transition "2 - 3"
dagre@^0.8.5:
version "0.8.5"
resolved "https://registry.yarnpkg.com/dagre/-/dagre-0.8.5.tgz#ba30b0055dac12b6c1fcc247817442777d06afee"
integrity sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==
dependencies:
graphlib "^2.1.8"
lodash "^4.17.15"
damerau-levenshtein@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7"
@ -8565,13 +8569,6 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6
resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=
graphlib@^2.1.8:
version "2.1.8"
resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.8.tgz#5761d414737870084c92ec7b5dbcb0592c9d35da"
integrity sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==
dependencies:
lodash "^4.17.15"
growly@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"