pmg-gui/js/Dashboard.js
Thomas Lamprecht 9b7b055365 dashboard: increase height of second row slightly
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-07-13 16:04:37 +02:00

495 lines
10 KiB
JavaScript

Ext.define('PMG.Dashboard', {
extend: 'Ext.panel.Panel',
xtype: 'pmgDashboard',
controller: {
xclass: 'Ext.app.ViewController',
openDashboardOptions: function() {
var me = this;
var viewModel = me.getViewModel();
Ext.create('Ext.window.Window', {
modal: true,
width: 300,
title: gettext('Dashboard Options'),
layout: {
type: 'auto',
},
items: [{
xtype: 'form',
bodyPadding: '10 10 10 10',
defaultButton: 'savebutton',
items: [{
xtype: 'proxmoxintegerfield',
itemId: 'hours',
labelWidth: 100,
anchor: '100%',
allowBlank: false,
minValue: 1,
maxValue: 24,
value: viewModel.get('hours'),
fieldLabel: gettext('Hours to show'),
}],
buttons: [{
text: gettext('Save'),
reference: 'loginButton',
formBind: true,
handler: function() {
var win = this.up('window');
var hours = win.down('#hours').getValue();
me.setHours(hours, true);
win.close();
},
}],
}],
}).show();
},
setHours: function(hours, setState) {
var me = this;
var viewModel = me.getViewModel();
viewModel.set('hours', hours);
viewModel.notify();
Ext.Array.forEach(['recentmails', 'receivers'], function(item) {
viewModel.getStore(item).reload();
});
if (setState) {
var sp = Ext.state.Manager.getProvider();
sp.set('dashboard-hours', hours);
}
},
updateMailStats: function(store, records, success) {
if (!success) {
return;
}
var me = this;
var viewModel = me.getViewModel();
var count = 0;
var bytes_in = 0;
var bytes_out = 0;
var ptime = 0;
var avg_ptime = 'N/A';
records.forEach(function(item) {
bytes_in += item.data.bytes_in;
bytes_out += item.data.bytes_out;
// unnormalize
count += (item.data.count*item.data.timespan)/60;
ptime += item.data.ptimesum;
});
if (count) {
avg_ptime = (ptime/count).toFixed(2) + " s";
}
viewModel.set('bytes_in', Proxmox.Utils.format_size(bytes_in));
viewModel.set('bytes_out', Proxmox.Utils.format_size(bytes_out));
viewModel.set('avg_ptime', avg_ptime);
},
updateClusterStats: function(store, records, success) {
if (!success) {
return;
}
var me = this;
var viewmodel = me.getViewModel();
var subStatus = 2; // 2 = all good, 1 = different leves, 0 = none
var subLevel = "";
var cpu = 0;
var mem = 0;
var hd = 0;
var count = records.length;
var errors = [];
records.forEach(function(item) {
// subscription level check
if (subStatus && item.data.level) {
if (subLevel !== "" && subLevel !== item.data.level) {
subStatus = 1;
} else if (subLevel === "") {
subLevel = item.data.level;
}
} else {
subStatus = 0;
}
// resources count
cpu += item.data.cpu || 0;
var memory = item.data.memory || { used: 0, total: 1 };
mem += memory.used/memory.total;
var rootfs = item.data.rootfs || { used: 0, total: 1 };
hd += rootfs.used/rootfs.total;
if (item.data.conn_error && count > 1) {
count--;
errors.push({
name: item.data.name,
msg: item.data.conn_error,
});
}
});
var subscriptionPanel = me.lookup('subscription');
subscriptionPanel.setSubStatus(subStatus);
me.lookup('nodeInfo').setSubscriptionStatus(subStatus);
// the node info already displays this information in case there is no cluster
me.lookup('clusterResources').setHidden(records.length === 1);
cpu = cpu/count;
mem = mem/count;
hd = hd/count;
var cpuPanel = me.lookup('cpu');
cpuPanel.updateValue(cpu);
var memPanel = me.lookup('mem');
memPanel.updateValue(mem);
var hdPanel = me.lookup('hd');
hdPanel.updateValue(hd);
if (errors.length && !viewmodel.get('error_shown')) {
var text = "";
errors.forEach(function(error) {
text += error.name + ':<br>' + error.msg + '<br>';
});
Ext.Msg.alert(gettext('Error'), text);
viewmodel.set('error_shown', true);
}
},
updateRepositoryStatus: function(store, records, success) {
if (!success) {
return;
}
let me = this;
me.lookup('nodeInfo').setRepositoryInfo(records[0].data['standard-repos']);
},
init: function(view) {
var me = this;
var sp = Ext.state.Manager.getProvider();
var hours = sp.get('dashboard-hours') || 12;
me.setHours(hours, false);
},
},
viewModel: {
data: {
timespan: 300, // in seconds
hours: 12, // in hours
error_shown: false,
'bytes_in': 0,
'bytes_out': 0,
'avg_ptime': 0.0,
},
stores: {
cluster: {
storeid: 'dash-cluster',
type: 'update',
interval: 5000,
autoStart: true,
autoDestroy: true,
proxy: {
extraParams: { list_single_node: 1 },
type: 'proxmox',
url: '/api2/json/config/cluster/status',
},
listeners: {
load: 'updateClusterStats',
},
},
recentmails: {
storeid: 'dash-recent',
interval: 5000,
type: 'update',
autoStart: true,
autoDestroy: true,
proxy: {
type: 'proxmox',
url: '/api2/json/statistics/recent',
extraParams: {
hours: '{hours}',
timespan: '{timespan}',
},
},
fields: [
{
type: 'number', name: 'count',
convert: PMG.Utils.convert_field_to_per_min,
},
{
type: 'number', name: 'count_in',
convert: PMG.Utils.convert_field_to_per_min,
},
{
type: 'number', name: 'count_out',
convert: PMG.Utils.convert_field_to_per_min,
},
{
type: 'number', name: 'spam',
convert: PMG.Utils.convert_field_to_per_min,
},
{
type: 'number', name: 'spam_in',
convert: PMG.Utils.convert_field_to_per_min,
},
{
type: 'number', name: 'spam_out',
convert: PMG.Utils.convert_field_to_per_min,
},
{
type: 'number', name: 'virus',
convert: PMG.Utils.convert_field_to_per_min,
},
{
type: 'number', name: 'virus_in',
convert: PMG.Utils.convert_field_to_per_min,
},
{ type: 'integer', name: 'virus_out' },
{ type: 'integer', name: 'bytes_in' },
{ type: 'integer', name: 'bytes_out' },
{ type: 'number', name: 'ptimesum' },
{ type: 'date', dateFormat: 'timestamp', name: 'time' },
],
listeners: {
load: 'updateMailStats',
},
},
receivers: {
storeid: 'dash-receivers',
interval: 10000,
type: 'update',
autoStart: true,
autoDestroy: true,
proxy: {
type: 'proxmox',
url: '/api2/json/statistics/recentreceivers',
extraParams: {
hours: '{hours}',
},
},
fields: [
{ type: 'integer', name: 'count' },
{ type: 'string', name: 'receiver' },
],
},
repositories: {
storeid: 'dash-repositories',
type: 'update',
interval: 15000,
autoStart: true,
autoLoad: true,
autoDestroy: true,
proxy: {
type: 'proxmox',
url: '/api2/json/nodes/localhost/apt/repositories',
},
listeners: {
load: 'updateRepositoryStatus',
},
},
},
},
bind: {
title: gettext('Dashboard') + ' (' +
Ext.String.format(gettext('{0} hours'), '{hours}') + ')',
},
layout: {
type: 'column',
},
border: false,
bodyPadding: '20 0 0 20',
defaults: {
columnWidth: 0.5,
xtype: 'panel',
margin: '0 20 20 0',
},
tools: [
{
type: 'gear',
handler: 'openDashboardOptions',
},
],
scrollable: true,
items: [
{
height: 300,
flex: 1,
iconCls: 'fa fa-tachometer',
title: gettext('E-Mail Volume'),
layout: {
type: 'vbox',
align: 'stretch',
},
defaults: {
xtype: 'pmgMiniGraph',
bind: {
store: '{recentmails}',
},
},
items: [
{
fields: ['count'],
fieldTitles: [gettext('Mails / min')],
seriesConfig: {
colors: ['#00617F'],
style: {
opacity: 0.60,
lineWidth: 1,
},
highlightCfg: {
opacity: 1,
scaling: 1,
},
},
},
{
fields: ['spam'],
fieldTitles: [gettext('Spam / min')],
seriesConfig: {
colors: ['#E67300'],
style: {
opacity: 0.60,
lineWidth: 1,
},
highlightCfg: {
opacity: 1,
scaling: 1,
},
},
},
],
},
{
xtype: 'container',
height: 300,
layout: {
type: 'vbox',
align: 'stretch',
},
items: [
{
xtype: 'pmgMailProcessing',
title: gettext('E-Mail Processing'),
iconCls: 'fa fa-hourglass-half',
height: 180,
bind: {
data: {
'bytes_in': '{bytes_in}',
'bytes_out': '{bytes_out}',
'avg_ptime': '{avg_ptime}',
},
},
},
{
iconCls: 'fa fa-ticket',
title: 'Subscription',
reference: 'subscription',
xtype: 'pmgSubscriptionInfo',
margin: '10 0 0 0',
height: 110,
},
],
},
{
xtype: 'pmgNodeInfoPanel',
reference: 'nodeInfo',
height: 275,
bodyPadding: '15 5 15 5',
iconCls: 'fa fa-tasks',
},
{
height: 275,
iconCls: 'fa fa-list',
title: gettext('Top Receivers'),
bodyPadding: '20 20 20 20',
layout: {
type: 'vbox',
pack: 'center',
align: 'stretch',
},
items: [{
xtype: 'grid',
bind: {
store: '{receivers}',
},
emptyText: gettext('No data in database'),
// remove all borders/lines/headers
border: false,
bodyBorder: false,
hideHeaders: true,
header: false,
columnLines: false,
rowLines: false,
viewConfig: {
stripeRows: false,
},
columns: [
{
dataIndex: 'receiver',
flex: 1,
text: gettext('Receiver'),
},
{
dataIndex: 'count',
align: 'right',
text: gettext('Count'),
},
],
}],
},
{
height: 250,
iconCls: 'fa fa-tasks',
title: gettext('Cluster Resources (average)'),
reference: 'clusterResources',
hidden: true,
bodyPadding: '0 20 0 20',
layout: {
type: 'hbox',
align: 'center',
},
defaults: {
xtype: 'proxmoxGauge',
spriteFontSize: '20px',
flex: 1,
},
items: [
{
title: gettext('CPU'),
reference: 'cpu',
},
{
title: gettext('Memory'),
reference: 'mem',
},
{
title: gettext('Storage'),
reference: 'hd',
},
],
},
],
});