mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-06-27 04:22:05 +00:00
Show collapse for record type of topic entity (#16063)
* fix minor lineage issues * fix cypress * fix lineage cypress
This commit is contained in:
parent
eac0466b4d
commit
876a02bcdb
1
.github/e2eLabeler.yml
vendored
1
.github/e2eLabeler.yml
vendored
@ -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*"
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
@ -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'),
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
@ -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', () => {
|
||||
|
@ -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,
|
||||
|
@ -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',
|
||||
|
@ -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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user