From 427f42dec374c47647aa52f983a4f5cda5d52e23 Mon Sep 17 00:00:00 2001 From: Jared Tabor Date: Wed, 25 Mar 2015 14:23:04 -0400 Subject: [PATCH] changed default project/playbook scheme + actions changed the design of the 'Reset to default project/playbook' on the job template form. Also added actions on the inventory properties accordion for scan job templates for scheduling and copying --- awx/ui/static/js/controllers/Inventories.js | 148 ++++++++++++++++++- awx/ui/static/js/controllers/JobTemplates.js | 99 ++++++------- awx/ui/static/js/forms/Inventories.js | 22 +++ awx/ui/static/js/forms/JobTemplates.js | 26 ++-- awx/ui/static/js/helpers/JobTemplates.js | 1 - awx/ui/static/js/lists/JobTemplates.js | 1 - awx/ui/static/partials/inventories.html | 9 +- 7 files changed, 235 insertions(+), 71 deletions(-) diff --git a/awx/ui/static/js/controllers/Inventories.js b/awx/ui/static/js/controllers/Inventories.js index 830d8c1f1e..b21fdd3bf7 100644 --- a/awx/ui/static/js/controllers/Inventories.js +++ b/awx/ui/static/js/controllers/Inventories.js @@ -482,7 +482,8 @@ InventoriesAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log export function InventoriesEdit($scope, $rootScope, $compile, $location, $log, $routeParams, InventoryForm, GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, generateList, OrganizationList, SearchInit, PaginateInit, - LookUpInit, GetBasePath, ParseTypeChange, Wait, ToJSON, ParseVariableString, Stream, RelatedSearchInit, RelatedPaginateInit, Prompt, PlaybookRun) { + LookUpInit, GetBasePath, ParseTypeChange, Wait, ToJSON, ParseVariableString, Stream, RelatedSearchInit, RelatedPaginateInit, + Prompt, PlaybookRun, CreateDialog) { ClearScope(); @@ -664,10 +665,152 @@ export function InventoriesEdit($scope, $rootScope, $compile, $location, $log, $ PlaybookRun({ scope: $scope, id: this.scan_job_template.id }); }; + $scope.scheduleScanJob = function(){ + $location.path('/job_templates/'+this.scan_job_template.id+'/schedules'); + }; + $scope.editScanJob = function(){ $location.path($location.path()+'/job_templates/'+this.scan_job_template.id); }; + $scope.copyScanJobTemplate = function(){ + var id = this.scan_job_template.id, + name = this.scan_job_template.name, + element, + buttons = [{ + "label": "Cancel", + "onClick": function() { + $(this).dialog('close'); + }, + "icon": "fa-times", + "class": "btn btn-default", + "id": "copy-close-button" + },{ + "label": "Copy", + "onClick": function() { + copyAction(); + // setTimeout(function(){ + // scope.$apply(function(){ + // if(mode==='survey-taker'){ + // scope.$emit('SurveyTakerCompleted'); + // } else{ + // scope.saveSurvey(); + // } + // }); + // }); + }, + "icon": "fa-copy", + "class": "btn btn-primary", + "id": "job-copy-button" + }], + copyAction = function () { + // retrieve the copy of the job template object from the api, then overwrite the name and throw away the id + Wait('start'); + var url = GetBasePath('job_templates')+id; + Rest.setUrl(url); + Rest.get() + .success(function (data) { + data.name = $scope.new_copy_name; + delete data.id; + $scope.$emit('GoToCopy', data); + }) + .error(function (data) { + Wait('stop'); + ProcessErrors($scope, data, status, null, { hdr: 'Error!', + msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); + }); + }; + + + CreateDialog({ + id: 'copy-job-modal' , + title: "Copy", + scope: $scope, + buttons: buttons, + width: 500, + height: 300, + minWidth: 200, + callback: 'CopyDialogReady' + }); + + $('#job_name').text(name); + $('#copy-job-modal').show(); + + + if ($scope.removeCopyDialogReady) { + $scope.removeCopyDialogReady(); + } + $scope.removeCopyDialogReady = $scope.$on('CopyDialogReady', function() { + //clear any old remaining text + $scope.new_copy_name = "" ; + $scope.copy_form.$setPristine(); + $('#copy-job-modal').dialog('open'); + $('#job-copy-button').attr('ng-disabled', "!copy_form.$valid"); + element = angular.element(document.getElementById('job-copy-button')); + $compile(element)($scope); + + }); + + if ($scope.removeGoToCopy) { + $scope.removeGoToCopy(); + } + $scope.removeGoToCopy = $scope.$on('GoToCopy', function(e, data) { + var url = GetBasePath('job_templates'), + old_survey_url = (data.related.survey_spec) ? data.related.survey_spec : "" ; + Rest.setUrl(url); + Rest.post(data) + .success(function (data) { + if(data.survey_enabled===true){ + $scope.$emit("CopySurvey", data, old_survey_url); + } + else { + $('#copy-job-modal').dialog('close'); + Wait('stop'); + $location.path($location.path() + '/job_templates/' + data.id); + } + + }) + .error(function (data) { + Wait('stop'); + ProcessErrors($scope, data, status, null, { hdr: 'Error!', + msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); + }); + }); + + if ($scope.removeCopySurvey) { + $scope.removeCopySurvey(); + } + $scope.removeCopySurvey = $scope.$on('CopySurvey', function(e, new_data, old_url) { + // var url = data.related.survey_spec; + Rest.setUrl(old_url); + Rest.get() + .success(function (survey_data) { + + Rest.setUrl(new_data.related.survey_spec); + Rest.post(survey_data) + .success(function () { + $('#copy-job-modal').dialog('close'); + Wait('stop'); + $location.path($location.path() + '/' + new_data.id); + }) + .error(function (data) { + Wait('stop'); + ProcessErrors($scope, data, status, null, { hdr: 'Error!', + msg: 'Call to ' + new_data.related.survey_spec + ' failed. DELETE returned status: ' + status }); + }); + + + }) + .error(function (data) { + Wait('stop'); + ProcessErrors($scope, data, status, null, { hdr: 'Error!', + msg: 'Call to ' + old_url + ' failed. DELETE returned status: ' + status }); + }); + + }); + + }; + $scope.deleteScanJob = function () { var id = this.scan_job_template.id , action = function () { @@ -698,7 +841,8 @@ export function InventoriesEdit($scope, $rootScope, $compile, $location, $log, $ InventoriesEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'InventoryForm', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'generateList', 'OrganizationList', 'SearchInit', - 'PaginateInit', 'LookUpInit', 'GetBasePath', 'ParseTypeChange', 'Wait', 'ToJSON', 'ParseVariableString', 'Stream', 'RelatedSearchInit', 'RelatedPaginateInit', 'Prompt', 'PlaybookRun' + 'PaginateInit', 'LookUpInit', 'GetBasePath', 'ParseTypeChange', 'Wait', 'ToJSON', 'ParseVariableString', 'Stream', 'RelatedSearchInit', 'RelatedPaginateInit', + 'Prompt', 'PlaybookRun', 'CreateDialog' ]; diff --git a/awx/ui/static/js/controllers/JobTemplates.js b/awx/ui/static/js/controllers/JobTemplates.js index 8de864f0ca..5610037087 100644 --- a/awx/ui/static/js/controllers/JobTemplates.js +++ b/awx/ui/static/js/controllers/JobTemplates.js @@ -342,37 +342,6 @@ export function JobTemplatesAdd($scope, $rootScope, $compile, $location, $log, $ parent_scope: $scope }); - - $scope.jobTypeChange = function(){ - if($scope.job_type){ - if($scope.job_type.value === 'scan'){ - $scope.default_scan = true; - $scope.project_name = 'Default'; - $scope.project = null; - $scope.toggleScanInfo(); - } - else{ - $scope.default_scan = false; - $scope.project_name = null; - $scope.project = null; - $scope.playbook_options = []; - $scope.playbook = 'null'; - } - } - }; - - $scope.toggleScanInfo = function() { - if($scope.default_scan){ - $scope.project_name = 'Default'; - $scope.project = null; - } - if(!$scope.default_scan){ - $scope.project_name = null; - $scope.playbook_options = []; - $scope.playbook = 'null'; - } - }; - if ($routeParams.inventory_id) { // This means that the job template form was accessed via inventory prop's // This also means the job is a scan job. @@ -393,10 +362,10 @@ export function JobTemplatesAdd($scope, $rootScope, $compile, $location, $log, $ // Update playbook select whenever project value changes selectPlaybook = function (oldValue, newValue) { var url; - if($scope.job_type.value === 'scan' && $scope.default_scan === true){ - $scope.playbook_options = ['Default']; - $scope.playbook = 'Default'; - Wait('stop'); + if($scope.job_type.value === 'scan' && $scope.project_name === "Default"){ + $scope.playbook_options = ['Default']; + $scope.playbook = 'Default'; + Wait('stop'); } else if (oldValue !== newValue) { if ($scope.project) { @@ -420,6 +389,32 @@ export function JobTemplatesAdd($scope, $rootScope, $compile, $location, $log, $ } }; + $scope.jobTypeChange = function(){ + if($scope.job_type){ + if($scope.job_type.value === 'scan'){ + // $scope.project_name = 'Default'; + // $scope.project = null; + $scope.toggleScanInfo(); + } + else if($scope.project_name === "Default"){ + $scope.project_name = null; + $scope.playbook_options = []; + // $scope.playbook = 'null'; + $scope.job_templates_form.playbook.$setPristine(); + } + } + }; + + $scope.toggleScanInfo = function() { + $scope.project_name = 'Default'; + if($scope.project === null){ + selectPlaybook(); + } + else { + $scope.project = null; + } + }; + // Detect and alert user to potential SCM status issues checkSCMStatus = function (oldValue, newValue) { if (oldValue !== newValue && !Empty($scope.project)) { @@ -686,10 +681,10 @@ export function JobTemplatesEdit($scope, $rootScope, $compile, $location, $log, getPlaybooks = function (project) { var url; - if($scope.job_type.value === 'scan' && $scope.default_scan === true){ - $scope.playbook_options = ['Default']; - $scope.playbook = 'Default'; - Wait('stop'); + if($scope.job_type.value === 'scan' && $scope.project_name === "Default"){ + $scope.playbook_options = ['Default']; + $scope.playbook = 'Default'; + Wait('stop'); } else if (!Empty(project)) { url = GetBasePath('projects') + project + '/playbooks/'; @@ -725,31 +720,27 @@ export function JobTemplatesEdit($scope, $rootScope, $compile, $location, $log, $scope.jobTypeChange = function(){ if($scope.job_type){ if($scope.job_type.value === 'scan'){ - $scope.default_scan = true; - $scope.project_name = 'Default'; - $scope.project = null; + // $scope.project_name = 'Default'; + // $scope.project = null; $scope.toggleScanInfo(); } - else{ - $scope.default_scan = false; + else if($scope.project_name === "Default"){ $scope.project_name = null; $scope.playbook_options = []; - $scope.playbook = 'null'; + // $scope.playbook = 'null'; + $scope.job_templates_form.playbook.$setPristine(); } } }; $scope.toggleScanInfo = function() { - if($scope.default_scan){ - $scope.project_name = 'Default'; - $scope.project = null; + $scope.project_name = 'Default'; + if($scope.project === null){ getPlaybooks(); - } - if(!$scope.default_scan){ - $scope.project_name = null; - $scope.playbook_options = []; - $scope.playbook = 'null'; - } + } + else { + $scope.project = null; + } }; // Detect and alert user to potential SCM status issues diff --git a/awx/ui/static/js/forms/Inventories.js b/awx/ui/static/js/forms/Inventories.js index 1b20e523f4..b745ce7b00 100644 --- a/awx/ui/static/js/forms/Inventories.js +++ b/awx/ui/static/js/forms/Inventories.js @@ -114,6 +114,14 @@ export default }, fields: { + // smart_status: { + // label: 'Status', + // // columnClass: 'col-md-2 col-sm-2 col-xs-2', + // searchable: false, + // nosort: true, + // ngInclude: "'/static/partials/job-template-smart-status.html'", + // type: 'template' + // }, name: { key: true, label: 'Name', @@ -131,6 +139,12 @@ export default awToolTip: 'Launch the scan job template', 'class': 'btn btn-default' }, + schedule: { + label: 'Schedule', + ngClick: 'scheduleScanJob()', + awToolTip: 'Schedule future job template runs', + dataPlacement: 'top', + }, edit: { label: 'Edit', ngClick: "editScanJob()", @@ -144,6 +158,14 @@ export default icon: 'icon-trash', "class": 'btn-danger', awToolTip: 'Delete the scan job template' + }, + copy: { + label: 'Copy', + ngClick: "copyScanJobTemplate()", + "class": 'btn-danger btn-xs', + awToolTip: 'Copy template', + dataPlacement: 'top', + ngHide: 'job_template.summary_fields.can_copy === false' } } } diff --git a/awx/ui/static/js/forms/JobTemplates.js b/awx/ui/static/js/forms/JobTemplates.js index 96e6db7d4f..c8fc483f53 100644 --- a/awx/ui/static/js/forms/JobTemplates.js +++ b/awx/ui/static/js/forms/JobTemplates.js @@ -103,8 +103,6 @@ export default dataTitle: 'Project', dataPlacement: 'right', dataContainer: "body", - ngDisabled: 'default_scan === true', - ngRequired: 'default_scan === false' }, playbook: { label: 'Playbook', @@ -117,19 +115,23 @@ export default dataTitle: 'Playbook', dataPlacement: 'right', dataContainer: "body", - ngDisabled: 'default_scan === true', - ngRequired: 'default_scan === false' }, + // default_scan: { + // label: "Use default scan job project and playbook", + // type: 'checkbox', + // ngChange: 'toggleScanInfo()', + // ngShow: 'job_type.value === "scan" && project_name !== "Default"', + // column: 1, + // awPopOver: "

Scan jobs templates use a default project and default playbook. Uncheck this box to override these defaults.

", + // dataTitle: 'Scan jobs', + // dataPlacement: 'right', + // dataContainer: "body" + // }, default_scan: { - label: "Use default scan job project and playbook", - type: 'checkbox', - ngChange: 'toggleScanInfo()', - ngShow: 'job_type.value === "scan"', + type: 'custom', column: 1, - awPopOver: "

Scan jobs templates use a default project and default playbook. Uncheck this box to override these defaults.

", - dataTitle: 'Scan jobs', - dataPlacement: 'right', - dataContainer: "body" + ngShow: 'job_type.value === "scan" && project_name !== "Default"', + control: 'Reset to default project and playbook' }, credential: { label: 'Machine Credential', diff --git a/awx/ui/static/js/helpers/JobTemplates.js b/awx/ui/static/js/helpers/JobTemplates.js index 7ab79fc385..bc69745570 100644 --- a/awx/ui/static/js/helpers/JobTemplates.js +++ b/awx/ui/static/js/helpers/JobTemplates.js @@ -173,7 +173,6 @@ angular.module('JobTemplatesHelper', ['Utilities']) if(scope.project === "" && scope.playbook === ""){ - scope.default_scan = true; scope.toggleScanInfo(); } diff --git a/awx/ui/static/js/lists/JobTemplates.js b/awx/ui/static/js/lists/JobTemplates.js index 6b1afb5df2..536768a692 100644 --- a/awx/ui/static/js/lists/JobTemplates.js +++ b/awx/ui/static/js/lists/JobTemplates.js @@ -95,7 +95,6 @@ export default awToolTip: 'Copy template', dataPlacement: 'top', ngHide: 'job_template.summary_fields.can_copy===false' - } } }); diff --git a/awx/ui/static/partials/inventories.html b/awx/ui/static/partials/inventories.html index 5fb9122c65..b4869d6bdf 100644 --- a/awx/ui/static/partials/inventories.html +++ b/awx/ui/static/partials/inventories.html @@ -1,6 +1,13 @@
-
+
+