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 C4C2F6B9AE for ; Wed, 27 Jan 2021 11:34:40 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 6247A211C9 for ; Wed, 27 Jan 2021 11:34:08 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [212.186.127.180]) (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 id 8FE0B20FF4 for ; Wed, 27 Jan 2021 11:34:03 +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 5A6EF46136 for ; Wed, 27 Jan 2021 11:34:03 +0100 (CET) From: Dominik Csapak To: pbs-devel@lists.proxmox.com Date: Wed, 27 Jan 2021 11:33:56 +0100 Message-Id: <20210127103401.32535-11-d.csapak@proxmox.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210127103401.32535-1-d.csapak@proxmox.com> References: <20210127103401.32535-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.255 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pbs-devel] [PATCH proxmox-backup 10/15] ui: tape: add BackupOverview Panel 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: Wed, 27 Jan 2021 10:34:40 -0000 shows all tapes with the relevant info * which pool it belongs to * what backups are on it * which media-set * location * etc. This is very rough, and maybe not the best way to display this information. It may make sense to reverse the tree, i.e. having pools at top-level, then media-sets, then tapes, then snapshots.. Signed-off-by: Dominik Csapak --- www/Makefile | 1 + www/tape/BackupOverview.js | 150 +++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 www/tape/BackupOverview.js diff --git a/www/Makefile b/www/Makefile index 827633a3..aad5f7ce 100644 --- a/www/Makefile +++ b/www/Makefile @@ -20,6 +20,7 @@ TAPE_UI_FILES= \ tape/window/LabelMedia.js \ tape/window/PoolEdit.js \ tape/window/TapeBackup.js \ + tape/BackupOverview.js \ TapeManagement.js endif diff --git a/www/tape/BackupOverview.js b/www/tape/BackupOverview.js new file mode 100644 index 00000000..4743dcc0 --- /dev/null +++ b/www/tape/BackupOverview.js @@ -0,0 +1,150 @@ +Ext.define('PBS.TapeManagement.BackupOverview', { + extend: 'Ext.tree.Panel', + alias: 'widget.pbsBackupOverview', + + controller: { + xclass: 'Ext.app.ViewController', + + backup: function() { + let me = this; + Ext.create('PBS.TapeManagement.TapeBackupWindow', { + listeners: { + destroy: function() { + me.reload(); + }, + }, + }).show(); + }, + + reload: async function() { + let me = this; + let view = me.getView(); + + Proxmox.Utils.setErrorMask(view, true); + + try { + let list_response = await PBS.Async.api2({ + url: '/api2/extjs/tape/media/list', + }); + let list = list_response.result.data.sort( + (a, b) => a['label-text'].localeCompare(b['label-text']), + ); + + let content = {}; + + let content_response = await PBS.Async.api2({ + url: '/api2/extjs/tape/media/content', + }); + + let content_list = content_response.result.data.sort( + (a, b) => a.snapshot.localeCompare(b.snapshot), + ); + + for (let entry of content_list) { + let tape = entry['label-text']; + entry['label-text'] = entry.snapshot; + entry.leaf = true; + if (content[tape] === undefined) { + content[tape] = [entry]; + } else { + content[tape].push(entry); + } + } + + for (let child of list) { + let tape = child['label-text']; + if (content[tape]) { + child.children = content[tape]; + child.leaf = false; + } else { + child.leaf = true; + } + } + + view.setRootNode({ + expanded: true, + children: list, + }); + + Proxmox.Utils.setErrorMask(view, false); + } catch (error) { + Proxmox.Utils.setErrorMask(view, error.toString()); + } + }, + }, + + listeners: { + activate: 'reload', + }, + + store: { + sorters: 'label-text', + data: [], + }, + + rootVisible: false, + + tbar: [ + { + text: gettext('Reload'), + handler: 'reload', + }, + '-', + { + text: gettext('New Backup'), + handler: 'backup', + }, + ], + + columns: [ + { + xtype: 'treecolumn', + text: gettext('Tape/Backup'), + dataIndex: 'label-text', + flex: 3, + }, + { + text: gettext('Location'), + dataIndex: 'location', + flex: 1, + renderer: function(value) { + if (!value) { + return ""; + } + let result; + if ((result = /^online-(.+)$/.exec(value)) !== null) { + return Ext.htmlEncode(result[1]); + } + + return value; + }, + }, + { + text: gettext('Status'), + dataIndex: 'status', + flex: 1, + }, + { + text: gettext('Media Set'), + dataIndex: 'media-set-name', + flex: 2, + }, + { + text: gettext('Pool'), + dataIndex: 'pool', + flex: 1, + }, + { + text: gettext('Sequence Nr.'), + dataIndex: 'seq-nr', + flex: 0.5, + }, + { + text: gettext('Backup Time'), + dataIndex: 'backup-time', + renderer: (time) => time !== undefined ? new Date(time*1000) : "", + flex: 1, + }, + ], +}); + -- 2.20.1