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 8804F68F8F for ; Mon, 1 Mar 2021 12:22:46 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 847F51E993 for ; Mon, 1 Mar 2021 12:22:46 +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 B237A1E978 for ; Mon, 1 Mar 2021 12:22:44 +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 78DD84580B for ; Mon, 1 Mar 2021 12:22:44 +0100 (CET) From: Dominik Csapak To: pbs-devel@lists.proxmox.com Date: Mon, 1 Mar 2021 12:22:41 +0100 Message-Id: <20210301112243.15842-3-d.csapak@proxmox.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210301112243.15842-1-d.csapak@proxmox.com> References: <20210301112243.15842-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.205 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 3/5] ui: NavigationTree: add entries for changers/drives 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: Mon, 01 Mar 2021 11:22:46 -0000 and only check TapeManagement once in the init function we now have 2 updatestores that update individually (one for datastores, one for drives/changers) Signed-off-by: Dominik Csapak --- www/NavigationTree.js | 103 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 89 insertions(+), 14 deletions(-) diff --git a/www/NavigationTree.js b/www/NavigationTree.js index e37447ce..8f9b366c 100644 --- a/www/NavigationTree.js +++ b/www/NavigationTree.js @@ -8,6 +8,16 @@ Ext.define('pbs-datastore-list', { idProperty: 'store', }); +Ext.define('pbs-tape-drive-list', { + extend: 'Ext.data.Model', + fields: ['name', 'changer'], + proxy: { + type: 'proxmox', + url: "/api2/json/tape/drive", + }, + idProperty: 'name', +}); + Ext.define('PBS.store.NavigationStore', { extend: 'Ext.data.TreeStore', @@ -101,34 +111,99 @@ Ext.define('PBS.view.main.NavigationTree', { view.rstore = Ext.create('Proxmox.data.UpdateStore', { autoStart: true, interval: 15 * 1000, - storeId: 'pbs-datastore-list', storeid: 'pbs-datastore-list', model: 'pbs-datastore-list', }); view.rstore.on('load', this.onLoad, this); view.on('destroy', view.rstore.stopUpdate); + + if (PBS.TapeManagement !== undefined) { + view.tapestore = Ext.create('Proxmox.data.UpdateStore', { + autoStart: true, + interval: 2 * 1000, + storeid: 'pbs-tape-drive-list', + model: 'pbs-tape-drive-list', + }); + + let root = view.getStore().getRoot(); + root.insertChild(3, { + text: "Tape Backup", + iconCls: 'pbs-icon-tape', + id: 'tape_management', + path: 'pbsTapeManagement', + expanded: true, + children: [], + }); + + view.tapestore.on('load', this.onTapeDriveLoad, this); + view.on('destroy', view.tapestore.stopUpdate); + } }, - onLoad: function(store, records, success) { + onTapeDriveLoad: function(store, records, success) { if (!success) return; - var view = this.getView(); + let view = this.getView(); let root = view.getStore().getRoot(); - if (PBS.TapeManagement !== undefined) { - if (!root.findChild('id', 'tape_management', false)) { - root.insertChild(3, { - text: "Tape Backup", - iconCls: 'pbs-icon-tape', - id: 'tape_management', - path: 'pbsTapeManagement', - expanded: true, - children: [], - }); + records.sort((a, b) => a.data.name.localeCompare(b.data.name)); + let list = root.findChild('id', 'tape_management', false); + let newSet = {}; + + for (const drive of records) { + let path, text, iconCls; + if (drive.data.changer !== undefined) { + text = drive.data.changer; + path = `Changer-${text}`; + iconCls = 'fa fa-circle'; + } else { + text = drive.data.name; + path = `Drive-${text}`; + iconCls = 'fa fa-square'; + } + newSet[path] = { + text, + path, + iconCls, + leaf: true, + }; + } + + let paths = Object.keys(newSet).sort(); + + let oldIdx = 0; + for (let newIdx = 0; newIdx < paths.length; newIdx++) { + let newPath = paths[newIdx]; + // find index to insert + while (oldIdx < list.childNodes.length && newPath > list.getChildAt(oldIdx).data.path) { + oldIdx++; + } + + if (oldIdx >= list.childNodes.length || list.getChildAt(oldIdx).data.path !== newPath) { + list.insertChild(oldIdx, newSet[newPath]); } } + list.eachChild((child) => { + if (!newSet[child.data.path]) { + list.removeChild(child, true); + } + }); + + if (view.pathToSelect !== undefined) { + let path = view.pathToSelect; + delete view.pathToSelect; + view.select(path, true); + } + }, + + onLoad: function(store, records, success) { + if (!success) return; + var view = this.getView(); + + let root = view.getStore().getRoot(); + records.sort((a, b) => a.id.localeCompare(b.id)); var list = root.findChild('id', 'datastores', false); @@ -191,7 +266,7 @@ Ext.define('PBS.view.main.NavigationTree', { select: function(path, silent) { var me = this; - if (me.rstore.isLoaded()) { + if (me.rstore.isLoaded() && (!PBS.TapeManagement || me.tapestore.isLoaded())) { if (silent) { me.suspendEvents(false); } -- 2.20.1