js: Enhance server side container closing (#5065)

* Let response header `X-Icinga-Container` either influence a request's
`$target` or `$redirectTarget`, but not both

* Issuing a `__CLOSE__` in a detail url still closes `#col2` and
refreshes `#col1`
* Issuing a `__CLOSE__` for a nested container still empties it
* Issuing a `__CLOSE__` in a modal, now refreshes the modal openers
container (now also `#col1`)
This commit is contained in:
Johannes Meyer 2023-08-11 16:07:38 +02:00 committed by GitHub
commit 243192ba93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 53 additions and 18 deletions

View File

@ -40,7 +40,7 @@
var $a = $(event.currentTarget);
var url = $a.attr('href');
var $modal = _this.$ghost.clone();
var $urlTarget = _this.icinga.loader.getLinkTargetFor($a, false);
var $redirectTarget = $a.closest('.container');
_this.modalOpener = event.currentTarget;
@ -50,8 +50,8 @@
// Add showCompact, we don't want controls in a modal
url = _this.icinga.utils.addUrlFlag(url, 'showCompact');
// Set the toggle's base target on the modal to use it as redirect target
$modal.data('redirectTarget', $urlTarget);
// Set the toggle's container to use it as redirect target
$modal.data('redirectTarget', $redirectTarget);
// Final preparations, the id is required so that it's not `display:none` anymore
$modal.attr('id', 'modal');
@ -68,7 +68,7 @@
if (req.status >= 500) {
// Yes, that's done twice (by us and by the base fail handler),
// but `renderContentToContainer` does too many useful things..
_this.icinga.loader.renderContentToContainer(req.responseText, $urlTarget, req.action);
_this.icinga.loader.renderContentToContainer(req.responseText, $redirectTarget, req.action);
} else if (req.status > 0) {
var msg = $(req.responseText).find('.error-message').text();
if (msg && msg !== errorThrown) {
@ -115,7 +115,6 @@
var req = _this.icinga.loader.submitForm($form, $autoSubmittedBy, $button);
req.addToHistory = false;
req.$redirectTarget = $modal.data('redirectTarget');
req.done(function (data, textStatus, req) {
var title = req.getResponseHeader('X-Icinga-Title');
if (!! title) {
@ -129,6 +128,10 @@
delete $modal[0].dataset.noIcingaAjax;
});
if (! ('baseTarget' in $form[0].dataset)) {
req.$redirectTarget = $modal.data('redirectTarget');
}
if (typeof $autoSubmittedBy === 'undefined') {
// otherwise the form is submitted several times by clicking the "Submit" button several times
$form.find('input[type=submit],button[type=submit],button:not([type])').prop('disabled', true);

View File

@ -565,24 +565,35 @@
return true;
} else if (redirect.match(/__CLOSE__/)) {
if (req.$redirectTarget.is('#col1')) {
if (req.$target.is('#col1') && req.$redirectTarget.is('#col1')) {
icinga.logger.warn('Cannot close #col1');
return false;
}
if (req.$redirectTarget.is('.container') && req.$redirectTarget.parent().closest('.container').length > 0) {
if (req.$redirectTarget.is('.container') && ! req.$redirectTarget.is('#main > :scope')) {
// If it is a container that is not a top level container, we just empty it
req.$redirectTarget.empty();
return true;
}
if (! req.$redirectTarget.is('#col2')) {
icinga.logger.debug('Cannot close container', req.$redirectTarget);
return false;
}
// Close right column as requested
icinga.ui.layout1col();
if (!! req.getResponseHeader('X-Icinga-Extra-Updates')) {
icinga.logger.debug('Not refreshing #col1 due to outstanding extra updates');
return true;
}
// Refresh left column and produce a new history state for it
var $col1 = $('#col1');
var col1Url = icinga.history.getCol1State();
var refresh = this.loadUrl(col1Url, $col1);
let $refreshTarget = $('#col1');
let refreshUrl = icinga.history.getCol1State();
let refresh = this.loadUrl(refreshUrl, $refreshTarget);
refresh.addToHistory = true;
refresh.scripted = true;
var _this = this;
@ -590,7 +601,7 @@
// TODO: Find a better solution than a hardcoded one
// This is still the *cheat* to get live results
// (in case there's a delay and a change is not instantly effective)
var secondRefresh = _this.loadUrl(col1Url, $col1);
var secondRefresh = _this.loadUrl(refreshUrl, $refreshTarget);
if (secondRefresh !== refresh) {
// Only change these properties if it's not still the first refresh
secondRefresh.addToHistory = false;
@ -699,6 +710,7 @@
var target = req.getResponseHeader('X-Icinga-Container');
var newBody = false;
var oldNotifications = false;
var isRedirect = !! req.getResponseHeader('X-Icinga-Redirect');
if (target) {
if (target === 'ignore') {
return;
@ -706,17 +718,26 @@
var $newTarget = this.identifyLinkTarget(target, req.$target);
if ($newTarget.length) {
// If we change the target, oncomplete will fail to clean up
if (isRedirect) {
req.$redirectTarget = $newTarget;
} else {
// If we change the target, oncomplete will fail to clean up.
// This fixes the problem, not using req.$target would be better
delete this.requests[req.$target.attr('id')];
req.$target = $newTarget;
req.$redirectTarget = $newTarget;
}
if (target === 'layout') {
oldNotifications = $('#notifications li').detach();
this.icinga.ui.layout1col();
newBody = true;
} else if ($newTarget.attr('id') === 'col2') {
if (_this.icinga.ui.isOneColLayout()) {
_this.icinga.ui.layout2col();
} else if (target === '_next') {
_this.icinga.ui.moveToLeft();
}
}
}
}
@ -735,7 +756,7 @@
this.icinga.ui.reloadCss();
}
if (req.getResponseHeader('X-Icinga-Redirect')) {
if (isRedirect) {
return;
}
@ -993,7 +1014,18 @@
return;
}
if (url === '__CLOSE__') {
if ($target.is('#col2')) {
_this.icinga.ui.layout1col();
} else if ($target.is('#main > :scope')) {
_this.icinga.logger.warn('Invalid target ID. Cannot close ', $target);
} else if ($target.is('.container')) {
// If it is a container that is not a top level container, we just empty it
$target.empty();
}
} else {
_this.loadUrl(url, $target).addToHistory = false;
}
});
}