mirror of
https://github.com/ansible/awx.git
synced 2026-03-01 00:38:45 -03:30
AC-550 When user views inventory update status (by clicking on the status link) an alert at the top of the dialog will show when the error is caused by a license violation.
This commit is contained in:
@@ -63,7 +63,7 @@ angular.module('ActivityDetailDefinition', [])
|
|||||||
},
|
},
|
||||||
changes: {
|
changes: {
|
||||||
label: 'Changes',
|
label: 'Changes',
|
||||||
type: 'lgtextarea',
|
type: 'textarea',
|
||||||
ngHide: "!changes || changes =='' || changes == 'null'",
|
ngHide: "!changes || changes =='' || changes == 'null'",
|
||||||
readonly: true
|
readonly: true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,29 +16,38 @@ angular.module('InventoryStatusDefinition', [])
|
|||||||
'class': 'horizontal-narrow',
|
'class': 'horizontal-narrow',
|
||||||
|
|
||||||
fields: {
|
fields: {
|
||||||
|
license_error: {
|
||||||
|
type: 'alertblock',
|
||||||
|
'class': "alert-info",
|
||||||
|
alertTxt: "The invenvtory update process exceeded the available number of licensed hosts. " +
|
||||||
|
"<strong><a ng-click=\"viewLicense()\" href=\"\">View your license</a></strong> " +
|
||||||
|
"for more information.",
|
||||||
|
ngShow: 'license_error',
|
||||||
|
closeable: false
|
||||||
|
},
|
||||||
created: {
|
created: {
|
||||||
label: 'Created',
|
label: 'Created',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
readonly: true
|
readonly: true
|
||||||
},
|
},
|
||||||
status: {
|
status: {
|
||||||
label: 'Status',
|
label: 'Status',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
readonly: true
|
readonly: true
|
||||||
},
|
},
|
||||||
result_stdout: {
|
result_stdout: {
|
||||||
label: 'Std Out',
|
label: 'Std Out',
|
||||||
type: 'textarea',
|
type: 'textarea',
|
||||||
ngShow: "result_stdout",
|
ngShow: "result_stdout",
|
||||||
readonly: true,
|
readonly: true,
|
||||||
rows: 15
|
rows: 15
|
||||||
},
|
},
|
||||||
result_traceback: {
|
result_traceback: {
|
||||||
label: 'Traceback',
|
label: 'Traceback',
|
||||||
type: 'textarea',
|
type: 'textarea',
|
||||||
ngShow: "result_traceback",
|
ngShow: "result_traceback",
|
||||||
readonly: true,
|
readonly: true,
|
||||||
rows: 15
|
rows: 15
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}); //Form
|
}); //Form
|
||||||
@@ -79,8 +79,8 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
|
|||||||
}
|
}
|
||||||
}])
|
}])
|
||||||
|
|
||||||
.factory('ViewUpdateStatus', [ 'Rest', 'ProcessErrors', 'GetBasePath', 'ShowUpdateStatus', 'Alert',
|
.factory('ViewUpdateStatus', [ 'Rest', 'ProcessErrors', 'GetBasePath', 'ShowUpdateStatus', 'Alert', 'Wait',
|
||||||
function(Rest, ProcessErrors, GetBasePath, ShowUpdateStatus, Alert) {
|
function(Rest, ProcessErrors, GetBasePath, ShowUpdateStatus, Alert, Wait) {
|
||||||
return function(params) {
|
return function(params) {
|
||||||
|
|
||||||
var scope = params.scope;
|
var scope = params.scope;
|
||||||
@@ -104,14 +104,19 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
|
|||||||
'clicking the Update button.', 'alert-info');
|
'clicking the Update button.', 'alert-info');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
Wait('start');
|
||||||
Rest.setUrl(group.related.inventory_source);
|
Rest.setUrl(group.related.inventory_source);
|
||||||
Rest.get()
|
Rest.get()
|
||||||
.success( function(data, status, headers, config) {
|
.success( function(data, status, headers, config) {
|
||||||
var url = (data.related.current_update) ? data.related.current_update : data.related.last_update;
|
var url = (data.related.current_update) ? data.related.current_update : data.related.last_update;
|
||||||
ShowUpdateStatus({ group_name: data.summary_fields.group.name,
|
ShowUpdateStatus({
|
||||||
last_update: url });
|
group_name: data.summary_fields.group.name,
|
||||||
|
last_update: url,
|
||||||
|
license_error: [ (data.summary_fields.last_update && data.summary_fields.last_update.license_error) ? true : false ]
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.error( function(data, status, headers, config) {
|
.error( function(data, status, headers, config) {
|
||||||
|
Wait('stop');
|
||||||
ProcessErrors(scope, data, status, form,
|
ProcessErrors(scope, data, status, form,
|
||||||
{ hdr: 'Error!', msg: 'Failed to retrieve inventory source: ' + group.related.inventory_source +
|
{ hdr: 'Error!', msg: 'Failed to retrieve inventory source: ' + group.related.inventory_source +
|
||||||
' POST returned status: ' + status });
|
' POST returned status: ' + status });
|
||||||
@@ -1120,63 +1125,66 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
|
|||||||
|
|
||||||
|
|
||||||
.factory('ShowUpdateStatus', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GenerateForm',
|
.factory('ShowUpdateStatus', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GenerateForm',
|
||||||
'Prompt', 'ProcessErrors', 'GetBasePath', 'FormatDate', 'InventoryStatusForm',
|
'Prompt', 'ProcessErrors', 'GetBasePath', 'FormatDate', 'InventoryStatusForm', 'Wait',
|
||||||
function($rootScope, $location, $log, $routeParams, Rest, Alert, GenerateForm, Prompt, ProcessErrors, GetBasePath,
|
function($rootScope, $location, $log, $routeParams, Rest, Alert, GenerateForm, Prompt, ProcessErrors, GetBasePath,
|
||||||
FormatDate, InventoryStatusForm) {
|
FormatDate, InventoryStatusForm, Wait) {
|
||||||
return function(params) {
|
return function(params) {
|
||||||
|
|
||||||
var group_name = params.group_name;
|
var group_name = params.group_name;
|
||||||
var last_update = params.last_update;
|
var last_update = params.last_update;
|
||||||
var generator = GenerateForm;
|
var generator = GenerateForm;
|
||||||
var form = InventoryStatusForm;
|
var form = InventoryStatusForm;
|
||||||
|
var license_error = params.license_error
|
||||||
var scope;
|
var scope;
|
||||||
|
|
||||||
if (last_update == undefined || last_update == null || last_update == ''){
|
if (last_update == undefined || last_update == null || last_update == ''){
|
||||||
|
Wait('stop');
|
||||||
Alert('Missing Configuration', 'The selected group is not configured for inventory updates. ' +
|
Alert('Missing Configuration', 'The selected group is not configured for inventory updates. ' +
|
||||||
'You must first edit the group, provide Source settings, and then run an update.', 'alert-info');
|
'You must first edit the group, provide Source settings, and then run an update.', 'alert-info');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if ($rootScope.removeShowStatus) {
|
||||||
|
$rootScope.removeShowStatus();
|
||||||
|
}
|
||||||
|
$rootScope.removeShowStatus = $rootScope.$on('showStatus', function(e, results) {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
// Retrieve detail record and prepopulate the form
|
// Retrieve detail record and prepopulate the form
|
||||||
Rest.setUrl(last_update);
|
Rest.setUrl(last_update);
|
||||||
Rest.get()
|
Rest.get()
|
||||||
.success( function(data, status, headers, config) {
|
.success( function(data, status, headers, config) {
|
||||||
// load up the form
|
$('#form-modal').on('shown.bs.modal', function() {
|
||||||
|
Wait('stop');
|
||||||
|
});
|
||||||
scope = generator.inject(form, { mode: 'edit', modal: true, related: false});
|
scope = generator.inject(form, { mode: 'edit', modal: true, related: false});
|
||||||
generator.reset();
|
generator.reset();
|
||||||
var results = data;
|
|
||||||
for (var fld in form.fields) {
|
for (var fld in form.fields) {
|
||||||
if (results[fld]) {
|
if (data[fld]) {
|
||||||
if (fld == 'created') {
|
if (fld == 'created') {
|
||||||
scope[fld] = FormatDate(new Date(results[fld]));
|
scope[fld] = FormatDate(new Date(data[fld]));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
scope[fld] = results[fld];
|
scope[fld] = data[fld];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//else {
|
|
||||||
// if (results.summary_fields.project[fld]) {
|
|
||||||
// scope[fld] = results.summary_fields.project[fld]
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
scope.license_error = license_error;
|
||||||
scope.formModalAction = function() {
|
scope.formModalAction = function() {
|
||||||
$('#form-modal').modal("hide");
|
$('#form-modal').modal("hide");
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.formModalActionLabel = 'OK';
|
scope.formModalActionLabel = 'OK';
|
||||||
scope.formModalCancelShow = false;
|
scope.formModalCancelShow = false;
|
||||||
scope.formModalInfo = false;
|
scope.formModalInfo = false;
|
||||||
scope.formModalHeader = group_name + '<span class="subtitle"> - Inventory Update</span>';
|
scope.formModalHeader = group_name + '<span class="subtitle"> - Inventory Update</span>';
|
||||||
|
|
||||||
$('#form-modal .btn-success').removeClass('btn-success').addClass('btn-none');
|
$('#form-modal .btn-success').removeClass('btn-success').addClass('btn-none');
|
||||||
$('#form-modal').addClass('skinny-modal');
|
$('#form-modal').addClass('skinny-modal');
|
||||||
|
|
||||||
if (!scope.$$phase) {
|
if (!scope.$$phase) {
|
||||||
scope.$digest();
|
scope.$digest();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.error( function(data, status, headers, config) {
|
.error( function(data, status, headers, config) {
|
||||||
|
Wait('stop');
|
||||||
$('#form-modal').modal("hide");
|
$('#form-modal').modal("hide");
|
||||||
ProcessErrors(scope, data, status, null,
|
ProcessErrors(scope, data, status, null,
|
||||||
{ hdr: 'Error!', msg: 'Failed to retrieve last update: ' + last_update + '. GET status: ' + status });
|
{ hdr: 'Error!', msg: 'Failed to retrieve last update: ' + last_update + '. GET status: ' + status });
|
||||||
|
|||||||
@@ -101,61 +101,22 @@ textarea {
|
|||||||
opacity: .4;
|
opacity: .4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.popover {
|
|
||||||
z-index: 2000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TB tooltip overrides */
|
/* TB tooltip overrides */
|
||||||
|
|
||||||
|
.popover {
|
||||||
|
z-index: 2000;
|
||||||
|
}
|
||||||
|
|
||||||
.tooltip {
|
.tooltip {
|
||||||
z-index: 1050;
|
z-index: 1050;
|
||||||
opacity: 1.0;
|
opacity: 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
.alert {
|
||||||
.tooltip-inner {
|
margin-top: 15px;
|
||||||
color: @tip-color;
|
margin-bottom: 15px;
|
||||||
background-color: @tip-background;
|
|
||||||
border-radius: 6px;
|
|
||||||
padding: 5px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip.in {
|
|
||||||
opacity: 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip.top .tooltip-arrow {
|
|
||||||
border-top-color: @tip-background;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip.top-left .tooltip-arrow {
|
|
||||||
border-top-color: @tip-background;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip.top-right .tooltip-arrow {
|
|
||||||
border-top-color: @tip-background;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip.right .tooltip-arrow {
|
|
||||||
border-top-color: @tip-background;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip.left .tooltip-arrow {
|
|
||||||
border-top-color: @tip-background;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip.bottom .tooltip-arrow {
|
|
||||||
border-top-color: @tip-background;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip.bottom-left .tooltip-arrow {
|
|
||||||
border-top-color: @tip-background;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip.bottom-right .tooltip-arrow {
|
|
||||||
border-top-color: @tip-background;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
border-color: #e3e3e3;
|
border-color: #e3e3e3;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -356,7 +356,7 @@ angular.module('Utilities',['RestServices', 'Utilities'])
|
|||||||
}])
|
}])
|
||||||
|
|
||||||
.factory('Wait', [ '$rootScope', function($rootScope) {
|
.factory('Wait', [ '$rootScope', function($rootScope) {
|
||||||
return function(directive) {
|
return function(directive, callback) {
|
||||||
// Display a spinning icon in the center of the screen to freeze the
|
// Display a spinning icon in the center of the screen to freeze the
|
||||||
// UI while waiting on async things to complete (i.e. API calls).
|
// UI while waiting on async things to complete (i.e. API calls).
|
||||||
// Wait('start' | 'stop');
|
// Wait('start' | 'stop');
|
||||||
@@ -375,11 +375,11 @@ angular.module('Utilities',['RestServices', 'Utilities'])
|
|||||||
$('.spinny').css({
|
$('.spinny').css({
|
||||||
top: y,
|
top: y,
|
||||||
left: x
|
left: x
|
||||||
}).fadeIn(400);
|
}).fadeIn(400, callback);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$rootScope.waiting = false;
|
$rootScope.waiting = false;
|
||||||
$('.spinny, .overlay').fadeOut(1000);
|
$('.spinny, .overlay').fadeOut(500, callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}])
|
}])
|
||||||
|
|||||||
@@ -437,10 +437,13 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies', 'Utilities'])
|
|||||||
var html = '';
|
var html = '';
|
||||||
|
|
||||||
if (field.type == 'alertblock') {
|
if (field.type == 'alertblock') {
|
||||||
html += "<div class=\"alert alert-dismissable " + field['class'] + "\" ";
|
html += "<div class=\"alert ";
|
||||||
|
html += (field.closeable == undefined || field.closeable == true) ? "alert-dismissable " : "";
|
||||||
|
html += field['class'] + "\" ";
|
||||||
html += (field.ngShow) ? this.attr(field, 'ngShow') : "";
|
html += (field.ngShow) ? this.attr(field, 'ngShow') : "";
|
||||||
html += ">\n";
|
html += ">\n";
|
||||||
html += "<button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">×</button>\n";
|
html += (field.closeable == undefined || field.closeable == true) ?
|
||||||
|
"<button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">×</button>\n" : "";
|
||||||
html += field.alertTxt;
|
html += field.alertTxt;
|
||||||
html += "</div>\n";
|
html += "</div>\n";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user