Decouple editing a wf node with editing a node link

This commit is contained in:
mabashian 2018-10-04 20:29:10 -06:00
parent 1e10d4323f
commit 87d6253176
14 changed files with 1504 additions and 1194 deletions

View File

@ -122,6 +122,7 @@ function TemplatesStrings (BaseString) {
INVENTORY_WILL_NOT_OVERRIDE: t.s('The inventory of this node will not be overridden by the parent workflow inventory.'),
INVENTORY_PROMPT_WILL_OVERRIDE: t.s('The inventory of this node will be overridden if a parent workflow inventory is provided at launch.'),
INVENTORY_PROMPT_WILL_NOT_OVERRIDE: t.s('The inventory of this node will not be overridden if a parent workflow inventory is provided at launch.'),
EDIT_LINK: ({ parentName, childName }) => t.s('EDIT LINK | {{parentName}} to {{childName}}', { parentName, childName })
}
}

View File

@ -1,4 +1,9 @@
.link circle, .link .linkCross, .node .addCircle, .node .removeCircle, .node .WorkflowChart-hoverPath {
.link circle,
.link polygon,
.link .linkCross,
.node circle,
.node .linkIcon,
.node .WorkflowChart-hoverPath {
opacity: 0;
}
@ -18,6 +23,18 @@
fill: @default-err-hov;
}
.node .linkCircle {
fill: @default-link;
}
.node .linkIcon {
color: @default-bg;
}
.linkCircle.removeHovering {
fill: @default-link-hov;
}
.node {
font-size: 12px;
font-family: 'Open Sans', sans-serif, 'FontAwesome';
@ -50,8 +67,12 @@
.WorkflowChart-alwaysShowAdd .linkCross,
.hovering .addCircle,
.hovering .removeCircle,
.addHovering .betweenNodesCircle,
.hovering .linkCircle,
.hovering .linkIcon,
.hovering .WorkflowChart-hoverPath,
.hovering .linkCross {
.addHovering .linkCross {
cursor: pointer;
opacity: 1;
}
@ -136,3 +157,17 @@
.WorkflowChart-dashedNode {
stroke-dasharray: 5,5;
}
.linkOverlay {
fill: @default-interface-txt;
}
.linkActiveEdit.linkOverlay,
.overlayHovering .linkOverlay {
cursor: pointer;
opacity: 0.4;
}
.overlayHovering .linkPath {
cursor: pointer;
}

View File

@ -0,0 +1,7 @@
import workflowLinkForm from './workflow-link-form.directive';
import workflowNodeForm from './workflow-node-form.directive';
export default
angular.module('templates.workflowMaker.forms', [])
.directive('workflowLinkForm', workflowLinkForm)
.directive('workflowNodeForm', workflowNodeForm);

View File

@ -0,0 +1,38 @@
/*************************************************
* Copyright (c) 2018 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default ['$scope', 'TemplatesStrings', 'CreateSelect2', '$timeout',
function($scope, TemplatesStrings, CreateSelect2, $timeout) {
$scope.strings = TemplatesStrings;
$scope.edgeTypeOptions = [
{
label: $scope.strings.get('workflow_maker.ALWAYS'),
value: 'always'
},
{
label: $scope.strings.get('workflow_maker.ON_SUCCESS'),
value: 'success'
},
{
label: $scope.strings.get('workflow_maker.ON_FAILURE'),
value: 'failure'
}
];
$scope.$watch('linkConfig.edgeType', () => {
if (_.has($scope, 'linkConfig.edgeType')) {
$scope.edgeType = {
value: $scope.linkConfig.edgeType
};
CreateSelect2({
element: '#workflow_node_edge_2',
multiple: false
});
}
});
}
];

View File

@ -0,0 +1,22 @@
/*************************************************
* Copyright (c) 2018 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
import workflowLinkFormController from './workflow-link-form.controller';
export default ['templateUrl',
function(templateUrl) {
return {
scope: {
linkConfig: '<',
cancel: '&',
select: '&'
},
restrict: 'E',
templateUrl: templateUrl('templates/workflows/workflow-maker/forms/workflow-link-form'),
controller: workflowLinkFormController
};
}
];

View File

@ -0,0 +1,25 @@
<div class="WorkflowMaker-formTitle">{{:: strings.get('workflow_maker.EDIT_LINK', {parentName: linkConfig.parent.name, childName: linkConfig.child.name}) }}</div>
<div class="WorkflowMaker-form">
<div class="form-group Form-formGroup Form-formGroup--singleColumn">
<label for="edgeType" class="Form-inputLabelContainer">
<span class="Form-requiredAsterisk">*</span>
<span class="Form-inputLabel">{{:: strings.get('workflow_maker.RUN') }}</span>
</label>
<div>
<select
id="workflow_node_edge_2"
ng-options="v as v.label for v in edgeTypeOptions track by v.value"
ng-model="edgeType"
class="form-control Form-dropDown"
name="edgeType"
tabindex="-1"
aria-hidden="true">
</select>
</div>
</div>
<div class="buttons Form-buttons" id="workflow_maker_controls">
<button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_cancel_link_btn" ng-click="cancel()"> {{:: strings.get('CANCEL') }}</button>
<button type="button" class="btn btn-sm Form-saveButton" id="workflow_maker_select_link_btn" ng-click="select({parentId: linkConfig.parent.id, childId: linkConfig.child.id, edgeType: edgeType.value})" ng-disabled="!edgeType"> {{:: strings.get('workflow_maker.SELECT') }}</button>
</div>
</div>
</div>

View File

@ -0,0 +1,11 @@
/*************************************************
* Copyright (c) 2018 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default ['$scope',
function($scope) {
console.log('inside wnf controller');
}
];

View File

@ -0,0 +1,21 @@
/*************************************************
* Copyright (c) 2018 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
import workflowNodeFormController from './workflow-node-form.controller';
export default ['templateUrl',
function(templateUrl) {
return {
scope: {},
restrict: 'E',
templateUrl: templateUrl('templates/workflows/workflow-maker/forms/workflow-node-form'),
controller: workflowNodeFormController,
link: function(scope) {
console.log('inside link function for workflow node form');
}
};
}
];

View File

@ -0,0 +1,51 @@
<div class="Form-tabHolder">
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': workflowMakerFormConfig.activeTab === 'jobs'}" ng-click="toggleFormTab('jobs')">{{strings.get('workflow_maker.JOBS')}}</div>
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': workflowMakerFormConfig.activeTab === 'project_sync'}" ng-click="toggleFormTab('project_sync')">{{strings.get('workflow_maker.PROJECT_SYNC')}}</div>
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': workflowMakerFormConfig.activeTab === 'inventory_sync'}" ng-click="toggleFormTab('inventory_sync')">{{strings.get('workflow_maker.INVENTORY_SYNC')}}</div>
</div>
<div class="WorkflowMaker-formLists">
<div id="workflow-jobs-list" ui-view="jobTemplateList" ng-show="workflowMakerFormConfig.activeTab === 'jobs'"></div>
<div id="workflow-project-sync-list" ui-view="projectSyncList" ng-show="workflowMakerFormConfig.activeTab === 'project_sync'"></div>
<div id="workflow-inventory-sync-list" ui-view="inventorySyncList" ng-show="workflowMakerFormConfig.activeTab === 'inventory_sync'"></div>
</div>
<span ng-show="selectedTemplate &&
((selectedTemplate.type === 'job_template' && workflowMakerFormConfig.activeTab === 'jobs') ||
(selectedTemplate.type === 'project' && workflowMakerFormConfig.activeTab === 'project_sync') ||
(selectedTemplate.type === 'inventory_source' && workflowMakerFormConfig.activeTab === 'inventory_sync'))">
<div ng-if="selectedTemplate && selectedTemplateInvalid">
<div class="WorkflowMaker-invalidJobTemplateWarning">
<span class="fa fa-warning"></span>
<span>{{:: strings.get('workflows.INVALID_JOB_TEMPLATE') }}</span>
</div>
</div>
<div ng-if="selectedTemplate && credentialRequiresPassword">
<div class="WorkflowMaker-invalidJobTemplateWarning">
<span class="fa fa-warning"></span>
<span>{{:: strings.get('workflows.CREDENTIAL_WITH_PASS') }}</span>
</div>
</div>
<div class="form-group Form-formGroup Form-formGroup--singleColumn" ng-show="selectedTemplate && !selectedTemplateInvalid && !(credentialRequiresPassword && !promptData.launchConf.ask_credential_on_launch)">
<label for="verbosity" class="Form-inputLabelContainer">
<span class="Form-requiredAsterisk">*</span>
<span class="Form-inputLabel">{{:: strings.get('workflow_maker.RUN') }}</span>
</label>
<div>
<select
id="workflow_node_edge"
ng-options="v as v.label for v in edgeTypeOptions track by v.value"
ng-model="edgeType"
class="form-control Form-dropDown"
name="edgeType"
tabindex="-1"
ng-disabled="!workflowJobTemplateObj.summary_fields.user_capabilities.edit"
aria-hidden="true">
</select>
</div>
</div>
<div class="buttons Form-buttons" id="workflow_maker_controls">
<button type="button" class="btn btn-sm Form-primaryButton Form-primaryButton--noMargin" id="workflow_maker_prompt_btn" ng-show="showPromptButton" ng-click="openPromptModal()"> {{:: strings.get('prompt.PROMPT') }}</button>
<button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_cancel_btn" ng-show="(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)" ng-click="cancelNodeForm()"> {{:: strings.get('CANCEL') }}</button>
<button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_close_btn" ng-show="!(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)" ng-click="cancelNodeForm()"> {{:: strings.get('CLOSE') }}</button>
<button type="button" class="btn btn-sm Form-saveButton" id="workflow_maker_select_btn" ng-show="(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate) && !selectedTemplateInvalid && !(credentialRequiresPassword && !promptData.launchConf.ask_credential_on_launch)" ng-click="confirmNodeForm()" ng-disabled="!selectedTemplate || promptModalMissingReqFields || credentialRequiresPassword"> {{:: strings.get('workflow_maker.SELECT') }}</button>
</div>
</span>

View File

@ -1,8 +1,9 @@
import workflowMaker from './workflow-maker.directive';
import WorkflowMakerController from './workflow-maker.controller';
import workflowMakerForms from './forms/main';
export default
angular.module('templates.workflowMaker', [])
angular.module('templates.workflowMaker', [workflowMakerForms.name])
// In order to test this controller I had to expose it at the module level
// like so. Is this correct? Is there a better pattern for doing this?
.controller('WorkflowMakerController', WorkflowMakerController)

View File

@ -127,7 +127,6 @@
color: @list-title-txt;
font-size: 14px;
font-weight: bold;
text-transform: uppercase;
margin-bottom: 20px;
}
.WorkflowMaker-formHelp {

View File

@ -203,7 +203,7 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
});
});
} else {
if (params.node.edited || !params.node.originalParentId || (params.node.originalParentId && params.parentId !== params.node.originalParentId)) {
if (params.node.edited || !params.node.originalParentId || (params.node.originalParentId && (params.parentId !== params.node.originalParentId || params.node.originalEdge !== params.node.edgeType))) {
if (params.node.edited) {
@ -446,6 +446,10 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
$scope.cancelNodeForm();
}
if ($scope.linkBeingEdited) {
$scope.cancelLinkForm();
}
$scope.workflowMakerFormConfig.nodeMode = "add";
$scope.addParent = parent;
$scope.betweenTwoNodes = betweenTwoNodes;
@ -572,6 +576,10 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
$scope.startEditNode = function (nodeToEdit) {
$scope.editNodeHelpMessage = null;
if ($scope.linkBeingEdited) {
$scope.cancelLinkForm();
}
if (!$scope.nodeBeingEdited || ($scope.nodeBeingEdited && $scope.nodeBeingEdited.id !== nodeToEdit.id)) {
if ($scope.placeholderNode || $scope.nodeBeingEdited) {
$scope.cancelNodeForm();
@ -893,6 +901,91 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
};
/* EDIT LINK FUNCTIONS */
$scope.startEditLink = (parentId, childId) => {
const setupLinkEdit = () => {
const parentNode = WorkflowService.searchTree({
element: $scope.treeData.data,
matchingId: parentId,
byNodeId: true
});
parentNode.isLinkEditParent = true;
// Loop across children looking for childId
const childNode = _.find(parentNode.children, {'nodeId': childId});
childNode.isLinkEditChild = true;
$scope.linkBeingEdited = {
parent: parentNode,
child: childNode
}
$scope.linkConfig = {
parent: {
id: parentId,
name: parentNode.unifiedJobTemplate.name
},
child: {
id: childId,
name: childNode.unifiedJobTemplate.name
},
edgeType: childNode.edgeType
}
$scope.editLink = true;
$scope.$broadcast("refreshWorkflowChart");
}
if ($scope.nodeBeingEdited || $scope.placeholderNode) {
$scope.cancelNodeForm();
}
if ($scope.linkBeingEdited) {
if ($scope.linkBeingEdited.parent.nodeId !== parentId || $scope.linkBeingEdited.child.nodeId !== childId) {
$scope.linkBeingEdited.parent.isLinkEditParent = false;
$scope.linkBeingEdited.child.isLinkEditChild = false;
setupLinkEdit()
}
} else {
setupLinkEdit();
}
};
$scope.confirmLinkForm = (parentId, childId, edgeType) => {
$scope.linkBeingEdited.parent.isLinkEditParent = false;
$scope.linkBeingEdited.child.isLinkEditChild = false;
const parentNode = WorkflowService.searchTree({
element: $scope.treeData.data,
matchingId: parentId,
byNodeId: true
});
// Loop across children looking for childId
const childNode = _.find(parentNode.children, {'nodeId': childId});
childNode.edgeType = edgeType;
$scope.linkBeingEdited = null;
$scope.editLink = false;
$scope.$broadcast("refreshWorkflowChart");
}
$scope.cancelLinkForm = () => {
$scope.linkBeingEdited.parent.isLinkEditParent = false;
$scope.linkBeingEdited.child.isLinkEditChild = false;
$scope.linkBeingEdited = null;
$scope.editLink = false;
$scope.$broadcast("refreshWorkflowChart");
};
/* DELETE NODE FUNCTIONS */
function resetDeleteNode() {
@ -912,6 +1005,10 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
$scope.confirmDeleteNode = function () {
if ($scope.nodeToBeDeleted) {
if ($scope.linkBeingEdited) {
$scope.cancelLinkForm();
}
// TODO: turn this into a promise so that we can handle errors
WorkflowService.removeNodeFromTree({

View File

@ -81,68 +81,69 @@
</div>
</div>
</div>
<workflow-chart ng-if="modalOpen" tree-data="treeData.data" add-node="startAddNode(parent, betweenTwoNodes)" edit-node="startEditNode(nodeToEdit)" delete-node="startDeleteNode(nodeToDelete)" workflow-zoomed="workflowZoomed(zoom)" can-add-workflow-job-template="canAddWorkflowJobTemplate" workflow-job-template-obj="workflowJobTemplateObj" mode="edit" class="WorkflowMaker-chart"></workflow-chart>
<workflow-chart ng-if="modalOpen" tree-data="treeData.data" add-node="startAddNode(parent, betweenTwoNodes)" edit-node="startEditNode(nodeToEdit)" edit-link="startEditLink(parentId, childId)" delete-node="startDeleteNode(nodeToDelete)" workflow-zoomed="workflowZoomed(zoom)" can-add-workflow-job-template="canAddWorkflowJobTemplate" workflow-job-template-obj="workflowJobTemplateObj" mode="edit" class="WorkflowMaker-chart"></workflow-chart>
</div>
<div class="WorkflowMaker-contentRight">
<div class="WorkflowMaker-formTitle">{{(workflowMakerFormConfig.nodeMode === 'edit' && nodeBeingEdited) ? ((nodeBeingEdited.unifiedJobTemplate && nodeBeingEdited.unifiedJobTemplate.name) ? nodeBeingEdited.unifiedJobTemplate.name : strings.get('workflow_maker.EDIT_TEMPLATE')) : strings.get('workflow_maker.ADD_A_TEMPLATE')}}</div>
<div class="WorkflowMaker-formHelp" ng-show="workflowMakerFormConfig.nodeMode === 'idle'" ng-bind="treeData.data.totalNodes === 0 ? strings.get('workflow_maker.PLEASE_CLICK_THE_START_BUTTON') : strings.get('workflow_maker.PLEASE_HOVER_OVER_A_TEMPLATE')"></div>
<div class="WorkflowMaker-form" ng-show="workflowMakerFormConfig.nodeMode === 'add' || workflowMakerFormConfig.nodeMode === 'edit'">
<div class="Form-tabHolder">
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': workflowMakerFormConfig.activeTab === 'jobs'}" ng-click="toggleFormTab('jobs')">{{strings.get('workflow_maker.JOBS')}}</div>
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': workflowMakerFormConfig.activeTab === 'project_sync'}" ng-click="toggleFormTab('project_sync')">{{strings.get('workflow_maker.PROJECT_SYNC')}}</div>
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': workflowMakerFormConfig.activeTab === 'inventory_sync'}" ng-click="toggleFormTab('inventory_sync')">{{strings.get('workflow_maker.INVENTORY_SYNC')}}</div>
<span ng-show="!editLink">
<div class="WorkflowMaker-formTitle">{{(workflowMakerFormConfig.nodeMode === 'edit' && nodeBeingEdited) ? ((nodeBeingEdited.unifiedJobTemplate && nodeBeingEdited.unifiedJobTemplate.name) ? nodeBeingEdited.unifiedJobTemplate.name : strings.get('workflow_maker.EDIT_TEMPLATE')) : strings.get('workflow_maker.ADD_A_TEMPLATE')}}</div>
<div class="WorkflowMaker-formHelp" ng-show="workflowMakerFormConfig.nodeMode === 'idle'" ng-bind="treeData.data.totalNodes === 0 ? strings.get('workflow_maker.PLEASE_CLICK_THE_START_BUTTON') : strings.get('workflow_maker.PLEASE_HOVER_OVER_A_TEMPLATE')"></div>
<div class="WorkflowMaker-form" ng-show="workflowMakerFormConfig.nodeMode === 'add' || workflowMakerFormConfig.nodeMode === 'edit'">
<div class="Form-tabHolder">
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': workflowMakerFormConfig.activeTab === 'jobs'}" ng-click="toggleFormTab('jobs')">{{strings.get('workflow_maker.JOBS')}}</div>
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': workflowMakerFormConfig.activeTab === 'project_sync'}" ng-click="toggleFormTab('project_sync')">{{strings.get('workflow_maker.PROJECT_SYNC')}}</div>
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': workflowMakerFormConfig.activeTab === 'inventory_sync'}" ng-click="toggleFormTab('inventory_sync')">{{strings.get('workflow_maker.INVENTORY_SYNC')}}</div>
</div>
<div class="WorkflowMaker-formLists">
<div id="workflow-jobs-list" ui-view="jobTemplateList" ng-show="workflowMakerFormConfig.activeTab === 'jobs'"></div>
<div id="workflow-project-sync-list" ui-view="projectSyncList" ng-show="workflowMakerFormConfig.activeTab === 'project_sync'"></div>
<div id="workflow-inventory-sync-list" ui-view="inventorySyncList" ng-show="workflowMakerFormConfig.activeTab === 'inventory_sync'"></div>
</div>
<span ng-show="selectedTemplate &&
((selectedTemplate.type === 'job_template' && workflowMakerFormConfig.activeTab === 'jobs') ||
(selectedTemplate.type === 'project' && workflowMakerFormConfig.activeTab === 'project_sync') ||
(selectedTemplate.type === 'inventory_source' && workflowMakerFormConfig.activeTab === 'inventory_sync'))">
<div ng-if="selectedTemplate && selectedTemplateInvalid">
<div class="WorkflowMaker-invalidJobTemplateWarning">
<span class="fa fa-warning"></span>
<span>{{:: strings.get('workflows.INVALID_JOB_TEMPLATE') }}</span>
</div>
</div>
<div ng-if="selectedTemplate && credentialRequiresPassword">
<div class="WorkflowMaker-invalidJobTemplateWarning">
<span class="fa fa-warning"></span>
<span>{{:: strings.get('workflows.CREDENTIAL_WITH_PASS') }}</span>
</div>
</div>
<div class="form-group Form-formGroup Form-formGroup--singleColumn" ng-show="selectedTemplate && !selectedTemplateInvalid && !(credentialRequiresPassword && !promptData.launchConf.ask_credential_on_launch) && workflowMakerFormConfig.nodeMode === 'add'">
<label for="verbosity" class="Form-inputLabelContainer">
<span class="Form-requiredAsterisk">*</span>
<span class="Form-inputLabel">{{:: strings.get('workflow_maker.RUN') }}</span>
</label>
<div>
<select
id="workflow_node_edge"
ng-options="v as v.label for v in edgeTypeOptions track by v.value"
ng-model="edgeType"
class="form-control Form-dropDown"
name="edgeType"
tabindex="-1"
ng-disabled="!workflowJobTemplateObj.summary_fields.user_capabilities.edit"
aria-hidden="true">
</select>
</div>
</div>
<div class="buttons Form-buttons" id="workflow_maker_controls">
<button type="button" class="btn btn-sm Form-primaryButton Form-primaryButton--noMargin" id="workflow_maker_prompt_btn" ng-show="showPromptButton" ng-click="openPromptModal()"> {{:: strings.get('prompt.PROMPT') }}</button>
<button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_cancel_btn" ng-show="(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)" ng-click="cancelNodeForm()"> {{:: strings.get('CANCEL') }}</button>
<button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_close_btn" ng-show="!(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)" ng-click="cancelNodeForm()"> {{:: strings.get('CLOSE') }}</button>
<button type="button" class="btn btn-sm Form-saveButton" id="workflow_maker_select_btn" ng-show="(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate) && !selectedTemplateInvalid && !(credentialRequiresPassword && !promptData.launchConf.ask_credential_on_launch)" ng-click="confirmNodeForm()" ng-disabled="!selectedTemplate || promptModalMissingReqFields || credentialRequiresPassword"> {{:: strings.get('workflow_maker.SELECT') }}</button>
</div>
</span>
</div>
<div class="WorkflowMaker-formLists">
<div id="workflow-jobs-list" ui-view="jobTemplateList" ng-show="workflowMakerFormConfig.activeTab === 'jobs'"></div>
<div id="workflow-project-sync-list" ui-view="projectSyncList" ng-show="workflowMakerFormConfig.activeTab === 'project_sync'"></div>
<div id="workflow-inventory-sync-list" ui-view="inventorySyncList" ng-show="workflowMakerFormConfig.activeTab === 'inventory_sync'"></div>
</div>
<span ng-show="selectedTemplate &&
((selectedTemplate.type === 'job_template' || selectedTemplate.type === 'workflow_job_template' && workflowMakerFormConfig.activeTab === 'jobs') ||
(selectedTemplate.unified_job_type === 'job' || selectedTemplate.unified_job_type === 'workflow_job' && workflowMakerFormConfig.activeTab === 'jobs') ||
(selectedTemplate.type === 'project' && workflowMakerFormConfig.activeTab === 'project_sync') ||
(selectedTemplate.unified_job_type === 'inventory_update' && workflowMakerFormConfig.activeTab === 'inventory_sync') ||
(selectedTemplate.type === 'inventory_source' && workflowMakerFormConfig.activeTab === 'inventory_sync'))">
<div ng-if="selectedTemplate && selectedTemplateInvalid">
<div class="WorkflowMaker-invalidJobTemplateWarning">
<span class="fa fa-warning"></span>
<span>{{:: strings.get('workflows.INVALID_JOB_TEMPLATE') }}</span>
</div>
</div>
<div ng-if="selectedTemplate && credentialRequiresPassword">
<div class="WorkflowMaker-invalidJobTemplateWarning">
<span class="fa fa-warning"></span>
<span>{{:: strings.get('workflows.CREDENTIAL_WITH_PASS') }}</span>
</div>
</div>
<div class="form-group Form-formGroup Form-formGroup--singleColumn" ng-show="selectedTemplate && !selectedTemplateInvalid && !(credentialRequiresPassword && !promptData.launchConf.ask_credential_on_launch)">
<label for="verbosity" class="Form-inputLabelContainer">
<span class="Form-requiredAsterisk">*</span>
<span class="Form-inputLabel">{{:: strings.get('workflow_maker.RUN') }}</span>
</label>
<div>
<select
id="workflow_node_edge"
ng-options="v as v.label for v in edgeTypeOptions track by v.value"
ng-model="edgeType"
class="form-control Form-dropDown"
name="edgeType"
tabindex="-1"
ng-disabled="!workflowJobTemplateObj.summary_fields.user_capabilities.edit"
aria-hidden="true">
</select>
</div>
</div>
<div ng-show="editNodeHelpMessage" class="WorkflowMaker-formHelp" ng-bind="editNodeHelpMessage"></div>
<br />
<div class="buttons Form-buttons" id="workflow_maker_controls">
<button type="button" class="btn btn-sm Form-primaryButton Form-primaryButton--noMargin" id="workflow_maker_prompt_btn" ng-show="showPromptButton" ng-click="openPromptModal()"> {{:: strings.get('prompt.PROMPT') }}</button>
<button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_cancel_btn" ng-show="(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)" ng-click="cancelNodeForm()"> {{:: strings.get('CANCEL') }}</button>
<button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_close_btn" ng-show="!(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)" ng-click="cancelNodeForm()"> {{:: strings.get('CLOSE') }}</button>
<button type="button" class="btn btn-sm Form-saveButton" id="workflow_maker_select_btn" ng-show="(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate) && !selectedTemplateInvalid && !(credentialRequiresPassword && !promptData.launchConf.ask_credential_on_launch)" ng-click="confirmNodeForm()" ng-disabled="!selectedTemplate || promptModalMissingReqFields || credentialRequiresPassword"> {{:: strings.get('workflow_maker.SELECT') }}</button>
</div>
</span>
</div>
</span>
<span ng-if="editLink">
<workflow-link-form link-config="linkConfig" select="confirmLinkForm(parentId, childId, edgeType)" cancel="cancelLinkForm()"/>
</span>
</div>
</div>
<div class="WorkflowMaker-buttonHolder">