diff --git a/awx/ui/client/src/forms/JobTemplates.js b/awx/ui/client/src/forms/JobTemplates.js
index d7e0b502ee..00f4c5f131 100644
--- a/awx/ui/client/src/forms/JobTemplates.js
+++ b/awx/ui/client/src/forms/JobTemplates.js
@@ -33,7 +33,7 @@ export default
name: {
label: i18n._('Name'),
type: 'text',
- ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)',
+ ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)',
required: true,
column: 1
},
@@ -41,7 +41,7 @@ export default
label: i18n._('Description'),
type: 'text',
column: 1,
- ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
},
job_type: {
label: i18n._('Job Type'),
@@ -63,7 +63,7 @@ export default
ngShow: "!job_type.value || job_type.value !== 'scan'",
text: i18n._('Prompt on launch')
},
- ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
},
inventory: {
label: i18n._('Inventory'),
@@ -87,7 +87,7 @@ export default
ngShow: "!job_type.value || job_type.value !== 'scan'",
text: i18n._('Prompt on launch')
},
- ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
},
project: {
label: i18n._('Project'),
@@ -110,13 +110,13 @@ export default
dataTitle: i18n._('Project'),
dataPlacement: 'right',
dataContainer: "body",
- ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
},
playbook: {
label: i18n._('Playbook'),
type:'select',
ngOptions: 'book for book in playbook_options track by book',
- ngDisabled: "(job_type.value === 'scan' && project_name === 'Default') || !(job_template_obj.summary_fields.user_capabilities.edit || canAdd)",
+ ngDisabled: "(job_type.value === 'scan' && project_name === 'Default') || !(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)",
id: 'playbook-select',
awRequiredWhen: {
reqExpression: "playbookrequired",
@@ -154,7 +154,7 @@ export default
variable: 'ask_credential_on_launch',
text: i18n._('Prompt on launch')
},
- ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
},
cloud_credential: {
label: i18n._('Cloud Credential'),
@@ -172,7 +172,7 @@ export default
dataTitle: i18n._('Cloud Credential'),
dataPlacement: 'right',
dataContainer: "body",
- ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
},
network_credential: {
label: i18n._('Network Credential'),
@@ -189,7 +189,7 @@ export default
dataTitle: i18n._('Network Credential'),
dataPlacement: 'right',
dataContainer: "body",
- ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
},
forks: {
label: i18n._('Forks'),
@@ -207,7 +207,7 @@ export default
dataTitle: i18n._('Forks'),
dataPlacement: 'right',
dataContainer: "body",
- ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)' // TODO: get working
+ ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)' // TODO: get working
},
limit: {
label: i18n._('Limit'),
@@ -223,7 +223,7 @@ export default
variable: 'ask_limit_on_launch',
text: i18n._('Prompt on launch')
},
- ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
},
verbosity: {
label: i18n._('Verbosity'),
@@ -236,7 +236,7 @@ export default
dataTitle: i18n._('Verbosity'),
dataPlacement: 'right',
dataContainer: "body",
- ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
},
job_tags: {
label: i18n._('Job Tags'),
@@ -254,7 +254,7 @@ export default
variable: 'ask_tags_on_launch',
text: i18n._('Prompt on launch')
},
- ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
},
skip_tags: {
label: i18n._('Skip Tags'),
@@ -272,7 +272,7 @@ export default
variable: 'ask_skip_tags_on_launch',
text: i18n._('Prompt on launch')
},
- ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
},
checkbox_group: {
label: i18n._('Options'),
@@ -287,7 +287,7 @@ export default
dataTitle: i18n._('Become Privilege Escalation'),
dataContainer: "body",
labelClass: 'stack-inline',
- ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
}, {
name: 'allow_callbacks',
label: i18n._('Allow Provisioning Callbacks'),
@@ -300,7 +300,7 @@ export default
dataTitle: i18n._('Allow Provisioning Callbacks'),
dataContainer: "body",
labelClass: 'stack-inline',
- ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
}]
},
callback_url: {
@@ -314,7 +314,7 @@ export default
dataPlacement: 'top',
dataTitle: i18n._('Provisioning Callback URL'),
dataContainer: "body",
- ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
},
host_config_key: {
label: i18n._('Host Config Key'),
@@ -328,7 +328,7 @@ export default
dataPlacement: 'right',
dataTitle: i18n._("Host Config Key"),
dataContainer: "body",
- ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
},
labels: {
label: i18n._('Labels'),
@@ -340,7 +340,7 @@ export default
dataPlacement: 'right',
awPopOver: i18n._("
Optional labels that describe this job template, such as 'dev' or 'test'. Labels can be used to group and filter job templates and completed jobs in the Tower display.
"),
dataContainer: 'body',
- ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
},
variables: {
label: i18n._('Extra Variables'),
@@ -362,14 +362,14 @@ export default
variable: 'ask_variables_on_launch',
text: i18n._('Prompt on launch')
},
- ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)' // TODO: get working
+ ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)' // TODO: get working
}
},
buttons: { //for now always generates tags
add_survey: {
ngClick: 'addSurvey()',
- ngShow: 'job_type.value !== "scan" && !survey_exists && (job_template_obj.summary_fields.user_capabilities.edit || canAdd)',
+ ngShow: 'job_type.value !== "scan" && !survey_exists && (job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)',
awFeature: 'surveys',
awToolTip: 'Surveys allow users to be prompted at job launch with a series of questions related to the job. This allows for variables to be defined that affect the playbook run at time of launch.',
dataPlacement: 'top'
@@ -377,25 +377,25 @@ export default
edit_survey: {
ngClick: 'editSurvey()',
awFeature: 'surveys',
- ngShow: 'job_type.value !== "scan" && survey_exists && (job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngShow: 'job_type.value !== "scan" && survey_exists && (job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
},
view_survey: {
ngClick: 'editSurvey()',
awFeature: 'surveys',
- ngShow: 'job_type.value !== "scan" && survey_exists && !(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngShow: 'job_type.value !== "scan" && survey_exists && !(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
},
cancel: {
ngClick: 'formCancel()',
- ngShow: '(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngShow: '(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
},
close: {
ngClick: 'formCancel()',
- ngShow: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngShow: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
},
save: {
ngClick: 'formSave()', //$scope.function to call on click, optional
ngDisabled: "job_templates_form.$invalid",//true //Disable when $pristine or $invalid, optional and when can_edit = false, for permission reasons
- ngShow: '(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngShow: '(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
}
},
@@ -422,7 +422,7 @@ export default
awToolTip: 'Add a permission',
actionClass: 'btn List-buttonSubmit',
buttonContent: '+ ADD',
- ngShow: '(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngShow: '(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
}
},
diff --git a/awx/ui/client/src/forms/WorkflowMaker.js b/awx/ui/client/src/forms/WorkflowMaker.js
index 56e5c42dd7..6f2a0bef4b 100644
--- a/awx/ui/client/src/forms/WorkflowMaker.js
+++ b/awx/ui/client/src/forms/WorkflowMaker.js
@@ -28,6 +28,7 @@ export default
label: 'Type',
type: 'radio_group',
ngShow: 'selectedTemplate && showTypeOptions',
+ ngDisabled: '!canAddWorkflowJobTemplate',
options: [
{
label: 'On Success',
@@ -63,6 +64,7 @@ export default
dataPlacement: 'right',
dataContainer: "body",
ngShow: "selectedTemplate.ask_credential_on_launch",
+ ngDisabled: '!canAddWorkflowJobTemplate',
awRequiredWhen: {
reqExpression: 'selectedTemplate && selectedTemplate.ask_credential_on_launch'
}
@@ -82,6 +84,7 @@ export default
dataPlacement: 'right',
dataContainer: "body",
ngShow: "selectedTemplate.ask_inventory_on_launch",
+ ngDisabled: '!canAddWorkflowJobTemplate',
awRequiredWhen: {
reqExpression: 'selectedTemplate && selectedTemplate.ask_inventory_on_launch'
}
@@ -100,6 +103,7 @@ export default
dataPlacement: 'right',
dataContainer: "body",
ngShow: "selectedTemplate.ask_job_type_on_launch",
+ ngDisabled: '!canAddWorkflowJobTemplate',
awRequiredWhen: {
reqExpression: 'selectedTemplate && selectedTemplate.ask_job_type_on_launch'
}
@@ -114,7 +118,8 @@ export default
dataTitle: 'Limit',
dataPlacement: 'right',
dataContainer: "body",
- ngShow: "selectedTemplate.ask_limit_on_launch"
+ ngShow: "selectedTemplate.ask_limit_on_launch",
+ ngDisabled: '!canAddWorkflowJobTemplate'
},
job_tags: {
label: 'Job Tags',
@@ -128,7 +133,8 @@ export default
dataTitle: "Job Tags",
dataPlacement: "right",
dataContainer: "body",
- ngShow: "selectedTemplate.ask_tags_on_launch"
+ ngShow: "selectedTemplate.ask_tags_on_launch",
+ ngDisabled: '!canAddWorkflowJobTemplate'
},
skip_tags: {
label: 'Skip Tags',
@@ -142,16 +148,23 @@ export default
dataTitle: "Skip Tags",
dataPlacement: "right",
dataContainer: "body",
- ngShow: "selectedTemplate.ask_skip_tags_on_launch"
+ ngShow: "selectedTemplate.ask_skip_tags_on_launch",
+ ngDisabled: '!canAddWorkflowJobTemplate'
}
},
buttons: {
cancel: {
- ngClick: 'cancelNodeForm()'
+ ngClick: 'cancelNodeForm()',
+ ngShow: 'canAddWorkflowJobTemplate'
+ },
+ close: {
+ ngClick: 'cancelNodeForm()',
+ ngShow: '!canAddWorkflowJobTemplate'
},
save: {
ngClick: 'saveNodeForm()',
- ngDisabled: "workflow_maker_form.$invalid || !selectedTemplate"
+ ngDisabled: "workflow_maker_form.$invalid || !selectedTemplate",
+ ngShow: 'canAddWorkflowJobTemplate'
}
}
})
diff --git a/awx/ui/client/src/forms/Workflows.js b/awx/ui/client/src/forms/Workflows.js
index 8f5ecb9bdc..66841c1557 100644
--- a/awx/ui/client/src/forms/Workflows.js
+++ b/awx/ui/client/src/forms/Workflows.js
@@ -29,14 +29,15 @@ export default
name: {
label: 'Name',
type: 'text',
- addRequired: true,
- editRequired: true,
+ required: true,
+ ngDisabled: '!(workflow_job_template_obj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)',
column: 1
},
description: {
label: 'Description',
type: 'text',
- column: 1
+ column: 1,
+ ngDisabled: '!(workflow_job_template_obj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)'
},
organization: {
label: 'Organization',
@@ -48,7 +49,8 @@ export default
dataTitle: 'Organization',
dataContainer: 'body',
dataPlacement: 'right',
- column: 1
+ column: 1,
+ ngDisabled: '!(workflow_job_template_obj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)'
},
labels: {
label: 'Labels',
@@ -59,7 +61,8 @@ export default
dataTitle: 'Labels',
dataPlacement: 'right',
awPopOver: "Optional labels that describe this job template, such as 'dev' or 'test'. Labels can be used to group and filter job templates and completed jobs in the Tower display.
",
- dataContainer: 'body'
+ dataContainer: 'body',
+ ngDisabled: '!(workflow_job_template_obj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)'
},
variables: {
label: 'Extra Variables',
@@ -76,17 +79,24 @@ export default
"--- somevar: somevalue password: magic \n",
dataTitle: 'Extra Variables',
dataPlacement: 'right',
- dataContainer: "body"
+ dataContainer: "body",
+ ngDisabled: '!(workflow_job_template_obj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)' // TODO: get working
}
},
buttons: { //for now always generates tags
cancel: {
- ngClick: 'formCancel()'
+ ngClick: 'formCancel()',
+ ngShow: '(workflow_job_template_obj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)'
+ },
+ close: {
+ ngClick: 'formCancel()',
+ ngShow: '!(workflow_job_template_obj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)'
},
save: {
ngClick: 'formSave()', //$scope.function to call on click, optional
- ngDisabled: "workflow_form.$invalid || can_edit!==true"//true //Disable when $pristine or $invalid, optional and when can_edit = false, for permission reasons
+ ngDisabled: "workflow_form.$invalid || can_edit!==true", //Disable when $pristine or $invalid, optional and when can_edit = false, for permission reasons
+ ngShow: '(workflow_job_template_obj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)'
}
},
@@ -108,7 +118,7 @@ export default
awToolTip: 'Add a permission',
actionClass: 'btn List-buttonSubmit',
buttonContent: '+ ADD',
- ngShow: '(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
+ ngShow: '(workflow_job_template_obj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)'
}
},
diff --git a/awx/ui/client/src/job-templates/edit-job-template/job-template-edit.controller.js b/awx/ui/client/src/job-templates/edit-job-template/job-template-edit.controller.js
index 71554b411c..0ce5645a3d 100644
--- a/awx/ui/client/src/job-templates/edit-job-template/job-template-edit.controller.js
+++ b/awx/ui/client/src/job-templates/edit-job-template/job-template-edit.controller.js
@@ -31,7 +31,7 @@ export default
$scope.$watch('job_template_obj.summary_fields.user_capabilities.edit', function(val) {
if (val === false) {
- $scope.canAdd = false;
+ $scope.canAddJobTemplate = false;
}
});
diff --git a/awx/ui/client/src/job-templates/edit-workflow/workflow-edit.controller.js b/awx/ui/client/src/job-templates/edit-workflow/workflow-edit.controller.js
index b79b10ce83..c666f44815 100644
--- a/awx/ui/client/src/job-templates/edit-workflow/workflow-edit.controller.js
+++ b/awx/ui/client/src/job-templates/edit-workflow/workflow-edit.controller.js
@@ -20,7 +20,7 @@
$scope.$watch('workflow_job_template_obj.summary_fields.user_capabilities.edit', function(val) {
if (val === false) {
- $scope.canAdd = false;
+ $scope.canAddWorkflowJobTemplate = false;
}
});
@@ -125,13 +125,6 @@
}
function init() {
- // // Inject the edit form
- // generator.inject(form, {
- // mode: 'edit' ,
- // scope: $scope,
- // related: false
- // });
- // generator.reset();
// Select2-ify the lables input
CreateSelect2({
@@ -140,24 +133,6 @@
addNew: true
});
- // // Make the variables textarea look nice
- // ParseTypeChange({
- // scope: $scope,
- // field_id: 'workflow_job_template_variables',
- // onChange: function() {
- // $scope[form.name + '_form'].$setDirty();
- // }
- // });
-
- // // Initialize the organization lookup
- // LookUpInit({
- // scope: $scope,
- // form: form,
- // list: OrganizationList,
- // field: 'organization',
- // input_type: 'radio'
- // });
-
Rest.setUrl('api/v1/labels');
Wait("start");
Rest.get()
diff --git a/awx/ui/client/src/job-templates/list/job-templates-list.controller.js b/awx/ui/client/src/job-templates/list/job-templates-list.controller.js
index 57a6a38939..52cc08e966 100644
--- a/awx/ui/client/src/job-templates/list/job-templates-list.controller.js
+++ b/awx/ui/client/src/job-templates/list/job-templates-list.controller.js
@@ -22,8 +22,13 @@ export default ['$scope', '$rootScope', '$location', '$stateParams', 'Rest', 'Al
$scope.canAdd = false;
rbacUiControlService.canAdd("job_templates")
- .then(function(canAdd) {
- $scope.canAdd = canAdd;
+ .then(function(canAddJobTemplate) {
+ $scope.canAddJobTemplate = canAddJobTemplate;
+ });
+
+ rbacUiControlService.canAdd("workflow_job_templates")
+ .then(function(canAddWorkflowJobTemplate) {
+ $scope.canAddWorkflowJobTemplate = canAddWorkflowJobTemplate;
});
// search init
$scope.list = list;
diff --git a/awx/ui/client/src/job-templates/main.js b/awx/ui/client/src/job-templates/main.js
index e404e4d19e..c450115d50 100644
--- a/awx/ui/client/src/job-templates/main.js
+++ b/awx/ui/client/src/job-templates/main.js
@@ -108,7 +108,7 @@ angular.module('jobTemplates', [surveyMaker.name, jobTemplatesList.name, jobTemp
},
views: {
'modal': {
- template: ` `
+ template: ` `
},
'jobTemplateList@templates.editWorkflowJobTemplate.workflowMaker': {
templateProvider: function(WorkflowMakerJobTemplateList, generateList) {
@@ -260,8 +260,8 @@ angular.module('jobTemplates', [surveyMaker.name, jobTemplatesList.name, jobTemp
});
return html;
},
- controller: ['$scope',
- function($scope) {
+ controller: ['$scope', '$timeout', 'CreateSelect2',
+ function($scope, $timeout, CreateSelect2) {
function resetPromptFields() {
$scope.credential = null;
$scope.credential_name = null;
@@ -296,6 +296,14 @@ angular.module('jobTemplates', [surveyMaker.name, jobTemplatesList.name, jobTemp
_.forOwn(options.presetValues, function(value, key) {
$scope[key] = value;
});
+
+ // The default needs to be in place before we can select2-ify the dropdown
+ $timeout(function() {
+ CreateSelect2({
+ element: '#workflow_maker_job_type',
+ multiple: false
+ });
+ });
});
$scope.$on('setEdgeType', function(e, edgeType) {
diff --git a/awx/ui/client/src/job-templates/workflow-chart/workflow-chart.directive.js b/awx/ui/client/src/job-templates/workflow-chart/workflow-chart.directive.js
index 29c7ebd61d..f989bbc2a0 100644
--- a/awx/ui/client/src/job-templates/workflow-chart/workflow-chart.directive.js
+++ b/awx/ui/client/src/job-templates/workflow-chart/workflow-chart.directive.js
@@ -10,6 +10,7 @@ export default [
return {
scope: {
treeData: '=',
+ canAddWorkflowJobTemplate: '=',
addNode: '&',
editNode: '&',
deleteNode: '&'
@@ -17,7 +18,12 @@ export default [
restrict: 'E',
link: function(scope, element) {
- var margin = {top: 20, right: 20, bottom: 20, left: 20},
+ scope.$watch('canAddWorkflowJobTemplate', function() {
+ // Redraw the graph if permissions change
+ update();
+ });
+
+ let margin = {top: 20, right: 20, bottom: 20, left: 20},
width = 950,
height = 590 - margin.top - margin.bottom,
i = 0,
@@ -26,21 +32,21 @@ export default [
rootW = 60,
rootH = 40;
- var tree = d3.layout.tree()
+ let tree = d3.layout.tree()
.size([height, width]);
- var line = d3.svg.line()
+ let line = d3.svg.line()
.x(function(d){return d.x;})
.y(function(d){return d.y;});
function lineData(d){
- var sourceX = d.source.isStartNode ? d.source.y + rootW : d.source.y + rectW;
- var sourceY = d.source.isStartNode ? d.source.x + 10 + rootH / 2 : d.source.x + rectH / 2;
- var targetX = d.target.y;
- var targetY = d.target.x + rectH / 2;
+ let sourceX = d.source.isStartNode ? d.source.y + rootW : d.source.y + rectW;
+ let sourceY = d.source.isStartNode ? d.source.x + 10 + rootH / 2 : d.source.x + rectH / 2;
+ let targetX = d.target.y;
+ let targetY = d.target.x + rectH / 2;
- var points = [
+ let points = [
{
x: sourceX,
y: sourceY
@@ -65,23 +71,23 @@ export default [
}
}
- var svg = d3.select(element[0]).append("svg")
+ let svg = d3.select(element[0]).append("svg")
.attr("width", width)
.attr("height", height)
.attr("class", "WorkflowChart-svg")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
- var node = svg.selectAll(".node"),
+ let node = svg.selectAll(".node"),
link = svg.selectAll(".link");
function update() {
// Declare the nodes
- var nodes = tree.nodes(scope.treeData);
+ let nodes = tree.nodes(scope.treeData);
node = node.data(nodes, function(d) { d.y = d.depth * 180; return d.id || (d.id = ++i); });
link = link.data(tree.links(nodes), function(d) { return d.source.id + "-" + d.target.id; });
- var nodeEnter = node.enter().append("g")
+ let nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("id", function(d){return "node-" + d.id;})
.attr("parent", function(d){return d.parent ? d.parent.id : null;})
@@ -89,7 +95,7 @@ export default [
.attr("fill", "red");
nodeEnter.each(function(d) {
- var thisNode = d3.select(this);
+ let thisNode = d3.select(this);
if(d.isStartNode) {
thisNode.append("rect")
.attr("width", 60)
@@ -174,7 +180,7 @@ export default [
.attr("cx", rectW)
.attr("r", 10)
.attr("class", "addCircle nodeCircle")
- .style("display", function(d) { return d.placeholder ? "none" : null; })
+ .style("display", function(d) { return d.placeholder || scope.canAddWorkflowJobTemplate === false ? "none" : null; })
.call(add_node)
.on("mouseover", function(d) {
d3.select("#node-" + d.id)
@@ -196,7 +202,7 @@ export default [
.size(60)
.type("cross")
)
- .style("display", function(d) { return d.placeholder ? "none" : null; })
+ .style("display", function(d) { return d.placeholder || scope.canAddWorkflowJobTemplate === false ? "none" : null; })
.call(add_node)
.on("mouseover", function(d) {
d3.select("#node-" + d.id)
@@ -216,7 +222,7 @@ export default [
.attr("cy", rectH)
.attr("r", 10)
.attr("class", "removeCircle")
- .style("display", function(d) { return (d.canDelete === false || d.placeholder) ? "none" : null; })
+ .style("display", function(d) { return (d.canDelete === false || d.placeholder || scope.canAddWorkflowJobTemplate === false) ? "none" : null; })
.call(remove_node)
.on("mouseover", function(d) {
d3.select("#node-" + d.id)
@@ -238,7 +244,7 @@ export default [
.size(60)
.type("cross")
)
- .style("display", function(d) { return (d.canDelete === false || d.placeholder) ? "none" : null; })
+ .style("display", function(d) { return (d.canDelete === false || d.placeholder || scope.canAddWorkflowJobTemplate === false) ? "none" : null; })
.call(remove_node)
.on("mouseover", function(d) {
d3.select("#node-" + d.id)
@@ -257,7 +263,7 @@ export default [
node.exit().remove();
- var linkEnter = link.enter().append("g")
+ let linkEnter = link.enter().append("g")
.attr("class", "nodeConnector")
.attr("id", function(d){return "link-" + d.source.id + "-" + d.target.id;});
@@ -294,7 +300,7 @@ export default [
})
.attr("r", 10)
.attr("class", "addCircle linkCircle")
- .style("display", function(d) { return (d.source.placeholder || d.target.placeholder) ? "none" : null; })
+ .style("display", function(d) { return (d.source.placeholder || d.target.placeholder || scope.canAddWorkflowJobTemplate === false) ? "none" : null; })
.call(add_node_between)
.on("mouseover", function(d) {
d3.select("#link-" + d.source.id + "-" + d.target.id)
@@ -317,7 +323,7 @@ export default [
.size(60)
.type("cross")
)
- .style("display", function(d) { return (d.source.placeholder || d.target.placeholder) ? "none" : null; })
+ .style("display", function(d) { return (d.source.placeholder || d.target.placeholder || scope.canAddWorkflowJobTemplate === false) ? "none" : null; })
.call(add_node_between)
.on("mouseover", function(d) {
d3.select("#link-" + d.source.id + "-" + d.target.id)
@@ -335,19 +341,19 @@ export default [
link.exit().remove();
// Transition nodes and links to their new positions.
- var t = svg.transition();
+ let t = svg.transition();
t.selectAll(".nodeCircle")
- .style("display", function(d) { return d.placeholder ? "none" : null; });
+ .style("display", function(d) { return d.placeholder || scope.canAddWorkflowJobTemplate === false ? "none" : null; });
t.selectAll(".nodeAddCross")
- .style("display", function(d) { return d.placeholder ? "none" : null; });
+ .style("display", function(d) { return d.placeholder || scope.canAddWorkflowJobTemplate === false ? "none" : null; });
t.selectAll(".removeCircle")
- .style("display", function(d) { return (d.canDelete === false || d.placeholder) ? "none" : null; });
+ .style("display", function(d) { return (d.canDelete === false || d.placeholder || scope.canAddWorkflowJobTemplate === false) ? "none" : null; });
t.selectAll(".nodeRemoveCross")
- .style("display", function(d) { return (d.canDelete === false || d.placeholder) ? "none" : null; });
+ .style("display", function(d) { return (d.canDelete === false || d.placeholder || scope.canAddWorkflowJobTemplate === false) ? "none" : null; });
t.selectAll(".link")
.attr("class", function(d) {
@@ -412,27 +418,33 @@ export default [
function add_node() {
this.on("click", function(d) {
- scope.addNode({
- parent: d,
- betweenTwoNodes: false
- });
+ if(scope.canAddWorkflowJobTemplate !== false) {
+ scope.addNode({
+ parent: d,
+ betweenTwoNodes: false
+ });
+ }
});
}
function add_node_between() {
this.on("click", function(d) {
- scope.addNode({
- parent: d,
- betweenTwoNodes: true
- });
+ if(scope.canAddWorkflowJobTemplate !== false) {
+ scope.addNode({
+ parent: d,
+ betweenTwoNodes: true
+ });
+ }
});
}
function remove_node() {
this.on("click", function(d) {
- scope.deleteNode({
- nodeToDelete: d
- });
+ if(scope.canAddWorkflowJobTemplate !== false) {
+ scope.deleteNode({
+ nodeToDelete: d
+ });
+ }
});
}
diff --git a/awx/ui/client/src/job-templates/workflow-maker/workflow-maker.controller.js b/awx/ui/client/src/job-templates/workflow-maker/workflow-maker.controller.js
index e571a32952..01cc4441c2 100644
--- a/awx/ui/client/src/job-templates/workflow-maker/workflow-maker.controller.js
+++ b/awx/ui/client/src/job-templates/workflow-maker/workflow-maker.controller.js
@@ -7,11 +7,11 @@
export default ['$scope', 'WorkflowHelpService', 'generateList', 'JobTemplateList', 'ProjectList',
'GetBasePath', 'Wait', 'JobTemplateService', '$state',
'ProcessErrors', 'InventorySourcesList', 'CreateSelect2', 'WorkflowMakerForm',
- 'GenerateForm', 'InventoryList', 'CredentialList', '$q', '$timeout',
+ 'GenerateForm', 'InventoryList', 'CredentialList', '$q',
function($scope, WorkflowHelpService, GenerateList, JobTemplateList, ProjectList,
GetBasePath, Wait, JobTemplateService, $state,
ProcessErrors, InventorySourcesList, CreateSelect2, WorkflowMakerForm,
- GenerateForm, InventoryList, CredentialList, $q, $timeout) {
+ GenerateForm, InventoryList, CredentialList, $q) {
let form = WorkflowMakerForm();
@@ -274,13 +274,6 @@ export default ['$scope', 'WorkflowHelpService', 'generateList', 'JobTemplateLis
};
}
- // The default needs to be in place before we can select2-ify the dropdown
- $timeout(function() {
- CreateSelect2({
- element: '#workflow_maker_job_type',
- multiple: false
- });
- });
}
if ($scope.nodeBeingEdited.unifiedJobTemplate.ask_limit_on_launch) {
diff --git a/awx/ui/client/src/job-templates/workflow-maker/workflow-maker.directive.js b/awx/ui/client/src/job-templates/workflow-maker/workflow-maker.directive.js
index e2d81c01ca..95da492a14 100644
--- a/awx/ui/client/src/job-templates/workflow-maker/workflow-maker.directive.js
+++ b/awx/ui/client/src/job-templates/workflow-maker/workflow-maker.directive.js
@@ -10,7 +10,8 @@ export default ['templateUrl', 'CreateDialog', 'Wait',
function(templateUrl, CreateDialog, Wait) {
return {
scope: {
- treeData: '='
+ treeData: '=',
+ canAddWorkflowJobTemplate: '='
},
restrict: 'E',
templateUrl: templateUrl('job-templates/workflow-maker/workflow-maker'),
diff --git a/awx/ui/client/src/job-templates/workflow-maker/workflow-maker.partial.html b/awx/ui/client/src/job-templates/workflow-maker/workflow-maker.partial.html
index e886fe2904..77cdd18d9c 100644
--- a/awx/ui/client/src/job-templates/workflow-maker/workflow-maker.partial.html
+++ b/awx/ui/client/src/job-templates/workflow-maker/workflow-maker.partial.html
@@ -60,7 +60,7 @@
-
+
{{(workflowMakerFormConfig.nodeMode === 'edit' && nodeBeingEdited && nodeBeingEdited.unifiedJobTemplate && nodeBeingEdited.unifiedJobTemplate.name) ? nodeBeingEdited.unifiedJobTemplate.name : "ADD A TEMPLATE"}}
@@ -82,6 +82,6 @@
Close
- Save
+ Save
diff --git a/awx/ui/client/src/lists/JobTemplates.js b/awx/ui/client/src/lists/JobTemplates.js
index a85c49613b..80c1002074 100644
--- a/awx/ui/client/src/lists/JobTemplates.js
+++ b/awx/ui/client/src/lists/JobTemplates.js
@@ -64,14 +64,16 @@ export default
options: [
{
optionContent: 'Job Template',
- optionSref: 'templates.addJobTemplate'
+ optionSref: 'templates.addJobTemplate',
+ ngShow: 'canAddJobTemplate'
},
{
optionContent: 'Workflow Job Template',
- optionSref: 'templates.addWorkflowJobTemplate'
+ optionSref: 'templates.addWorkflowJobTemplate',
+ ngShow: 'canAddWorkflowJobTemplate'
}
],
- ngShow: 'canAdd'
+ ngShow: 'canAddJobTemplate || canAddWorkflowJobTemplate'
}
},
diff --git a/awx/ui/client/src/shared/list-generator/list-actions.partial.html b/awx/ui/client/src/shared/list-generator/list-actions.partial.html
index 764c04d1ef..796b370924 100644
--- a/awx/ui/client/src/shared/list-generator/list-actions.partial.html
+++ b/awx/ui/client/src/shared/list-generator/list-actions.partial.html
@@ -10,7 +10,7 @@
@@ -37,7 +37,7 @@