mirror of
https://github.com/Icinga/icingaweb2.git
synced 2025-09-24 10:27:46 +02:00
dashboard.js: Use js class syntax
This commit is contained in:
parent
e5f501dae3
commit
52809312d2
@ -4,211 +4,186 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
try {
|
|
||||||
var 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}
|
|
||||||
*/
|
|
||||||
const WIDGET_TYPES = { Dashlet : 'Dashlets', Dashboard : 'Dashboards', DashboardHome : 'Homes' };
|
|
||||||
|
|
||||||
Icinga.Behaviors = Icinga.Behaviors || {};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Behavior for the enhanced Icinga Web 2 dashboards
|
* Behavior for the enhanced Icinga Web 2 dashboards
|
||||||
*
|
*
|
||||||
* @param {Icinga} icinga The current Icinga Object
|
* @param {Icinga} icinga The current Icinga Object
|
||||||
*
|
|
||||||
* @constructor
|
|
||||||
*/
|
*/
|
||||||
var Dashboard = function (icinga) {
|
class Dashboard extends Icinga.EventListener {
|
||||||
Icinga.EventListener.call(this, icinga);
|
constructor(icinga) {
|
||||||
|
super(icinga);
|
||||||
|
|
||||||
this.icinga = icinga;
|
try {
|
||||||
|
this.Sortable = require('icinga/icinga-php-library/vendor/Sortable');
|
||||||
this.on('rendered', '#main > .container', this.onRendered, this);
|
} catch (e) {
|
||||||
this.on('end', '.dashboard-settings, .dashboard-list-control, .dashlet-list-item', this.elementDropped, this);
|
console.warn('Unable to provide Sortable. Library not available:', e);
|
||||||
// This is for the normal dashboard/dashlets view
|
return;
|
||||||
this.on('end', '.dashboard.content', this.elementDropped, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
Dashboard.prototype = new Icinga.EventListener();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the widget type of the given element
|
|
||||||
*
|
|
||||||
* @param {HTMLElement} target
|
|
||||||
*
|
|
||||||
* @returns {null|string}
|
|
||||||
*/
|
|
||||||
Dashboard.prototype.getTypeFor = function (target) {
|
|
||||||
if (target.matches('.dashboard-settings')) {
|
|
||||||
return WIDGET_TYPES.DashboardHome;
|
|
||||||
} else if (target.matches('.dashboard-item-list')) {
|
|
||||||
return WIDGET_TYPES.Dashboard;
|
|
||||||
} else if (target.matches('.dashlet-item-list') || target.matches('.dashboard.content')) {
|
|
||||||
return WIDGET_TYPES.Dashlet;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set up a request with the reordered widget and post the data to the controller
|
|
||||||
*
|
|
||||||
* @param event
|
|
||||||
*
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
Dashboard.prototype.elementDropped = function (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 WIDGET_TYPES.DashboardHome: {
|
|
||||||
let home = item.dataset.icingaHome;
|
|
||||||
data[home] = orgEvt.newIndex;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case WIDGET_TYPES.Dashboard: {
|
|
||||||
let pane = item.dataset.icingaPane,
|
/**
|
||||||
home = orgEvt.to.closest('.home-list-control').dataset.icingaHome;
|
* Possible type of widgets this behavior is being applied to
|
||||||
if (orgEvt.to !== orgEvt.from) {
|
*
|
||||||
data.originals = {
|
* @type {object}
|
||||||
originalHome : orgEvt.from.closest('.home-list-control').dataset.icingaHome,
|
*/
|
||||||
originalPane : pane
|
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')) {
|
||||||
|
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: {
|
||||||
data[home] = { [pane] : orgEvt.newIndex };
|
let pane = item.dataset.icingaPane,
|
||||||
break;
|
home = orgEvt.to.closest('.home-list-control').dataset.icingaHome;
|
||||||
}
|
|
||||||
case WIDGET_TYPES.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;
|
|
||||||
home = parent.closest('.home-list-control').dataset.icingaHome;
|
|
||||||
|
|
||||||
if (orgEvt.to !== orgEvt.from) {
|
if (orgEvt.to !== orgEvt.from) {
|
||||||
let parent = orgEvt.from.closest('.dashboard-list-control');
|
|
||||||
data.originals = {
|
data.originals = {
|
||||||
originalHome : parent.closest('.home-list-control').dataset.icingaHome,
|
originalHome : orgEvt.from.closest('.home-list-control').dataset.icingaHome,
|
||||||
originalPane : parent.dataset.icingaPane
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
dashlet = { [dashlet] : orgEvt.newIndex };
|
if (! data.redirectPath) {
|
||||||
data[home] = { [pane] : dashlet };
|
data.redirectPath = 'dashboards/settings';
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Object.keys(data).length) {
|
|
||||||
data.Type = _this.getTypeFor(orgEvt.to);
|
|
||||||
if (! data.hasOwnProperty('originals')) {
|
|
||||||
data.originals = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! data.hasOwnProperty('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');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get whether the given element is a valid target of the drag & drop events
|
|
||||||
*
|
|
||||||
* @param to
|
|
||||||
* @param from
|
|
||||||
* @param item
|
|
||||||
* @param event
|
|
||||||
*
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
Dashboard.prototype.isValid = function (to, from, item, event) {
|
|
||||||
if (typeof from.options.group === 'undefined' || typeof to.options.group === 'undefined') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return from.options.group.name === to.options.group.name;
|
|
||||||
};
|
|
||||||
|
|
||||||
Dashboard.prototype.onRendered = function (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 WIDGET_TYPES.DashboardHome: {
|
|
||||||
groupName = WIDGET_TYPES.DashboardHome;
|
|
||||||
draggable = '.home-list-control';
|
|
||||||
handle = '.home-list-control > h1';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WIDGET_TYPES.Dashboard: {
|
|
||||||
groupName = WIDGET_TYPES.Dashboard;
|
|
||||||
draggable = '.dashboard-list-control';
|
|
||||||
handle = '.dashboard-list-control > h1'
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WIDGET_TYPES.Dashlet: {
|
|
||||||
groupName = WIDGET_TYPES.Dashlet;
|
|
||||||
if (sortable.matches('.dashboard.content')) {
|
|
||||||
draggable = '> .container';
|
|
||||||
} else {
|
|
||||||
draggable = '.dashlet-list-item';
|
|
||||||
}
|
|
||||||
|
|
||||||
handle = draggable;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let options = {
|
data = { dashboardData : JSON.stringify(data) };
|
||||||
scroll : true,
|
let url = _this.icinga.config.baseUrl + '/dashboards/reorder-widgets';
|
||||||
invertSwap : true,
|
_this.icinga.loader.loadUrl(url, $('#col1'), data, 'post');
|
||||||
delay : 100,
|
}
|
||||||
dataIdAttr : 'id',
|
}
|
||||||
direction : 'vertical',
|
|
||||||
draggable : draggable,
|
|
||||||
handle : handle,
|
|
||||||
group : {
|
|
||||||
name : groupName,
|
|
||||||
put : _this['isValid'],
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Sortable.create(sortable, options);
|
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.Behaviors.Dashboard = Dashboard;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user