mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-11-05 21:13:14 +00:00
This commit is contained in:
parent
1ddcc94ccd
commit
4ad0d9f76c
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 Collate
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { findByTestId, queryByTestId, render } from '@testing-library/react';
|
||||||
|
import React from 'react';
|
||||||
|
import { ArrowHeadType, EdgeProps, Position } from 'react-flow-renderer';
|
||||||
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
|
import { CustomEdge } from './CustomEdge.component';
|
||||||
|
|
||||||
|
jest.mock('../../constants/Lineage.constants', () => ({
|
||||||
|
foreignObjectSize: 40,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const mockCustomEdgeProp = {
|
||||||
|
id: 'id1',
|
||||||
|
sourceX: 20,
|
||||||
|
sourceY: 20,
|
||||||
|
targetX: 20,
|
||||||
|
targetY: 20,
|
||||||
|
sourcePosition: Position.Left,
|
||||||
|
targetPosition: Position.Right,
|
||||||
|
style: {},
|
||||||
|
arrowHeadType: ArrowHeadType.ArrowClosed,
|
||||||
|
markerEndId: '',
|
||||||
|
data: {
|
||||||
|
source: 'node1',
|
||||||
|
target: 'node2',
|
||||||
|
onEdgeClick: jest.fn(),
|
||||||
|
selectedNode: {
|
||||||
|
id: 'node1',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as EdgeProps;
|
||||||
|
|
||||||
|
describe('Test CustomEdge Component', () => {
|
||||||
|
it('Check if CustomeEdge has all child elements', async () => {
|
||||||
|
const { container } = render(<CustomEdge {...mockCustomEdgeProp} />, {
|
||||||
|
wrapper: MemoryRouter,
|
||||||
|
});
|
||||||
|
|
||||||
|
const deleteButton = await findByTestId(container, 'delete-button');
|
||||||
|
const edgePathElement = await findByTestId(
|
||||||
|
container,
|
||||||
|
'react-flow-edge-path'
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(deleteButton).toBeInTheDocument();
|
||||||
|
expect(edgePathElement).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Check if CustomeEdge has selectedNode as empty object', async () => {
|
||||||
|
const { container } = render(
|
||||||
|
<CustomEdge
|
||||||
|
{...mockCustomEdgeProp}
|
||||||
|
data={{ ...mockCustomEdgeProp.data, selectedNode: {} }}
|
||||||
|
/>,
|
||||||
|
{
|
||||||
|
wrapper: MemoryRouter,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const edgePathElement = await findByTestId(
|
||||||
|
container,
|
||||||
|
'react-flow-edge-path'
|
||||||
|
);
|
||||||
|
|
||||||
|
const deleteButton = queryByTestId(container, 'delete-button');
|
||||||
|
|
||||||
|
expect(deleteButton).not.toBeInTheDocument();
|
||||||
|
expect(edgePathElement).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -35,7 +35,8 @@ export const CustomEdge = ({
|
|||||||
markerEndId,
|
markerEndId,
|
||||||
data,
|
data,
|
||||||
}: EdgeProps) => {
|
}: EdgeProps) => {
|
||||||
const { onEdgeClick, ...rest } = data;
|
const { onEdgeClick, selectedNode, ...rest } = data;
|
||||||
|
|
||||||
const edgePath = getBezierPath({
|
const edgePath = getBezierPath({
|
||||||
sourceX,
|
sourceX,
|
||||||
sourceY,
|
sourceY,
|
||||||
@ -57,12 +58,15 @@ export const CustomEdge = ({
|
|||||||
<path
|
<path
|
||||||
className="react-flow__edge-path"
|
className="react-flow__edge-path"
|
||||||
d={edgePath}
|
d={edgePath}
|
||||||
|
data-testid="react-flow-edge-path"
|
||||||
id={id}
|
id={id}
|
||||||
markerEnd={markerEnd}
|
markerEnd={markerEnd}
|
||||||
style={style}
|
style={style}
|
||||||
/>
|
/>
|
||||||
|
{(rest as CustomEdgeData)?.source?.includes(selectedNode?.id) ||
|
||||||
|
(rest as CustomEdgeData)?.target?.includes(selectedNode?.id) ? (
|
||||||
<foreignObject
|
<foreignObject
|
||||||
className="tw-opacity-0 hover:tw-opacity-100"
|
data-testid="delete-button"
|
||||||
height={foreignObjectSize}
|
height={foreignObjectSize}
|
||||||
requiredExtensions="http://www.w3.org/1999/xhtml"
|
requiredExtensions="http://www.w3.org/1999/xhtml"
|
||||||
width={foreignObjectSize}
|
width={foreignObjectSize}
|
||||||
@ -71,9 +75,14 @@ export const CustomEdge = ({
|
|||||||
<button
|
<button
|
||||||
className="tw-cursor-pointer tw-flex tw-z-9999"
|
className="tw-cursor-pointer tw-flex tw-z-9999"
|
||||||
onClick={(event) => onEdgeClick?.(event, rest as CustomEdgeData)}>
|
onClick={(event) => onEdgeClick?.(event, rest as CustomEdgeData)}>
|
||||||
<SVGIcons alt="times-circle" icon="icon-times-circle" width="14px" />
|
<SVGIcons
|
||||||
|
alt="times-circle"
|
||||||
|
icon="icon-times-circle"
|
||||||
|
width="14px"
|
||||||
|
/>
|
||||||
</button>
|
</button>
|
||||||
</foreignObject>
|
</foreignObject>
|
||||||
|
) : null}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -215,6 +215,9 @@ const Entitylineage: FunctionComponent<EntityLineageProp> = ({
|
|||||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||||
setElements((es) => es.filter((e) => e.id !== data.id));
|
setElements((es) => es.filter((e) => e.id !== data.id));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get new downstreamEdges
|
||||||
|
*/
|
||||||
const newDownStreamEdges = lineageData.downstreamEdges?.filter(
|
const newDownStreamEdges = lineageData.downstreamEdges?.filter(
|
||||||
(dn) =>
|
(dn) =>
|
||||||
!lineageData.downstreamEdges?.find(
|
!lineageData.downstreamEdges?.find(
|
||||||
@ -222,6 +225,10 @@ const Entitylineage: FunctionComponent<EntityLineageProp> = ({
|
|||||||
edgeData.fromId === dn.fromEntity && edgeData.toId === dn.toEntity
|
edgeData.fromId === dn.fromEntity && edgeData.toId === dn.toEntity
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get new upstreamEdges
|
||||||
|
*/
|
||||||
const newUpStreamEdges = lineageData.upstreamEdges?.filter(
|
const newUpStreamEdges = lineageData.upstreamEdges?.filter(
|
||||||
(up) =>
|
(up) =>
|
||||||
!lineageData.upstreamEdges?.find(
|
!lineageData.upstreamEdges?.find(
|
||||||
@ -230,10 +237,20 @@ const Entitylineage: FunctionComponent<EntityLineageProp> = ({
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get new nodes that have either downstreamEdge or upstreamEdge
|
||||||
|
*/
|
||||||
|
const newNodes = lineageData.nodes?.filter(
|
||||||
|
(n) =>
|
||||||
|
!isUndefined(newDownStreamEdges?.find((d) => d.toEntity === n.id)) ||
|
||||||
|
!isUndefined(newUpStreamEdges?.find((u) => u.fromEntity === n.id))
|
||||||
|
);
|
||||||
|
|
||||||
setNewAddedNode({} as FlowElement);
|
setNewAddedNode({} as FlowElement);
|
||||||
setSelectedEntity({} as EntityReference);
|
setSelectedEntity({} as EntityReference);
|
||||||
entityLineageHandler({
|
entityLineageHandler({
|
||||||
...lineageData,
|
...lineageData,
|
||||||
|
nodes: newNodes,
|
||||||
downstreamEdges: newDownStreamEdges,
|
downstreamEdges: newDownStreamEdges,
|
||||||
upstreamEdges: newUpStreamEdges,
|
upstreamEdges: newUpStreamEdges,
|
||||||
});
|
});
|
||||||
@ -698,6 +715,9 @@ const Entitylineage: FunctionComponent<EntityLineageProp> = ({
|
|||||||
if (!isEmpty(selectedNode)) {
|
if (!isEmpty(selectedNode)) {
|
||||||
setExpandNode(undefined);
|
setExpandNode(undefined);
|
||||||
}
|
}
|
||||||
|
setElements((pre) => {
|
||||||
|
return pre.map((el) => ({ ...el, data: { ...el.data, selectedNode } }));
|
||||||
|
});
|
||||||
}, [selectedNode]);
|
}, [selectedNode]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user