diff --git a/modules/monitoring/application/views/scripts/show/service.phtml b/modules/monitoring/application/views/scripts/show/service.phtml index 9f21e98e0..fdf2fa5b3 100644 --- a/modules/monitoring/application/views/scripts/show/service.phtml +++ b/modules/monitoring/application/views/scripts/show/service.phtml @@ -2,7 +2,7 @@ render('show/components/header.phtml') ?>

This service's current state

-
+
render('show/components/output.phtml') ?> diff --git a/public/js/icinga/events.js b/public/js/icinga/events.js index 681e9ec1a..37a8551ff 100644 --- a/public/js/icinga/events.js +++ b/public/js/icinga/events.js @@ -28,7 +28,7 @@ var icinga = this.icinga; $('.dashboard > div', el).each(function(idx, el) { - var url = $(el).attr('data-icinga-url'); + var url = $(el).data('icingaUrl'); if (typeof url === 'undefined') return; icinga.loader.loadUrl(url, $(el)).autorefresh = true; }); @@ -37,13 +37,14 @@ $('table.action tr', el).each(function(idx, el) { var $a = $('a[href]', el).first(); if ($a.length) { + // TODO: Find out whether we leak memory on IE with this: $(el).attr('href', $a.attr('href')); } }); $('.icinga-module', el).each(function(idx, mod) { var $mod = $(mod); - var moduleName = $mod.data('icinga-module'); + var moduleName = $mod.data('icingaModule'); if (icinga.hasModule(moduleName)) { var module = icinga.module(moduleName); // NOT YET, the applyOnloadDings: module.applyEventHandlers(mod); @@ -134,7 +135,7 @@ // .closest is not required unless subelements to trigger this var $form = $(event.currentTarget).closest('form'); - var url = $form.attr('action'); + var url = $form.attr('action').replace('&', '&'); // WHY?? var method = $form.attr('method'); var $target; var data = $form.serializeArray(); @@ -244,6 +245,9 @@ // ...the only exception are class="action" tables... if ($el.closest('table.action').length) { + if ($el.closest('#col2').length) { + this.icinga.ui.moveToLeft(); + } $target = $('#col2'); } @@ -253,6 +257,9 @@ // Simulate _next to prepare migration to dynamic column layout if (targetId === '_next') { + if ($el.closest('#col2').length) { + this.icinga.ui.moveToLeft(); + } targetId = 'col2'; } diff --git a/public/js/icinga/loader.js b/public/js/icinga/loader.js index 9795f0431..0b40d4718 100644 --- a/public/js/icinga/loader.js +++ b/public/js/icinga/loader.js @@ -45,7 +45,7 @@ * @param {object} data Optional parameters, usually for POST requests * @param {string} method HTTP method, default is 'GET' */ - loadUrl: function (url, $target, data, method) { + loadUrl: function (url, $target, data, method, autorefresh = false) { var id = null; // Default method is GET @@ -60,18 +60,11 @@ id = $target.attr('id'); } - if (typeof $target !== 'undefined') { - // TODO: We shouldn't use data but keep this information somewhere else. - if ($target.data('icingaUrl') !== url) { - $target.removeAttr('data-icinga-url'); - $target.removeAttr('data-icinga-refresh'); - $target.removeData('icingaUrl'); - $target.removeData('icingaRefresh'); - } - } - // If we have a pending request for the same target... if (id in this.requests) { + if (autorefresh) { + return false; + } // ...ignore the new request if it is already pending with the same URL if (this.requests[id].url === url) { this.icinga.logger.debug('Request to ', url, ' is already running for ', $target); @@ -113,7 +106,7 @@ req.fail(this.onFailure); req.complete(this.onComplete); req.historyTriggered = false; - req.autorefresh = false; + req.autorefresh = autorefresh; if (id) { this.requests[id] = req; } @@ -144,17 +137,21 @@ } }, + filterAutorefreshingContainers: function () { + return $(this).data('icingaRefresh') > 0; + }, + autorefresh: function () { var self = this; if (self.autorefreshEnabled !== true) { return; } - $('.container[data-icinga-refresh]').each(function (idx, el) { + $('.container').filter(this.filterAutorefreshingContainers).each(function (idx, el) { var $el = $(el); var id = $el.attr('id'); if (id in self.requests) { - self.icinga.logger.debug('No refresh, request pending', id); + self.icinga.logger.debug('No refresh, request pending for ', id); return; } @@ -185,10 +182,15 @@ return; } - self.icinga.logger.info( - 'Autorefreshing ' + id + ' ' + interval + ' ms passed' - ); - self.loadUrl($el.data('icingaUrl'), $el).autorefresh = true; + if (self.loadUrl($el.data('icingaUrl'), $el, undefined, undefined, true) === false) { + self.icinga.logger.debug( + 'NOT autorefreshing ' + id + ', even if ' + interval + ' ms passed. Request pending?' + ); + } else { + self.icinga.logger.debug( + 'Autorefreshing ' + id + ' ' + interval + ' ms passed' + ); + } el = null; }); }, @@ -287,6 +289,17 @@ newBody = true; } + var moduleName = req.getResponseHeader('X-Icinga-Module'); + if (moduleName) { + req.$target.addClass('icinga-module'); + req.$target.data('icingaModule', moduleName); + req.$target.addClass('module-' + moduleName); + } else { + req.$target.removeClass('icinga-module'); + req.$target.removeData('icingaModule'); + req.$target.attr('class', 'container'); // TODO: remove module-$name + } + var title = req.getResponseHeader('X-Icinga-Title'); if (title && req.$target.closest('.dashboard').length === 0) { this.icinga.ui.setTitle(title); @@ -295,13 +308,9 @@ var refresh = req.getResponseHeader('X-Icinga-Refresh'); if (refresh) { // Hmmmm... .data() doesn't work here? - req.$target.attr('data-icinga-refresh', refresh); - req.$target.attr('data-last-update', (new Date()).getTime()); req.$target.data('lastUpdate', (new Date()).getTime()); req.$target.data('icingaRefresh', refresh); } else { - req.$target.removeAttr('data-icinga-refresh'); - req.$target.removeAttr('data-last-update'); req.$target.removeData('icingaRefresh'); req.$target.removeData('lastUpdate'); } @@ -342,7 +351,6 @@ return; } - req.$target.attr('data-icinga-url', req.url); req.$target.data('icingaUrl', req.url); // Update history when necessary. Don't do so for requests triggered diff --git a/public/js/icinga/ui.js b/public/js/icinga/ui.js index 8056a0d4f..ff43be353 100644 --- a/public/js/icinga/ui.js +++ b/public/js/icinga/ui.js @@ -40,7 +40,7 @@ .fadeOut('slow', function() { icinga.ui.fixControls(); - this.remove(); + $(this).remove(); }); }, @@ -91,17 +91,35 @@ return this; }, - flipContent: function () { - var col1 = $('#col1 > div').detach(); - var col2 = $('#col2 > div').detach(); - $('#col2').html(''); - $('#col1').html(''); - - col1.appendTo('#col2'); - col2.appendTo('#col1'); + moveToLeft: function () { + var col2 = this.cutContainer($('#col2')); + var kill = this.cutContainer($('#col1')); + this.pasteContainer($('#col1'), col2); this.fixControls(); }, + cutContainer: function ($col) { + return { + 'elements': $('#' + $col.attr('id') + ' > div').detach(), + 'data': { + 'data-icinga-url': $col.data('icingaUrl'), + 'data-icinga-refresh': $col.data('icingaRefresh'), + 'data-last-update': $col.data('lastUpdate'), + 'data-icinga-module': $col.data('icingaModule') + }, + 'class': $col.attr('class') + } + }, + + pasteContainer: function ($col, backup) { + backup['elements'].appendTo($col); + $col.attr('class', backup['class']); // TODO: ie memleak? remove first? + $col.data('icingaUrl', backup['data']['data-icinga-url']); + $col.data('icingaRefresh', backup['data']['data-icinga-refresh']); + $col.data('lastUpdate', backup['data']['data-last-update']); + $col.data('icingaModule', backup['data']['data-icinga-module']); + }, + triggerWindowResize: function () { this.onWindowResize({data: {self: this}}); }, @@ -136,7 +154,7 @@ $('#layout').removeClass(this.currentLayout + '-layout').addClass(layout); this.currentLayout = matched[1]; if (this.currentLayout === 'poor' || this.currentLayout === 'minimal') { - this.icinga.events.layout1col(); + this.layout1col(); } return true; } @@ -155,10 +173,10 @@ var $col2 = $('#col2'); icinga.logger.debug('Switching to single col'); $('#layout').removeClass('twocols'); - $col2.removeAttr('data-icinga-url'); - $col2.removeAttr('data-icinga-refresh'); $col2.removeData('icingaUrl'); $col2.removeData('icingaRefresh'); + $col2.removeData('lastUpdate'); + $col2.removeData('icingaModule'); this.icinga.loader.stopPendingRequestsFor($col2); $col2.html(''); this.fixControls();