AC-423, AC-424, AC-425, AC-426 resolved issues.

This commit is contained in:
chouseknecht
2013-09-10 02:39:58 -04:00
parent eff8a6426a
commit de9c8a258c
12 changed files with 163 additions and 42 deletions

View File

@@ -145,11 +145,47 @@ function JobTemplatesAdd ($scope, $rootScope, $compile, $location, $log, $routeP
} }
}; };
// Detect and alert user to potential SCM status issues
var checkSCMStatus = function(oldValue, newValue) {
if (oldValue !== newValue) {
Rest.setUrl(GetBasePath('projects') + scope.project + '/');
Rest.get()
.success( function(data, status, headers, config) {
var msg;
switch(data.status) {
case 'failed':
msg = "The selected project has a <em>failed</em> status. Review the project's SCM settings" +
" and run an update before adding it to a template.";
break;
case 'never updated':
msg = 'The selected project has a <em>never updated</em> status. You will need to run a successful' +
' update in order to selected a playbook. Without a valid playbook you will not be able ' +
' to save this template.';
break;
case 'missing':
msg = 'The selected project has a status of <em>missing</em>. Please check the server and make sure ' +
' the directory exists and file permissions are set correctly.';
break;
}
if (msg) {
Alert('Waning', msg, 'alert-info');
}
})
.error( function(data, status, headers, config) {
ProcessErrors(scope, data, status, form,
{ hdr: 'Error!', msg: 'Failed to get project ' + scope.project +'. GET returned status: ' + status });
});
}
}
// Register a watcher on project_name // Register a watcher on project_name
if (scope.selectPlaybookUnregister) { if (scope.selectPlaybookUnregister) {
scope.selectPlaybookUnregister(); scope.selectPlaybookUnregister();
} }
scope.selectPlaybookUnregister = scope.$watch('project_name', selectPlaybook); scope.selectPlaybookUnregister = scope.$watch('project_name', function(oldval, newval) {
selectPlaybook(oldval, newval);
checkSCMStatus(oldval, newval);
});
LookUpInit({ LookUpInit({
scope: scope, scope: scope,
@@ -273,6 +309,39 @@ function JobTemplatesEdit ($scope, $rootScope, $compile, $location, $log, $route
} }
} }
// Detect and alert user to potential SCM status issues
var checkSCMStatus = function() {
Rest.setUrl(GetBasePath('projects') + scope.project + '/');
Rest.get()
.success( function(data, status, headers, config) {
var msg;
switch(data.status) {
case 'failed':
msg = "The selected project has a <em>failed</em> status. Review the project's SCM settings" +
" and run an update before adding it to a template.";
break;
case 'never updated':
msg = 'The selected project has a <em>never updated</em> status. You will need to run a successful' +
' update in order to selected a playbook. Without a valid playbook you will not be able ' +
' to save this template.';
break;
case 'missing':
msg = 'The selected project has a status of <em>missing</em>. Please check the server and make sure ' +
' the directory exists and file permissions are set correctly.';
break;
}
if (msg) {
Alert('Waning', msg, 'alert-info');
}
})
.error( function(data, status, headers, config) {
ProcessErrors(scope, data, status, form,
{ hdr: 'Error!', msg: 'Failed to get project ' + scope.project +'. GET returned status: ' + status });
});
}
// Register a watcher on project_name. Refresh the playbook list on change. // Register a watcher on project_name. Refresh the playbook list on change.
if (scope.selectPlaybookUnregister) { if (scope.selectPlaybookUnregister) {
scope.selectPlaybookUnregister(); scope.selectPlaybookUnregister();
@@ -281,6 +350,7 @@ function JobTemplatesEdit ($scope, $rootScope, $compile, $location, $log, $route
if (oldValue !== newValue && newValue !== '' && newValue !== null && newValue !== undefined) { if (oldValue !== newValue && newValue !== '' && newValue !== null && newValue !== undefined) {
scope.playbook = null; scope.playbook = null;
getPlaybooks(scope.project); getPlaybooks(scope.project);
checkSCMStatus();
} }
}); });

