From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 99C37B86D6 for ; Tue, 5 Dec 2023 11:54:18 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 7403C192E1 for ; Tue, 5 Dec 2023 11:53:48 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Tue, 5 Dec 2023 11:53:47 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 0180B44C42 for ; Tue, 5 Dec 2023 11:53:47 +0100 (CET) From: Dominik Csapak To: pbs-devel@lists.proxmox.com Date: Tue, 5 Dec 2023 11:53:44 +0100 Message-Id: <20231205105345.1656325-4-d.csapak@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20231205105345.1656325-1-d.csapak@proxmox.com> References: <20231205105345.1656325-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.018 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record T_SCC_BODY_TEXT_LINE -0.01 - Subject: [pbs-devel] [PATCH proxmox-backup v2 3/4] ui: datastore content: add snapshot information to context menu X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 05 Dec 2023 10:54:18 -0000 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 --- www/Makefile | 1 + www/datastore/Content.js | 22 ++++ www/window/SnapshotInfo.js | 259 +++++++++++++++++++++++++++++++++++++ 3 files changed, 282 insertions(+) create mode 100644 www/window/SnapshotInfo.js diff --git a/www/Makefile b/www/Makefile index be7e27ab..071ef5d8 100644 --- a/www/Makefile +++ b/www/Makefile @@ -87,6 +87,7 @@ JSSRC= \ window/ZFSCreate.js \ window/InfluxDbEdit.js \ window/DatastoreRepoInfo.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 87317ec1..f715f814 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'), }); } @@ -1331,6 +1343,7 @@ Ext.define('PBS.datastore.SnapshotCmdMenu', { onVerify: undefined, onProtectionChange: undefined, + onShowInformation: undefined, onForget: undefined, items: [ @@ -1352,6 +1365,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}', + }, + }, { xtype: 'menuseparator' }, { text: gettext('Remove'), diff --git a/www/window/SnapshotInfo.js b/www/window/SnapshotInfo.js new file mode 100644 index 00000000..f2cc7a55 --- /dev/null +++ b/www/window/SnapshotInfo.js @@ -0,0 +1,259 @@ +Ext.define('PBS.window.SnapshotInfo', { + extend: 'Ext.window.Window', + alias: 'widget.pbsSnapshotInfo', + + modal: true, + width: 700, + resizable: true, + 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: 'container', + layout: { + type: 'hbox', + align: 'stretch', + }, + items: [ + { + xtype: 'container', + flex: 1, + layout: { + type: 'vbox', + align: 'stretch', + }, + defaults: { + xtype: 'pmxInfoWidget', + printBar: false, + padding: '2 0', + }, + items: [ + { + xtype: 'box', + html: ` ${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', + }, + ], + }, + { + // spacer + xtype: 'box', + padding: 10, + }, + { + xtype: 'container', + flex: 1, + layout: { + type: 'vbox', + align: 'stretch', + }, + defaults: { + xtype: 'pmxInfoWidget', + printBar: false, + padding: '2 0', + }, + items: [ + { + xtype: 'box', + html: ` ${gettext('Verification')}`, + reference: 'verify-title', + padding: '0 0 10 0', + }, + { + title: gettext('Verify State'), + reference: 'verify-state', + }, + { + title: gettext('Last Verificaton'), + iconCls: 'fa fa-list-alt', + reference: 'verify-last', + }, + ], + }, + ], + }, + { + // spacer + xtype: 'box', + padding: 10, + }, + { + xtype: 'tabpanel', + height: 200, + items: [{ + title: gettext('Files'), + xtype: 'grid', + reference: 'files', + store: { + data: [], + }, + 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.indexOf(v); + if (modeIdx === -1) { + modeIdx = 0; + } + let iconCls = PBS.Utils.cryptIconCls[modeIdx]; + return ` ${PBS.Utils.cryptText[modeIdx]}`; + }, + }, + ], + }, { + xtype: 'box', + padding: 10, + style: { + 'white-space': 'pre', + }, + scrollable: true, + title: gettext('Comment'), + reference: 'comment', + }, { + xtype: 'box', + padding: 10, + style: { + 'white-space': 'pre', + }, + scrollable: true, + title: gettext('Group Comment'), + reference: 'group-comment', + }], + }, + ], + + 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('comment').setData(result.data.comment); + me.lookup('group-comment').setData(result.data['group-notes']); + + 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 = ` ${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').updateValue(Proxmox.Utils.NoneText); + me.lookup('verify-last').updateValue(Proxmox.Utils.NoneText); + } + + 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); + } + }, + failure: function(response, opts) { + Ext.Msg.alert(gettext('Error'), response.htmlStatus, function() { + me.close(); + }); + }, + }); + }, +}); -- 2.30.2