mirror of
https://github.com/ansible/awx.git
synced 2026-05-19 14:57:39 -02:30
Combines the two start node components into one. Removes use of document.getElementById in workflow components in favor of refs.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useRef, useState } from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { withI18n } from '@lingui/react';
|
import { withI18n } from '@lingui/react';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
@@ -14,19 +14,19 @@ const StartG = styled.g`
|
|||||||
pointer-events: ${props => (props.ignorePointerEvents ? 'none' : 'auto')};
|
pointer-events: ${props => (props.ignorePointerEvents ? 'none' : 'auto')};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
function VisualizerStartNode({
|
function WorkflowStartNode({
|
||||||
addingLink,
|
addingLink,
|
||||||
i18n,
|
i18n,
|
||||||
nodePositions,
|
nodePositions,
|
||||||
onAddNodeClick,
|
onAddNodeClick,
|
||||||
onUpdateHelpText,
|
onUpdateHelpText,
|
||||||
readOnly,
|
showActionTooltip,
|
||||||
}) {
|
}) {
|
||||||
|
const ref = useRef(null);
|
||||||
const [hovering, setHovering] = useState(false);
|
const [hovering, setHovering] = useState(false);
|
||||||
|
|
||||||
const handleNodeMouseEnter = () => {
|
const handleNodeMouseEnter = () => {
|
||||||
const nodeEl = document.getElementById('node-1');
|
ref.current.parentNode.appendChild(ref.current);
|
||||||
nodeEl.parentNode.appendChild(nodeEl);
|
|
||||||
setHovering(true);
|
setHovering(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -36,6 +36,7 @@ function VisualizerStartNode({
|
|||||||
ignorePointerEvents={addingLink}
|
ignorePointerEvents={addingLink}
|
||||||
onMouseEnter={handleNodeMouseEnter}
|
onMouseEnter={handleNodeMouseEnter}
|
||||||
onMouseLeave={() => setHovering(false)}
|
onMouseLeave={() => setHovering(false)}
|
||||||
|
ref={ref}
|
||||||
transform={`translate(${nodePositions[1].x},0)`}
|
transform={`translate(${nodePositions[1].x},0)`}
|
||||||
>
|
>
|
||||||
<rect
|
<rect
|
||||||
@@ -50,7 +51,7 @@ function VisualizerStartNode({
|
|||||||
<text x="13" y="30" dy=".35em" fill="white">
|
<text x="13" y="30" dy=".35em" fill="white">
|
||||||
START
|
START
|
||||||
</text>
|
</text>
|
||||||
{!readOnly && hovering && (
|
{showActionTooltip && hovering && (
|
||||||
<WorkflowActionTooltip
|
<WorkflowActionTooltip
|
||||||
actions={[
|
actions={[
|
||||||
<WorkflowActionTooltipItem
|
<WorkflowActionTooltipItem
|
||||||
@@ -75,12 +76,18 @@ function VisualizerStartNode({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
VisualizerStartNode.propTypes = {
|
WorkflowStartNode.propTypes = {
|
||||||
addingLink: bool.isRequired,
|
addingLink: bool,
|
||||||
nodePositions: shape().isRequired,
|
nodePositions: shape().isRequired,
|
||||||
onAddNodeClick: func.isRequired,
|
onAddNodeClick: func,
|
||||||
readOnly: bool.isRequired,
|
showActionTooltip: bool.isRequired,
|
||||||
onUpdateHelpText: func.isRequired,
|
onUpdateHelpText: func,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withI18n()(VisualizerStartNode);
|
WorkflowStartNode.defaultProps = {
|
||||||
|
addingLink: false,
|
||||||
|
onAddNodeClick: () => {},
|
||||||
|
onUpdateHelpText: () => {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default withI18n()(WorkflowStartNode);
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { mount } from 'enzyme';
|
||||||
|
import WorkflowStartNode from './WorkflowStartNode';
|
||||||
|
|
||||||
|
const nodePositions = {
|
||||||
|
1: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('WorkflowStartNode', () => {
|
||||||
|
test('mounts successfully', () => {
|
||||||
|
const wrapper = mount(
|
||||||
|
<svg>
|
||||||
|
<WorkflowStartNode
|
||||||
|
nodePositions={nodePositions}
|
||||||
|
showActionTooltip={false}
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
expect(wrapper).toHaveLength(1);
|
||||||
|
});
|
||||||
|
test('tooltip shown on hover', () => {
|
||||||
|
const wrapper = mount(
|
||||||
|
<svg>
|
||||||
|
<WorkflowStartNode nodePositions={nodePositions} showActionTooltip />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
expect(wrapper.find('WorkflowActionTooltip')).toHaveLength(0);
|
||||||
|
wrapper.find('WorkflowStartNode').simulate('mouseenter');
|
||||||
|
expect(wrapper.find('WorkflowActionTooltip')).toHaveLength(1);
|
||||||
|
wrapper.find('WorkflowStartNode').simulate('mouseleave');
|
||||||
|
expect(wrapper.find('WorkflowActionTooltip')).toHaveLength(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -7,4 +7,5 @@ export { default as WorkflowKey } from './WorkflowKey';
|
|||||||
export { default as WorkflowLinkHelp } from './WorkflowLinkHelp';
|
export { default as WorkflowLinkHelp } from './WorkflowLinkHelp';
|
||||||
export { default as WorkflowNodeHelp } from './WorkflowNodeHelp';
|
export { default as WorkflowNodeHelp } from './WorkflowNodeHelp';
|
||||||
export { default as WorkflowNodeTypeLetter } from './WorkflowNodeTypeLetter';
|
export { default as WorkflowNodeTypeLetter } from './WorkflowNodeTypeLetter';
|
||||||
|
export { default as WorkflowStartNode } from './WorkflowStartNode';
|
||||||
export { default as WorkflowTools } from './WorkflowTools';
|
export { default as WorkflowTools } from './WorkflowTools';
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ import {
|
|||||||
import {
|
import {
|
||||||
WorkflowOutputLink,
|
WorkflowOutputLink,
|
||||||
WorkflowOutputNode,
|
WorkflowOutputNode,
|
||||||
WorkflowOutputStartNode,
|
|
||||||
} from '@screens/Job/WorkflowOutput';
|
} from '@screens/Job/WorkflowOutput';
|
||||||
import {
|
import {
|
||||||
WorkflowHelp,
|
WorkflowHelp,
|
||||||
WorkflowKey,
|
WorkflowKey,
|
||||||
WorkflowLinkHelp,
|
WorkflowLinkHelp,
|
||||||
WorkflowNodeHelp,
|
WorkflowNodeHelp,
|
||||||
|
WorkflowStartNode,
|
||||||
WorkflowTools,
|
WorkflowTools,
|
||||||
} from '@components/Workflow';
|
} from '@components/Workflow';
|
||||||
|
|
||||||
@@ -75,8 +75,7 @@ function WorkflowOutputGraph({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handlePanToMiddle = () => {
|
const handlePanToMiddle = () => {
|
||||||
const svgElement = document.getElementById('workflow-svg');
|
const svgBoundingClientRect = svgRef.current.getBoundingClientRect();
|
||||||
const svgBoundingClientRect = svgElement.getBoundingClientRect();
|
|
||||||
d3.select(svgRef.current).call(
|
d3.select(svgRef.current).call(
|
||||||
zoomRef.transform,
|
zoomRef.transform,
|
||||||
d3.zoomIdentity
|
d3.zoomIdentity
|
||||||
@@ -88,8 +87,7 @@ function WorkflowOutputGraph({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleZoomChange = newScale => {
|
const handleZoomChange = newScale => {
|
||||||
const svgElement = document.getElementById('workflow-svg');
|
const svgBoundingClientRect = svgRef.current.getBoundingClientRect();
|
||||||
const svgBoundingClientRect = svgElement.getBoundingClientRect();
|
|
||||||
const currentScaleAndOffset = d3.zoomTransform(
|
const currentScaleAndOffset = d3.zoomTransform(
|
||||||
d3.select(svgRef.current).node()
|
d3.select(svgRef.current).node()
|
||||||
);
|
);
|
||||||
@@ -121,8 +119,7 @@ function WorkflowOutputGraph({
|
|||||||
.node()
|
.node()
|
||||||
.getBBox();
|
.getBBox();
|
||||||
|
|
||||||
const svgElement = document.getElementById('workflow-svg');
|
const svgBoundingClientRect = svgRef.current.getBoundingClientRect();
|
||||||
const svgBoundingClientRect = svgElement.getBoundingClientRect();
|
|
||||||
|
|
||||||
const [scaleToFit, yTranslate] = getScaleAndOffsetToFit(
|
const [scaleToFit, yTranslate] = getScaleAndOffsetToFit(
|
||||||
gBoundingClientRect,
|
gBoundingClientRect,
|
||||||
@@ -175,9 +172,10 @@ function WorkflowOutputGraph({
|
|||||||
>
|
>
|
||||||
<g id="workflow-g" ref={gRef}>
|
<g id="workflow-g" ref={gRef}>
|
||||||
{nodePositions && [
|
{nodePositions && [
|
||||||
<WorkflowOutputStartNode
|
<WorkflowStartNode
|
||||||
key="start"
|
key="start"
|
||||||
nodePositions={nodePositions}
|
nodePositions={nodePositions}
|
||||||
|
showActionTooltip={false}
|
||||||
/>,
|
/>,
|
||||||
links.map(link => (
|
links.map(link => (
|
||||||
<WorkflowOutputLink
|
<WorkflowOutputLink
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import { shape } from 'prop-types';
|
import { shape } from 'prop-types';
|
||||||
import {
|
import {
|
||||||
generateLine,
|
generateLine,
|
||||||
@@ -7,23 +7,18 @@ import {
|
|||||||
} from '@util/workflow';
|
} from '@util/workflow';
|
||||||
|
|
||||||
function WorkflowOutputLink({ link, nodePositions, onUpdateLinkHelp }) {
|
function WorkflowOutputLink({ link, nodePositions, onUpdateLinkHelp }) {
|
||||||
|
const ref = useRef(null);
|
||||||
const [hovering, setHovering] = useState(false);
|
const [hovering, setHovering] = useState(false);
|
||||||
const [pathD, setPathD] = useState();
|
const [pathD, setPathD] = useState();
|
||||||
const [pathStroke, setPathStroke] = useState('#CCCCCC');
|
const [pathStroke, setPathStroke] = useState('#CCCCCC');
|
||||||
|
|
||||||
const handleLinkMouseEnter = () => {
|
const handleLinkMouseEnter = () => {
|
||||||
const linkEl = document.getElementById(
|
ref.current.parentNode.appendChild(ref.current);
|
||||||
`link-${link.source.id}-${link.target.id}`
|
|
||||||
);
|
|
||||||
linkEl.parentNode.appendChild(linkEl);
|
|
||||||
setHovering(true);
|
setHovering(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleLinkMouseLeave = () => {
|
const handleLinkMouseLeave = () => {
|
||||||
const linkEl = document.getElementById(
|
ref.current.parentNode.prepend(ref.current);
|
||||||
`link-${link.source.id}-${link.target.id}`
|
|
||||||
);
|
|
||||||
linkEl.parentNode.prepend(linkEl);
|
|
||||||
setHovering(null);
|
setHovering(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -46,6 +41,7 @@ function WorkflowOutputLink({ link, nodePositions, onUpdateLinkHelp }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<g
|
<g
|
||||||
|
ref={ref}
|
||||||
id={`link-${link.source.id}-${link.target.id}`}
|
id={`link-${link.source.id}-${link.target.id}`}
|
||||||
onMouseEnter={handleLinkMouseEnter}
|
onMouseEnter={handleLinkMouseEnter}
|
||||||
onMouseLeave={handleLinkMouseLeave}
|
onMouseLeave={handleLinkMouseLeave}
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { shape } from 'prop-types';
|
|
||||||
import { constants as wfConstants } from '@util/workflow';
|
|
||||||
|
|
||||||
function WorkflowOutputStartNode({ nodePositions }) {
|
|
||||||
return (
|
|
||||||
<g id="node-1" transform={`translate(${nodePositions[1].x},0)`}>
|
|
||||||
<rect
|
|
||||||
fill="#0279BC"
|
|
||||||
height={wfConstants.rootH}
|
|
||||||
rx="2"
|
|
||||||
ry="2"
|
|
||||||
width={wfConstants.rootW}
|
|
||||||
y="10"
|
|
||||||
/>
|
|
||||||
{/* TODO: We need to be able to handle translated text here */}
|
|
||||||
<text x="13" y="30" dy=".35em" fill="white">
|
|
||||||
START
|
|
||||||
</text>
|
|
||||||
</g>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
WorkflowOutputStartNode.propTypes = {
|
|
||||||
nodePositions: shape().isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default WorkflowOutputStartNode;
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { mount } from 'enzyme';
|
|
||||||
import WorkflowOutputStartNode from './WorkflowOutputStartNode';
|
|
||||||
|
|
||||||
const nodePositions = {
|
|
||||||
1: {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('WorkflowOutputStartNode', () => {
|
|
||||||
test('mounts successfully', () => {
|
|
||||||
const wrapper = mount(
|
|
||||||
<svg>
|
|
||||||
<WorkflowOutputStartNode nodePositions={nodePositions} />
|
|
||||||
</svg>
|
|
||||||
);
|
|
||||||
expect(wrapper).toHaveLength(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -2,5 +2,4 @@ export { default as WorkflowOutput } from './WorkflowOutput';
|
|||||||
export { default as WorkflowOutputGraph } from './WorkflowOutputGraph';
|
export { default as WorkflowOutputGraph } from './WorkflowOutputGraph';
|
||||||
export { default as WorkflowOutputLink } from './WorkflowOutputLink';
|
export { default as WorkflowOutputLink } from './WorkflowOutputLink';
|
||||||
export { default as WorkflowOutputNode } from './WorkflowOutputNode';
|
export { default as WorkflowOutputNode } from './WorkflowOutputNode';
|
||||||
export { default as WorkflowOutputStartNode } from './WorkflowOutputStartNode';
|
|
||||||
export { default as WorkflowOutputToolbar } from './WorkflowOutputToolbar';
|
export { default as WorkflowOutputToolbar } from './WorkflowOutputToolbar';
|
||||||
|
|||||||
@@ -14,12 +14,12 @@ import {
|
|||||||
WorkflowKey,
|
WorkflowKey,
|
||||||
WorkflowLinkHelp,
|
WorkflowLinkHelp,
|
||||||
WorkflowNodeHelp,
|
WorkflowNodeHelp,
|
||||||
|
WorkflowStartNode,
|
||||||
WorkflowTools,
|
WorkflowTools,
|
||||||
} from '@components/Workflow';
|
} from '@components/Workflow';
|
||||||
import {
|
import {
|
||||||
VisualizerLink,
|
VisualizerLink,
|
||||||
VisualizerNode,
|
VisualizerNode,
|
||||||
VisualizerStartNode,
|
|
||||||
} from '@screens/Template/WorkflowJobTemplateVisualizer';
|
} from '@screens/Template/WorkflowJobTemplateVisualizer';
|
||||||
|
|
||||||
const PotentialLink = styled.polyline`
|
const PotentialLink = styled.polyline`
|
||||||
@@ -148,8 +148,7 @@ function VisualizerGraph({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handlePanToMiddle = () => {
|
const handlePanToMiddle = () => {
|
||||||
const svgElement = document.getElementById('workflow-svg');
|
const svgBoundingClientRect = svgRef.current.getBoundingClientRect();
|
||||||
const svgBoundingClientRect = svgElement.getBoundingClientRect();
|
|
||||||
d3.select(svgRef.current).call(
|
d3.select(svgRef.current).call(
|
||||||
zoomRef.transform,
|
zoomRef.transform,
|
||||||
d3.zoomIdentity
|
d3.zoomIdentity
|
||||||
@@ -161,8 +160,7 @@ function VisualizerGraph({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleZoomChange = newScale => {
|
const handleZoomChange = newScale => {
|
||||||
const svgElement = document.getElementById('workflow-svg');
|
const svgBoundingClientRect = svgRef.current.getBoundingClientRect();
|
||||||
const svgBoundingClientRect = svgElement.getBoundingClientRect();
|
|
||||||
const currentScaleAndOffset = d3.zoomTransform(
|
const currentScaleAndOffset = d3.zoomTransform(
|
||||||
d3.select(svgRef.current).node()
|
d3.select(svgRef.current).node()
|
||||||
);
|
);
|
||||||
@@ -194,8 +192,7 @@ function VisualizerGraph({
|
|||||||
.node()
|
.node()
|
||||||
.getBBox();
|
.getBBox();
|
||||||
|
|
||||||
const svgElement = document.getElementById('workflow-svg');
|
const svgBoundingClientRect = svgRef.current.getBoundingClientRect();
|
||||||
const svgBoundingClientRect = svgElement.getBoundingClientRect();
|
|
||||||
|
|
||||||
const [scaleToFit, yTranslate] = getScaleAndOffsetToFit(
|
const [scaleToFit, yTranslate] = getScaleAndOffsetToFit(
|
||||||
gBoundingClientRect,
|
gBoundingClientRect,
|
||||||
@@ -276,12 +273,12 @@ function VisualizerGraph({
|
|||||||
/>
|
/>
|
||||||
<g id="workflow-g" ref={gRef}>
|
<g id="workflow-g" ref={gRef}>
|
||||||
{nodePositions && [
|
{nodePositions && [
|
||||||
<VisualizerStartNode
|
<WorkflowStartNode
|
||||||
addingLink={addingLink}
|
addingLink={addingLink}
|
||||||
key="start"
|
key="start"
|
||||||
nodePositions={nodePositions}
|
nodePositions={nodePositions}
|
||||||
onAddNodeClick={onAddNodeClick}
|
onAddNodeClick={onAddNodeClick}
|
||||||
readOnly={readOnly}
|
showActionTooltip={!readOnly}
|
||||||
onUpdateHelpText={setHelpText}
|
onUpdateHelpText={setHelpText}
|
||||||
/>,
|
/>,
|
||||||
links.map(link => {
|
links.map(link => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { withI18n } from '@lingui/react';
|
import { withI18n } from '@lingui/react';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
@@ -30,6 +30,7 @@ function VisualizerLink({
|
|||||||
onUpdateLinkHelp,
|
onUpdateLinkHelp,
|
||||||
readOnly,
|
readOnly,
|
||||||
}) {
|
}) {
|
||||||
|
const ref = useRef(null);
|
||||||
const [hovering, setHovering] = useState(false);
|
const [hovering, setHovering] = useState(false);
|
||||||
const [pathD, setPathD] = useState();
|
const [pathD, setPathD] = useState();
|
||||||
const [pathStroke, setPathStroke] = useState('#CCCCCC');
|
const [pathStroke, setPathStroke] = useState('#CCCCCC');
|
||||||
@@ -80,18 +81,12 @@ function VisualizerLink({
|
|||||||
];
|
];
|
||||||
|
|
||||||
const handleLinkMouseEnter = () => {
|
const handleLinkMouseEnter = () => {
|
||||||
const linkEl = document.getElementById(
|
ref.current.parentNode.appendChild(ref.current);
|
||||||
`link-${link.source.id}-${link.target.id}`
|
|
||||||
);
|
|
||||||
linkEl.parentNode.appendChild(linkEl);
|
|
||||||
setHovering(true);
|
setHovering(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleLinkMouseLeave = () => {
|
const handleLinkMouseLeave = () => {
|
||||||
const linkEl = document.getElementById(
|
ref.current.parentNode.prepend(ref.current);
|
||||||
`link-${link.source.id}-${link.target.id}`
|
|
||||||
);
|
|
||||||
linkEl.parentNode.prepend(linkEl);
|
|
||||||
setHovering(null);
|
setHovering(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -120,6 +115,7 @@ function VisualizerLink({
|
|||||||
ignorePointerEvents={addingLink}
|
ignorePointerEvents={addingLink}
|
||||||
onMouseEnter={handleLinkMouseEnter}
|
onMouseEnter={handleLinkMouseEnter}
|
||||||
onMouseLeave={handleLinkMouseLeave}
|
onMouseLeave={handleLinkMouseLeave}
|
||||||
|
ref={ref}
|
||||||
>
|
>
|
||||||
<polygon
|
<polygon
|
||||||
fill="#E1E1E1"
|
fill="#E1E1E1"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useRef, useState } from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { withI18n } from '@lingui/react';
|
import { withI18n } from '@lingui/react';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
@@ -54,11 +54,11 @@ function VisualizerNode({
|
|||||||
onUpdateHelpText,
|
onUpdateHelpText,
|
||||||
updateNodeHelp,
|
updateNodeHelp,
|
||||||
}) {
|
}) {
|
||||||
|
const ref = useRef(null);
|
||||||
const [hovering, setHovering] = useState(false);
|
const [hovering, setHovering] = useState(false);
|
||||||
|
|
||||||
const handleNodeMouseEnter = () => {
|
const handleNodeMouseEnter = () => {
|
||||||
const nodeEl = document.getElementById(`node-${node.id}`);
|
ref.current.parentNode.appendChild(ref.current);
|
||||||
nodeEl.parentNode.appendChild(nodeEl);
|
|
||||||
setHovering(true);
|
setHovering(true);
|
||||||
if (addingLink) {
|
if (addingLink) {
|
||||||
onUpdateHelpText(
|
onUpdateHelpText(
|
||||||
@@ -168,6 +168,7 @@ function VisualizerNode({
|
|||||||
noPointerEvents={isAddLinkSourceNode}
|
noPointerEvents={isAddLinkSourceNode}
|
||||||
onMouseEnter={handleNodeMouseEnter}
|
onMouseEnter={handleNodeMouseEnter}
|
||||||
onMouseLeave={handleNodeMouseLeave}
|
onMouseLeave={handleNodeMouseLeave}
|
||||||
|
ref={ref}
|
||||||
transform={`translate(${nodePositions[node.id].x},${nodePositions[node.id]
|
transform={`translate(${nodePositions[node.id].x},${nodePositions[node.id]
|
||||||
.y - nodePositions[1].y})`}
|
.y - nodePositions[1].y})`}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -2,6 +2,5 @@ export { default as Visualizer } from './Visualizer';
|
|||||||
export { default as VisualizerGraph } from './VisualizerGraph';
|
export { default as VisualizerGraph } from './VisualizerGraph';
|
||||||
export { default as VisualizerLink } from './VisualizerLink';
|
export { default as VisualizerLink } from './VisualizerLink';
|
||||||
export { default as VisualizerNode } from './VisualizerNode';
|
export { default as VisualizerNode } from './VisualizerNode';
|
||||||
export { default as VisualizerStartNode } from './VisualizerStartNode';
|
|
||||||
export { default as VisualizerStartScreen } from './VisualizerStartScreen';
|
export { default as VisualizerStartScreen } from './VisualizerStartScreen';
|
||||||
export { default as VisualizerToolbar } from './VisualizerToolbar';
|
export { default as VisualizerToolbar } from './VisualizerToolbar';
|
||||||
|
|||||||
Reference in New Issue
Block a user