View File

@@ -34,11 +34,17 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest,
} }
scope.projectsPostRefresh = scope.$on('PostRefresh', function() { scope.projectsPostRefresh = scope.$on('PostRefresh', function() {
for (var i=0; i < scope.projects.length; i++) { for (var i=0; i < scope.projects.length; i++) {
if (scope.projects[i].scm_type == null) { switch(scope.projects[i].status) {
// override the last_update_failed on manual projects- it should be false so we get a case 'updating':
// green badge. if projet scm_type changed from something to manual, last_update_failed case 'successful':
// will contain status of last update, which is not what we want. case 'ok':
scope.projects[i].last_update_failed = false; scope.projects[i].badge = 'false';
break;
case 'never updated':
case 'failed':
case 'missing':
scope.projects[i].badge = 'true';
break;
} }
scope.projects[i].last_updated = (scope.projects[i].last_updated !== null) ? scope.projects[i].last_updated = (scope.projects[i].last_updated !== null) ?
FormatDate(new Date(scope.projects[i].last_updated)) : null; FormatDate(new Date(scope.projects[i].last_updated)) : null;
@@ -89,7 +95,7 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest,
statusCheckRemove(); statusCheckRemove();
}); });
// Refresh the project list so we're looking at the latest data // Refresh the project list so we're looking at the latest data
scope.search(list.iterator); scope.search(list.iterator);
} }
@@ -124,7 +130,7 @@ 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++) { for (var i=0; i < scope.projects.length; i++) {
if (scope.projects[i].id == project_id) { if (scope.projects[i].id == project_id) {
if (scope.projects[i].scm_type == "") { if (scope.projects[i].scm_type == "" || scope.projects[i].scm_type == null ) {
Alert('Missing SCM Setup', 'Before running an SCM update, edit the project and provide the SCM access information.', 'alert-info'); Alert('Missing SCM Setup', 'Before running an SCM update, edit the project and provide the SCM access information.', 'alert-info');
} }
else if (scope.projects[i].status == 'updating') { else if (scope.projects[i].status == 'updating') {
@@ -140,7 +146,7 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest,
ProjectsList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'ProjectList', 'GenerateList', ProjectsList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'ProjectList', 'GenerateList',
'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors',
'GetBasePath', 'SelectionInit', 'ProjectUpdate', 'ProjectStatus', 'FormatDate']; 'GetBasePath', 'SelectionInit', 'ProjectUpdate', 'ProjectStatus', 'FormatDate' ];
function ProjectsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, ProjectsForm, function ProjectsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, ProjectsForm,
@@ -162,7 +168,6 @@ function ProjectsAdd ($scope, $rootScope, $compile, $location, $log, $routeParam
generator.reset(); generator.reset();
LoadBreadCrumbs(); LoadBreadCrumbs();
GetProjectPath({ scope: scope, master: master }); GetProjectPath({ scope: scope, master: master });
//console.log(scope.)
scope.scm_type = null; scope.scm_type = null;
master.scm_type = null; master.scm_type = null;

View File

@@ -51,8 +51,6 @@ angular.module('JobTemplateFormDefinition', [])
type: 'lookup', type: 'lookup',
sourceModel: 'inventory', sourceModel: 'inventory',
sourceField: 'name', sourceField: 'name',
addRequired: true,
editRequired: true,
ngClick: 'lookUpInventory()', ngClick: 'lookUpInventory()',
awRequiredWhen: {variable: "inventoryrequired", init: "true" }, awRequiredWhen: {variable: "inventoryrequired", init: "true" },
column: 1 column: 1
@@ -62,8 +60,6 @@ angular.module('JobTemplateFormDefinition', [])
type: 'lookup', type: 'lookup',
sourceModel: 'project', sourceModel: 'project',
sourceField: 'name', sourceField: 'name',
addRequired: true,
editRequired: true,
ngClick: 'lookUpProject()', ngClick: 'lookUpProject()',
awRequiredWhen: {variable: "projectrequired", init: "true" }, awRequiredWhen: {variable: "projectrequired", init: "true" },
column: 1 column: 1
@@ -73,8 +69,6 @@ angular.module('JobTemplateFormDefinition', [])
type:'select', type:'select',
ngOptions: 'book for book in playbook_options', ngOptions: 'book for book in playbook_options',
id: 'playbook-select', id: 'playbook-select',
addRequired: true,
editRequired: true,
awRequiredWhen: {variable: "playbookrequired", init: "true" }, awRequiredWhen: {variable: "playbookrequired", init: "true" },
column: 1 column: 1
}, },

View File

@@ -19,6 +19,7 @@ angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'Credential
var html = ''; var html = '';
var field, element, dialogScope, fld; var field, element, dialogScope, fld;
var base = $location.path().replace(/^\//,'').split('/')[0]; var base = $location.path().replace(/^\//,'').split('/')[0];
var extra_html = params.extra_html;
function navigate(canceled) { function navigate(canceled) {
//Decide where to send the user once the modal dialog closes //Decide where to send the user once the modal dialog closes
@@ -31,7 +32,6 @@ angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'Credential
} }
} }
else { else {
console.log('navigating to: ' + base);
$location.path('/' + base); $location.path('/' + base);
} }
} }
@@ -58,6 +58,9 @@ angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'Credential
if (form.name == 'credential') { if (form.name == 'credential') {
cancel(); cancel();
} }
else {
scope.$emit('UpdateSubmitted');
}
} }
scope.startJob = function() { scope.startJob = function() {
@@ -96,14 +99,15 @@ angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'Credential
if (passwords.length > 0) { if (passwords.length > 0) {
// We need to prompt for passwords // We need to prompt for passwords
html += html += "<form class=\"form-horizontal\" name=\"password_form\" novalidate>\n"; html += "<form class=\"form-horizontal\" name=\"password_form\" novalidate>\n";
html += (extra_html) ? extra_html : "";
for (var i=0; i < passwords.length; i++) { for (var i=0; i < passwords.length; i++) {
// Add the password field // Add the password field
field = (form.fields[passwords[i]]) ? form.fields[passwords[i]] : ProjectsForm.fields[passwords[i]]; field = (form.fields[passwords[i]]) ? form.fields[passwords[i]] : ProjectsForm.fields[passwords[i]];
fld = passwords[i]; fld = passwords[i];
scope[fld] = ''; scope[fld] = '';
html += "<div class=\"form-group\">\n"; html += "<div class=\"form-group\">\n";
html += "<label class=\"control-label col-lg-3\" for=\"" + fld + '">' + field.label + '</label>' + "\n"; html += "<label class=\"control-label col-lg-3 normal-weight\" for=\"" + fld + '">* ' + field.label + '</label>' + "\n";
html += "<div class=\"col-lg-9\">\n"; html += "<div class=\"col-lg-9\">\n";
html += "<input type=\"password\" "; html += "<input type=\"password\" ";
html += "ng-model=\"" + fld + '" '; html += "ng-model=\"" + fld + '" ';
@@ -124,7 +128,7 @@ angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'Credential
field = (form.fields[field.associated]) ? form.fields[field.associated] : ProjectsForm.fields[field.associated]; field = (form.fields[field.associated]) ? form.fields[field.associated] : ProjectsForm.fields[field.associated];
scope[fld] = ''; scope[fld] = '';
html += "<div class=\"form-group\">\n"; html += "<div class=\"form-group\">\n";
html += "<label class=\"control-label col-lg-3\" for=\"" + fld + '">' + field.label + '</label>' + "\n"; html += "<label class=\"control-label col-lg-3 normal-weight\" for=\"" + fld + '">* ' + field.label + '</label>' + "\n";
html += "<div class=\"col-lg-9\">\n"; html += "<div class=\"col-lg-9\">\n";
html += "<input type=\"password\" "; html += "<input type=\"password\" ";
html += "ng-model=\"" + fld + '" '; html += "ng-model=\"" + fld + '" ';
@@ -150,6 +154,9 @@ angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'Credential
element.html(html); element.html(html);
$compile(element.contents())(scope); $compile(element.contents())(scope);
$('#password-modal').modal(); $('#password-modal').modal();
$('#password-modal').on('shown.bs.modal', function() {
$('#password-body').find('input[type="password"]:first').focus();
});
} }
else { else {
scope.startJob(); scope.startJob();
@@ -282,19 +289,21 @@ angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'Credential
scope.removeUpdateSubmitted(); scope.removeUpdateSubmitted();
} }
scope.removeUpdateSubmitted = scope.$on('UpdateSubmitted', function() { scope.removeUpdateSubmitted = scope.$on('UpdateSubmitted', function() {
$location.path('/projects'); // Refresh the project list after update request submitted
scope.refresh();
}); });
if (scope.removeSCMSubmit) { if (scope.removeSCMSubmit) {
scope.removeSCMSubmit(); scope.removeSCMSubmit();
} }
scope.removeSCMSubmit = scope.$on('SCMSubmit', function(e, passwords_needed_to_update) { scope.removeSCMSubmit = scope.$on('SCMSubmit', function(e, passwords_needed_to_update, extra_html) {
// After the call to update, kick off the job. // After the call to update, kick off the job.
PromptPasswords({ PromptPasswords({
scope: scope, scope: scope,
passwords: passwords_needed_to_update, passwords: passwords_needed_to_update,
start_url: url, start_url: url,
form: ProjectsForm form: ProjectsForm,
extra_html: extra_html
}); });
}); });
@@ -303,7 +312,36 @@ angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'Credential
Rest.get() Rest.get()
.success( function(data, status, headers, config) { .success( function(data, status, headers, config) {
if (data.can_update) { if (data.can_update) {
scope.$emit('SCMSubmit', data.passwords_needed_to_update); var extra_html = '';
for (var i=0; i < scope.projects.length; i++) {
if (scope.projects[i].id == project_id) {
extra_html += "<div class=\"form-group\">\n";
extra_html += "<label class=\"control-label col-lg-3 normal-weight\" for=\"scm_url\">SCM URL</label>\n";
extra_html += "<div class=\"col-lg-9\">\n";
extra_html += "<input type=\"text\" readonly";
extra_html += ' name=\"scm_url\" ';
extra_html += "class=\"form-control\" ";
extra_html += "value=\"" + scope.projects[i].scm_url + "\" ";
extra_html += "/>";
extra_html += "</div>\n";
extra_html += "</div>\n";
if (scope.projects[i].scm_username) {
extra_html += "<div class=\"form-group\">\n";
extra_html += "<label class=\"control-label col-lg-3 normal-weight\" for=\"scm_username\">SCM Username</label>\n";
extra_html += "<div class=\"col-lg-9\">\n";
extra_html += "<input type=\"text\" readonly";
extra_html += ' name=\"scm_username\" ';
extra_html += "class=\"form-control\" ";
extra_html += "value=\"" + scope.projects[i].scm_username + "\" ";
extra_html += "/>";
extra_html += "</div>\n";
extra_html += "</div>\n";
}
break;
}
}
extra_html += "</p>";
scope.$emit('SCMSubmit', data.passwords_needed_to_update, extra_html);
} }
else { else {
Alert('Permission Denied', 'You do not have access to update this project. Please contact your system administrator.', Alert('Permission Denied', 'You do not have access to update this project. Please contact your system administrator.',

View File

@@ -15,8 +15,8 @@
*/ */
angular.module('LookUpHelper', [ 'RestServices', 'Utilities', 'SearchHelper', 'PaginateHelper', 'ListGenerator', 'ApiLoader' ]) angular.module('LookUpHelper', [ 'RestServices', 'Utilities', 'SearchHelper', 'PaginateHelper', 'ListGenerator', 'ApiLoader' ])
.factory('LookUpInit', ['Alert', 'Rest', 'GenerateList', 'SearchInit', 'PaginateInit', 'GetBasePath', .factory('LookUpInit', ['Alert', 'Rest', 'GenerateList', 'SearchInit', 'PaginateInit', 'GetBasePath', 'FormatDate',
function(Alert, Rest, GenerateList, SearchInit, PaginateInit, GetBasePath) { function(Alert, Rest, GenerateList, SearchInit, PaginateInit, GetBasePath, FormatDate) {
return function(params) { return function(params) {
var scope = params.scope; // form scope var scope = params.scope; // form scope
@@ -26,7 +26,6 @@ angular.module('LookUpHelper', [ 'RestServices', 'Utilities', 'SearchHelper', 'P
var field = params.field; // form field var field = params.field; // form field
var postAction = params.postAction //action to perform post user selection var postAction = params.postAction //action to perform post user selection
// Show pop-up // Show pop-up
var name = list.iterator.charAt(0).toUpperCase() + list.iterator.substring(1); var name = list.iterator.charAt(0).toUpperCase() + list.iterator.substring(1);
var defaultUrl = (list.name == 'inventories') ? GetBasePath('inventory') : GetBasePath(list.name); var defaultUrl = (list.name == 'inventories') ? GetBasePath('inventory') : GetBasePath(list.name);
@@ -92,6 +91,14 @@ angular.module('LookUpHelper', [ 'RestServices', 'Utilities', 'SearchHelper', 'P
listScope.lookupPostRefreshRemove(); listScope.lookupPostRefreshRemove();
} }
listScope.lookupPostRefreshRemove = scope.$on('PostRefresh', function() { listScope.lookupPostRefreshRemove = scope.$on('PostRefresh', function() {
for (var fld in list.fields) {
if (list.fields[fld].type && list.fields[fld].type == 'date') {
//convert dates to our standard format
for (var i=0; i < scope[list.name].length; i++) {
scope[list.name][i][fld] = FormatDate(new Date(scope[list.name][i][fld]));
}
}
}
listScope['toggle_' + list.iterator](scope[field]); listScope['toggle_' + list.iterator](scope[field]);
}); });

View File

@@ -9,9 +9,10 @@
* *
*/ */
angular.module('ProjectsHelper', ['RestServices', 'Utilities', 'ProjectStatusDefinition']) angular.module('ProjectsHelper', ['RestServices', 'Utilities', 'ProjectStatusDefinition', 'ProjectFormDefinition'])
.factory('ProjectStatus', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GenerateForm',
'Prompt', 'ProcessErrors', 'GetBasePath', 'FormatDate', 'ProjectStatusForm', .factory('ProjectStatus', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GenerateForm',
'Prompt', 'ProcessErrors', 'GetBasePath', 'FormatDate', 'ProjectStatusForm',
function($rootScope, $location, $log, $routeParams, Rest, Alert, GenerateForm, Prompt, ProcessErrors, GetBasePath, function($rootScope, $location, $log, $routeParams, Rest, Alert, GenerateForm, Prompt, ProcessErrors, GetBasePath,
FormatDate, ProjectStatusForm) { FormatDate, ProjectStatusForm) {
return function(params) { return function(params) {
@@ -65,3 +66,5 @@ angular.module('ProjectsHelper', ['RestServices', 'Utilities', 'ProjectStatusDef
}); });
} }
}]); }]);

View File

@@ -23,7 +23,7 @@ angular.module('ProjectsListDefinition', [])
name: { name: {
key: true, key: true,
label: 'Name', label: 'Name',
badgeIcon: "\{\{ 'icon-failures-' + project.last_update_failed \}\}", badgeIcon: "\{\{ 'icon-failures-' + project.badge \}\}",
badgePlacement: 'left' badgePlacement: 'left'
}, },
description: { description: {

View File

@@ -26,7 +26,10 @@ body {
/* Helper Classes */ /* Helper Classes */
.pad-right-sm { padding-right: 10px; } .pad-right-sm { padding-right: 10px; }
.pad-left-lg { padding-left: 50px; } .pad-left-lg { padding-left: 50px; }
.normal-weight { font-weight: normal; }
/* Working... spinner */
.spinny { .spinny {
display: none; display: none;
position: absolute; position: absolute;
@@ -507,6 +510,7 @@ select.field-mini-height {
.job-running, .job-running,
.job-success, .job-success,
.job-successful, .job-successful,
.job-waiting,
.icon-failures-false, .icon-failures-false,
.license-valid, .license-valid,
input[type="text"].job-success, input[type="text"].job-success,

View File

@@ -110,9 +110,7 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService', 'Hos
validity = true; validity = true;
if ( scope[attrs.awRequiredWhen] && (elm.attr('required') == null || elm.attr('required') == undefined) ) { if ( scope[attrs.awRequiredWhen] && (elm.attr('required') == null || elm.attr('required') == undefined) ) {
$(elm).attr('required','required'); $(elm).attr('required','required');
console.log('here');
if ($(elm).hasClass('lookup')) { if ($(elm).hasClass('lookup')) {
console.log('adding!');
$(elm).parent().parent().parent().find('label').prepend('* '); $(elm).parent().parent().parent().find('label').prepend('* ');
} }
} }

View File

@@ -126,6 +126,9 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies'])
} }
}); });
} }
if (!this.scope.$$phase) {
this.scope.$digest();
}
return this.scope; return this.scope;
}, },

View File

@@ -193,7 +193,7 @@ angular.module('GeneratorHelpers', ['GeneratorHelpers'])
html += (field.ngShow) ? "<span " + Attr(field,'ngShow') + ">" : ""; html += (field.ngShow) ? "<span " + Attr(field,'ngShow') + ">" : "";
// Badge // Badge
if (field.badgeIcon && field.badgePlacement && field.badgePlacement == 'left') { if (options.mode !== 'lookup' && field.badgeIcon && field.badgePlacement && field.badgePlacement == 'left') {
html += Badge(field); html += Badge(field);
} }
@@ -262,7 +262,7 @@ angular.module('GeneratorHelpers', ['GeneratorHelpers'])
"></div>\n" : ""; "></div>\n" : "";
// Badge // Badge
if (field.badgeIcon && field.badgePlacement && field.badgePlacement !== 'left') { if (options.mode !== 'lookup' && field.badgeIcon && field.badgePlacement && field.badgePlacement !== 'left') {
html += Badge(field); html += Badge(field);
} }
} }

View File

@@ -202,12 +202,11 @@
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" ng-click="cancelJob()" aria-hidden="true">&times;</button> <button type="button" class="close" ng-click="cancelJob()" aria-hidden="true">&times;</button>
<h3>Password Required</h3> <h3>Authentication Required</h3>
</div>
<div class="modal-body" id="password-body">
</div> </div>
<div class="modal-body" id="password-body"></div>
<div class="modal-footer"> <div class="modal-footer">
<a href="#" ng-click="cancelJob()" class="btn btn-default">Cancel</a> <a href="" ng-click="cancelJob()" class="btn btn-default">Cancel</a>
<a href="" ng-click="startJob()" class="btn btn-primary" ng-disabled="password_form.$pristine || password_form.$invalid">Continue</a> <a href="" ng-click="startJob()" class="btn btn-primary" ng-disabled="password_form.$pristine || password_form.$invalid">Continue</a>
</div> </div>
</div><!-- modal-content --> </div><!-- modal-content -->