diff --git a/awx/ui/client/src/templates/job_templates/add-job-template/job-template-add.controller.js b/awx/ui/client/src/templates/job_templates/add-job-template/job-template-add.controller.js index f2ab5e3792..2d8ad53545 100644 --- a/awx/ui/client/src/templates/job_templates/add-job-template/job-template-add.controller.js +++ b/awx/ui/client/src/templates/job_templates/add-job-template/job-template-add.controller.js @@ -89,6 +89,17 @@ element:'#job_template_verbosity', multiple: false }); + CreateSelect2({ + element:'#job_template_job_tags', + multiple: true, + addNew: true + }); + + CreateSelect2({ + element:'#job_template_skip_tags', + multiple: true, + addNew: true + }); } }); @@ -260,6 +271,8 @@ data.ask_inventory_on_launch = $scope.ask_inventory_on_launch ? $scope.ask_inventory_on_launch : false; data.ask_variables_on_launch = $scope.ask_variables_on_launch ? $scope.ask_variables_on_launch : false; data.ask_credential_on_launch = $scope.ask_credential_on_launch ? $scope.ask_credential_on_launch : false; + data.job_tags = (Array.isArray($scope.job_tags)) ? $scope.job_tags.join() : ""; + data.skip_tags = (Array.isArray($scope.skip_tags)) ? $scope.skip_tags.join() : ""; if ($scope.selectedCredentials && $scope.selectedCredentials .machine && $scope.selectedCredentials .machine) { @@ -296,6 +309,19 @@ .filter("[data-label-is-present=true]") .map((i, val) => ({name: $(val).text()})); + $scope.job_tags = _.map($scope.job_tags, function(i){return i.value;}); + $("#job_template_job_tags").siblings(".select2").first().find(".select2-selection__choice").each(function(optionIndex, option){ + $scope.job_tags.push(option.title); + }); + + $scope.skip_tags = _.map($scope.skip_tags, function(i){return i.value;}); + $("#job_template_skip_tags").siblings(".select2").first().find(".select2-selection__choice").each(function(optionIndex, option){ + $scope.skip_tags.push(option.title); + }); + + data.job_tags = (Array.isArray($scope.job_tags)) ? _.uniq($scope.job_tags).join() : ""; + data.skip_tags = (Array.isArray($scope.skip_tags)) ? _.uniq($scope.skip_tags).join() : ""; + Rest.setUrl(defaultUrl); Rest.post(data) .then(({data}) => { diff --git a/awx/ui/client/src/templates/job_templates/edit-job-template/job-template-edit.controller.js b/awx/ui/client/src/templates/job_templates/edit-job-template/job-template-edit.controller.js index 8a3b5b9a75..a357ae9c19 100644 --- a/awx/ui/client/src/templates/job_templates/edit-job-template/job-template-edit.controller.js +++ b/awx/ui/client/src/templates/job_templates/edit-job-template/job-template-edit.controller.js @@ -55,6 +55,8 @@ export default $scope.instance_groups = InstanceGroupsData; $scope.credentialNotPresent = false; $scope.surveyTooltip = i18n._('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.'); + $scope.job_tag_options = []; + $scope.skip_tag_options = []; SurveyControllerInit({ scope: $scope, @@ -175,6 +177,18 @@ export default element:'#playbook-select', multiple: false }); + + CreateSelect2({ + element:'#job_template_job_tags', + multiple: true, + addNew: true + }); + + CreateSelect2({ + element:'#job_template_skip_tags', + multiple: true, + addNew: true + }); } $scope.jobTypeChange = function() { @@ -469,6 +483,8 @@ export default data.ask_inventory_on_launch = $scope.ask_inventory_on_launch ? $scope.ask_inventory_on_launch : false; data.ask_variables_on_launch = $scope.ask_variables_on_launch ? $scope.ask_variables_on_launch : false; data.ask_credential_on_launch = $scope.ask_credential_on_launch ? $scope.ask_credential_on_launch : false; + data.job_tags = (Array.isArray($scope.job_tags)) ? $scope.job_tags.join() : ""; + data.skip_tags = (Array.isArray($scope.skip_tags)) ? $scope.skip_tags.join() : ""; if ($scope.selectedCredentials && $scope.selectedCredentials .machine && $scope.selectedCredentials .machine) { @@ -505,6 +521,20 @@ export default .filter("[data-label-is-present=true]") .map((i, val) => ({name: $(val).text()})); + $scope.job_tags = _.map($scope.job_tags, function(i){return i.value;}); + $("#job_template_job_tags").siblings(".select2").first().find(".select2-selection__choice").each(function(optionIndex, option){ + $scope.job_tags.push(option.title); + }); + + $scope.skip_tags = _.map($scope.skip_tags, function(i){return i.value;}); + $("#job_template_skip_tags").siblings(".select2").first().find(".select2-selection__choice").each(function(optionIndex, option){ + $scope.skip_tags.push(option.title); + }); + + data.job_tags = (Array.isArray($scope.job_tags)) ? _.uniq($scope.job_tags).join() : ""; + data.skip_tags = (Array.isArray($scope.skip_tags)) ? _.uniq($scope.skip_tags).join() : ""; + + Rest.setUrl(defaultUrl + $state.params.job_template_id); Rest.put(data) .success(function (data) { diff --git a/awx/ui/client/src/templates/job_templates/factories/callback-help-init.factory.js b/awx/ui/client/src/templates/job_templates/factories/callback-help-init.factory.js index 5ad9c9d010..e72220a4f0 100644 --- a/awx/ui/client/src/templates/job_templates/factories/callback-help-init.factory.js +++ b/awx/ui/client/src/templates/job_templates/factories/callback-help-init.factory.js @@ -113,6 +113,16 @@ export default scope.ask_skip_tags_on_launch = (data.ask_skip_tags_on_launch) ? true : false; master.ask_skip_tags_on_launch = scope.ask_skip_tags_on_launch; + scope.job_tag_options = (data.job_tags) ? data.job_tags.split(',') + .map((i) => ({name: i, label: i, value: i})) : []; + scope.job_tags = scope.job_tag_options; + master.job_tags = scope.job_tags; + + scope.skip_tag_options = (data.skip_tags) ? data.skip_tags.split(',') + .map((i) => ({name: i, label: i, value: i})) : []; + scope.skip_tags = scope.skip_tag_options; + master.skip_tags = scope.skip_tags; + scope.ask_job_type_on_launch = (data.ask_job_type_on_launch) ? true : false; master.ask_job_type_on_launch = scope.ask_job_type_on_launch; diff --git a/awx/ui/client/src/templates/job_templates/job-template.form.js b/awx/ui/client/src/templates/job_templates/job-template.form.js index e2b076d60b..5c67e9f217 100644 --- a/awx/ui/client/src/templates/job_templates/job-template.form.js +++ b/awx/ui/client/src/templates/job_templates/job-template.form.js @@ -212,9 +212,10 @@ function(NotificationsList, CompletedJobsList, i18n) { }, job_tags: { label: i18n._('Job Tags'), - type: 'textarea', - rows: 5, + type: 'select', + multiSelect: true, 'elementClass': 'Form-textInput', + ngOptions: 'tag.label for tag in job_tag_options track by tag.value', column: 2, awPopOver: "
" + i18n._("Provide a comma separated list of tags.") + "
\n" + "" + i18n._("Tags are useful when you have a large playbook, and you want to run a specific part of a play or task.") + "
" + @@ -230,9 +231,10 @@ function(NotificationsList, CompletedJobsList, i18n) { }, skip_tags: { label: i18n._('Skip Tags'), - type: 'textarea', - rows: 5, + type: 'select', + multiSelect: true, 'elementClass': 'Form-textInput', + ngOptions: 'tag.label for tag in skip_tag_options track by tag.value', column: 2, awPopOver: "" + i18n._("Provide a comma separated list of tags.") + "
\n" + "" + i18n._("Skip tags are useful when you have a large playbook, and you want to skip specific parts of a play or task.") + "
" +