mirror of
https://github.com/Icinga/icingaweb2.git
synced 2025-09-26 19:29:00 +02:00
196 lines
7.6 KiB
JavaScript
196 lines
7.6 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);
|
|
this.on('end', '.dashboard-settings, .dashboard-list-control, .dashlet-list-item', this.elementDropped, this);
|
|
// This is for the normal dashboard/dashlets view
|
|
this.on('end', '.dashboard.content', 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') || target.matches('.dashboard.content')) {
|
|
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,
|
|
pane,
|
|
home;
|
|
|
|
if (orgEvt.to.matches('.dashboard.content')) {
|
|
let parentData = orgEvt.to.dataset.icingaPane.split('|', 2);
|
|
home = parentData.shift();
|
|
pane = parentData.shift();
|
|
|
|
data.redirectPath = 'dashboards';
|
|
} else { // Dashboard manager view
|
|
let parent = orgEvt.to.closest('.dashboard-list-control');
|
|
pane = parent.dataset.icingaPane;
|
|
// If there is only default home in the dashboard manager view, there won't be rendered
|
|
// ".home-list-control", so we need to look for an alternative
|
|
home = parent.closest('.home-list-control, .dashboard-settings').dataset.icingaHome;
|
|
|
|
if (orgEvt.to !== orgEvt.from) {
|
|
let parent = orgEvt.from.closest('.dashboard-list-control');
|
|
data.originals = {
|
|
originalHome : parent.closest('.home-list-control').dataset.icingaHome,
|
|
originalPane : parent.dataset.icingaPane
|
|
}
|
|
}
|
|
}
|
|
|
|
dashlet = { [dashlet] : orgEvt.newIndex };
|
|
data[home] = { [pane] : dashlet };
|
|
}
|
|
}
|
|
|
|
if (Object.keys(data).length) {
|
|
data.Type = _this.getTypeFor(orgEvt.to);
|
|
if (! data.originals) {
|
|
data.originals = null;
|
|
}
|
|
|
|
if (! data.redirectPath) {
|
|
data.redirectPath = 'dashboards/settings';
|
|
}
|
|
|
|
data = { dashboardData : JSON.stringify(data) };
|
|
let url = _this.icinga.config.baseUrl + '/dashboards/reorder-widgets';
|
|
_this.icinga.loader.loadUrl(url, $('#col1'), data, 'post');
|
|
}
|
|
}
|
|
|
|
onRendered(e) {
|
|
let _this = e.data.self;
|
|
e.target.querySelectorAll('.dashboard-settings, .dashboard.content,'
|
|
+ ' .dashboard-item-list, .dashlet-item-list')
|
|
.forEach(sortable => {
|
|
let groupName = _this.getTypeFor(sortable),
|
|
draggable,
|
|
handle;
|
|
|
|
switch (groupName) {
|
|
case _this.widgetTypes.DashboardHome:
|
|
groupName = _this.widgetTypes.DashboardHome;
|
|
draggable = '.home-list-control';
|
|
handle = '.home-list-control > h1';
|
|
break;
|
|
case _this.widgetTypes.Dashboard:
|
|
groupName = _this.widgetTypes.Dashboard;
|
|
draggable = '.dashboard-list-control';
|
|
handle = '.dashboard-list-control > h1'
|
|
break;
|
|
case _this.widgetTypes.Dashlet:
|
|
groupName = _this.widgetTypes.Dashlet;
|
|
if (sortable.matches('.dashboard.content')) {
|
|
draggable = '> .container';
|
|
} else {
|
|
draggable = '.dashlet-list-item';
|
|
}
|
|
|
|
handle = draggable;
|
|
}
|
|
|
|
let options = {
|
|
scroll : true,
|
|
invertSwap : true,
|
|
delay : 100,
|
|
dataIdAttr : 'id',
|
|
direction : 'vertical',
|
|
draggable : draggable,
|
|
handle : handle,
|
|
group : { name : groupName }
|
|
};
|
|
|
|
_this.Sortable.create(sortable, options);
|
|
});
|
|
}
|
|
}
|
|
|
|
Icinga.Behaviors = Icinga.Behaviors || {};
|
|
|
|
Icinga.Behaviors.Dashboard = Dashboard;
|
|
|
|
})(Icinga, jQuery);
|