Files
iTop/js/layouts/object/object-details.js

133 lines
4.4 KiB
JavaScript

/*
* @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
;
$(function()
{
// the widget definition, where 'itop' is the namespace,
// 'object_details' the widget name
$.widget( 'itop.object_details', $.itop.panel,
{
// default options
options:
{
},
css_classes:
{
},
js_selectors:
{
},
// the constructor
_create: function()
{
this._super();
this._initializeSubmittingButtonsObserver();
},
// events bound via _bind are removed automatically
// revert other modifications here
_destroy: function()
{
this._super();
},
_bindEvents: function ()
{
this._super();
// Keep URL's hash parameters when clicking on a link of the header
// Note: ":first" used to only target the header of the object, not what could be in the content of its body
this.element.on('click', '[data-role="ibo-panel--header-right"]:first a', function() {
aMatches = /#(.*)$/.exec(window.location.href);
if (aMatches != null) {
currentHash = aMatches[1];
if (/#(.*)$/.test(this.href)) {
this.href = this.href.replace(/#(.*)$/, '#'+currentHash);
}
}
});
},
/**
* Initialize the observer on the submitting buttons (cancel, apply, transitions, ...) to display only the grouped button depending on the available space
* @private
*/
_initializeSubmittingButtonsObserver: function()
{
// This only applies in edit mode
if (this._getObjectMode() !== 'edit') {
return false;
}
// If no ResizeObserver, fallback is that transition buttons will overflow on smaller screen
if (window.ResizeObserver === undefined) {
return false;
}
// Check if transitions available
const oHeaderElem = this.element.find('[data-role="ibo-panel--header"]:first');
const oButtonsToolbarElem = oHeaderElem.find('[data-role="ibo-panel--header-right"] [data-role="ibo-toolbar"]');
const oTransitionButtonsElems = oButtonsToolbarElem.find('[name="next_action"][data-role="ibo-button"]');
if (oHeaderElem.find('[name="next_action"][data-role="ibo-button"]').length === 0) {
return false;
}
let iCurrentHeaderWidth = 0;
let iCurrentHeaderHeight = 0;
let hTimeout = null;
const oObserver = new ResizeObserver(function(aEntries) {
// Throttle the processing in order to limit CPU usage
clearTimeout(hTimeout);
hTimeout = setTimeout(() => {
let iNewHeaderWidth = parseInt(oHeaderElem.outerWidth());
let iNewHeaderHeight = parseInt(oHeaderElem.outerHeight());
if (Math.abs(iNewHeaderWidth - iCurrentHeaderWidth) < 5 && Math.abs(iNewHeaderHeight - iCurrentHeaderHeight) === 0) {
return;
}
let oLastTransitionButton = oButtonsToolbarElem.find('[name="next_action"][data-role="ibo-button"]:last');
// 1. Make transition buttons invisible BUT occuping space, so we can check where the last one would be
oTransitionButtonsElems.css('visibility', 'hidden');
oTransitionButtonsElems.removeClass('ibo-is-hidden');
// 2. Measure position
let iLastTransitionButtonBorderX = parseInt(oLastTransitionButton.offset().left + oLastTransitionButton.outerWidth());
// 3. Make transition buttons invisible AND not occuping space again
oTransitionButtonsElems.addClass('ibo-is-hidden');
oTransitionButtonsElems.css('visibility', '');
let iPanelRightBorderX = parseInt(oHeaderElem.offset().left + oHeaderElem.outerWidth());
if (iLastTransitionButtonBorderX > iPanelRightBorderX) {
oButtonsToolbarElem.find('.action[data-role="ibo-button"]:not([name="cancel"])').addClass('ibo-is-hidden');
oButtonsToolbarElem.find('[data-role="ibo-button-group"]:last').removeClass('ibo-is-hidden');
}
else {
oButtonsToolbarElem.find('.action[data-role="ibo-button"]:not([name="cancel"])').removeClass('ibo-is-hidden');
oButtonsToolbarElem.find('[data-role="ibo-button-group"]:last').addClass('ibo-is-hidden');
}
iCurrentHeaderWidth = parseInt(oHeaderElem.outerWidth());
iCurrentHeaderHeight = parseInt(oHeaderElem.outerHeight());
}, 100);
});
// Note: ":first" used to only target the header of the object, not what could be in the content of its body
oObserver.observe(oHeaderElem[0]);
},
// Helpers
/**
* @return {String} The current object display mode ({@see PHP \cmdbAbstractObject for possible values})
* @private
*/
_getObjectMode: function()
{
return this.element.attr('data-object-mode');
}
});
});