Latest UI changes.

This commit is contained in:
chouseknecht
2013-09-06 00:41:22 -04:00
parent dfc687dfae
commit 8cdbaa83b2
14 changed files with 98 additions and 95 deletions

View File

@@ -15,6 +15,12 @@ var $AnsibleConfig =
tooltip_delay: {show: 500, hide: 100}, // Default number of milliseconds to delay displaying/hiding tooltips tooltip_delay: {show: 500, hide: 100}, // Default number of milliseconds to delay displaying/hiding tooltips
debug_mode: true // Enable console logging messages debug_mode: true, // Enable console logging messages
} password_strength: 45 // User password strength. Integer between 0 and 100, 100 being impossibly strong.
// This value controls progress bar colors:
// 0 to password_strength - 15 = red;
// password_strength - 15 to password_strength = yellow
// > password_strength = green
// It also controls password validation. Passwords are rejected if the score is not > password_strength.
}

View File

@@ -75,11 +75,11 @@ function InventoriesList ($scope, $rootScope, $location, $log, $routeParams, Res
// Failed jobs link. Go to the jobs tabs, find all jobs for the inventory and sort by status // Failed jobs link. Go to the jobs tabs, find all jobs for the inventory and sort by status
scope.viewJobs = function(id) { scope.viewJobs = function(id) {
$location.url('/jobs/?inventory__int=' + id + '&order_by=status'); $location.url('/jobs/?inventory__int=' + id);
} }
scope.viewFailedJobs = function(id) { scope.viewFailedJobs = function(id) {
$location.url('/jobs/?inventory__int=' + id + '&status=failed&order_by=status'); $location.url('/jobs/?inventory__int=' + id + '&status=failed');
} }
scope.editHosts = function(id) { scope.editHosts = function(id) {

View File

@@ -63,12 +63,8 @@ function JobsListCtrl ($scope, $rootScope, $location, $log, $routeParams, Rest,
scope[list.iterator + 'SearchValue'] = $routeParams['id__int']; scope[list.iterator + 'SearchValue'] = $routeParams['id__int'];
scope[list.iterator + 'SearchFieldLabel'] = 'Job ID'; scope[list.iterator + 'SearchFieldLabel'] = 'Job ID';
} }
scope.search(list.iterator);
// Called from Inventories page, failed jobs link. Now sort by status so faild jobs appear at top of list scope.search(list.iterator);
//if ($routeParams.order_by) {
// scope.sort($routeParams.order_by);
//}
LoadBreadCrumbs(); LoadBreadCrumbs();

View File

@@ -58,26 +58,38 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest,
} }
scope.showSCMStatus = function(id) { scope.showSCMStatus = function(id) {
var project; // Refresh the project list
for (var i=0; i < scope.projects.length; i++) { var statusCheckRemove = scope.$on('PostRefresh', function() {
if (scope.projects[i].id == id) { var project;
project = scope.projects[i]; for (var i=0; i < scope.projects.length; i++) {
break; if (scope.projects[i].id == id) {
project = scope.projects[i];
break;
}
} }
} if (project.scm_type !== null) {
if (project.scm_type !== null) { if (project.related.last_update !== undefined && project.status !== 'updating') {
if (project.related.last_update !== undefined) { ProjectStatus({ project_id: id, last_update: project.related.last_update });
ProjectStatus({ project_id: id, last_update: project.related.last_update }); }
} else if (project.status == 'updating') {
else { Alert('Pending Status', 'An update is currently running. Status details cannot be viewed until the update process ' +
Alert('No Updates Available', 'There is no SCM update information available for this project. An update has not yet been ' + ' completes. Use the refresh button to monitor progress of the update proess.', 'alert-info');
' completed. If you have not already done so, start an update for this project.', 'alert-info'); }
} else {
} Alert('No Updates Available', 'There is no SCM update information available for this project. An update has not yet been ' +
else { ' completed. If you have not already done so, start an update for this project.', 'alert-info');
Alert('Missing SCM Configuration', 'The selected project is not configured for SCM. You must first edit the project, provide SCM settings, ' + }
'and then start an update.', 'alert-info'); }
} else {
Alert('Missing SCM Configuration', 'The selected project is not configured for SCM. You must first edit the project, provide SCM settings, ' +
'and then run an update.', 'alert-info');
}
statusCheckRemove();
});
// Refresh the project list so we're looking at the latest data
scope.search(list.iterator);
} }
scope.deleteProject = function(id, name) { scope.deleteProject = function(id, name) {

View File

@@ -279,7 +279,7 @@ angular.module('JobFormDefinition', [])
label: 'Refresh', label: 'Refresh',
icon: 'icon-refresh', icon: 'icon-refresh',
ngClick: "refresh()", ngClick: "refresh()",
"class": 'btn-sm btn-success', "class": 'btn-sm btn-primary',
awToolTip: 'Refresh job status &amp; output', awToolTip: 'Refresh job status &amp; output',
mode: 'all' mode: 'all'
}, },

