From ae66873ce95c35aaa2acf3ce5faef7cbf37fe22b Mon Sep 17 00:00:00 2001 From: Dominik Csapak Date: Tue, 9 Jun 2020 10:01:14 +0200 Subject: [PATCH] ui: add datastore usages to dashboard shows an overview over the datastores, including a small chart of the past month and an estimation of when its full Signed-off-by: Dominik Csapak --- www/Dashboard.js | 4 + www/Makefile | 1 + www/dashboard/DataStoreStatistics.js | 141 +++++++++++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 www/dashboard/DataStoreStatistics.js diff --git a/www/Dashboard.js b/www/Dashboard.js index 25bce92e..922c32fd 100644 --- a/www/Dashboard.js +++ b/www/Dashboard.js @@ -193,6 +193,10 @@ Ext.define('PBS.Dashboard', { } ] }, + { + xtype: 'pbsDatastoresStatistics', + height: 250, + }, { xtype: 'container', height: 250, diff --git a/www/Makefile b/www/Makefile index 0cbd223a..9ebc155d 100644 --- a/www/Makefile +++ b/www/Makefile @@ -18,6 +18,7 @@ JSSRC= \ window/SyncJobEdit.js \ window/ACLEdit.js \ window/DataStoreEdit.js \ + dashboard/DataStoreStatistics.js \ Utils.js \ LoginView.js \ VersionInfo.js \ diff --git a/www/dashboard/DataStoreStatistics.js b/www/dashboard/DataStoreStatistics.js new file mode 100644 index 00000000..6736e616 --- /dev/null +++ b/www/dashboard/DataStoreStatistics.js @@ -0,0 +1,141 @@ +Ext.define('pbs-datastore-statistics', { + extend: 'Ext.data.Model', + + fields: [ + 'store', 'total', 'used', 'avail', 'estimated-full-date', 'history', + { + name: 'usage', + calculate: function(data) { + let used = data.used || 0; + let total = data.total || 0; + if (total > 0) { + return used/total; + } else { + return -1; + } + } + }, + ], + + proxy: { + type: 'proxmox', + url: "/api2/json/status/datastore-usage" + }, + idProperty: 'store', +}); + +Ext.define('PBS.DatastoreStatistics', { + extend: 'Ext.grid.Panel', + alias: 'widget.pbsDatastoresStatistics', + + title: gettext('Datastore Usage'), + + emptyText: gettext('No Data'), + + controller: { + xclass: 'Ext.app.ViewController', + + render_estimate: function(value) { + if (!value) { + return gettext('Not enough data'); + } + + let now = new Date(); + let estimate = new Date(value*1000); + + let timespan = (estimate - now)/1000; + + if (+estimate <= +now || isNaN(timespan)) { + return gettext('Never'); + } + + let duration = Proxmox.Utils.format_duration_human(timespan); + return Ext.String.format(gettext("in {0}"), duration); + }, + + init: function(view) { + Proxmox.Utils.monStoreErrors(view, view.getStore().rstore); + }, + }, + + columns: [ + { + text: gettext('Name'), + dataIndex: 'store', + sortable: true, + }, + { + text: gettext('Size'), + dataIndex: 'total', + sortable: true, + width: 90, + renderer: Proxmox.Utils.format_size, + }, + { + text: gettext('Used'), + dataIndex: 'used', + sortable: true, + width: 90, + renderer: Proxmox.Utils.format_size, + }, + { + text: gettext('Usage %'), + dataIndex: 'usage', + sortable: true, + xtype: 'widgetcolumn', + widget: { + xtype: 'progressbarwidget', + bind: '{record.usage}', + textTpl: [ + '', + '{value:number("0.00")*100}%', + '', + Proxmox.Utils.unknownText, + '', + ], + }, + }, + { + text: gettext('Estimated Full'), + dataIndex: 'estimated-full-date', + sortable: true, + renderer: 'render_estimate', + flex: 1, + minWidth: 130, + maxWidth: 200, + }, + { + text: gettext("History (last Month)"), + width: 100, + xtype: 'widgetcolumn', + dataIndex: 'history', + flex: 1, + widget: { + xtype: 'sparklineline', + bind: '{record.history}', + spotRadius: 0, + fillColor: '#ddd', + lineColor: '#555', + lineWidth: 0, + chartRangeMin: 0, + chartRangeMax: 1, + tipTpl: '{y:number("0.00")*100}%' + } + }, + ], + + store: { + type: 'diff', + autoDestroy: true, + autoDestroyRstore: true, + sorters: 'store', + rstore: { + type: 'update', + storeid: 'pbs-datastore-statistics', + model: 'pbs-datastore-statistics', + autoStart: true, + interval: 30000, + }, + }, + +})