mirror of
https://github.com/ansible/awx.git
synced 2026-05-08 01:47:35 -02:30
AC-502 start of new dashboard.
This commit is contained in:
@@ -70,7 +70,7 @@ angular.module('ansible', [
|
|||||||
'LicenseFormDefinition',
|
'LicenseFormDefinition',
|
||||||
'License',
|
'License',
|
||||||
'HostGroupsFormDefinition',
|
'HostGroupsFormDefinition',
|
||||||
'ObjectCountWidget',
|
'JobStatusWidget',
|
||||||
'JobsHelper',
|
'JobsHelper',
|
||||||
'InventoryStatusDefinition'
|
'InventoryStatusDefinition'
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ function Authenticate($cookieStore, $window, $scope, $rootScope, $location, Auth
|
|||||||
$('#login-username').focus();
|
$('#login-username').focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Just in case, make sure the wait widget is not active
|
||||||
|
Wait('stop');
|
||||||
|
|
||||||
// Display the login dialog
|
// Display the login dialog
|
||||||
$('#login-modal').modal({ show: true, keyboard: false, backdrop: 'static' });
|
$('#login-modal').modal({ show: true, keyboard: false, backdrop: 'static' });
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
function Home ($routeParams, $scope, $rootScope, $location, Wait, ObjectCount, ClearScope)
|
function Home ($routeParams, $scope, $rootScope, $location, Wait, JobStatus, ClearScope)
|
||||||
{
|
{
|
||||||
ClearScope('home'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
ClearScope('home'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
||||||
//scope.
|
//scope.
|
||||||
@@ -23,10 +23,10 @@ function Home ($routeParams, $scope, $rootScope, $location, Wait, ObjectCount, C
|
|||||||
Wait('start');
|
Wait('start');
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectCount({ target: 'container1' });
|
JobStatus({ target: 'container1' });
|
||||||
|
|
||||||
$rootScope.$on('WidgetLoaded', function() {
|
$rootScope.$on('WidgetLoaded', function() {
|
||||||
// Once all the widget report back 'loaded', turn off Wait widget
|
// Once all the widgets report back 'loaded', turn off Wait widget
|
||||||
loadedCount++;
|
loadedCount++;
|
||||||
if ( loadedCount == waitCount ) {
|
if ( loadedCount == waitCount ) {
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
@@ -34,4 +34,4 @@ function Home ($routeParams, $scope, $rootScope, $location, Wait, ObjectCount, C
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Home.$inject=[ '$routeParams', '$scope', '$rootScope', '$location', 'Wait', 'ObjectCount', 'ClearScope'];
|
Home.$inject=[ '$routeParams', '$scope', '$rootScope', '$location', 'Wait', 'JobStatus', 'ClearScope'];
|
||||||
@@ -74,32 +74,28 @@ function JobHostSummaryList ($scope, $rootScope, $location, $log, $routeParams,
|
|||||||
Rest.setUrl(GetBasePath('jobs') + scope.job_id);
|
Rest.setUrl(GetBasePath('jobs') + scope.job_id);
|
||||||
Rest.get()
|
Rest.get()
|
||||||
.success( function(data, status, headers, config) {
|
.success( function(data, status, headers, config) {
|
||||||
|
LoadBreadCrumbs({ path: '/jobs/' + data.id, title: data.id + ' - ' +
|
||||||
|
data.summary_fields.job_template.name });
|
||||||
scope.job_status = data.status;
|
scope.job_status = data.status;
|
||||||
scope.$emit('setHostLink', data.inventory);
|
|
||||||
if (!(data.status == 'pending' || data.status == 'waiting' || data.status == 'running')) {
|
if (!(data.status == 'pending' || data.status == 'waiting' || data.status == 'running')) {
|
||||||
if ($rootScope.timer) {
|
if ($rootScope.timer) {
|
||||||
clearInterval($rootScope.timer);
|
clearInterval($rootScope.timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
scope.$emit('setHostLink', data.inventory);
|
||||||
})
|
})
|
||||||
.error( function(data, status, headers, config) {
|
.error( function(data, status, headers, config) {
|
||||||
ProcessErrors(scope, data, status, null,
|
ProcessErrors(scope, data, status, null,
|
||||||
{ hdr: 'Error!', msg: 'Failed to get job status for job: ' + scope.job_id + '. GET status: ' + status });
|
{ hdr: 'Error!', msg: 'Failed to get job status for job: ' + scope.job_id + '. GET status: ' + status });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// Make the host name appear in breadcrumbs
|
||||||
|
LoadBreadCrumbs({ path: '/hosts/' + scope['host_id'], title: $routeParams['host_name'] });
|
||||||
if ($routeParams['inventory']) {
|
if ($routeParams['inventory']) {
|
||||||
scope.$emit('setHostLink', $routeParams['inventory']);
|
scope.$emit('setHostLink', $routeParams['inventory']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (base == 'hosts' && $routeParams['host_name']) {
|
|
||||||
// Make the host name appear in breadcrumbs
|
|
||||||
LoadBreadCrumbs({ path: '/hosts/' + scope['host_id'], title: $routeParams['host_name'] });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LoadBreadCrumbs({ path: '/jobs/' + scope.job_id, title: scope.job_id + ' - ' +
|
|
||||||
scope.jobhosts[0].summary_fields.job.job_template_name });
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
SearchInit({ scope: scope, set: 'jobhosts', list: list, url: defaultUrl });
|
SearchInit({ scope: scope, set: 'jobhosts', list: list, url: defaultUrl });
|
||||||
|
|||||||
@@ -42,10 +42,12 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest,
|
|||||||
scope.projects[i].status = 'n/a';
|
scope.projects[i].status = 'n/a';
|
||||||
}
|
}
|
||||||
switch(scope.projects[i].status) {
|
switch(scope.projects[i].status) {
|
||||||
|
case 'n/a':
|
||||||
|
scope.projects[i].badge = 'none';
|
||||||
|
break;
|
||||||
case 'updating':
|
case 'updating':
|
||||||
case 'successful':
|
case 'successful':
|
||||||
case 'ok':
|
case 'ok':
|
||||||
case 'n/a':
|
|
||||||
scope.projects[i].badge = 'false';
|
scope.projects[i].badge = 'false';
|
||||||
break;
|
break;
|
||||||
case 'never updated':
|
case 'never updated':
|
||||||
|
|||||||
@@ -31,13 +31,14 @@ angular.module('JobsListDefinition', [])
|
|||||||
},
|
},
|
||||||
created: {
|
created: {
|
||||||
label: 'Date',
|
label: 'Date',
|
||||||
link: true,
|
link: false,
|
||||||
searchable: false
|
searchable: false
|
||||||
},
|
},
|
||||||
job_template: {
|
job_template: {
|
||||||
label: 'Job Template',
|
label: 'Job Template',
|
||||||
ngBind: 'job.summary_fields.job_template.name',
|
ngBind: 'job.summary_fields.job_template.name',
|
||||||
ngHref: "\{\{ '/#/job_templates/?name=' + job.summary_fields.job_template.name \}\}",
|
//ngHref: "\{\{ '/#/job_templates/?name=' + job.summary_fields.job_template.name \}\}",
|
||||||
|
ngHref:"\{\{ '/#/job_templates/' + job.job_template \}\}",
|
||||||
sourceModel: 'job_template',
|
sourceModel: 'job_template',
|
||||||
sourceField: 'name'
|
sourceField: 'name'
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ angular.module('ProjectsListDefinition', [])
|
|||||||
label: 'Update Status',
|
label: 'Update Status',
|
||||||
ngClick: 'showSCMStatus(\{\{ project.id \}\})',
|
ngClick: 'showSCMStatus(\{\{ project.id \}\})',
|
||||||
awToolTip: 'View details of last SCM Update',
|
awToolTip: 'View details of last SCM Update',
|
||||||
dataPlacement: 'bottom',
|
dataPlacement: 'top',
|
||||||
badgeIcon: "\{\{ 'icon-failures-' + project.badge \}\}",
|
badgeIcon: "\{\{ 'icon-failures-' + project.badge \}\}",
|
||||||
badgePlacement: 'left'
|
badgePlacement: 'left'
|
||||||
},
|
},
|
||||||
|
|||||||
159
awx/ui/static/js/widgets/JobStatus.js
Normal file
159
awx/ui/static/js/widgets/JobStatus.js
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
/*********************************************
|
||||||
|
* Copyright (c) 2013 AnsibleWorks, Inc.
|
||||||
|
*
|
||||||
|
* JobStatus.js
|
||||||
|
*
|
||||||
|
* Dashboard widget showing object counts and license availability.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
angular.module('JobStatusWidget', ['RestServices', 'Utilities'])
|
||||||
|
.factory('JobStatus', ['$rootScope', '$compile', 'Rest', 'GetBasePath', 'ProcessErrors', 'Wait',
|
||||||
|
function($rootScope, $compile, Rest, GetBasePath, ProcessErrors, Wait) {
|
||||||
|
return function(params) {
|
||||||
|
|
||||||
|
var scope = $rootScope.$new();
|
||||||
|
var jobCount, jobFails, inventoryCount, inventoryFails, groupCount, groupFails, hostCount, hostFails;
|
||||||
|
var counts = 0;
|
||||||
|
var expectedCounts = 8;
|
||||||
|
var target = params.target;
|
||||||
|
|
||||||
|
scope.$on('CountReceived', function() {
|
||||||
|
|
||||||
|
function makeRow(label, count, fail) {
|
||||||
|
return "<tr><td><a href=\"/#/" + label.toLowerCase() + "\">" + label +
|
||||||
|
"</a></td><td class=\"failed-column text-right\"><a href=\"/blah/blah\">" +
|
||||||
|
fail + "</a></td><td class=\"text-right\"><a href=\"/blah/blah\">" +
|
||||||
|
count + "</a></td></tr>";
|
||||||
|
}
|
||||||
|
|
||||||
|
counts++;
|
||||||
|
if (counts == expectedCounts) {
|
||||||
|
// all the counts came back, now generate the HTML
|
||||||
|
var html = "<div class=\"panel panel-default\">\n";
|
||||||
|
html += "<div class=\"panel-heading\">Job Status</div>\n";
|
||||||
|
html += "<div class=\"panel-body\">\n";
|
||||||
|
html += "<table class=\"table table-condensed table-hover\">\n";
|
||||||
|
html += "<thead>\n";
|
||||||
|
html += "<tr>\n";
|
||||||
|
html += "<th></th>\n";
|
||||||
|
html += "<th class=\"text-right\">Failed</th>\n";
|
||||||
|
html += "<th class=\"text-right\">Total</th>\n";
|
||||||
|
html += "</tr>\n";
|
||||||
|
html += "</thead>\n";
|
||||||
|
html += "<tbody>\n";
|
||||||
|
html += makeRow('Jobs', jobCount, jobFails);
|
||||||
|
html += makeRow('Inventories', inventoryCount, inventoryFails);
|
||||||
|
html += makeRow('Groups', groupCount, groupFails);
|
||||||
|
html += makeRow('Hosts', hostCount, hostFails);
|
||||||
|
html += "</tbody>\n";
|
||||||
|
html += "</table>\n";
|
||||||
|
html += "</div>\n";
|
||||||
|
html += "</div>\n";
|
||||||
|
html += "</div>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
var element = angular.element(document.getElementById(target));
|
||||||
|
element.html(html);
|
||||||
|
$compile(element)(scope);
|
||||||
|
$rootScope.$emit('WidgetLoaded');
|
||||||
|
});
|
||||||
|
|
||||||
|
var url = GetBasePath('jobs') + '?page=1';
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.get()
|
||||||
|
.success( function(data, status, headers, config) {
|
||||||
|
jobCount=data.count;
|
||||||
|
scope.$emit('CountReceived');
|
||||||
|
})
|
||||||
|
.error( function(data, status, headers, config) {
|
||||||
|
ProcessErrors(scope, data, status, null,
|
||||||
|
{ hdr: 'Error!', msg: 'Failed to get ' + url + '. GET status: ' + status });
|
||||||
|
});
|
||||||
|
|
||||||
|
url = GetBasePath('jobs') + '?failed=true&page=1';
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.get()
|
||||||
|
.success( function(data, status, headers, config) {
|
||||||
|
jobFails=data.count;
|
||||||
|
scope.$emit('CountReceived');
|
||||||
|
})
|
||||||
|
.error( function(data, status, headers, config) {
|
||||||
|
ProcessErrors(scope, data, status, null,
|
||||||
|
{ hdr: 'Error!', msg: 'Failed to get ' + url + '. GET status: ' + status });
|
||||||
|
});
|
||||||
|
|
||||||
|
url = GetBasePath('inventory') + '?page=1';
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.get()
|
||||||
|
.success( function(data, status, headers, config) {
|
||||||
|
inventoryCount=data.count;
|
||||||
|
scope.$emit('CountReceived');
|
||||||
|
})
|
||||||
|
.error( function(data, status, headers, config) {
|
||||||
|
ProcessErrors(scope, data, status, null,
|
||||||
|
{ hdr: 'Error!', msg: 'Failed to get ' + url + '. GET status: ' + status });
|
||||||
|
});
|
||||||
|
|
||||||
|
url = GetBasePath('inventory') + '?has_active_failures=true&page=1';
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.get()
|
||||||
|
.success( function(data, status, headers, config) {
|
||||||
|
inventoryFails=data.count;
|
||||||
|
scope.$emit('CountReceived');
|
||||||
|
})
|
||||||
|
.error( function(data, status, headers, config) {
|
||||||
|
ProcessErrors(scope, data, status, null,
|
||||||
|
{ hdr: 'Error!', msg: 'Failed to get ' + url + '. GET status: ' + status });
|
||||||
|
});
|
||||||
|
|
||||||
|
url = GetBasePath('groups') + '?page=1';
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.get()
|
||||||
|
.success( function(data, status, headers, config) {
|
||||||
|
groupCount = data.count;
|
||||||
|
scope.$emit('CountReceived');
|
||||||
|
})
|
||||||
|
.error( function(data, status, headers, config) {
|
||||||
|
ProcessErrors(scope, data, status, null,
|
||||||
|
{ hdr: 'Error!', msg: 'Failed to get ' + url + '. GET status: ' + status });
|
||||||
|
});
|
||||||
|
|
||||||
|
url = GetBasePath('groups') + '?has_active_failures=true&page=1';
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.get()
|
||||||
|
.success( function(data, status, headers, config) {
|
||||||
|
groupFails = data.count;
|
||||||
|
scope.$emit('CountReceived');
|
||||||
|
})
|
||||||
|
.error( function(data, status, headers, config) {
|
||||||
|
ProcessErrors(scope, data, status, null,
|
||||||
|
{ hdr: 'Error!', msg: 'Failed to get ' + url + '. GET status: ' + status });
|
||||||
|
});
|
||||||
|
|
||||||
|
url = GetBasePath('hosts') + '?page=1';
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.get()
|
||||||
|
.success( function(data, status, headers, config) {
|
||||||
|
hostCount = data.count;
|
||||||
|
scope.$emit('CountReceived');
|
||||||
|
})
|
||||||
|
.error( function(data, status, headers, config) {
|
||||||
|
ProcessErrors(scope, data, status, null,
|
||||||
|
{ hdr: 'Error!', msg: 'Failed to get ' + url + '. GET status: ' + status });
|
||||||
|
});
|
||||||
|
|
||||||
|
url = GetBasePath('hosts') + '?has_active_failures=true&page=1';
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.get()
|
||||||
|
.success( function(data, status, headers, config) {
|
||||||
|
hostFails = data.count;
|
||||||
|
scope.$emit('CountReceived');
|
||||||
|
})
|
||||||
|
.error( function(data, status, headers, config) {
|
||||||
|
ProcessErrors(scope, data, status, null,
|
||||||
|
{ hdr: 'Error!', msg: 'Failed to get ' + url + '. GET status: ' + status });
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}]);
|
||||||
@@ -9,7 +9,8 @@
|
|||||||
|
|
||||||
@black: #171717;
|
@black: #171717;
|
||||||
@warning: #FF9900;
|
@warning: #FF9900;
|
||||||
@red: #da4f49;;
|
@red: #da4f49;
|
||||||
|
@red-hover: #AE3F3A;
|
||||||
@green: #5bb75b;
|
@green: #5bb75b;
|
||||||
@blue: #1778c3; /* logo blue */
|
@blue: #1778c3; /* logo blue */
|
||||||
@blue-link: #0088cc;
|
@blue-link: #0088cc;
|
||||||
@@ -1175,6 +1176,17 @@ tr td button i {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Home page */
|
||||||
|
|
||||||
|
.failed-column {
|
||||||
|
a:link, a:visited {
|
||||||
|
color: @red;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: @red-hover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Large desktop */
|
/* Large desktop */
|
||||||
|
|
||||||
|
|||||||
@@ -108,7 +108,7 @@
|
|||||||
<script src="{{ STATIC_URL }}js/helpers/Projects.js"></script>
|
<script src="{{ STATIC_URL }}js/helpers/Projects.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/helpers/Users.js"></script>
|
<script src="{{ STATIC_URL }}js/helpers/Users.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/helpers/Jobs.js"></script>
|
<script src="{{ STATIC_URL }}js/helpers/Jobs.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/widgets/ObjectCount.js"></script>
|
<script src="{{ STATIC_URL }}js/widgets/JobStatus.js"></script>
|
||||||
|
|
||||||
<script src="{{ STATIC_URL }}lib/less/less-1.4.1.min.js"></script>
|
<script src="{{ STATIC_URL }}lib/less/less-1.4.1.min.js"></script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user