diff --git a/awx/ui_next/src/components/Workflow/WorkflowNodeHelp.jsx b/awx/ui_next/src/components/Workflow/WorkflowNodeHelp.jsx
index 355c29c7d6..574610cde1 100644
--- a/awx/ui_next/src/components/Workflow/WorkflowNodeHelp.jsx
+++ b/awx/ui_next/src/components/Workflow/WorkflowNodeHelp.jsx
@@ -135,7 +135,7 @@ function WorkflowNodeHelp({ node, i18n }) {
{i18n._(t`Job Status`)}
{jobStatus}
- {node.job.elapsed && (
+ {typeof node.job.elapsed === 'number' && (
<>
{i18n._(t`Elapsed`)}
@@ -159,7 +159,7 @@ function WorkflowNodeHelp({ node, i18n }) {
{nodeType}
)}
- {node.job && (
+ {node.job && node.job.type !== 'workflow_approval' && (
{i18n._(t`Click to view job details`)}
)}
>
diff --git a/awx/ui_next/src/components/Workflow/workflowReducer.js b/awx/ui_next/src/components/Workflow/workflowReducer.js
index 2afce88d0f..1c2ae05fdd 100644
--- a/awx/ui_next/src/components/Workflow/workflowReducer.js
+++ b/awx/ui_next/src/components/Workflow/workflowReducer.js
@@ -1,5 +1,18 @@
import { t } from '@lingui/macro';
+export function initReducer() {
+ return {
+ contentError: null,
+ isLoading: true,
+ links: [],
+ nextNodeId: 0,
+ nodePositions: null,
+ nodes: [],
+ showLegend: false,
+ showTools: false,
+ };
+}
+
export default function visualizerReducer(state, action) {
switch (action.type) {
case 'CREATE_LINK':
@@ -25,6 +38,8 @@ export default function visualizerReducer(state, action) {
return deleteNode(state);
case 'GENERATE_NODES_AND_LINKS':
return generateNodesAndLinks(state, action.nodes, action.i18n);
+ case 'RESET':
+ return initReducer();
case 'SELECT_SOURCE_FOR_LINKING':
return selectSourceForLinking(state, action.node);
case 'SET_ADD_LINK_SOURCE_NODE':
diff --git a/awx/ui_next/src/screens/Job/Job.jsx b/awx/ui_next/src/screens/Job/Job.jsx
index 726c526c18..14efb2d14e 100644
--- a/awx/ui_next/src/screens/Job/Job.jsx
+++ b/awx/ui_next/src/screens/Job/Job.jsx
@@ -123,7 +123,7 @@ class Job extends Component {
exact
/>
job &&
@@ -131,7 +131,7 @@ class Job extends Component {
}
/>
job &&
diff --git a/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutput.jsx b/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutput.jsx
index c4cbb886fe..b304348cb9 100644
--- a/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutput.jsx
+++ b/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutput.jsx
@@ -10,7 +10,9 @@ import {
import { layoutGraph } from '@components/Workflow/WorkflowUtils';
import ContentError from '@components/ContentError';
import ContentLoading from '@components/ContentLoading';
-import workflowReducer from '@components/Workflow/workflowReducer';
+import workflowReducer, {
+ initReducer,
+} from '@components/Workflow/workflowReducer';
import { WorkflowJobsAPI } from '@api';
import WorkflowOutputGraph from './WorkflowOutputGraph';
import WorkflowOutputToolbar from './WorkflowOutputToolbar';
@@ -41,17 +43,7 @@ const fetchWorkflowNodes = async (jobId, pageNo = 1, nodes = []) => {
};
function WorkflowOutput({ job, i18n }) {
- const [state, dispatch] = useReducer(workflowReducer, {
- contentError: null,
- isLoading: true,
- links: [],
- nextNodeId: 0,
- nodePositions: null,
- nodes: [],
- showLegend: false,
- showTools: false,
- });
-
+ const [state, dispatch] = useReducer(workflowReducer, {}, initReducer);
const { contentError, isLoading, links, nodePositions, nodes } = state;
useEffect(() => {
@@ -69,6 +61,7 @@ function WorkflowOutput({ job, i18n }) {
dispatch({ type: 'SET_IS_LOADING', value: false });
}
}
+ dispatch({ type: 'RESET' });
fetchData();
}, [job.id, i18n]);
@@ -84,7 +77,7 @@ function WorkflowOutput({ job, i18n }) {
dispatch({ type: 'SET_NODE_POSITIONS', value: newNodePositions });
}
- }, [links, nodes]);
+ }, [job.id, links, nodes]);
if (isLoading) {
return (
diff --git a/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutputNode.jsx b/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutputNode.jsx
index 88a57390c2..8b2f841a62 100644
--- a/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutputNode.jsx
+++ b/awx/ui_next/src/screens/Job/WorkflowOutput/WorkflowOutputNode.jsx
@@ -11,7 +11,10 @@ import { secondsToHHMMSS } from '@util/dates';
import { constants as wfConstants } from '@components/Workflow/WorkflowUtils';
const NodeG = styled.g`
- cursor: ${props => (props.job ? 'pointer' : 'default')};
+ cursor: ${props =>
+ props.job && props.job.type !== 'workflow_approval'
+ ? 'pointer'
+ : 'default'};
`;
const JobTopLine = styled.div`
@@ -75,7 +78,7 @@ function WorkflowOutputNode({ i18n, mouseEnter, mouseLeave, node }) {
}
const handleNodeClick = () => {
- if (node.job) {
+ if (node.job && node.job.type !== 'workflow_aproval') {
history.push(`/jobs/${node.job.id}/details`);
}
};