[pve-devel] [PATCH manager 2/7] add new StatusView component

Dominik Csapak d.csapak at proxmox.com
Mon Jul 11 15:46:13 CEST 2016


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 at proxmox.com>
---
 www/manager6/Utils.js            |  27 +++++++++
 www/manager6/panel/StatusView.js | 125 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 152 insertions(+)
 create mode 100644 www/manager6/panel/StatusView.js

diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js
index 36c551c..92b024d 100644
--- a/www/manager6/Utils.js
+++ b/www/manager6/Utils.js
@@ -1015,6 +1015,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) {
diff --git a/www/manager6/panel/StatusView.js b/www/manager6/panel/StatusView.js
new file mode 100644
index 0000000..46553e4
--- /dev/null
+++ b/www/manager6/panel/StatusView.js
@@ -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');
+    }
+
+});
-- 
2.1.4




More information about the pve-devel mailing list