From fc3f19bd2bcc0ec0f6473459371b227a59b77a23 Mon Sep 17 00:00:00 2001 From: mabashian Date: Tue, 28 Jan 2020 16:01:46 -0500 Subject: [PATCH] Fix some styling discrepancies between Chrome and Firefox in the workflow viz/output graphs. Cleans up deleted job/job template use cases. Show message indicating that the ujt associated with a node has been deleted. --- .../components/Workflow/WorkflowNodeHelp.jsx | 107 +++++++++++------- .../Workflow/WorkflowNodeHelp.test.jsx | 1 + .../Workflow/WorkflowNodeTypeLetter.jsx | 21 ++-- .../Job/WorkflowOutput/WorkflowOutputNode.jsx | 47 ++++---- .../WorkflowOutputNode.test.jsx | 4 +- .../VisualizerNode.jsx | 27 +++-- 6 files changed, 122 insertions(+), 85 deletions(-) diff --git a/awx/ui_next/src/components/Workflow/WorkflowNodeHelp.jsx b/awx/ui_next/src/components/Workflow/WorkflowNodeHelp.jsx index ce25921463..355c29c7d6 100644 --- a/awx/ui_next/src/components/Workflow/WorkflowNodeHelp.jsx +++ b/awx/ui_next/src/components/Workflow/WorkflowNodeHelp.jsx @@ -1,7 +1,8 @@ -import React, { Fragment } from 'react'; +import React from 'react'; import { withI18n } from '@lingui/react'; -import { t } from '@lingui/macro'; +import { t, Trans } from '@lingui/macro'; import styled from 'styled-components'; +import { ExclamationTriangleIcon } from '@patternfly/react-icons'; import { shape } from 'prop-types'; import { secondsToHHMMSS } from '@util/dates'; @@ -18,11 +19,23 @@ const GridDL = styled.dl` } `; +const ResourceDeleted = styled.p` + margin-bottom: ${props => (props.job ? '10px' : '0px')}; +`; + +const StyledExclamationTriangleIcon = styled(ExclamationTriangleIcon)` + color: #f0ad4d; + height: 20px; + margin-right: 10px; + width: 20px; +`; + function WorkflowNodeHelp({ node, i18n }) { let nodeType; - if (node.unifiedJobTemplate) { - const type = - node.unifiedJobTemplate.unified_job_type || node.unifiedJobTemplate.type; + if (node.unifiedJobTemplate || node.job) { + const type = node.unifiedJobTemplate + ? node.unifiedJobTemplate.unified_job_type || node.unifiedJobTemplate.type + : node.job.type; switch (type) { case 'job_template': case 'job': @@ -97,43 +110,59 @@ function WorkflowNodeHelp({ node, i18n }) { } return ( - - - {node.unifiedJobTemplate && ( - -
- {i18n._(t`Name`)} -
-
{node.unifiedJobTemplate.name}
-
- {i18n._(t`Type`)} -
-
{nodeType}
-
- )} - {node.job && ( - -
- {i18n._(t`Job Status`)} -
-
{jobStatus}
- {node.job.elapsed && ( - -
- {i18n._(t`Elapsed`)} -
-
- {secondsToHHMMSS(node.job.elapsed)} -
-
- )} -
- )} -
+ <> + {!node.unifiedJobTemplate && ( + <> + + + + The resource associated with this node has been deleted. + + + + )} + {node.job && ( + +
+ {i18n._(t`Name`)} +
+
{node.job.name}
+
+ {i18n._(t`Type`)} +
+
{nodeType}
+
+ {i18n._(t`Job Status`)} +
+
{jobStatus}
+ {node.job.elapsed && ( + <> +
+ {i18n._(t`Elapsed`)} +
+
+ {secondsToHHMMSS(node.job.elapsed)} +
+ + )} +
+ )} + {node.unifiedJobTemplate && !node.job && ( + +
+ {i18n._(t`Name`)} +
+
{node.unifiedJobTemplate.name}
+
+ {i18n._(t`Type`)} +
+
{nodeType}
+
+ )} {node.job && (

{i18n._(t`Click to view job details`)}

)} -
+ ); } diff --git a/awx/ui_next/src/components/Workflow/WorkflowNodeHelp.test.jsx b/awx/ui_next/src/components/Workflow/WorkflowNodeHelp.test.jsx index 01e771a140..30980cf353 100644 --- a/awx/ui_next/src/components/Workflow/WorkflowNodeHelp.test.jsx +++ b/awx/ui_next/src/components/Workflow/WorkflowNodeHelp.test.jsx @@ -10,6 +10,7 @@ describe('WorkflowNodeHelp', () => { test('renders the expected content for a completed job template job', () => { const node = { job: { + name: 'Foo Job Template', elapsed: 9000, status: 'successful', }, diff --git a/awx/ui_next/src/components/Workflow/WorkflowNodeTypeLetter.jsx b/awx/ui_next/src/components/Workflow/WorkflowNodeTypeLetter.jsx index 8abe9f4e77..5e01977d88 100644 --- a/awx/ui_next/src/components/Workflow/WorkflowNodeTypeLetter.jsx +++ b/awx/ui_next/src/components/Workflow/WorkflowNodeTypeLetter.jsx @@ -3,13 +3,15 @@ import styled from 'styled-components'; import { shape } from 'prop-types'; import { PauseIcon } from '@patternfly/react-icons'; -const NodeTypeLetter = styled.foreignObject` +const NodeTypeLetter = styled.div` background-color: #393f43; border-radius: 50%; color: white; font-size: 10px; line-height: 20px; text-align: center; + height: 20px; + width: 20px; `; const CenteredPauseIcon = styled(PauseIcon)` @@ -19,11 +21,14 @@ const CenteredPauseIcon = styled(PauseIcon)` function WorkflowNodeTypeLetter({ node }) { let nodeTypeLetter; if ( - node.unifiedJobTemplate && - (node.unifiedJobTemplate.type || node.unifiedJobTemplate.unified_job_type) + (node.unifiedJobTemplate && + (node.unifiedJobTemplate.type || + node.unifiedJobTemplate.unified_job_type)) || + (node.job && node.job.type) ) { - const ujtType = - node.unifiedJobTemplate.type || node.unifiedJobTemplate.unified_job_type; + const ujtType = node.unifiedJobTemplate + ? node.unifiedJobTemplate.type || node.unifiedJobTemplate.unified_job_type + : node.job.type; switch (ujtType) { case 'job_template': case 'job': @@ -51,9 +56,9 @@ function WorkflowNodeTypeLetter({ node }) { } return ( - - {nodeTypeLetter} - + + {nodeTypeLetter} + ); } diff --git a/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutputNode.jsx b/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutputNode.jsx index e8fcf8f68c..48bcba9617 100644 --- a/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutputNode.jsx +++ b/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutputNode.jsx @@ -43,7 +43,7 @@ const Elapsed = styled.div` } `; -const NodeContents = styled.foreignObject` +const NodeContents = styled.div` font-size: 13px; padding: 0px 10px; `; @@ -98,29 +98,28 @@ function WorkflowOutputNode({ history, i18n, mouseEnter, mouseLeave, node }) { strokeWidth="2px" width={wfConstants.nodeW} /> - - {node.job ? ( - <> - - -

- {node.unifiedJobTemplate - ? node.unifiedJobTemplate.name - : i18n._(t`DELETED`)} -

-
- {secondsToHHMMSS(node.job.elapsed)} - - ) : ( - - {node.unifiedJobTemplate - ? node.unifiedJobTemplate.name - : i18n._(t`DELETED`)} - - )} -
- - {node.unifiedJobTemplate && } + + + {node.job ? ( + <> + + +

{node.job.name}

+
+ {secondsToHHMMSS(node.job.elapsed)} + + ) : ( + + {node.unifiedJobTemplate + ? node.unifiedJobTemplate.name + : i18n._(t`DELETED`)} + + )} +
+
+ {(node.unifiedJobTemplate || node.job) && ( + + )} ); } diff --git a/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutputNode.test.jsx b/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutputNode.test.jsx index e819d079f3..198c01c3d1 100644 --- a/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutputNode.test.jsx +++ b/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutputNode.test.jsx @@ -24,7 +24,7 @@ const nodeWithoutJT = { job: { elapsed: 7, id: 9000, - name: 'Automation JT', + name: 'Automation JT 2', status: 'successful', type: 'job', }, @@ -87,7 +87,7 @@ describe('WorkflowOutputNode', () => { ); - expect(wrapper.contains(

DELETED

)).toEqual(true); + expect(wrapper.contains(

Automation JT 2

)).toEqual(true); expect(wrapper.find('WorkflowOutputNode__Elapsed').text()).toBe('00:00:07'); }); test('node contents displayed correctly when Job deleted', () => { diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerNode.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerNode.jsx index bd66921fad..7b7e6eeaab 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerNode.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerNode.jsx @@ -26,7 +26,7 @@ const NodeG = styled.g` cursor: ${props => (props.job ? 'pointer' : 'default')}; `; -const NodeContents = styled.foreignObject` +const NodeContents = styled.div` font-size: 13px; padding: 0px 10px; background-color: ${props => @@ -183,25 +183,28 @@ function VisualizerNode({ ? '#007ABC' : '#93969A' } - strokeWidth="4px" + strokeWidth="2px" width={wfConstants.nodeW} /> - updateNodeHelp(node), onMouseLeave: () => updateNodeHelp(null), })} onClick={() => handleNodeClick()} - width="180" + width="178" + x="1" + y="1" > - - {node.unifiedJobTemplate - ? node.unifiedJobTemplate.name - : i18n._(t`DELETED`)} - - + + + {node.unifiedJobTemplate + ? node.unifiedJobTemplate.name + : i18n._(t`DELETED`)} + + + {node.unifiedJobTemplate && } {hovering && !addingLink && (