,
]}
+ isOpen
+ onClose={onCancel}
+ title={i18n._(t`Remove All Nodes`)}
+ variant="danger"
>
{i18n._(
@@ -39,4 +40,9 @@ function DeleteAllNodesModal({ i18n, onConfirm, onCancel }) {
);
}
+DeleteAllNodesModal.propTypes = {
+ onCancel: func.isRequired,
+ onConfirm: func.isRequired,
+};
+
export default withI18n()(DeleteAllNodesModal);
diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkDeleteModal.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkDeleteModal.jsx
index db8222b8b8..390940937d 100644
--- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkDeleteModal.jsx
+++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkDeleteModal.jsx
@@ -2,6 +2,7 @@ import React, { Fragment } from 'react';
import { Button } from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
+import { func, shape } from 'prop-types';
import AlertModal from '@components/AlertModal';
function LinkDeleteModal({ i18n, linkToDelete, onConfirm, onCancel }) {
@@ -13,18 +14,18 @@ function LinkDeleteModal({ i18n, linkToDelete, onConfirm, onCancel }) {
onClose={onCancel}
actions={[
,
,
@@ -45,4 +46,10 @@ function LinkDeleteModal({ i18n, linkToDelete, onConfirm, onCancel }) {
);
}
+LinkDeleteModal.propTypes = {
+ linkToDelete: shape().isRequired,
+ onCancel: func.isRequired,
+ onConfirm: func.isRequired,
+};
+
export default withI18n()(LinkDeleteModal);
diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModal.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModal.jsx
index 6c76c80e4f..1e9c486e44 100644
--- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModal.jsx
+++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModal.jsx
@@ -1,23 +1,17 @@
import React, { useState } from 'react';
-import { Button, Modal } from '@patternfly/react-core';
+import { Button, FormGroup, Modal } from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
-import { FormGroup } from '@patternfly/react-core';
+import { func, node, string } from 'prop-types';
import AnsibleSelect from '@components/AnsibleSelect';
-function LinkModal({
- i18n,
- header,
- onCancel,
- onConfirm,
- edgeType = 'success',
-}) {
- const [newEdgeType, setNewEdgeType] = useState(edgeType);
+function LinkModal({ linkType, header, i18n, onCancel, onConfirm }) {
+ const [newLinkType, setNewLinkType] = useState(linkType);
return (
onConfirm(newEdgeType)}
+ onClick={() => onConfirm(newLinkType)}
>
{i18n._(t`Save`)}
,
@@ -42,7 +36,7 @@ function LinkModal({
{
- setNewEdgeType(value);
+ setNewLinkType(value);
}}
/>
@@ -69,4 +63,15 @@ function LinkModal({
);
}
+LinkModal.propTypes = {
+ linkType: string,
+ header: node.isRequired,
+ onCancel: func.isRequired,
+ onConfirm: func.isRequired,
+};
+
+LinkModal.defaultProps = {
+ linkType: 'success',
+};
+
export default withI18n()(LinkModal);
diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeDeleteModal.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeDeleteModal.jsx
index 5d98bc2550..31f20fcd76 100644
--- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeDeleteModal.jsx
+++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeDeleteModal.jsx
@@ -2,6 +2,7 @@ import React, { Fragment } from 'react';
import { Button } from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
+import { func, shape } from 'prop-types';
import AlertModal from '@components/AlertModal';
function NodeDeleteModal({ i18n, nodeToDelete, onConfirm, onCancel }) {
@@ -45,4 +46,10 @@ function NodeDeleteModal({ i18n, nodeToDelete, onConfirm, onCancel }) {
);
}
+NodeDeleteModal.propTypes = {
+ nodeToDelete: shape().isRequired,
+ onCancel: func.isRequired,
+ onConfirm: func.isRequired,
+};
+
export default withI18n()(NodeDeleteModal);
diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModal/NodeModal.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModal/NodeModal.jsx
index ed7bd6d546..6848fc1ec8 100644
--- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModal/NodeModal.jsx
+++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModal/NodeModal.jsx
@@ -2,82 +2,84 @@ import React, { useState } from 'react';
import { withRouter } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
+import { bool, func, node, shape } from 'prop-types';
import {
Button,
WizardContextConsumer,
WizardFooter,
} from '@patternfly/react-core';
-import NodeTypeStep from './NodeTypeStep/NodeTypeStep';
-import RunStep from './RunStep';
-import NodeNextButton from './NodeNextButton';
-import { Wizard } from '@components/Wizard';
+import Wizard from '@components/Wizard';
+import { NodeTypeStep } from './NodeTypeStep';
+import { RunStep, NodeNextButton } from '.';
function NodeModal({
+ askLinkType,
history,
i18n,
- title,
+ nodeToEdit,
onClose,
onSave,
- node,
- askLinkType,
+ title,
}) {
- let defaultNodeType = 'job_template';
- let defaultNodeResource = null;
- let defaultApprovalName = '';
let defaultApprovalDescription = '';
+ let defaultApprovalName = '';
let defaultApprovalTimeout = 0;
- if (node && node.unifiedJobTemplate) {
+ let defaultNodeResource = null;
+ let defaultNodeType = 'job_template';
+ if (nodeToEdit && nodeToEdit.unifiedJobTemplate) {
if (
- node &&
- node.unifiedJobTemplate &&
- (node.unifiedJobTemplate.type || node.unifiedJobTemplate.unified_job_type)
+ nodeToEdit &&
+ nodeToEdit.unifiedJobTemplate &&
+ (nodeToEdit.unifiedJobTemplate.type ||
+ nodeToEdit.unifiedJobTemplate.unified_job_type)
) {
const ujtType =
- node.unifiedJobTemplate.type ||
- node.unifiedJobTemplate.unified_job_type;
+ nodeToEdit.unifiedJobTemplate.type ||
+ nodeToEdit.unifiedJobTemplate.unified_job_type;
switch (ujtType) {
case 'job_template':
case 'job':
defaultNodeType = 'job_template';
- defaultNodeResource = node.unifiedJobTemplate;
+ defaultNodeResource = nodeToEdit.unifiedJobTemplate;
break;
case 'project':
case 'project_update':
defaultNodeType = 'project_sync';
- defaultNodeResource = node.unifiedJobTemplate;
+ defaultNodeResource = nodeToEdit.unifiedJobTemplate;
break;
case 'inventory_source':
case 'inventory_update':
defaultNodeType = 'inventory_source_sync';
- defaultNodeResource = node.unifiedJobTemplate;
+ defaultNodeResource = nodeToEdit.unifiedJobTemplate;
break;
case 'workflow_job_template':
case 'workflow_job':
defaultNodeType = 'workflow_job_template';
- defaultNodeResource = node.unifiedJobTemplate;
+ defaultNodeResource = nodeToEdit.unifiedJobTemplate;
break;
case 'workflow_approval_template':
case 'workflow_approval':
defaultNodeType = 'approval';
- defaultApprovalName = node.unifiedJobTemplate.name;
- defaultApprovalDescription = node.unifiedJobTemplate.description;
- defaultApprovalTimeout = node.unifiedJobTemplate.timeout;
+ defaultApprovalName = nodeToEdit.unifiedJobTemplate.name;
+ defaultApprovalDescription =
+ nodeToEdit.unifiedJobTemplate.description;
+ defaultApprovalTimeout = nodeToEdit.unifiedJobTemplate.timeout;
break;
default:
}
}
}
- const [nodeType, setNodeType] = useState(defaultNodeType);
- const [linkType, setLinkType] = useState('success');
- const [nodeResource, setNodeResource] = useState(defaultNodeResource);
- const [triggerNext, setTriggerNext] = useState(0);
- const [approvalName, setApprovalName] = useState(defaultApprovalName);
const [approvalDescription, setApprovalDescription] = useState(
defaultApprovalDescription
);
+ const [approvalName, setApprovalName] = useState(defaultApprovalName);
const [approvalTimeout, setApprovalTimeout] = useState(
defaultApprovalTimeout
);
+ const [linkType, setLinkType] = useState('success');
+ const [nodeResource, setNodeResource] = useState(defaultNodeResource);
+ const [nodeType, setNodeType] = useState(defaultNodeType);
+ const [triggerNext, setTriggerNext] = useState(0);
const clearQueryParams = () => {
const parts = history.location.search.replace(/^\?/, '').split('&');
@@ -95,19 +97,17 @@ function NodeModal({
const resource =
nodeType === 'approval'
? {
- name: approvalName,
description: approvalDescription,
+ name: approvalName,
timeout: approvalTimeout,
type: 'workflow_approval_template',
}
: nodeResource;
- // TODO: pick edgeType or linkType and be consistent across all files.
-
onSave({
- nodeType,
- edgeType: linkType,
+ linkType,
nodeResource: resource,
+ nodeType,
});
};
@@ -145,15 +145,15 @@ function NodeModal({
(nodeType === 'approval' && approvalName !== ''),
component: (
),
@@ -198,15 +198,27 @@ function NodeModal({
return (
);
}
+NodeModal.propTypes = {
+ askLinkType: bool.isRequired,
+ nodeToEdit: shape(),
+ onClose: func.isRequired,
+ onSave: func.isRequired,
+ title: node.isRequired,
+};
+
+NodeModal.defaultProps = {
+ nodeToEdit: null,
+};
+
export default withI18n()(withRouter(NodeModal));
diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModal/NodeNextButton.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModal/NodeNextButton.jsx
index a941cb33da..046b2b4db8 100644
--- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModal/NodeNextButton.jsx
+++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModal/NodeNextButton.jsx
@@ -1,22 +1,20 @@
import React, { useEffect } from 'react';
-import { withI18n } from '@lingui/react';
-import { t } from '@lingui/macro';
+import { func, number, shape, string } from 'prop-types';
import { Button } from '@patternfly/react-core';
function NodeNextButton({
- i18n,
activeStep,
+ buttonText,
+ onClick,
onNext,
triggerNext,
- onClick,
- buttonText,
}) {
useEffect(() => {
if (!triggerNext) {
return;
}
onNext();
- }, [triggerNext]);
+ }, [onNext, triggerNext]);
return (