diff --git a/awx/ui_next/src/components/Workflow/WorkflowKey.jsx b/awx/ui_next/src/components/Workflow/WorkflowKey.jsx index e0e75dd995..6c5cdd5be1 100644 --- a/awx/ui_next/src/components/Workflow/WorkflowKey.jsx +++ b/awx/ui_next/src/components/Workflow/WorkflowKey.jsx @@ -2,18 +2,25 @@ import React from 'react'; import { withI18n } from '@lingui/react'; import { t } from '@lingui/macro'; import styled from 'styled-components'; -import { ExclamationTriangleIcon, PauseIcon } from '@patternfly/react-icons'; +import { func } from 'prop-types'; +import { + ExclamationTriangleIcon, + PauseIcon, + TimesIcon, +} from '@patternfly/react-icons'; const Wrapper = styled.div` background-color: white; border: 1px solid #c7c7c7; margin-left: 20px; min-width: 100px; + position: relative; `; const Header = styled.div` border-bottom: 1px solid #c7c7c7; padding: 10px; + position: relative; `; const Key = styled.ul` @@ -63,11 +70,19 @@ const AlwaysLink = styled(Link)` background-color: #337ab7; `; -function WorkflowKey({ i18n }) { +const Close = styled(TimesIcon)` + cursor: pointer; + position: absolute; + right: 10px; + top: 15px; +`; + +function WorkflowKey({ i18n, onClose }) { return (
{i18n._(t`Key`)} +
  • @@ -113,4 +128,8 @@ function WorkflowKey({ i18n }) { ); } +WorkflowKey.propTypes = { + onClose: func.isRequired, +}; + export default withI18n()(WorkflowKey); diff --git a/awx/ui_next/src/components/Workflow/WorkflowKey.test.jsx b/awx/ui_next/src/components/Workflow/WorkflowKey.test.jsx index 6fac4c4ef8..05d8762acd 100644 --- a/awx/ui_next/src/components/Workflow/WorkflowKey.test.jsx +++ b/awx/ui_next/src/components/Workflow/WorkflowKey.test.jsx @@ -4,7 +4,7 @@ import WorkflowKey from './WorkflowKey'; describe('WorkflowKey', () => { test('renders the expected content', () => { - const wrapper = mountWithContexts(); + const wrapper = mountWithContexts( {}} />); expect(wrapper).toHaveLength(1); }); }); diff --git a/awx/ui_next/src/components/Workflow/WorkflowTools.jsx b/awx/ui_next/src/components/Workflow/WorkflowTools.jsx index a1aa6f4c08..31ca802ee4 100644 --- a/awx/ui_next/src/components/Workflow/WorkflowTools.jsx +++ b/awx/ui_next/src/components/Workflow/WorkflowTools.jsx @@ -13,12 +13,14 @@ import { HomeIcon, MinusIcon, PlusIcon, + TimesIcon, } from '@patternfly/react-icons'; const Wrapper = styled.div` background-color: white; border: 1px solid #c7c7c7; height: 135px; + position: relative; `; const Header = styled.div` @@ -42,8 +44,16 @@ const Tools = styled.div` padding: 20px; `; +const Close = styled(TimesIcon)` + cursor: pointer; + position: absolute; + right: 10px; + top: 15px; +`; + function WorkflowTools({ i18n, + onClose, onFitGraph, onPan, onPanToMiddle, @@ -70,6 +80,7 @@ function WorkflowTools({
    {i18n._(t`Tools`)} +
    { test('renders the expected content', () => { const wrapper = mountWithContexts( {}} onFitGraph={() => {}} onPan={() => {}} onPanToMiddle={() => {}} @@ -15,12 +16,14 @@ describe('WorkflowTools', () => { ); expect(wrapper).toHaveLength(1); }); - test('clicking zoom buttons passes callback correctly updated scale', () => { + test('clicking zoom/pan buttons passes callback correct values', () => { + const pan = jest.fn(); const zoomChange = jest.fn(); const wrapper = mountWithContexts( {}} onFitGraph={() => {}} - onPan={() => {}} + onPan={pan} onPanToMiddle={() => {}} onZoomChange={zoomChange} zoomPercentage={95.7} @@ -30,18 +33,6 @@ describe('WorkflowTools', () => { expect(zoomChange).toHaveBeenCalledWith(1.1); wrapper.find('MinusIcon').simulate('click'); expect(zoomChange).toHaveBeenCalledWith(0.8); - }); - test('clicking pan buttons passes callback correct string direction', () => { - const pan = jest.fn(); - const wrapper = mountWithContexts( - {}} - onPan={pan} - onPanToMiddle={() => {}} - onZoomChange={() => {}} - zoomPercentage={100} - /> - ); wrapper.find('CaretLeftIcon').simulate('click'); expect(pan).toHaveBeenCalledWith('left'); wrapper.find('CaretUpIcon').simulate('click'); diff --git a/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutput.jsx b/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutput.jsx index d624a34ff0..6ff3a4350f 100644 --- a/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutput.jsx +++ b/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutput.jsx @@ -211,6 +211,8 @@ function WorkflowOutput({ job, i18n }) { links={graphLinks} nodePositions={nodePositions} nodes={graphNodes} + onUpdateShowKey={setShowKey} + onUpdateShowTools={setShowTools} showKey={showKey} showTools={showTools} /> diff --git a/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutputGraph.jsx b/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutputGraph.jsx index 89aff5467d..04ad3219da 100644 --- a/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutputGraph.jsx +++ b/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutputGraph.jsx @@ -1,6 +1,6 @@ import React, { Fragment, useEffect, useRef, useState } from 'react'; import * as d3 from 'd3'; -import { arrayOf, bool, shape } from 'prop-types'; +import { arrayOf, bool, shape, func } from 'prop-types'; import { calcZoomAndFit, getZoomTranslate } from '@util/workflow'; import { WorkflowOutputLink, @@ -18,6 +18,8 @@ function WorkflowOutputGraph({ links, nodePositions, nodes, + onUpdateShowKey, + onUpdateShowTools, showKey, showTools, }) { @@ -180,6 +182,7 @@ function WorkflowOutputGraph({
    {showTools && ( onUpdateShowTools(false)} onFitGraph={handleFitGraph} onPan={handlePan} onPanToMiddle={handlePanToMiddle} @@ -187,7 +190,7 @@ function WorkflowOutputGraph({ zoomPercentage={zoomPercentage} /> )} - {showKey && } + {showKey && onUpdateShowKey(false)} />}
    ); @@ -197,6 +200,8 @@ WorkflowOutputGraph.propTypes = { links: arrayOf(shape()).isRequired, nodePositions: shape().isRequired, nodes: arrayOf(shape()).isRequired, + onUpdateShowKey: func.isRequired, + onUpdateShowTools: func.isRequired, showKey: bool.isRequired, showTools: bool.isRequired, }; diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Visualizer.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Visualizer.jsx index 47c95424bd..8f003b29fb 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Visualizer.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Visualizer.jsx @@ -825,6 +825,8 @@ function Visualizer({ history, template, i18n }) { onEditNodeClick={startEditNode} onLinkEditClick={setLinkToEdit} onStartAddLinkClick={selectSourceNodeForLinking} + onUpdateShowKey={setShowKey} + onUpdateShowTools={setShowTools} onViewNodeClick={setNodeToView} readOnly={!template.summary_fields.user_capabilities.edit} showKey={showKey} diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerGraph.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerGraph.jsx index 99108d54cd..58081edad1 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerGraph.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerGraph.jsx @@ -47,6 +47,8 @@ function VisualizerGraph({ onEditNodeClick, onLinkEditClick, onStartAddLinkClick, + onUpdateShowKey, + onUpdateShowTools, onViewNodeClick, readOnly, showKey, @@ -329,6 +331,7 @@ function VisualizerGraph({
    {showTools && ( onUpdateShowTools(false)} onFitGraph={handleFitGraph} onPan={handlePan} onPanToMiddle={handlePanToMiddle} @@ -336,7 +339,7 @@ function VisualizerGraph({ zoomPercentage={zoomPercentage} /> )} - {showKey && } + {showKey && onUpdateShowKey(false)} />}
    ); @@ -356,6 +359,8 @@ VisualizerGraph.propTypes = { onEditNodeClick: func.isRequired, onLinkEditClick: func.isRequired, onStartAddLinkClick: func.isRequired, + onUpdateShowKey: func.isRequired, + onUpdateShowTools: func.isRequired, onViewNodeClick: func.isRequired, readOnly: bool.isRequired, showKey: bool.isRequired,