Merge pull request #3959 from Icinga/feature/asynchronous-content-updates-3953

Asynchronous Content Updates
This commit is contained in:
Johannes Meyer 2019-09-25 14:16:38 +02:00 committed by GitHub
commit ae013723ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 67 additions and 47 deletions

View File

@ -399,22 +399,6 @@
} }
}, },
cacheLoadedIcons: function($container) {
// TODO: this is just a prototype, disabled for now
return;
var _this = this;
$('img.icon', $container).each(function(idx, img) {
var src = $(img).attr('src');
if (typeof _this.iconCache[src] !== 'undefined') {
return;
}
var cache = new Image();
cache.src = src
_this.iconCache[src] = cache;
});
},
/** /**
* Handle successful XHR response * Handle successful XHR response
*/ */
@ -445,8 +429,6 @@
_this.loadUrl(_this.url('/layout/announcements'), $('#announcements')); _this.loadUrl(_this.url('/layout/announcements'), $('#announcements'));
} }
// div helps getting an XML tree
var $resp = $('<div>' + req.responseText + '</div>');
var active = false; var active = false;
var rendered = false; var rendered = false;
var classes; var classes;
@ -521,33 +503,32 @@
} }
// Handle search requests, still hardcoded. // Handle search requests, still hardcoded.
if (req.url.match(/^\/search/) && if (req.url.match(/^\/search/) && req.$target.data('icingaUrl').match(/^\/search/)) {
req.$target.data('icingaUrl').match(/^\/search/) && var $resp = $('<div>' + req.responseText + '</div>'); // div helps getting an XML tree
$('.dashboard', $resp).length > 0 && if ($('.dashboard', $resp).length > 0 && $('.dashboard .container', req.$target).length > 0) {
$('.dashboard .container', req.$target).length > 0) // TODO: We need dashboard pane and container identifiers (not ids)
{ var targets = [];
// TODO: We need dashboard pane and container identifiers (not ids) $('.dashboard .container', req.$target).each(function (idx, el) {
var targets = []; targets.push($(el));
$('.dashboard .container', req.$target).each(function (idx, el) { });
targets.push($(el));
});
var i = 0; var i = 0;
// Searching for '.dashboard .container' in $resp doesn't dork?! // Searching for '.dashboard .container' in $resp doesn't dork?!
$('.dashboard .container', $resp).each(function (idx, el) { $('.dashboard .container', $resp).each(function (idx, el) {
var $el = $(el); var $el = $(el);
if ($el.hasClass('dashboard')) { if ($el.hasClass('dashboard')) {
return; return;
} }
var url = $el.data('icingaUrl'); var url = $el.data('icingaUrl');
targets[i].data('icingaUrl', url); targets[i].data('icingaUrl', url);
var title = $('h1', $el).first(); var title = $('h1', $el).first();
$('h1', targets[i]).first().replaceWith(title); $('h1', targets[i]).first().replaceWith(title);
_this.loadUrl(url, targets[i]); _this.loadUrl(url, targets[i]);
i++; i++;
}); });
rendered = true; rendered = true;
}
} }
var referrer = req.referrer; var referrer = req.referrer;
@ -574,15 +555,34 @@
this.icinga.timer.unregister(req.progressTimer); this.icinga.timer.unregister(req.progressTimer);
} }
// .html() removes outer div we added above var contentSeparator = req.getResponseHeader('X-Icinga-Multipart-Content');
this.renderContentToContainer($resp.html(), req.$target, req.action, req.autorefresh, req.forceFocus, autoSubmit); if (!! contentSeparator) {
$.each(req.responseText.split(contentSeparator), function (idx, el) {
var match = el.match(/for=(?<id>\S+)\s+(?<html>.*)/m);
if (!! match) {
var $target = $('#' + match.groups.id);
if ($target.length) {
_this.renderContentToContainer(
match.groups.html, $target, 'replace', req.autorefresh, req.forceFocus, autoSubmit);
} else {
_this.icinga.logger.warn(
'Invalid target ID. Cannot render multipart to #' + match.groups.id);
}
} else {
_this.icinga.logger.error('Ill-formed multipart', el);
}
})
} else {
this.renderContentToContainer(
req.responseText, req.$target, req.action, req.autorefresh, req.forceFocus, autoSubmit);
}
if (oldNotifications) { if (oldNotifications) {
oldNotifications.appendTo($('#notifications')); oldNotifications.appendTo($('#notifications'));
} }
if (newBody) { if (newBody) {
this.icinga.ui.fixDebugVisibility().triggerWindowResize(); this.icinga.ui.fixDebugVisibility().triggerWindowResize();
} }
_this.cacheLoadedIcons(req.$target);
}, },
/** /**
@ -643,6 +643,26 @@
delete this.requests[req.$target.attr('id')]; delete this.requests[req.$target.attr('id')];
this.icinga.ui.fadeNotificationsAway(); this.icinga.ui.fadeNotificationsAway();
var extraUpdates = req.getResponseHeader('X-Icinga-Extra-Updates');
if (!! extraUpdates && req.getResponseHeader('X-Icinga-Redirect-Http') !== 'yes') {
var _this = this;
$.each(extraUpdates.split(','), function (idx, el) {
var parts = el.trim().split(';');
if (parts.length !== 2) {
_this.icinga.logger.error('Invalid extra update', el);
return;
}
var $target = $('#' + parts[0]);
if (! $target.length) {
_this.icinga.logger.warn('Invalid target ID. Cannot load extra URL', el);
return;
}
_this.loadUrl(parts[1], $target).addToHistory = false;
});
}
if (this.processRedirectHeader(req)) { if (this.processRedirectHeader(req)) {
return; return;
} }

View File

@ -681,7 +681,7 @@
* This is based on the assumption that the server only knows about the menu and first column * This is based on the assumption that the server only knows about the menu and first column
* and therefore does not need to protect its ids. (As the menu is most likely part of the sidebar) * and therefore does not need to protect its ids. (As the menu is most likely part of the sidebar)
*/ */
if ($cont.attr('id') === 'menu' || $cont.attr('id') === 'col1') { if ($cont.attr('id') === 'menu' || $cont.attr('id') === 'col1' || $cont.closest('#col1').length) {
return null; return null;
} }