mirror of
https://github.com/Icinga/icingaweb2.git
synced 2025-08-21 01:38:09 +02:00
180 lines
6.8 KiB
JavaScript
180 lines
6.8 KiB
JavaScript
/*! Icinga Web 2 | (c) 2022 Icinga GmbH | GPLv2+ */
|
|
|
|
;(function (Icinga, $) {
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* Behavior for the enhanced Icinga Web 2 dashboards
|
|
*
|
|
* @param {Icinga} icinga The current Icinga Object
|
|
*/
|
|
class Dashboard extends Icinga.EventListener {
|
|
constructor(icinga) {
|
|
super(icinga);
|
|
|
|
try {
|
|
this.Sortable = require('icinga/icinga-php-library/vendor/Sortable');
|
|
} catch (e) {
|
|
console.warn('Unable to provide Sortable. Library not available:', e);
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* Possible type of widgets this behavior is being applied to
|
|
*
|
|
* @type {object}
|
|
*/
|
|
this.widgetTypes = { Dashlet : 'Dashlets', Dashboard : 'Dashboards', DashboardHome : 'Homes' };
|
|
|
|
this.on('rendered', '#main > .container', this.onRendered, this);
|
|
// Registers the drop event for all the widget types
|
|
this.on('end', '.dashboard-settings', this.elementDropped, this);
|
|
}
|
|
|
|
/**
|
|
* Get the widget type of the given element
|
|
*
|
|
* @param {HTMLElement} target
|
|
*
|
|
* @returns {null|string}
|
|
*/
|
|
getTypeFor(target) {
|
|
if (target.matches('.dashboard-settings')) {
|
|
if (! target.querySelector('.home-list-control:first-child')) {
|
|
return this.widgetTypes.Dashboard;
|
|
}
|
|
|
|
return this.widgetTypes.DashboardHome;
|
|
} else if (target.matches('.dashboard-item-list')) {
|
|
return this.widgetTypes.Dashboard;
|
|
} else if (target.matches('.dashlet-item-list')) {
|
|
return this.widgetTypes.Dashlet;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Set up a request with the reordered widget and post the data to the controller
|
|
*
|
|
* @param event
|
|
*
|
|
* @returns {boolean}
|
|
*/
|
|
elementDropped(event) {
|
|
let _this = event.data.self,
|
|
orgEvt = event.originalEvent,
|
|
data = {};
|
|
|
|
if (orgEvt.to === orgEvt.from && orgEvt.newIndex === orgEvt.oldIndex) {
|
|
return false;
|
|
}
|
|
|
|
let item = orgEvt.item;
|
|
switch (_this.getTypeFor(orgEvt.to)) {
|
|
case _this.widgetTypes.DashboardHome: {
|
|
let home = item.dataset.icingaHome;
|
|
data[home] = orgEvt.newIndex;
|
|
break;
|
|
}
|
|
case _this.widgetTypes.Dashboard: {
|
|
let pane = item.dataset.icingaPane,
|
|
home = orgEvt.to.closest('.home-list-control, .dashboard-settings').dataset.icingaHome;
|
|
if (orgEvt.to !== orgEvt.from) {
|
|
let homeList = orgEvt.from.closest('.home-list-control, .dashboard-settings');
|
|
data.originals = {
|
|
originalHome : homeList.dataset.icingaHome,
|
|
originalPane : pane
|
|
};
|
|
}
|
|
|
|
data[home] = { [pane] : orgEvt.newIndex };
|
|
break;
|
|
}
|
|
case _this.widgetTypes.Dashlet: {
|
|
let dashlet = item.dataset.icingaDashlet;
|
|
|
|
let parent = orgEvt.to.closest('.dashboard-list-control');
|
|
let pane = parent.dataset.icingaPane;
|
|
// If there is only default home in the dashboard manager view, there won't be rendered a
|
|
// ".home-list-control", so we need to look for an alternative
|
|
let home = parent.closest('.home-list-control, .dashboard-settings').dataset.icingaHome;
|
|
|
|
if (orgEvt.to !== orgEvt.from) {
|
|
let parent = orgEvt.from.closest('.dashboard-list-control');
|
|
let orgHome = parent.closest('.home-list-control, .dashboard-settings').dataset.icingaHome;
|
|
data.originals = {
|
|
originalHome : orgHome,
|
|
originalPane : parent.dataset.icingaPane
|
|
}
|
|
}
|
|
|
|
dashlet = { [dashlet] : orgEvt.newIndex };
|
|
data[home] = { [pane] : dashlet };
|
|
}
|
|
}
|
|
|
|
if (Object.keys(data).length) {
|
|
if (! data.originals) {
|
|
data.originals = null;
|
|
}
|
|
|
|
data = { dashboardData : JSON.stringify(data) };
|
|
let url = _this.icinga.config.baseUrl + '/dashboards/reorder-widgets';
|
|
let req = _this.icinga.loader.loadUrl(url, $('#col1'), data, 'post');
|
|
|
|
req.addToHistory = false;
|
|
req.scripted = true;
|
|
}
|
|
}
|
|
|
|
onRendered(e) {
|
|
let _this = e.data.self;
|
|
|
|
if (e.currentTarget !== e.target || ! e.target.querySelector(':scope > .dashboard-manager')) {
|
|
// This is for the editor only, which has no nested .containers but a .dashboard-manager
|
|
return;
|
|
}
|
|
|
|
e.target.querySelectorAll('.dashboard-settings, .dashboard-item-list, .dashlet-item-list')
|
|
.forEach(sortable => {
|
|
let groupName = _this.getTypeFor(sortable),
|
|
draggable;
|
|
|
|
switch (groupName) {
|
|
case _this.widgetTypes.DashboardHome:
|
|
groupName = _this.widgetTypes.DashboardHome;
|
|
draggable = '.home-list-control';
|
|
break;
|
|
case _this.widgetTypes.Dashboard:
|
|
groupName = _this.widgetTypes.Dashboard;
|
|
draggable = '.dashboard-list-control';
|
|
break;
|
|
case _this.widgetTypes.Dashlet:
|
|
groupName = _this.widgetTypes.Dashlet;
|
|
draggable = '.dashlet-list-item';
|
|
}
|
|
|
|
let options = {
|
|
scroll : true,
|
|
invertSwap : true,
|
|
dataIdAttr : 'id',
|
|
direction : 'vertical',
|
|
draggable : draggable,
|
|
handle : 'h1 > .widget-drag-initiator',
|
|
group : { name : groupName },
|
|
chosenClass : 'draggable-widget-chosen'
|
|
};
|
|
|
|
_this.Sortable.create(sortable, options);
|
|
});
|
|
}
|
|
}
|
|
|
|
Icinga.Behaviors = Icinga.Behaviors || {};
|
|
|
|
Icinga.Behaviors.Dashboard = Dashboard;
|
|
|
|
})(Icinga, jQuery);
|