Connected inventory detail page to socket.io and removed refresh button.

This commit is contained in:
Chris Houseknecht
2014-04-22 02:57:35 -04:00
parent 0b0207e20e
commit bbab019567
7 changed files with 125 additions and 65 deletions

View File

@@ -471,11 +471,11 @@ InventoriesAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log
function InventoriesEdit($scope, $location, $routeParams, $compile, GenerateList, ClearScope, InventoryGroups, InventoryHosts, BuildTree, Wait, function InventoriesEdit($scope, $location, $routeParams, $compile, $log, GenerateList, ClearScope, InventoryGroups, InventoryHosts, BuildTree, Wait,
GetSyncStatusMsg, InjectHosts, HostsReload, GroupsEdit, GroupsDelete, Breadcrumbs, LoadBreadCrumbs, Empty, Rest, ProcessErrors, GetSyncStatusMsg, InjectHosts, HostsReload, GroupsEdit, GroupsDelete, Breadcrumbs, LoadBreadCrumbs, Empty, Rest, ProcessErrors,
InventoryUpdate, Alert, ToggleChildren, ViewUpdateStatus, GroupsCancelUpdate, Find, EditInventoryProperties, HostsEdit, InventoryUpdate, Alert, ToggleChildren, ViewUpdateStatus, GroupsCancelUpdate, Find, EditInventoryProperties, HostsEdit,
HostsDelete, ToggleHostEnabled, CopyMoveGroup, CopyMoveHost, Stream, GetBasePath, ShowJobSummary, ApplyEllipsis, WatchInventoryWindowResize, HostsDelete, ToggleHostEnabled, CopyMoveGroup, CopyMoveHost, Stream, GetBasePath, ShowJobSummary, ApplyEllipsis, WatchInventoryWindowResize,
HelpDialog, InventoryGroupsHelp, Store, ViewJob) { HelpDialog, InventoryGroupsHelp, Store, ViewJob, Socket) {
ClearScope(); ClearScope();
@@ -643,6 +643,38 @@ function InventoriesEdit($scope, $location, $routeParams, $compile, GenerateList
} }
}; };
if ($scope.removeWatchUpdateStatus) {
$scope.removeWatchUpdateStatus();
}
$scope.removeWatchUpdateStatus = $scope.$on('WatchUpdateStatus', function(e, job_id, group_id, tree_id) {
var io = Socket({ scope: $scope, endpoint: "jobs" }),
group = Find({ list: $scope.groups, key: 'id', val: tree_id }),
stat;
$log.debug('Watching for updates to job: ' + job_id + ' for group: ' + group_id + ' ' + group.name);
io.init();
io.on("status_changed", function(data) {
Wait('stop');
if (data.status === "failed" || data.status === "successful") {
$log.debug('Update completed. Refreshing the tree.');
$scope.refreshGroups(tree_id, group_id);
}
else {
$log.debug('Status changed to: ' + data.status);
stat = GetSyncStatusMsg({
status: data.status,
has_inventory_sources: group.has_inventory_sources,
source: group.source
});
$log.debug('changing tooltip to: ' + stat.tooltip);
group.status = data.status;
group.status_class = stat['class'];
group.status_tooltip = stat.tooltip;
group.launch_tooltip = stat.launch_tip;
group.launch_class = stat.launch_class;
}
});
});
$scope.createGroup = function () { $scope.createGroup = function () {
GroupsEdit({ GroupsEdit({
scope: $scope, scope: $scope,
@@ -813,10 +845,10 @@ function InventoriesEdit($scope, $location, $routeParams, $compile, GenerateList
} }
InventoriesEdit.$inject = ['$scope', '$location', '$routeParams', '$compile', 'GenerateList', 'ClearScope', 'InventoryGroups', 'InventoryHosts', InventoriesEdit.$inject = ['$scope', '$location', '$routeParams', '$compile', '$log', 'GenerateList', 'ClearScope', 'InventoryGroups', 'InventoryHosts',
'BuildTree', 'Wait', 'GetSyncStatusMsg', 'InjectHosts', 'HostsReload', 'GroupsEdit', 'GroupsDelete', 'Breadcrumbs', 'BuildTree', 'Wait', 'GetSyncStatusMsg', 'InjectHosts', 'HostsReload', 'GroupsEdit', 'GroupsDelete', 'Breadcrumbs',
'LoadBreadCrumbs', 'Empty', 'Rest', 'ProcessErrors', 'InventoryUpdate', 'Alert', 'ToggleChildren', 'ViewUpdateStatus', 'GroupsCancelUpdate', 'LoadBreadCrumbs', 'Empty', 'Rest', 'ProcessErrors', 'InventoryUpdate', 'Alert', 'ToggleChildren', 'ViewUpdateStatus', 'GroupsCancelUpdate',
'Find', 'EditInventoryProperties', 'HostsEdit', 'HostsDelete', 'ToggleHostEnabled', 'CopyMoveGroup', 'CopyMoveHost', 'Find', 'EditInventoryProperties', 'HostsEdit', 'HostsDelete', 'ToggleHostEnabled', 'CopyMoveGroup', 'CopyMoveHost',
'Stream', 'GetBasePath', 'ShowJobSummary', 'ApplyEllipsis', 'WatchInventoryWindowResize', 'HelpDialog', 'InventoryGroupsHelp', 'Store', 'Stream', 'GetBasePath', 'ShowJobSummary', 'ApplyEllipsis', 'WatchInventoryWindowResize', 'HelpDialog', 'InventoryGroupsHelp', 'Store',
'ViewJob' 'ViewJob', 'Socket'
]; ];

View File

@@ -46,7 +46,7 @@ function JobDetailController ($scope, $compile, $routeParams, ClearScope, Breadc
} }
}); });
return results; return results;
} };
// Reduce an array of objects down to just the bits we want from each object by // Reduce an array of objects down to just the bits we want from each object by
// passing in a function that returns just those parts. // passing in a function that returns just those parts.
@@ -59,7 +59,7 @@ function JobDetailController ($scope, $compile, $routeParams, ClearScope, Breadc
results.push(parameterFunction(row)); results.push(parameterFunction(row));
}); });
return results; return results;
} };
// Apply each event to the view // Apply each event to the view
@@ -67,8 +67,6 @@ function JobDetailController ($scope, $compile, $routeParams, ClearScope, Breadc
scope.removeEventsReady(); scope.removeEventsReady();
} }
scope.removeEventsReady = scope.$on('EventsReady', function(e, events) { scope.removeEventsReady = scope.$on('EventsReady', function(e, events) {
console.log('Inside EventsReady!');
console.log(events);
DigestEvents({ DigestEvents({
scope: scope, scope: scope,
events: events events: events
@@ -78,17 +76,14 @@ function JobDetailController ($scope, $compile, $routeParams, ClearScope, Breadc
event_socket.on("job_events-" + job_id, function(data) { event_socket.on("job_events-" + job_id, function(data) {
var matches; var matches;
data.id = data.event_id; data.id = data.event_id;
console.log(data);
if (api_complete) { if (api_complete) {
matches = processed_events.find(function(x) { return x === data.id }); matches = processed_events.find(function(x) { return x === data.id; });
if (matches.length === 0) { if (matches.length === 0) {
// event not processed // event not processed
console.log('process event: ' + data.id);
scope.$emit('EventsReady', [ data ]); scope.$emit('EventsReady', [ data ]);
} }
} }
else { else {
console.log('queue event: ' + data.id);
event_queue.push(data); event_queue.push(data);
} }
}); });
@@ -113,8 +108,6 @@ function JobDetailController ($scope, $compile, $routeParams, ClearScope, Breadc
}); });
return (!matched); //return true when event.id not in the list of processed_events return (!matched); //return true when event.id not in the list of processed_events
}); });
console.log('processing queued events: ');
console.log(events.reduce(function(x) { return x.id }));
if (events.length > 0) { if (events.length > 0) {
scope.$emit('EventsReady', events); scope.$emit('EventsReady', events);
api_complete = true; api_complete = true;
@@ -133,7 +126,7 @@ function JobDetailController ($scope, $compile, $routeParams, ClearScope, Breadc
Rest.setUrl(next); Rest.setUrl(next);
Rest.get() Rest.get()
.success(function(data) { .success(function(data) {
processed_events = processed_events.concat( data.results.reduce(function(x) { return x.id }) ); processed_events = processed_events.concat( data.results.reduce(function(x) { return x.id; }) );
scope.$emit('EventsReady', data.results); scope.$emit('EventsReady', data.results);
if (data.next) { if (data.next) {
scope.$emit('JobReady', data.next); scope.$emit('JobReady', data.next);

View File

@@ -137,7 +137,6 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
has_inventory_sources = params.has_inventory_sources, has_inventory_sources = params.has_inventory_sources,
launch_class = '', launch_class = '',
launch_tip = 'Start sync process', launch_tip = 'Start sync process',
stat, stat_class, status_tip; stat, stat_class, status_tip;
stat = status; stat = status;
@@ -157,14 +156,25 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
status_tip = 'Cloud source not configured. Click <i class="fa fa-pencil"></i> to update.'; status_tip = 'Cloud source not configured. Click <i class="fa fa-pencil"></i> to update.';
launch_tip = 'Cloud source not configured.'; launch_tip = 'Cloud source not configured.';
break; break;
case 'canceled':
status_tip = 'Sync canceled. Click to view log.';
break;
case 'failed': case 'failed':
status_tip = 'Sync failed. Click to view log.'; status_tip = 'Sync failed. Click to view log.';
break; break;
case 'successful': case 'successful':
status_tip = 'Sync completed. Click to view log.'; status_tip = 'Sync completed. Click to view log.';
break; break;
case 'pending':
status_tip = 'Sync pending.';
launch_class = "btn-disabled";
launch_tip = "Sync pending";
break;
case 'updating': case 'updating':
status_tip = 'Sync running'; case 'running':
launch_class = "btn-disabled";
launch_tip = "Sync running";
status_tip = "Sync running. Click to view log.";
break; break;
} }
@@ -268,13 +278,11 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
Rest.post() Rest.post()
.success(function () { .success(function () {
Wait('stop'); Wait('stop');
Alert('Inventory Sync Cancelled', 'Request to cancel the sync process was submitted to the task manger. ' + //Alert('Inventory Sync Cancelled', 'Request to cancel the sync process was submitted to the task manger. ' +
'Click the <i class="fa fa-refresh fa-lg"></i> button to monitor the status.', 'alert-info'); // 'Click the <i class="fa fa-refresh fa-lg"></i> button to monitor the status.', 'alert-info');
}) })
.error(function (data, status) { .error(function (data, status) {
Wait('stop'); ProcessErrors(scope, data, status, null, { hdr: 'Error!',
ProcessErrors(scope, data, status, null, {
hdr: 'Error!',
msg: 'Call to ' + url + ' failed. POST status: ' + status msg: 'Call to ' + url + ' failed. POST status: ' + status
}); });
}); });
@@ -292,16 +300,17 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
.success(function (data) { .success(function (data) {
if (data.can_cancel) { if (data.can_cancel) {
scope.$emit('CancelUpdate', url); scope.$emit('CancelUpdate', url);
} else { //} else {
// Wait('stop');
// Alert('Cancel Inventory Sync', 'The sync process completed. Click the <i class="fa fa-refresh fa-lg"></i> button to view ' +
// 'the latest status.', 'alert-info');
}
else {
Wait('stop'); Wait('stop');
Alert('Cancel Inventory Sync', 'The sync process completed. Click the <i class="fa fa-refresh fa-lg"></i> button to view ' +
'the latest status.', 'alert-info');
} }
}) })
.error(function (data, status) { .error(function (data, status) {
Wait('stop'); ProcessErrors(scope, data, status, null, { hdr: 'Error!',
ProcessErrors(scope, data, status, null, {
hdr: 'Error!',
msg: 'Call to ' + url + ' failed. GET status: ' + status msg: 'Call to ' + url + ' failed. GET status: ' + status
}); });
}); });
@@ -323,17 +332,11 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
scope.$emit('CheckCancel', data.related.last_update, data.related.current_update); scope.$emit('CheckCancel', data.related.last_update, data.related.current_update);
}) })
.error(function (data, status) { .error(function (data, status) {
Wait('stop'); ProcessErrors(scope, data, status, null, { hdr: 'Error!',
ProcessErrors(scope, data, status, null, {
hdr: 'Error!',
msg: 'Call to ' + group.related.inventory_source + ' failed. GET status: ' + status msg: 'Call to ' + group.related.inventory_source + ' failed. GET status: ' + status
}); });
}); });
} else {
Alert('Cancel Inventory Sync', 'The sync process completed. Click the <i class="fa fa-refresh fa-lg"></i> to' +
' view the latest status.', 'alert-info');
} }
}; };
} }
]) ])

