add new StatusView component

this adds a component StatusView which is intended to
replace the old statusview panels of qemu/lxc/nodes
(later maybe also pools and storages)

it extends Ext.panel.Panel and expects an rstore and title

it is not intended to be used directly but to be subclassed

it works like this:

on instantiating, it adds a listener to the rstore load,
so that on every rstore load 'updateValues' gets executed

there, if successful, looks for every subcomponent of type
'pveInfoWidget' and calls 'updateField' on it

'updateField' calculates the update text and value for
the info widgets based on the given class variables

using either:
textField -> which gets the value from the store and
displays it simple as text (with renderer and calculator)

or valueField and (optional) maxField
where it determines the usage
(also with a renderer and calculator)

for both there is a default calculator/renderer
but this can be overwritten when instantiating/declaring

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
Dominik Csapak 2016-08-19 10:47:48 +02:00 committed by Fabian Grünbichler
parent 2df2d90027
commit dd6350e3dd
2 changed files with 152 additions and 0 deletions

View File

@ -1022,6 +1022,33 @@ Ext.define('PVE.Utils', { statics: {
return PVE.Utils.format_task_description(type, id);
},
/* render functions for new status panel */
render_usage: function(val) {
return (val*100).toFixed(2) + '%';
},
render_cpu_usage: function(val, max) {
return Ext.String.format(gettext('{0}% of {1}') +
' ' + gettext('CPU(s)'), (val*100).toFixed(2), max);
},
render_size_usage: function(val, max) {
return (val*100/max).toFixed(2) + '% '+ '(' +
Ext.String.format(gettext('{0} of {1}'),
PVE.Utils.render_size(val), PVE.Utils.render_size(max)) + ')';
},
/* this is different for nodes */
render_node_cpu_usage: function(value, record) {
return PVE.Utils.render_cpu_usage(value, record.cpus);
},
/* this is different for nodes */
render_node_size_usage: function(record) {
return PVE.Utils.render_size_usage(record.used, record.total);
},
dialog_title: function(subject, create, isAdd) {
if (create) {
if (isAdd) {

View File

@ -0,0 +1,125 @@
Ext.define('PVE.panel.StatusView', {
extend: 'Ext.panel.Panel',
alias: 'widget.pveStatusView',
layout: {
type: 'column'
},
title: gettext('Status'),
getRecordValue: function(key, store) {
if (!key) {
throw "no key given";
}
var me = this;
if (store === undefined) {
store = me.getStore();
}
var rec = store.getById(key);
if (rec) {
return rec.data.value;
}
return '';
},
fieldRenderer: function(val,max) {
if (max === undefined) {
return val;
}
if (!Ext.isNumeric(max) || max === 1) {
return PVE.Utils.render_usage(val);
}
return PVE.Utils.render_size_usage(val,max);
},
fieldCalculator: function(used, max) {
if (!Ext.isNumeric(max) && Ext.isNumeric(used)) {
return used;
} else if(!Ext.isNumeric(used)) {
/* we come here if the field is from a node
* where the records are not mem and maxmem
* but mem.used and mem.total
*/
if (used.used !== undefined &&
used.total !== undefined) {
return used.used/used.total;
}
}
return used/max;
},
updateField: function(field) {
var me = this;
var text = '';
var renderer = me.fieldRenderer;
if (Ext.isFunction(field.renderer)) {
renderer = field.renderer;
}
if (field.textField !== undefined) {
field.updateValue(renderer(me.getRecordValue(field.textField)));
} else if(field.valueField !== undefined) {
var used = me.getRecordValue(field.valueField);
/*jslint confusion: true*/
/* string and int */
var max = field.maxField !== undefined ? me.getRecordValue(field.maxField) : 1;
var calculate = me.fieldCalculator;
if (Ext.isFunction(field.calculate)) {
calculate = field.calculate;
}
field.updateValue(renderer(used,max), calculate(used,max));
}
},
getStore: function() {
var me = this;
if (!me.rstore) {
throw "there is no rstore";
}
return me.rstore;
},
updateTitle: function() {
var me = this;
me.setTitle(me.getRecordValue('name'));
},
updateValues: function(store, records, success) {
if (!success) {
return; // do not update if store load was not successful
}
var me = this;
var itemsToUpdate = me.query('pveInfoWidget');
itemsToUpdate.forEach(me.updateField, me);
me.updateTitle(store);
},
initComponent: function() {
var me = this;
if (!me.rstore) {
throw "no rstore given";
}
if (!me.title) {
throw "no title given";
}
PVE.Utils.monStoreErrors(me, me.rstore);
me.callParent();
me.mon(me.rstore, 'load', 'updateValues');
}
});