[pbs-devel] [PATCH proxmox-backup 4/5] ui: datastore content: add snapshot information to context menu
Dominik Csapak
d.csapak at proxmox.com
Tue Nov 28 10:44:01 CET 2023
contains a summary of snapshot information, especially interesting since
it contains the upload statistics. This may allow us to reduce the
default column count in the grid.
Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
---
www/Makefile | 1 +
www/datastore/Content.js | 22 +++++
www/window/SnapshotInfo.js | 182 +++++++++++++++++++++++++++++++++++++
3 files changed, 205 insertions(+)
create mode 100644 www/window/SnapshotInfo.js
diff --git a/www/Makefile b/www/Makefile
index 04c12b31..34e0f851 100644
--- a/www/Makefile
+++ b/www/Makefile
@@ -86,6 +86,7 @@ JSSRC= \
window/VerifyAll.js \
window/ZFSCreate.js \
window/InfluxDbEdit.js \
+ window/SnapshotInfo.js \
dashboard/DataStoreStatistics.js \
dashboard/LongestTasks.js \
dashboard/RunningTasks.js \
diff --git a/www/datastore/Content.js b/www/datastore/Content.js
index 8d5d0815..d9e9d0b4 100644
--- a/www/datastore/Content.js
+++ b/www/datastore/Content.js
@@ -712,6 +712,17 @@ Ext.define('PBS.DataStoreContent', {
});
},
+ onShowInformation: function(view, rI, cI, item, e, rec) {
+ let me = this;
+ Ext.create('PBS.window.SnapshotInfo', {
+ autoShow: true,
+ datastore: view.datastore,
+ 'backup-type': rec.data['backup-type'],
+ 'backup-id': rec.data['backup-id'],
+ 'backup-time': (rec.data["backup-time"].getTime()/1000).toFixed(0),
+ });
+ },
+
onForget: function(table, rI, cI, item, e, { data }) {
let me = this;
let view = this.getView();
@@ -893,6 +904,7 @@ Ext.define('PBS.DataStoreContent', {
title: gettext('Snapshot'),
onVerify: createControllerCallback('onVerify'),
onProtectionChange: createControllerCallback('onProtectionChange'),
+ onShowInformation: createControllerCallback('onShowInformation'),
onForget: createControllerCallback('onForget'),
});
}
@@ -1330,6 +1342,7 @@ Ext.define('PBS.datastore.SnapshotCmdMenu', {
onVerify: undefined,
onProtectionChange: undefined,
+ onShowInformation: undefined,
onForget: undefined,
items: [
@@ -1351,6 +1364,15 @@ Ext.define('PBS.datastore.SnapshotCmdMenu', {
disabled: '{!onProtectionChange}',
},
},
+ {
+ text: gettext('Show Information'),
+ iconCls: 'fa fa-info-circle',
+ handler: function() { this.up('menu').onShowInformation(); },
+ cbind: {
+ hidden: '{!onShowInformation}',
+ disabled: '{!onShowInformation}',
+ },
+ },
{
text: gettext('Remove'),
iconCls: 'fa critical fa-trash-o',
diff --git a/www/window/SnapshotInfo.js b/www/window/SnapshotInfo.js
new file mode 100644
index 00000000..005f2334
--- /dev/null
+++ b/www/window/SnapshotInfo.js
@@ -0,0 +1,182 @@
+Ext.define('PBS.window.SnapshotInfo', {
+ extend: 'Ext.window.Window',
+ alias: 'widget.pbsSnapshotInfo',
+
+ modal: true,
+ width: 600,
+ resizable: false,
+ referenceHolder: true,
+
+ bodyPadding: 25,
+ defaults: {
+ xtype: 'pmxInfoWidget',
+ printBar: false,
+ padding: '2 0',
+ },
+
+ items: [
+ {
+ reference: 'backup-time',
+ iconCls: 'fa fa-clock-o',
+ title: gettext('Backup Time'),
+ },
+ {
+ reference: 'protected',
+ iconCls: 'fa fa-shield',
+ title: gettext('Protected'),
+ },
+ {
+ reference: 'size',
+ iconCls: 'fa fa-hdd-o',
+ title: gettext('Size'),
+ },
+ {
+ reference: 'owner',
+ iconCls: 'fa fa-user-o',
+ title: gettext('Owner'),
+ },
+ {
+ // spacer
+ xtype: 'box',
+ padding: 10,
+ },
+ {
+ xtype: 'grid',
+ reference: 'files',
+ store: {
+ data: [],
+ },
+ height: 170,
+ scrollable: true,
+ columns: [
+ {
+ dataIndex: 'filename',
+ text: gettext('Filename'),
+ flex: 1,
+ },
+ {
+ dataIndex: 'size',
+ text: gettext('Size'),
+ flex: 1,
+ renderer: (v) => v !== undefined ? Proxmox.Utils.format_size(v) : '',
+ },
+ {
+ dataIndex: 'crypt-mode',
+ text: gettext('Encrypted'),
+ flex: 1,
+ renderer: (v) => {
+ let modeIdx = PBS.Utils.cryptmap[v ?? 'none'] ?? 0;
+ return PBS.Utils.cryptText[modeIdx];
+ },
+ },
+ ],
+ },
+ {
+ // spacer
+ xtype: 'box',
+ padding: 10,
+ },
+ {
+ title: gettext('Verify State'),
+ iconCls: 'pve-icon-verify-lettering',
+ reference: 'verify-state',
+ },
+ {
+ title: gettext('Last Verificaton'),
+ iconCls: 'fa fa-list-alt',
+ reference: 'verify-last',
+ },
+ {
+ // spacer
+ xtype: 'box',
+ padding: 10,
+ },
+ {
+ xtype: 'box',
+ html: `<i class="fa fa-upload"></i> ${gettext('Upload Statistics')}`,
+ reference: 'upload-title',
+ padding: '0 0 10 0',
+ },
+ {
+ title: gettext('Size'),
+ reference: 'upload-size',
+ },
+ {
+ title: gettext('Compressed Size'),
+ reference: 'compressed-size',
+ },
+ {
+ title: gettext('Chunk Count'),
+ reference: 'chunk-count',
+ },
+ {
+ title: gettext('Duplicate Chunks'),
+ reference: 'duplicate-chunks',
+ },
+ ],
+
+ initComponent: function() {
+ let me = this;
+ let type = me['backup-type'];
+ let id = me['backup-id'];
+ let time = me['backup-time'];
+ let datetime = new Date(time*1000);
+ if (type === undefined || id === undefined || time === undefined) {
+ throw "snapshot id not given";
+ }
+
+ let snapshotText = `${type}/${id}/${PBS.Utils.render_datetime_utc(datetime)}`;
+ me.title = Ext.String.format(gettext('Snapshot {0}'), snapshotText);
+
+ me.callParent();
+ Proxmox.Utils.API2Request({
+ url: `/api2/extjs/admin/datastore/${me.datastore}/snapshot-information`,
+ params: {
+ 'backup-type': type,
+ 'backup-id': id,
+ 'backup-time': time,
+ },
+ method: 'GET',
+ success: ({ result }) => {
+ me.lookup('backup-time').updateValue(datetime);
+ me.lookup('protected').updateValue(Proxmox.Utils.format_boolean(result.data.protected));
+ me.lookup('size').updateValue(Proxmox.Utils.format_size(result.data.size));
+ me.lookup('owner').updateValue(result.data.owner);
+
+ me.lookup('files').getStore().setData(result.data.files);
+
+ let verification = result.data.verification;
+ if (verification !== undefined) {
+ let iconCls = 'times critical';
+ if (verification.state === 'ok') {
+ iconCls = 'check good';
+ }
+ let txt = Ext.htmlEncode(verification.state);
+ let verifyState = `<i class="fa fa-${iconCls}"></i> ${txt}`;
+
+ let task = Proxmox.Utils.parse_task_upid(verification.upid);
+ let verifyTime = Proxmox.Utils.render_timestamp(task.starttime);
+ me.lookup('verify-state').updateValue(verifyState);
+ me.lookup('verify-last').updateValue(verifyTime);
+ } else {
+ me.lookup('verify-state').setVisible(false);
+ me.lookup('verify-last').setVisible(false);
+ }
+
+ let uploadStats = result.data['upload-statistics'];
+ if (uploadStats !== undefined) {
+ me.lookup('upload-size').updateValue(Proxmox.Utils.format_size(uploadStats.size));
+ me.lookup('compressed-size').updateValue(Proxmox.Utils.format_size(uploadStats['compressed-size']));
+ me.lookup('chunk-count').updateValue(uploadStats.count);
+ me.lookup('duplicate-chunks').updateValue(uploadStats.duplicates);
+ } else {
+ me.lookup('upload-title').setVisible(false);
+ me.lookup('upload-size').setVisible(false);
+ me.lookup('compressed-size').setVisible(false);
+ me.lookup('chunk-count').setVisible(false);
+ me.lookup('duplicate-chunks').setVisible(false);
+ }
+ },
+ });
+ },
+});
--
2.39.2
More information about the pbs-devel
mailing list