View File

@@ -40,9 +40,8 @@
angular.module('JobDetailHelper', ['Utilities', 'RestServices']) angular.module('JobDetailHelper', ['Utilities', 'RestServices'])
.factory('DigestEvents', ['UpdatePlayStatus', 'UpdatePlayNoHostsMatched', 'UpdateHostStatus', 'UpdatePlayChild', 'AddHostResult', 'SelectPlay', 'SelectTask', .factory('DigestEvents', ['UpdatePlayStatus', 'UpdatePlayNoHostsMatched', 'UpdateHostStatus', 'UpdatePlayChild', 'AddHostResult', 'SelectPlay', 'SelectTask',
'GetHostCount', 'GetElapsed', 'UpdateJobStatus', 'GetHostCount', 'GetElapsed',
function(UpdatePlayStatus, UpdatePlayNoHostsMatched, UpdateHostStatus, UpdatePlayChild, AddHostResult, SelectPlay, SelectTask, GetHostCount, GetElapsed, function(UpdatePlayStatus, UpdatePlayNoHostsMatched, UpdateHostStatus, UpdatePlayChild, AddHostResult, SelectPlay, SelectTask, GetHostCount, GetElapsed) {
UpdateJobStatus) {
return function(params) { return function(params) {
var scope = params.scope, var scope = params.scope,
@@ -338,11 +337,11 @@ function(UpdatePlayStatus, UpdatePlayNoHostsMatched, UpdateHostStatus, UpdatePla
return function(params) { return function(params) {
var scope = params.scope, var scope = params.scope,
failed = params.failed, failed = params.failed,
modified = params.modified; modified = params.modified,
started = params.started; started = params.started;
if (failed && scope.job_status.status !== 'failed' && scope.job_status.status !== 'error' if (failed && scope.job_status.status !== 'failed' && scope.job_status.status !== 'error' &&
&& scope.job_status.status !== 'canceled') { scope.job_status.status !== 'canceled') {
scope.job_status.status = 'error'; scope.job_status.status = 'error';
} }
if (!Empty(modified)) { if (!Empty(modified)) {
@@ -352,13 +351,10 @@ function(UpdatePlayStatus, UpdatePlayNoHostsMatched, UpdateHostStatus, UpdatePla
scope.job_status.started = started; scope.job_status.started = started;
} }
if (!Empty(scope.job_status.finished) && !Empty(scope.job_status.started)) { if (!Empty(scope.job_status.finished) && !Empty(scope.job_status.started)) {
console.log('scope.job_status.started: ' + scope.job_status.started);
console.log('scope.job_status.finished: ' + scope.job_status.finished);
scope.job_status.elapsed = GetElapsed({ scope.job_status.elapsed = GetElapsed({
start: scope.job_status.started, start: scope.job_status.started,
end: scope.job_status.finished end: scope.job_status.finished
}); });
console.log('elapsed: ' + scope.job_status.elapsed);
} }
}; };
}]) }])
@@ -385,11 +381,11 @@ function(UpdatePlayStatus, UpdatePlayNoHostsMatched, UpdateHostStatus, UpdatePla
start: play.created, start: play.created,
end: modified end: modified
}); });
/*UpdateJobStatus({ UpdateJobStatus({
scope: scope, scope: scope,
failed: failed, failed: failed,
modified: modified modified: modified
});*/ });
return false; return false;
} }
return true; return true;