View File

@@ -273,19 +273,18 @@ angular.module('EventsHelper', ['RestServices', 'Utilities', 'JobEventDataDefini
scope.formModalInfoAction = function() { scope.formModalInfoAction = function() {
var generator = GenerateForm; var generator = GenerateForm;
var scope = generator.inject(JobEventDataForm, { mode: 'edit', modal: true, related: false, var scope = generator.inject(JobEventDataForm, { mode: 'edit', modal: true, related: false,
modal_selector: '#form-modal2', modal_body_id: 'form-modal2-body' }); modal_selector: '#form-modal2', modal_body_id: 'form-modal2-body', modal_title_id: 'formModal2Header' });
generator.reset(); generator.reset();
scope.formModal2Header = data['event_display'].replace(/^\u00a0*/g,'');
scope.event_data = JSON.stringify(data['event_data'], null, '\t');
scope.formModal2ActionLabel = 'OK';
scope.formModal2CancelShow = false;
scope.formModal2Info = false;
scope.formModalInfo = 'View JSON'; scope.formModalInfo = 'View JSON';
scope.formModal2Action = function() { scope.formModal2Action = function() {
$('#form-modal2').modal("hide"); $('#form-modal2').modal("hide");
} }
scope.formModal2ActionLabel = 'OK';
scope.formModal2CancelShow = false;
scope.formModal2Info = false;
$('#form-modal2 .btn-success').removeClass('btn-success').addClass('btn-none'); $('#form-modal2 .btn-success').removeClass('btn-success').addClass('btn-none');
//$('#form-modal2').addClass('skinny-modal');
scope.formModal2Header = data['event_display'].replace(/^\u00a0*/g,'');
scope.event_data = JSON.stringify(data['event_data'], null, '\t');
} }
if (typeof data['event_data']['res'] == 'string') { if (typeof data['event_data']['res'] == 'string') {

View File

@@ -24,8 +24,8 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
var defaultUrl = params.url; var defaultUrl = params.url;
var list = params.list; var list = params.list;
var iterator = (params.iterator) ? params.iterator : list.iterator; var iterator = (params.iterator) ? params.iterator : list.iterator;
var sort_order; var sort_order;
// Set default values // Set default values
for (fld in list.fields) { for (fld in list.fields) {
if (list.fields[fld].key) { if (list.fields[fld].key) {

View File

@@ -23,7 +23,9 @@ angular.module('InventoriesListDefinition', [])
key: true, key: true,
label: 'Name', label: 'Name',
badgeIcon: "\{\{ 'icon-failures-' + inventory.has_active_failures \}\}", badgeIcon: "\{\{ 'icon-failures-' + inventory.has_active_failures \}\}",
badgePlacement: 'left' badgePlacement: 'left',
badgeToolTip: 'Inventory contains hosts with active failures',
badgeTipPlacement: 'bottom'
}, },
description: { description: {
label: 'Description' label: 'Description'
@@ -52,10 +54,10 @@ angular.module('InventoriesListDefinition', [])
dropdown: { dropdown: {
type: 'DropDown', type: 'DropDown',
label: 'View', label: 'Jobs',
'class': 'btn-xs', 'class': 'btn-xs',
options: [ options: [
{ ngClick: 'viewJobs(\{\{ inventory.id \}\})', label: 'Jobs' }, { ngClick: 'viewJobs(\{\{ inventory.id \}\})', label: 'All Jobs' },
{ ngClick: "viewFailedJobs(\{\{ inventory.id \}\})", label: 'Failed jobs' } { ngClick: "viewFailedJobs(\{\{ inventory.id \}\})", label: 'Failed jobs' }
] ]
}, },

View File

@@ -67,7 +67,7 @@ angular.module('ProjectsListDefinition', [])
dataContainer: 'body', dataContainer: 'body',
icon: "icon-question-sign", icon: "icon-question-sign",
mode: 'all', mode: 'all',
'class': 'btn-xs btn-info btn-help', 'class': 'btn-xs btn-info btn-help pull-right',
awToolTip: 'Click for help', awToolTip: 'Click for help',
dataTitle: 'Project Status', dataTitle: 'Project Status',
iconSize: 'large', iconSize: 'large',
@@ -76,7 +76,6 @@ angular.module('ProjectsListDefinition', [])
}, },
fieldActions: { fieldActions: {
edit: { edit: {
label: 'Edit', label: 'Edit',
ngClick: "editProject(\{\{ project.id \}\})", ngClick: "editProject(\{\{ project.id \}\})",
@@ -98,7 +97,6 @@ angular.module('ProjectsListDefinition', [])
ngClick: 'SCMUpdate(\{\{ project.id \}\})', ngClick: 'SCMUpdate(\{\{ project.id \}\})',
awToolTip: 'Perform an SCM update on this project' awToolTip: 'Perform an SCM update on this project'
}, },
"delete": { "delete": {
label: 'Delete', label: 'Delete',
ngClick: "deleteProject(\{\{ project.id \}\},'\{\{ project.name \}\}')", ngClick: "deleteProject(\{\{ project.id \}\},'\{\{ project.name \}\}')",

View File

@@ -59,6 +59,10 @@ body {
opacity: .4; opacity: .4;
} }
.popover {
z-index: 2000;
}
.tooltip { .tooltip {
z-index: 1050; z-index: 1050;
} }

View File

@@ -360,7 +360,7 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService', 'Hos
var validity = true; var validity = true;
var score = chkPass(elm.val()); var score = chkPass(elm.val());
if (elm.val()) { if (elm.val()) {
validity = (score > 67) ? true : false; validity = (score > $AnsibleConfig.password_strength) ? true : false;
} }
ctrl.$setValidity('complexity', validity); ctrl.$setValidity('complexity', validity);
if (!scope.$$phase) { if (!scope.$$phase) {

View File

@@ -90,10 +90,15 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies'])
if (options.modal) { if (options.modal) {
this.scope.formModalActionDisabled = false; this.scope.formModalActionDisabled = false;
if (form) {
this.scope.formModalHeader = (options.mode == 'add') ? form.addTitle : form.editTitle; //Default title for default modal
}
this.scope.formModalInfo = false //Disable info button for default modal this.scope.formModalInfo = false //Disable info button for default modal
if (form) {
if (options.modal_title_id) {
this.scope[options.modal_title_id] = (options.mode == 'add') ? form.addTitle : form.editTitle;
}
else {
this.scope.formModalHeader = (options.mode == 'add') ? form.addTitle : form.editTitle; //Default title for default modal
}
}
if (options.modal_selector) { if (options.modal_selector) {
$(options.modal_selector).modal({ show: true, backdrop: 'static', keyboard: true }); $(options.modal_selector).modal({ show: true, backdrop: 'static', keyboard: true });
$(options.modal_selector).on('shown.bs.modal', function() { $(options.modal_selector).on('shown.bs.modal', function() {
@@ -434,23 +439,29 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies'])
if (field.chkPass) { if (field.chkPass) {
html += "<div class=\"error\" ng-show=\"" + this.form.name + '_form.' + fld + html += "<div class=\"error\" ng-show=\"" + this.form.name + '_form.' + fld +
".$error.complexity\">Password must meet minimum complexity</div>\n"; ".$error.complexity\">Password must be stronger</div>\n";
html += "<div class=\"pw-progress\">\n"; html += "<div class=\"pw-progress\">\n";
html += "<div class=\"progress progress-striped\">\n"; html += "<div class=\"progress progress-striped\">\n";
html += "<div id=\"progbar\" class=\"progress-bar\" role=\"progress\"></div>\n"; html += "<div id=\"progbar\" class=\"progress-bar\" role=\"progress\"></div>\n";
html += "</div>\n"; html += "</div>\n";
html += "<p>Password strength requirements:</p>"; html += "<div class=\"panel panel-default\">\n";
html += "<div class=\"panel-heading\"><h5>Password Strength</h5></div>\n";
html += "<div class=\"panel-body\">\n";
html += "<p>A password with reasonable strength is required. As you type the password " +
"a progress bar will measure the strength. Sufficient strength is reached when the bar turns green.</p>" +
"<p>Password strength is judged using the following:</p>";
html += "<ul class=\"pwddetails\">\n"; html += "<ul class=\"pwddetails\">\n";
html += "<li>Minimum 8 characters in length</li>\n"; html += "<li>Minimum 8 characters in length</li>\n";
html += "<li>Contains 3/4 of the following items:\n"; html += "<li>Contains a sufficient combination of the following items:\n";
html += "<ul>\n"; html += "<ul>\n";
html += "<li>UPPERCASE letters</li>\n"; html += "<li>UPPERCASE letters</li>\n";
html += "<li>lowercase letters</li>\n";
html += "<li>Numbers</li>\n"; html += "<li>Numbers</li>\n";
html += "<li>Symbols !@#$%^&*()</li>\n"; html += "<li>Symbols _!@#$%^&*()</li>\n";
html += "</ul>\n"; html += "</ul>\n";
html += "</li>\n"; html += "</li>\n";
html += "</ul>\n"; html += "</ul>\n";
html += "</div>\n";
html += "</div>\n";
html += "</div>\n"; html += "</div>\n";
} }

View File

@@ -1,8 +1,8 @@
/* /*
** Created by: Jeff Todnem (http://www.todnem.com/) ** Created by: Jeff Todnem (http://www.todnem.com/)
** Created on: 2007-08-14 ** Created on: 2007-08-14
** Last modified: 2013-07-31 by James Cammarata ** Modified: 2013-07-31 by James Cammarata
** **
** License Information: ** License Information:
** ------------------------------------------------------------------------- ** -------------------------------------------------------------------------
** Copyright (C) 2007 Jeff Todnem ** Copyright (C) 2007 Jeff Todnem
@@ -20,35 +20,9 @@
** You should have received a copy of the GNU General Public License along ** You should have received a copy of the GNU General Public License along
** with this program; if not, write to the Free Software Foundation, Inc., ** with this program; if not, write to the Free Software Foundation, Inc.,
** 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ** 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
** **
*/ **
** CLH 9/5/13 - Set required strength in config.js
/*
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != "function") {
window.onload = func;
}
else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
};
}
}
function $() {
var arrElms = [];
for (var i=0; i < arguments.length; i++) {
var elm = arguments[i];
if (typeof(elm == "string")) { elm = document.getElementById(elm); }
if (arguments.length == 1) { return elm; }
arrElms.push(elm);
}
return arrElms;
}
*/ */
String.prototype.strReverse = function() { String.prototype.strReverse = function() {
@@ -57,8 +31,6 @@ String.prototype.strReverse = function() {
newstring = this.charAt(s) + newstring; newstring = this.charAt(s) + newstring;
} }
return newstring; return newstring;
//strOrig = ' texttotrim ';
//strReversed = strOrig.revstring();
}; };
var nScore = 0; var nScore = 0;
@@ -80,7 +52,7 @@ function chkPass(pwd) {
sConsecNumber="0", sSeqAlpha="0", sSeqNumber="0", sSeqSymbol="0"; sConsecNumber="0", sSeqAlpha="0", sSeqNumber="0", sSeqSymbol="0";
var sAlphas = "abcdefghijklmnopqrstuvwxyz"; var sAlphas = "abcdefghijklmnopqrstuvwxyz";
var sNumerics = "01234567890"; var sNumerics = "01234567890";
var sSymbols = ")!@#$%^&*()"; var sSymbols = ")_!@#$%^&*()";
var sComplexity = "Too Short"; var sComplexity = "Too Short";
var sStandards = "Below"; var sStandards = "Below";
var nMinPwdLen = 8; var nMinPwdLen = 8;
@@ -225,17 +197,20 @@ function chkPass(pwd) {
if (nScore > 100) { nScore = 100; } else if (nScore < 0) { nScore = 0; } if (nScore > 100) { nScore = 100; } else if (nScore < 0) { nScore = 0; }
var progbar = $("#progbar"); var progbar = $("#progbar");
var required_strength = $AnsibleConfig.password_strength;
var warning_level = ($AnsibleConfig.password_strength - 15 < 0) ? 0 : $AnsibleConfig.password_strength - 15;
progbar.css("width", nScore + '%'); progbar.css("width", nScore + '%');
if (nScore >= 0 && nScore <= 33) { if (nScore >= 0 && nScore <= warning_level) {
sComplexity = 'Weak'; sComplexity = 'Weak';
progbar.addClass('progress-bar-danger') progbar.addClass('progress-bar-danger')
progbar.removeClass('progress-bar-success progress-bar-warning') progbar.removeClass('progress-bar-success progress-bar-warning')
} else if (nScore > 33 && nScore <= 67) { } else if (nScore > warning_level && nScore <= required_strength) {
sComplexity = 'Good'; sComplexity = 'Good';
progbar.addClass('progress-bar-warning') progbar.addClass('progress-bar-warning')
progbar.removeClass('progress-bar-success progress-bar-danger') progbar.removeClass('progress-bar-success progress-bar-danger')
} else if (nScore > 67) { } else if (nScore > required_strength) {
sComplexity = "Strong"; sComplexity = "Strong";
progbar.addClass('progress-bar-success') progbar.addClass('progress-bar-success')
progbar.removeClass('progress-bar-warning progress-bar-danger') progbar.removeClass('progress-bar-warning progress-bar-danger')
@@ -245,7 +220,7 @@ function chkPass(pwd) {
/* no password, so reset the displays */ /* no password, so reset the displays */
var progbar = $("#progbar"); var progbar = $("#progbar");
progbar.css("width", '0%'); progbar.css("width", '0%');
progbar.removeClass('progress-bar-success progress-bar-warning progress-bar-danger') progbar.removeClass('progress-bar-success progress-bar-warning')
} }
return nScore; return nScore;
} }

View File

@@ -240,12 +240,12 @@
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-target="#alert-modal" <button type="button" class="close" data-target="#alert-modal"
data-dismiss="modal" aria-hidden="true">&times;</button> data-dismiss="modal" aria-hidden="true">&times;</button>
<h3 ng-bind="formModal2Header"></h3> <h3 ng-bind-html-unsafe="formModal2Header"></h3>
</div> </div>
<div class="modal-body" id="form-modal2-body"></div> <div class="modal-body" id="form-modal2-body"></div>
<div class="modal-footer"> <div class="modal-footer">
<a href="" ng-bind="formModal2Info" ng-show="formModal2Info !== undefined && formModal2Info != ''" ng-click="formModal2InfoAction()" <a href="" ng-bind="formModal2Info" ng-show="formModal2Info !== undefined && formModal2Info != ''" ng-click="formModal2InfoAction()"
class="btn btn-sm pull-left"><i class="icon-zoom-in"></i> <span ng-bind="formModal2Info"></span></a> class="btn btn-default btn-sm pull-left"><i class="icon-zoom-in"></i> <span ng-bind="formModal2Info"></span></a>
<a href="#" ng-show="formModal2CancelShow" data-target="#form-modal2" data-dismiss="modal" class="btn btn-default">Cancel</a> <a href="#" ng-show="formModal2CancelShow" data-target="#form-modal2" data-dismiss="modal" class="btn btn-default">Cancel</a>
<a href="" ng-bind="formModal2ActionLabel" ng-click="formModal2Action()" class="btn btn-primary"></a> <a href="" ng-bind="formModal2ActionLabel" ng-click="formModal2Action()" class="btn btn-primary"></a>
</div> </div>