pve-manager/www/manager6/dc/Summary.js
Thomas Lamprecht a30dca2f9f ui: dc/Summary: eslint fixes and code cleanup/refactoring
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-05-18 15:14:51 +02:00

281 lines
6.3 KiB
JavaScript

Ext.define('PVE.dc.Summary', {
extend: 'Ext.panel.Panel',
alias: 'widget.pveDcSummary',
scrollable: true,
bodyPadding: 5,
layout: 'column',
defaults: {
padding: 5,
columnWidth: 1,
},
items: [
{
itemId: 'dcHealth',
xtype: 'pveDcHealth',
},
{
itemId: 'dcGuests',
xtype: 'pveDcGuests',
},
{
title: gettext('Resources'),
xtype: 'panel',
minHeight: 250,
bodyPadding: 5,
layout: 'hbox',
defaults: {
xtype: 'proxmoxGauge',
flex: 1,
},
items: [
{
title: gettext('CPU'),
itemId: 'cpu',
},
{
title: gettext('Memory'),
itemId: 'memory',
},
{
title: gettext('Storage'),
itemId: 'storage',
},
],
},
{
itemId: 'nodeview',
xtype: 'pveDcNodeView',
height: 250,
},
{
title: gettext('Subscriptions'),
height: 220,
items: [
{
itemId: 'subscriptions',
xtype: 'pveHealthWidget',
userCls: 'pointer',
listeners: {
element: 'el',
click: function() {
if (this.component.userCls === 'pointer') {
window.open('https://www.proxmox.com/en/proxmox-ve/pricing', '_blank');
}
},
},
},
],
},
],
listeners: {
resize: function(panel) {
Proxmox.Utils.updateColumns(panel);
},
},
initComponent: function() {
var me = this;
var rstore = Ext.create('Proxmox.data.UpdateStore', {
interval: 3000,
storeid: 'pve-cluster-status',
model: 'pve-dc-nodes',
proxy: {
type: 'proxmox',
url: "/api2/json/cluster/status",
},
});
var gridstore = Ext.create('Proxmox.data.DiffStore', {
rstore: rstore,
filters: {
property: 'type',
value: 'node',
},
sorters: {
property: 'id',
direction: 'ASC',
},
});
me.callParent();
me.getComponent('nodeview').setStore(gridstore);
var gueststatus = me.getComponent('dcGuests');
var cpustat = me.down('#cpu');
var memorystat = me.down('#memory');
var storagestat = me.down('#storage');
var sp = Ext.state.Manager.getProvider();
me.mon(PVE.data.ResourceStore, 'load', function(curstore, results) {
me.suspendLayout = true;
let cpu = 0, maxcpu = 0;
let memory = 0, maxmem = 0;
let used = 0, total = 0;
let countedStorage = {}, usableStorages = {};
let storages = sp.get('dash-storages') || '';
storages.split(',').filter(v => v !== '').forEach(storage => {
usableStorages[storage] = true;
});
let qemu = {
running: 0,
paused: 0,
stopped: 0,
template: 0,
};
let lxc = {
running: 0,
paused: 0,
stopped: 0,
template: 0,
};
let error = 0;
for (const { data } of results) {
switch (data.type) {
case 'node':
cpu += data.cpu * data.maxcpu;
maxcpu += data.maxcpu || 0;
memory += data.mem || 0;
maxmem += data.maxmem || 0;
if (gridstore.getById(data.id)) {
let griditem = gridstore.getById(data.id);
griditem.set('cpuusage', data.cpu);
let max = data.maxmem || 1;
let val = data.mem || 0;
griditem.set('memoryusage', val / max);
griditem.set('uptime', data.uptime);
griditem.commit(); // else the store marks the field as dirty
}
break;
case 'storage': {
let sid = !data.shared || data.storage === 'local' ? data.id : data.storage;
if (!Ext.Object.isEmpty(usableStorages)) {
if (usableStorages[data.id] !== true) {
break;
}
sid = data.id;
} else if (countedStorage[sid]) {
break;
}
used += data.disk;
total += data.maxdisk;
countedStorage[sid] = true;
break;
}
case 'qemu':
qemu[data.template ? 'template' : data.status]++;
if (data.hastate === 'error') {
error++;
}
break;
case 'lxc':
lxc[data.template ? 'template' : data.status]++;
if (data.hastate === 'error') {
error++;
}
break;
default: break;
}
}
let text = Ext.String.format(gettext('of {0} CPU(s)'), maxcpu);
cpustat.updateValue(cpu/maxcpu, text);
text = Ext.String.format(gettext('{0} of {1}'), Proxmox.Utils.render_size(memory), Proxmox.Utils.render_size(maxmem));
memorystat.updateValue(memory/maxmem, text);
text = Ext.String.format(gettext('{0} of {1}'), Proxmox.Utils.render_size(used), Proxmox.Utils.render_size(total));
storagestat.updateValue(used/total, text);
gueststatus.updateValues(qemu, lxc, error);
me.suspendLayout = false;
me.updateLayout(true);
});
let dcHealth = me.getComponent('dcHealth');
me.mon(rstore, 'load', dcHealth.updateStatus, dcHealth);
let subs = me.down('#subscriptions');
me.mon(rstore, 'load', function(store, records, success) {
var level;
var mixed = false;
for (let i = 0; i < records.length; i++) {
let node = records[i];
if (node.get('type') !== 'node' || node.get('status') === 'offline') {
continue;
}
let curlevel = node.get('level');
if (curlevel === '') { // no subscription beats all, set it and break the loop
level = '';
break;
}
if (level === undefined) { // save level
level = curlevel;
} else if (level !== curlevel) { // detect different levels
mixed = true;
}
}
let data = {
title: Proxmox.Utils.unknownText,
text: Proxmox.Utils.unknownText,
iconCls: PVE.Utils.get_health_icon(undefined, true),
};
if (level === '') {
data = {
title: gettext('No Subscription'),
iconCls: PVE.Utils.get_health_icon('critical', true),
text: gettext('You have at least one node without subscription.'),
};
subs.setUserCls('pointer');
} else if (mixed) {
data = {
title: gettext('Mixed Subscriptions'),
iconCls: PVE.Utils.get_health_icon('warning', true),
text: gettext('Warning: Your subscription levels are not the same.'),
};
subs.setUserCls('pointer');
} else if (level) {
data = {
title: PVE.Utils.render_support_level(level),
iconCls: PVE.Utils.get_health_icon('good', true),
text: gettext('Your subscription status is valid.'),
};
subs.setUserCls('');
}
subs.setData(data);
});
me.on('destroy', function() {
rstore.stopUpdate();
});
me.mon(sp, 'statechange', function(provider, key, value) {
if (key !== 'summarycolumns') {
return;
}
Proxmox.Utils.updateColumns(me);
});
rstore.startUpdate();
},
});