}
- />,
- {
- context: {
- router: {
- history,
- route: {
- location: history.location,
- match: { params: { id: 6 } },
- },
- },
- },
- }
- );
- await act(async () => {
- await waitForElement(wrapper, 'ContentLoading', el => el.length === 1);
- });
- expect(UnifiedJobTemplatesAPI.read).toBeCalledWith({
- jobtemplate__project: '6',
- order_by: 'name',
- page: 1,
- page_size: 20,
- type: 'job_template,workflow_job_template',
- });
- });
});
diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Visualizer.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Visualizer.jsx
index 754d0765e3..2cac0a8eae 100644
--- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Visualizer.jsx
+++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Visualizer.jsx
@@ -431,6 +431,7 @@ function Visualizer({ template, i18n }) {
{links.length > 0 ? (
diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerToolbar.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerToolbar.jsx
index 9f88c11931..abdab2a40f 100644
--- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerToolbar.jsx
+++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerToolbar.jsx
@@ -5,7 +5,7 @@ import {
} from '@contexts/Workflow';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
-import { func, shape } from 'prop-types';
+import { bool, func, shape } from 'prop-types';
import {
Badge as PFBadge,
Button,
@@ -20,6 +20,7 @@ import {
TrashAltIcon,
WrenchIcon,
} from '@patternfly/react-icons';
+import LaunchButton from '@components/LaunchButton';
import styled from 'styled-components';
const Badge = styled(PFBadge)`
@@ -45,12 +46,20 @@ const ActionButton = styled(Button)`
`;
ActionButton.displayName = 'ActionButton';
-function VisualizerToolbar({ i18n, onClose, onSave, template }) {
+function VisualizerToolbar({
+ i18n,
+ onClose,
+ onSave,
+ template,
+ hasUnsavedChanges,
+}) {
const dispatch = useContext(WorkflowDispatchContext);
const { nodes, showLegend, showTools } = useContext(WorkflowStateContext);
const totalNodes = nodes.reduce((n, node) => n + !node.isDeleted, 0) - 1;
+ const canLaunch =
+ template.summary_fields?.user_capabilities?.start && !hasUnsavedChanges;
return (