From 51333c0a8a22f7fcc9f62de2005c397eda7f935d Mon Sep 17 00:00:00 2001 From: chouseknecht Date: Fri, 30 Aug 2013 14:15:54 -0400 Subject: [PATCH] AC-351 Latest changes. --- awx/ui/static/js/app.js | 5 +- awx/ui/static/js/controllers/Projects.js | 6 +- .../{JobTemplate.js => JobSubmission.js} | 188 +++++++++++------- awx/ui/static/js/helpers/SCMUpdate.js | 28 --- awx/ui/static/js/lists/Projects.js | 6 +- awx/ui/static/lib/ansible/form-generator.js | 4 +- awx/ui/templates/ui/index.html | 5 +- 7 files changed, 131 insertions(+), 111 deletions(-) rename awx/ui/static/js/helpers/{JobTemplate.js => JobSubmission.js} (56%) delete mode 100644 awx/ui/static/js/helpers/SCMUpdate.js diff --git a/awx/ui/static/js/app.js b/awx/ui/static/js/app.js index 6b5b7fabf5..75f7912ca9 100644 --- a/awx/ui/static/js/app.js +++ b/awx/ui/static/js/app.js @@ -44,7 +44,7 @@ angular.module('ansible', [ 'LookUpHelper', 'JobTemplatesListDefinition', 'JobTemplateFormDefinition', - 'JobTemplateHelper', + 'JobSubmissionHelper', 'ProjectsListDefinition', 'ProjectFormDefinition', 'PermissionFormDefinition', @@ -65,8 +65,7 @@ angular.module('ansible', [ 'SelectionHelper', 'LicenseFormDefinition', 'License', - 'HostGroupsFormDefinition', - 'SCMUpdateHelper' + 'HostGroupsFormDefinition' ]) .config(['$routeProvider', function($routeProvider) { $routeProvider. diff --git a/awx/ui/static/js/controllers/Projects.js b/awx/ui/static/js/controllers/Projects.js index 466cf55a64..c286b1d76c 100644 --- a/awx/ui/static/js/controllers/Projects.js +++ b/awx/ui/static/js/controllers/Projects.js @@ -64,14 +64,14 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest, }); } - scope.scmUpdate = function(project_id) { + scope.SCMUpdate = function(project_id) { for (var i=0; i < scope.projects.length; i++) { if (scope.projects[i].id == project_id) { if (scope.projects[i].scm_type == "") { Alert('Missing SCM Setup', 'Before running an SCM update, edit the project and provide the SCM access information.', 'alert-info'); } else { - SCMUpdate({ scope: scope, project: scope.projects[i]}); + SCMUpdate({ scope: scope, project_id: project_id }); } break; } @@ -281,7 +281,7 @@ function ProjectsEdit ($scope, $rootScope, $compile, $location, $log, $routePara master['scm_type'] = scope['scm_type']; setAskCheckboxes(); - + // Initialize related search functions. Doing it here to make sure relatedSets object is populated. RelatedSearchInit({ scope: scope, form: form, relatedSets: relatedSets }); RelatedPaginateInit({ scope: scope, relatedSets: relatedSets }); diff --git a/awx/ui/static/js/helpers/JobTemplate.js b/awx/ui/static/js/helpers/JobSubmission.js similarity index 56% rename from awx/ui/static/js/helpers/JobTemplate.js rename to awx/ui/static/js/helpers/JobSubmission.js index 32731a51ee..a41e2ee702 100644 --- a/awx/ui/static/js/helpers/JobTemplate.js +++ b/awx/ui/static/js/helpers/JobSubmission.js @@ -1,20 +1,20 @@ /********************************************* * Copyright (c) 2013 AnsibleWorks, Inc. * - * JobTemplateHelper + * JobSubmission.js * */ -angular.module('JobTemplateHelper', [ 'RestServices', 'Utilities', 'CredentialFormDefinition', 'CredentialsListDefinition', - 'LookUpHelper', 'JobTemplateFormDefinition' ]) +angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'CredentialFormDefinition', 'CredentialsListDefinition', + 'LookUpHelper', 'JobTemplateFormDefinition', 'ProjectFormDefinition' ]) - .factory('PromptPasswords',['CredentialForm', '$compile', 'Rest', '$location', 'ProcessErrors', 'GetBasePath', - function(JobTemplateForm, $compile, Rest, $location, ProcessErrors, GetBasePath) { + .factory('PromptPasswords',['CredentialForm', '$compile', 'Rest', '$location', 'ProcessErrors', 'GetBasePath', 'Alert', + function(JobTemplateForm, $compile, Rest, $location, ProcessErrors, GetBasePath, Alert) { return function(params) { var scope = params.scope; var passwords = params.passwords; var start_url = params.start_url; - var form = JobTemplateForm; + var form = params.form; var html = ''; var field, element, dialogScope, fld; var base = $location.path().replace(/^\//,'').split('/')[0]; @@ -40,7 +40,9 @@ angular.module('JobTemplateHelper', [ 'RestServices', 'Utilities', 'CredentialFo Rest.setUrl(url); Rest.destroy() .success ( function(data, status, headers, config) { - navigate(true); + if (form.name == 'credential') { + navigate(true); + } }) .error( function(data, status, headers, config) { ProcessErrors(scope, data, status, null, @@ -51,7 +53,9 @@ angular.module('JobTemplateHelper', [ 'RestServices', 'Utilities', 'CredentialFo scope.cancelJob = function() { // User clicked cancel button $('#password-modal').modal('hide'); - cancelJob(); + if (form.name == 'credential') { + cancelJob(); + } } scope.startJob = function() { @@ -64,84 +68,95 @@ angular.module('JobTemplateHelper', [ 'RestServices', 'Utilities', 'CredentialFo value_supplied = true; } }); - if (value_supplied) { + if (passwords.length == 0 || value_supplied) { Rest.setUrl(start_url); Rest.post(pswd) .success( function(data, status, headers, config) { - navigate(false); + if (form.name == 'credential') { + navigate(false); + } }) .error( function(data, status, headers, config) { ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to start job. POST returned status: ' + status }); + { hdr: 'Error!', msg: 'POST to ' + start_url + ' failed with status: ' + status }); }); } else { - // No passwords provided, so we can't start the job. Rather than leave the job in a 'new' - // state, let's delete it. - scope.cancelJob(); + Alert('No Passwords', 'Required password(s) not provided. The request was not submitted.', 'alert-info'); + if (form.name == 'credential') { + // No passwords provided, so we can't start the job. Rather than leave the job in a 'new' + // state, let's delete it. + scope.cancelJob(); + } } } - - html += html += "
\n"; - for (var i=0; i < passwords.length; i++) { - // Add the password field - field = form.fields[passwords[i]]; - fld = passwords[i]; - scope[fld] = ''; - html += "
\n"; - html += "' + "\n"; - html += "
\n"; - html += "A value is required!\n"; - html += "\n"; - html += "
\n"; - html += "
\n"; - - // Add the related confirm field - fld = field.associated; - field = form.fields[field.associated]; - scope[fld] = ''; - html += "
\n"; - html += "' + "\n"; - html += "
\n"; - html += "A value is required!\n"; - if (field.awPassMatch) { - html += "Must match Password value\n"; + if (passwords.length > 0) { + // We need to prompt for passwords + html += html += "\n"; + for (var i=0; i < passwords.length; i++) { + // Add the password field + field = form.fields[passwords[i]]; + fld = passwords[i]; + scope[fld] = ''; + html += "
\n"; + html += "' + "\n"; + html += "
\n"; + html += "A value is required!\n"; + html += "\n"; + html += "
\n"; + html += "
\n"; + + // Add the related confirm field + fld = field.associated; + field = form.fields[field.associated]; + scope[fld] = ''; + html += "
\n"; + html += "' + "\n"; + html += "
\n"; + html += "A value is required!\n"; + if (field.awPassMatch) { + html += "Must match Password value\n"; + } + html += "\n"; + html += "
\n"; + html += "
\n"; } - html += "\n"; - html += "
\n"; - html += "
\n"; + html += "
\n"; + element = angular.element(document.getElementById('password-body')); + element.html(html); + $compile(element.contents())(scope); + $('#password-modal').modal({ }); } - html += "\n"; - element = angular.element(document.getElementById('password-body')); - element.html(html); - $compile(element.contents())(scope); - $('#password-modal').modal({ }); + else { + scope.startJob(); } - }]) + } + }]) .factory('SubmitJob',['PromptPasswords', '$compile', 'Rest', '$location', 'GetBasePath', 'CredentialList', - 'LookUpInit', 'JobTemplateForm', 'ProcessErrors', - function(PromptPasswords, $compile, Rest, $location, GetBasePath, CredentialList, LookUpInit, JobTemplateForm, + 'LookUpInit', 'CredentialForm', 'ProcessErrors', + function(PromptPasswords, $compile, Rest, $location, GetBasePath, CredentialList, LookUpInit, CredentialForm, ProcessErrors) { return function(params) { var scope = params.scope; @@ -179,7 +194,8 @@ angular.module('JobTemplateHelper', [ 'RestServices', 'Utilities', 'CredentialFo PromptPasswords({ scope: scope, passwords: data.passwords_needed_to_start, - start_url: data.related.start + start_url: data.related.start, + form: CredentialForm }); } else { @@ -248,6 +264,38 @@ angular.module('JobTemplateHelper', [ 'RestServices', 'Utilities', 'CredentialFo { hdr: 'Error!', msg: 'Failed to get job template details. GET returned status: ' + status }); }); }; + }]) + + // Sumbit SCM Update request + .factory('SCMUpdate',['PromptPasswords', '$compile', 'Rest', '$location', 'GetBasePath', 'ProcessErrors', 'Alert', + 'ProjectsForm', + function(PromptPasswords, $compile, Rest, $location, GetBasePath, ProcessErrors, Alert, ProjectsForm) { + return function(params) { + var scope = params.scope; + var project_id = params.project_id; + var url = GetBasePath('projects') + project_id + '/update/'; + // Check to see if we have permission to perform the update and if any passwords are needed + Rest.setUrl(url); + Rest.get() + .success( function(data, status, headers, config) { + if (data.can_update) { + PromptPasswords({ + scope: scope, + passwords: data.passwords_needed_to_update, + start_url: url, + form: ProjectsForm + }); + } + else { + Alert('Permission Denied', 'You do not have access to update this project. Please contact your system administrator.', + 'alert-danger'); + } + }) + .error( function(data, status, headers, config) { + ProcessErrors(scope, data, status, null, + { hdr: 'Error!', msg: 'Failed to get job template details. GET returned status: ' + status }); + }); + }; }]); diff --git a/awx/ui/static/js/helpers/SCMUpdate.js b/awx/ui/static/js/helpers/SCMUpdate.js deleted file mode 100644 index f76ba707db..0000000000 --- a/awx/ui/static/js/helpers/SCMUpdate.js +++ /dev/null @@ -1,28 +0,0 @@ -/********************************************* - * Copyright (c) 2013 AnsibleWorks, Inc. - * - * SCMUpdate.js - * - * Use to kick off an update the project - * - */ - -angular.module('SCMUpdateHelper', ['RestServices', 'Utilities']) - .factory('SCMUpdate', ['Alert', 'Rest', 'GetBasePath','ProcessErrors', - function(Alert, Rest, GetBasePath, ProcessErrors) { - return function(params) { - - var scope = params.scope; - var project = params.project; - - Rest.setUrl(project.related.update); - Rest.get() - .success( function(data, status, headers, config) { - console.log(data); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to access ' + project.related.update + '. GET status: ' + status }); - }); - } - }]); \ No newline at end of file diff --git a/awx/ui/static/js/lists/Projects.js b/awx/ui/static/js/lists/Projects.js index 4b7f421999..0c50f1466d 100644 --- a/awx/ui/static/js/lists/Projects.js +++ b/awx/ui/static/js/lists/Projects.js @@ -22,7 +22,9 @@ angular.module('ProjectsListDefinition', []) fields: { name: { key: true, - label: 'Name' + label: 'Name', + badgeIcon: "\{\{ 'icon-failures-' + project.last_update_failed \}\}", + badgePlacement: 'left' }, description: { label: 'Description' @@ -54,7 +56,7 @@ angular.module('ProjectsListDefinition', []) label: 'Update', icon: 'icon-cloud-download', "class": 'btn-xs btn-success', - ngClick: 'scmUpdate(\{\{ project.id \}\})', + ngClick: 'SCMUpdate(\{\{ project.id \}\})', awToolTip: 'Perform an SCM update on this project' }, diff --git a/awx/ui/static/lib/ansible/form-generator.js b/awx/ui/static/lib/ansible/form-generator.js index 9e298d3065..78df79a28d 100644 --- a/awx/ui/static/lib/ansible/form-generator.js +++ b/awx/ui/static/lib/ansible/form-generator.js @@ -321,8 +321,8 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies']) html += (field.ngChange) ? Attr(field,'ngChange') : ""; html += (field.id) ? Attr(field,'id') : ""; html += (field['class']) ? Attr(field,'class') : ""; - html += Attr(field,'trueValue'); - html += Attr(field,'falseValue'); + html += (field.trueValue !== undefined) ? Attr(field,'trueValue') : ""; + html += (field.falseValue !== undefined) ? Attr(field,'falseValue') : ""; html += (field.checked) ? "checked " : ""; html += (field.readonly) ? "disabled " : ""; html += " > " + field.label + "\n"; diff --git a/awx/ui/templates/ui/index.html b/awx/ui/templates/ui/index.html index 1d6cfd39bc..4cb104ff2a 100644 --- a/awx/ui/templates/ui/index.html +++ b/awx/ui/templates/ui/index.html @@ -89,7 +89,7 @@ - + @@ -100,8 +100,7 @@ - - + {% endif %}