View File

@@ -20,8 +20,8 @@ angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'Credential
Wait('start'); Wait('start');
Rest.setUrl(url); Rest.setUrl(url);
Rest.post(passwords) Rest.post(passwords)
.success(function () { .success(function(data) {
scope.$emit(callback); scope.$emit(callback, data);
}) })
.error(function (data, status) { .error(function (data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!', ProcessErrors(scope, data, status, null, { hdr: 'Error!',
@@ -445,10 +445,10 @@ function($location, Wait, GetBasePath, LookUpInit, JobTemplateForm, CredentialLi
url = params.url, url = params.url,
group_id = params.group_id, group_id = params.group_id,
tree_id = params.tree_id, tree_id = params.tree_id,
base = $location.path().replace(/^\//, '').split('/')[0], //base = $location.path().replace(/^\//, '').split('/')[0],
inventory_source; inventory_source;
if (scope.removeHostReloadComplete) { /*if (scope.removeHostReloadComplete) {
scope.removeHostReloadComplete(); scope.removeHostReloadComplete();
} }
scope.removeHostReloadComplete = scope.$on('HostReloadComplete', function () { scope.removeHostReloadComplete = scope.$on('HostReloadComplete', function () {
@@ -458,13 +458,44 @@ function($location, Wait, GetBasePath, LookUpInit, JobTemplateForm, CredentialLi
if (scope.removeHostReloadComplete) { if (scope.removeHostReloadComplete) {
scope.removeHostReloadComplete(); scope.removeHostReloadComplete();
} }
}); });*/
function getJobID(url) {
var result='';
url.split(/\//).every(function(path) {
if (/^\d+$/.test(path)) {
result = path;
return false;
}
return true;
});
return result;
}
if (scope.removeUpdateSubmitted) { if (scope.removeUpdateSubmitted) {
scope.removeUpdateSubmitted(); scope.removeUpdateSubmitted();
} }
scope.removeUpdateSubmitted = scope.$on('UpdateSubmitted', function () { scope.removeUpdateSubmitted = scope.$on('UpdateSubmitted', function () {
setTimeout(function() { // Get the current job
var path = url.replace(/update\/$/,'');
Rest.setUrl(path);
Rest.get()
.success(function(data) {
if (data.related.current_job) {
scope.$emit('WatchUpdateStatus', getJobID(data.related.current_job), group_id, tree_id);
}
else {
Wait('stop');
}
})
.error(function(data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed to get inventory source ' + url + ' GET returned: ' + status });
});
//console.log('job submitted. callback returned: ');
//console.log(data);
/*setTimeout(function() {
if (base === 'jobs') { if (base === 'jobs') {
scope.refreshJobs(); scope.refreshJobs();
} }
@@ -476,7 +507,7 @@ function($location, Wait, GetBasePath, LookUpInit, JobTemplateForm, CredentialLi
scope.refresh(); scope.refresh();
} }
scope.$emit('HostReloadComplete'); scope.$emit('HostReloadComplete');
}, 300); }, 300);*/
}); });
if (scope.removePromptForPasswords) { if (scope.removePromptForPasswords) {

View File

@@ -51,11 +51,11 @@ angular.module('InventoryGroupsDefinition', [])
awToolTip: "Edit inventory properties", awToolTip: "Edit inventory properties",
ngClick: 'editInventoryProperties()' ngClick: 'editInventoryProperties()'
}, },
refresh: { /*refresh: {
mode: 'all', mode: 'all',
awToolTip: "Refresh the page", awToolTip: "Refresh the page",
ngClick: "refreshGroups()" ngClick: "refreshGroups()"
}, },*/
stream: { stream: {
ngClick: "showGroupActivity()", ngClick: "showGroupActivity()",
awToolTip: "View Activity Stream", awToolTip: "View Activity Stream",
@@ -75,9 +75,9 @@ angular.module('InventoryGroupsDefinition', [])
ngClick: "viewUpdateStatus(group.id, group.group_id)", ngClick: "viewUpdateStatus(group.id, group.group_id)",
ngShow: "group.id > 1", // hide for all hosts ngShow: "group.id > 1", // hide for all hosts
awToolTip: "{{ group.status_tooltip }}", awToolTip: "{{ group.status_tooltip }}",
dataTipWatch: "group.launch_tooltip", dataTipWatch: "group.status_tooltip",
iconClass: "{{ 'fa icon-cloud-' + group.status_class }}", iconClass: "{{ 'fa icon-cloud-' + group.status_class }}",
ngClass: "group.launch_class", ngClass: "group.status_class",
dataPlacement: "top" dataPlacement: "top"
}, },
failed_hosts: { failed_hosts: {

View File

@@ -1126,7 +1126,9 @@ input[type="checkbox"].checkbox-no-label {
.icon-cloud-updating:before, .icon-cloud-updating:before,
.icon-cloud-running:before, .icon-cloud-running:before,
.icon-cloud-successful:before, .icon-cloud-successful:before,
.icon-cloud-pending:before,
.icon-cloud-failed:before, .icon-cloud-failed:before,
.icon-cloud-canceled:before,
.icon-cloud-error:before { .icon-cloud-error:before {
content: "\f0c2"; content: "\f0c2";
} }
@@ -1146,6 +1148,7 @@ input[type="checkbox"].checkbox-no-label {
.icon-cloud-updating, .icon-cloud-updating,
.icon-cloud-running, .icon-cloud-running,
.icon-cloud-successful, .icon-cloud-successful,
.icon-cloud-pending,
a.icon-cloud-updating:hover, a.icon-cloud-updating:hover,
a.icon-cloud-successful:hover { a.icon-cloud-successful:hover {
color: @green; color: @green;
@@ -1153,12 +1156,14 @@ input[type="checkbox"].checkbox-no-label {
.icon-cloud-failed, .icon-cloud-failed,
.icon-cloud-error, .icon-cloud-error,
.icon-cloud-canceled,
a.icon-cloud-failed:hover { a.icon-cloud-failed:hover {
color: @red; color: @red;
} }
.icon-cloud-updating, .icon-cloud-updating,
.icon-cloud-running { .icon-cloud-running,
.icon-cloud-pending {
.pulsate(); .pulsate();
} }