mirror of
https://github.com/ansible/awx.git
synced 2026-01-23 07:28:02 -03: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:
parent
f98b274177
commit
eddb6e1faf
@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useRef, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
@ -14,19 +14,19 @@ const StartG = styled.g`
|
||||
pointer-events: ${props => (props.ignorePointerEvents ? 'none' : 'auto')};
|
||||
`;
|
||||
|
||||
function VisualizerStartNode({
|
||||
function WorkflowStartNode({
|
||||
addingLink,
|
||||
i18n,
|
||||
nodePositions,
|
||||
onAddNodeClick,
|
||||
onUpdateHelpText,
|
||||
readOnly,
|
||||
showActionTooltip,
|
||||
}) {
|
||||
const ref = useRef(null);
|
||||
const [hovering, setHovering] = useState(false);
|
||||
|
||||
const handleNodeMouseEnter = () => {
|
||||
const nodeEl = document.getElementById('node-1');
|
||||
nodeEl.parentNode.appendChild(nodeEl);
|
||||
ref.current.parentNode.appendChild(ref.current);
|
||||
setHovering(true);
|
||||
};
|
||||
|
||||
@ -36,6 +36,7 @@ function VisualizerStartNode({
|
||||
ignorePointerEvents={addingLink}
|
||||
onMouseEnter={handleNodeMouseEnter}
|
||||
onMouseLeave={() => setHovering(false)}
|
||||
ref={ref}
|
||||
transform={`translate(${nodePositions[1].x},0)`}
|
||||
>
|
||||
<rect
|
||||
@ -50,7 +51,7 @@ function VisualizerStartNode({
|
||||
<text x="13" y="30" dy=".35em" fill="white">
|
||||
START
|
||||
</text>
|
||||
{!readOnly && hovering && (
|
||||
{showActionTooltip && hovering && (
|
||||
<WorkflowActionTooltip
|
||||
actions={[
|
||||
<WorkflowActionTooltipItem
|
||||
@ -75,12 +76,18 @@ function VisualizerStartNode({
|
||||
);
|
||||
}
|
||||
|
||||
VisualizerStartNode.propTypes = {
|
||||
addingLink: bool.isRequired,
|
||||
WorkflowStartNode.propTypes = {
|
||||
addingLink: bool,
|
||||
nodePositions: shape().isRequired,
|
||||
onAddNodeClick: func.isRequired,
|
||||
readOnly: bool.isRequired,
|
||||
onUpdateHelpText: func.isRequired,
|
||||
onAddNodeClick: func,
|
||||
showActionTooltip: bool.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 WorkflowNodeHelp } from './WorkflowNodeHelp';
|
||||
export { default as WorkflowNodeTypeLetter } from './WorkflowNodeTypeLetter';
|
||||
export { default as WorkflowStartNode } from './WorkflowStartNode';
|
||||
export { default as WorkflowTools } from './WorkflowTools';
|
||||
|
||||
@ -8,13 +8,13 @@ import {
|
||||
import {
|
||||
WorkflowOutputLink,
|
||||
WorkflowOutputNode,
|
||||
WorkflowOutputStartNode,
|
||||
} from '@screens/Job/WorkflowOutput';
|
||||
import {
|
||||
WorkflowHelp,
|
||||
WorkflowKey,
|
||||
WorkflowLinkHelp,
|
||||
WorkflowNodeHelp,
|
||||
WorkflowStartNode,
|
||||
WorkflowTools,
|
||||
} from '@components/Workflow';
|
||||
|
||||
@ -75,8 +75,7 @@ function WorkflowOutputGraph({
|
||||
};
|
||||
|
||||
const handlePanToMiddle = () => {
|
||||
const svgElement = document.getElementById('workflow-svg');
|
||||
const svgBoundingClientRect = svgElement.getBoundingClientRect();
|
||||
const svgBoundingClientRect = svgRef.current.getBoundingClientRect();
|
||||
d3.select(svgRef.current).call(
|
||||
zoomRef.transform,
|
||||
d3.zoomIdentity
|
||||
@ -88,8 +87,7 @@ function WorkflowOutputGraph({
|
||||
};
|
||||
|
||||
const handleZoomChange = newScale => {
|
||||
const svgElement = document.getElementById('workflow-svg');
|
||||
const svgBoundingClientRect = svgElement.getBoundingClientRect();
|
||||
const svgBoundingClientRect = svgRef.current.getBoundingClientRect();
|
||||
const currentScaleAndOffset = d3.zoomTransform(
|
||||
d3.select(svgRef.current).node()
|
||||
);
|
||||
@ -121,8 +119,7 @@ function WorkflowOutputGraph({
|
||||
.node()
|
||||
.getBBox();
|
||||
|
||||
const svgElement = document.getElementById('workflow-svg');
|
||||
const svgBoundingClientRect = svgElement.getBoundingClientRect();
|
||||
const svgBoundingClientRect = svgRef.current.getBoundingClientRect();
|
||||
|
||||
const [scaleToFit, yTranslate] = getScaleAndOffsetToFit(
|
||||
gBoundingClientRect,
|
||||
@ -175,9 +172,10 @@ function WorkflowOutputGraph({
|
||||
>
|
||||
<g id="workflow-g" ref={gRef}>
|
||||
{nodePositions && [
|
||||
<WorkflowOutputStartNode
|
||||
<WorkflowStartNode
|
||||
key="start"
|
||||
nodePositions={nodePositions}
|
||||
showActionTooltip={false}
|
||||
/>,
|
||||
links.map(link => (
|
||||
<WorkflowOutputLink
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { shape } from 'prop-types';
|
||||
import {
|
||||
generateLine,
|
||||
@ -7,23 +7,18 @@ import {
|
||||
} from '@util/workflow';
|
||||
|
||||
function WorkflowOutputLink({ link, nodePositions, onUpdateLinkHelp }) {
|
||||
const ref = useRef(null);
|
||||
const [hovering, setHovering] = useState(false);
|
||||
const [pathD, setPathD] = useState();
|
||||
const [pathStroke, setPathStroke] = useState('#CCCCCC');
|
||||
|
||||
const handleLinkMouseEnter = () => {
|
||||
const linkEl = document.getElementById(
|
||||
`link-${link.source.id}-${link.target.id}`
|
||||
);
|
||||
linkEl.parentNode.appendChild(linkEl);
|
||||
ref.current.parentNode.appendChild(ref.current);
|
||||
setHovering(true);
|
||||
};
|
||||
|
||||
const handleLinkMouseLeave = () => {
|
||||
const linkEl = document.getElementById(
|
||||
`link-${link.source.id}-${link.target.id}`
|
||||
);
|
||||
linkEl.parentNode.prepend(linkEl);
|
||||
ref.current.parentNode.prepend(ref.current);
|
||||
setHovering(null);
|
||||
};
|
||||
|
||||
@ -46,6 +41,7 @@ function WorkflowOutputLink({ link, nodePositions, onUpdateLinkHelp }) {
|
||||
|
||||
return (
|
||||
<g
|
||||
ref={ref}
|
||||
id={`link-${link.source.id}-${link.target.id}`}
|
||||
onMouseEnter={handleLinkMouseEnter}
|
||||
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 WorkflowOutputLink } from './WorkflowOutputLink';
|
||||
export { default as WorkflowOutputNode } from './WorkflowOutputNode';
|
||||
export { default as WorkflowOutputStartNode } from './WorkflowOutputStartNode';
|
||||
export { default as WorkflowOutputToolbar } from './WorkflowOutputToolbar';
|
||||
|
||||
@ -14,12 +14,12 @@ import {
|
||||
WorkflowKey,
|
||||
WorkflowLinkHelp,
|
||||
WorkflowNodeHelp,
|
||||
WorkflowStartNode,
|
||||
WorkflowTools,
|
||||
} from '@components/Workflow';
|
||||
import {
|
||||
VisualizerLink,
|
||||
VisualizerNode,
|
||||
VisualizerStartNode,
|
||||
} from '@screens/Template/WorkflowJobTemplateVisualizer';
|
||||
|
||||
const PotentialLink = styled.polyline`
|
||||
@ -148,8 +148,7 @@ function VisualizerGraph({
|
||||
};
|
||||
|
||||
const handlePanToMiddle = () => {
|
||||
const svgElement = document.getElementById('workflow-svg');
|
||||
const svgBoundingClientRect = svgElement.getBoundingClientRect();
|
||||
const svgBoundingClientRect = svgRef.current.getBoundingClientRect();
|
||||
d3.select(svgRef.current).call(
|
||||
zoomRef.transform,
|
||||
d3.zoomIdentity
|
||||
@ -161,8 +160,7 @@ function VisualizerGraph({
|
||||
};
|
||||
|
||||
const handleZoomChange = newScale => {
|
||||
const svgElement = document.getElementById('workflow-svg');
|
||||
const svgBoundingClientRect = svgElement.getBoundingClientRect();
|
||||
const svgBoundingClientRect = svgRef.current.getBoundingClientRect();
|
||||
const currentScaleAndOffset = d3.zoomTransform(
|
||||
d3.select(svgRef.current).node()
|
||||
);
|
||||
@ -194,8 +192,7 @@ function VisualizerGraph({
|
||||
.node()
|
||||
.getBBox();
|
||||
|
||||
const svgElement = document.getElementById('workflow-svg');
|
||||
const svgBoundingClientRect = svgElement.getBoundingClientRect();
|
||||
const svgBoundingClientRect = svgRef.current.getBoundingClientRect();
|
||||
|
||||
const [scaleToFit, yTranslate] = getScaleAndOffsetToFit(
|
||||
gBoundingClientRect,
|
||||
@ -276,12 +273,12 @@ function VisualizerGraph({
|
||||
/>
|
||||
<g id="workflow-g" ref={gRef}>
|
||||
{nodePositions && [
|
||||
<VisualizerStartNode
|
||||
<WorkflowStartNode
|
||||
addingLink={addingLink}
|
||||
key="start"
|
||||
nodePositions={nodePositions}
|
||||
onAddNodeClick={onAddNodeClick}
|
||||
readOnly={readOnly}
|
||||
showActionTooltip={!readOnly}
|
||||
onUpdateHelpText={setHelpText}
|
||||
/>,
|
||||
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 { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
@ -30,6 +30,7 @@ function VisualizerLink({
|
||||
onUpdateLinkHelp,
|
||||
readOnly,
|
||||
}) {
|
||||
const ref = useRef(null);
|
||||
const [hovering, setHovering] = useState(false);
|
||||
const [pathD, setPathD] = useState();
|
||||
const [pathStroke, setPathStroke] = useState('#CCCCCC');
|
||||
@ -80,18 +81,12 @@ function VisualizerLink({
|
||||
];
|
||||
|
||||
const handleLinkMouseEnter = () => {
|
||||
const linkEl = document.getElementById(
|
||||
`link-${link.source.id}-${link.target.id}`
|
||||
);
|
||||
linkEl.parentNode.appendChild(linkEl);
|
||||
ref.current.parentNode.appendChild(ref.current);
|
||||
setHovering(true);
|
||||
};
|
||||
|
||||
const handleLinkMouseLeave = () => {
|
||||
const linkEl = document.getElementById(
|
||||
`link-${link.source.id}-${link.target.id}`
|
||||
);
|
||||
linkEl.parentNode.prepend(linkEl);
|
||||
ref.current.parentNode.prepend(ref.current);
|
||||
setHovering(null);
|
||||
};
|
||||
|
||||
@ -120,6 +115,7 @@ function VisualizerLink({
|
||||
ignorePointerEvents={addingLink}
|
||||
onMouseEnter={handleLinkMouseEnter}
|
||||
onMouseLeave={handleLinkMouseLeave}
|
||||
ref={ref}
|
||||
>
|
||||
<polygon
|
||||
fill="#E1E1E1"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useRef, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
@ -54,11 +54,11 @@ function VisualizerNode({
|
||||
onUpdateHelpText,
|
||||
updateNodeHelp,
|
||||
}) {
|
||||
const ref = useRef(null);
|
||||
const [hovering, setHovering] = useState(false);
|
||||
|
||||
const handleNodeMouseEnter = () => {
|
||||
const nodeEl = document.getElementById(`node-${node.id}`);
|
||||
nodeEl.parentNode.appendChild(nodeEl);
|
||||
ref.current.parentNode.appendChild(ref.current);
|
||||
setHovering(true);
|
||||
if (addingLink) {
|
||||
onUpdateHelpText(
|
||||
@ -168,6 +168,7 @@ function VisualizerNode({
|
||||
noPointerEvents={isAddLinkSourceNode}
|
||||
onMouseEnter={handleNodeMouseEnter}
|
||||
onMouseLeave={handleNodeMouseLeave}
|
||||
ref={ref}
|
||||
transform={`translate(${nodePositions[node.id].x},${nodePositions[node.id]
|
||||
.y - nodePositions[1].y})`}
|
||||
>
|
||||
|
||||
@ -2,6 +2,5 @@ export { default as Visualizer } from './Visualizer';
|
||||
export { default as VisualizerGraph } from './VisualizerGraph';
|
||||
export { default as VisualizerLink } from './VisualizerLink';
|
||||
export { default as VisualizerNode } from './VisualizerNode';
|
||||
export { default as VisualizerStartNode } from './VisualizerStartNode';
|
||||
export { default as VisualizerStartScreen } from './VisualizerStartScreen';
|
||||
export { default as VisualizerToolbar } from './VisualizerToolbar';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user