From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <d.csapak@proxmox.com>
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 <pbs-devel@lists.proxmox.com>; 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 <pbs-devel@lists.proxmox.com>; 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 <pbs-devel@lists.proxmox.com>; 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 <pbs-devel@lists.proxmox.com>; Mon,  1 Mar 2021 12:22:44 +0100 (CET)
From: Dominik Csapak <d.csapak@proxmox.com>
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
 <pbs-devel.lists.proxmox.com>
List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pbs-devel>, 
 <mailto:pbs-devel-request@lists.proxmox.com?subject=unsubscribe>
List-Archive: <http://lists.proxmox.com/pipermail/pbs-devel/>
List-Post: <mailto:pbs-devel@lists.proxmox.com>
List-Help: <mailto:pbs-devel-request@lists.proxmox.com?subject=help>
List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel>, 
 <mailto:pbs-devel-request@lists.proxmox.com?subject=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 <d.csapak@proxmox.com>
---
 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