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 AE22F62A9D for ; Tue, 27 Oct 2020 16:21:13 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 489FC18C43 for ; Tue, 27 Oct 2020 16:20:18 +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 129D318C31 for ; Tue, 27 Oct 2020 16:20:16 +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 D152345F5E for ; Tue, 27 Oct 2020 16:20:15 +0100 (CET) From: Dominik Csapak To: pbs-devel@lists.proxmox.com Date: Tue, 27 Oct 2020 16:20:09 +0100 Message-Id: <20201027152011.7373-7-d.csapak@proxmox.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20201027152011.7373-1-d.csapak@proxmox.com> References: <20201027152011.7373-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.453 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 URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [data.name, data.id, a.id] Subject: [pbs-devel] [PATCH proxmox-backup 6/8] ui: NavigationTree: add 'Add Datastore' button below datastore list 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, 27 Oct 2020 15:21:13 -0000 and make 'Datastore' unclickable since we have all options and information on the relevant datastore panels, we do not need a datastore config anymore (besides the creation, which we add here) this also fixes the sorted insertion and removal of new/old datastores Signed-off-by: Dominik Csapak --- www/Makefile | 1 - www/NavigationTree.js | 67 ++++++++-- www/config/DataStoreConfig.js | 227 ---------------------------------- 3 files changed, 54 insertions(+), 241 deletions(-) delete mode 100644 www/config/DataStoreConfig.js diff --git a/www/Makefile b/www/Makefile index 97b9b848..75d389d9 100644 --- a/www/Makefile +++ b/www/Makefile @@ -17,7 +17,6 @@ JSSRC= \ config/ACLView.js \ config/SyncView.js \ config/VerifyView.js \ - config/DataStoreConfig.js \ window/UserEdit.js \ window/UserPassword.js \ window/VerifyJobEdit.js \ diff --git a/www/NavigationTree.js b/www/NavigationTree.js index c37e2613..54e0adeb 100644 --- a/www/NavigationTree.js +++ b/www/NavigationTree.js @@ -1,3 +1,13 @@ +Ext.define('pbs-datastore-list', { + extend: 'Ext.data.Model', + fields: ['name', 'comment'], + proxy: { + type: 'proxmox', + url: "/api2/json/admin/datastore", + }, + idProperty: 'store', +}); + Ext.define('PBS.store.NavigationStore', { extend: 'Ext.data.TreeStore', @@ -76,9 +86,18 @@ Ext.define('PBS.store.NavigationStore', { { text: gettext('Datastore'), iconCls: 'fa fa-archive', - path: 'pbsDataStoreConfig', + id: 'datastores', expanded: true, + expandable: false, leaf: false, + children: [ + { + text: gettext('Add Datastore'), + iconCls: 'fa fa-plus-circle', + leaf: true, + id: 'addbutton', + }, + ], }, ], }, @@ -110,21 +129,23 @@ Ext.define('PBS.view.main.NavigationTree', { let root = view.getStore().getRoot(); - // FIXME: newly added always get appended to the end.. - records.sort((a, b) => { - if (a.id > b.id) return 1; - if (a.id < b.id) return -1; - return 0; - }); + records.sort((a, b) => a.id.localeCompare(b.id)); - var list = root.findChild('path', 'pbsDataStoreConfig', false); + var list = root.findChild('id', 'datastores', false); var length = records.length; var lookup_hash = {}; - for (var i = 0; i < length; i++) { + let j = 0; + for (let i = 0; i < length; i++) { let name = records[i].id; lookup_hash[name] = true; - if (!list.findChild('text', name, false)) { - list.appendChild({ + + while (name.localeCompare(list.getChildAt(j).data.text) > 0 && + (j + 1) < list.childNodes.length) { + j++; + } + + if (list.getChildAt(j).data.text.localeCompare(name) !== 0) { + list.insertChild(j, { text: name, path: `DataStore-${name}`, iconCls: 'fa fa-database', @@ -136,12 +157,32 @@ Ext.define('PBS.view.main.NavigationTree', { var erase_list = []; list.eachChild(function(node) { let name = node.data.text; - if (!lookup_hash[name]) { + if (!lookup_hash[name] && node.data.id !== 'addbutton') { erase_list.push(node); } }); - Ext.Array.forEach(erase_list, function(node) { node.erase(); }); + Ext.Array.forEach(erase_list, function(node) { list.removeChild(node, true); }); + }, + }, + + listeners: { + itemclick: function(tl, info) { + if (info.node.data.id === 'datastores') { + return false; + } + if (info.node.data.id === 'addbutton') { + let me = this; + Ext.create('PBS.DataStoreEdit', { + listeners: { + destroy: function() { + me.rstore.reload(); + }, + }, + }).show(); + return false; + } + return true; }, }, diff --git a/www/config/DataStoreConfig.js b/www/config/DataStoreConfig.js deleted file mode 100644 index 440feea5..00000000 --- a/www/config/DataStoreConfig.js +++ /dev/null @@ -1,227 +0,0 @@ -Ext.define('pbs-datastore-list', { - extend: 'Ext.data.Model', - fields: ['name', 'comment'], - proxy: { - type: 'proxmox', - url: "/api2/json/admin/datastore", - }, - idProperty: 'store', -}); - -Ext.define('pbs-data-store-config', { - extend: 'Ext.data.Model', - fields: [ - 'name', 'path', 'comment', 'gc-schedule', 'prune-schedule', - 'keep-last', 'keep-hourly', 'keep-daily', - 'keep-weekly', 'keep-monthly', 'keep-yearly', - ], - proxy: { - type: 'proxmox', - url: "/api2/json/config/datastore", - }, - idProperty: 'name', -}); - -Ext.define('PBS.DataStoreConfig', { - extend: 'Ext.grid.GridPanel', - alias: 'widget.pbsDataStoreConfig', - - title: gettext('Datastore Configuration'), - - controller: { - xclass: 'Ext.app.ViewController', - - createDataStore: function() { - let me = this; - Ext.create('PBS.DataStoreEdit', { - listeners: { - destroy: function() { - me.reload(); - }, - }, - }).show(); - }, - - editDataStore: function() { - let me = this; - let view = me.getView(); - let selection = view.getSelection(); - if (selection.length < 1) return; - - let name = encodeURIComponent(selection[0].data.name); - Ext.create('PBS.DataStoreEdit', { - name: name, - listeners: { - destroy: function() { - me.reload(); - }, - }, - }).show(); - }, - - onVerify: function() { - var view = this.getView(); - - let rec = view.selModel.getSelection()[0]; - if (!(rec && rec.data)) return; - let data = rec.data; - - Proxmox.Utils.API2Request({ - url: `/admin/datastore/${data.name}/verify`, - method: 'POST', - failure: function(response) { - Ext.Msg.alert(gettext('Error'), response.htmlStatus); - }, - success: function(response, options) { - Ext.create('Proxmox.window.TaskViewer', { - upid: response.result.data, - }).show(); - }, - }); - }, - - garbageCollect: function() { - let me = this; - let view = me.getView(); - let selection = view.getSelection(); - if (selection.length < 1) return; - - let name = encodeURIComponent(selection[0].data.name); - Proxmox.Utils.API2Request({ - url: `/admin/datastore/${name}/gc`, - method: 'POST', - failure: function(response) { - Ext.Msg.alert(gettext('Error'), response.htmlStatus); - }, - success: function(response, options) { - Ext.create('Proxmox.window.TaskViewer', { - upid: response.result.data, - }).show(); - }, - }); - }, - - reload: function() { this.getView().getStore().rstore.load(); }, - - init: function(view) { - Proxmox.Utils.monStoreErrors(view, view.getStore().rstore); - }, - }, - - store: { - type: 'diff', - autoDestroy: true, - autoDestroyRstore: true, - sorters: 'name', - rstore: { - type: 'update', - storeid: 'pbs-data-store-config', - model: 'pbs-data-store-config', - autoStart: true, - interval: 10000, - }, - }, - - tbar: [ - { - xtype: 'proxmoxButton', - selModel: false, - text: gettext('Create'), - handler: 'createDataStore', - }, - { - xtype: 'proxmoxButton', - text: gettext('Edit'), - disabled: true, - handler: 'editDataStore', - }, - // remove_btn - '-', - { - xtype: 'proxmoxButton', - text: gettext('Verify'), - disabled: true, - handler: 'onVerify', - }, - { - xtype: 'proxmoxButton', - text: gettext('Start GC'), - disabled: true, - handler: 'garbageCollect', - }, - ], - - columns: [ - { - header: gettext('Name'), - sortable: true, - dataIndex: 'name', - flex: 1, - }, - { - header: gettext('Path'), - sortable: true, - dataIndex: 'path', - flex: 1, - }, - { - header: gettext('GC Schedule'), - sortable: false, - width: 120, - dataIndex: 'gc-schedule', - }, - { - header: gettext('Prune Schedule'), - sortable: false, - width: 120, - dataIndex: 'prune-schedule', - }, - { - header: gettext('Keep'), - columns: [ - { - text: gettext('Last'), - dataIndex: 'keep-last', - width: 70, - }, - { - text: gettext('Hourly'), - dataIndex: 'keep-hourly', - width: 70, - }, - { - text: gettext('Daily'), - dataIndex: 'keep-daily', - width: 70, - }, - { - text: gettext('Weekly'), - dataIndex: 'keep-weekly', - width: 70, - }, - { - text: gettext('Monthly'), - dataIndex: 'keep-monthly', - width: 70, - }, - { - text: gettext('Yearly'), - dataIndex: 'keep-yearly', - width: 70, - }, - ], - }, - { - header: gettext('Comment'), - sortable: false, - dataIndex: 'comment', - renderer: Ext.String.htmlEncode, - flex: 2, - }, - ], - - listeners: { - activate: 'reload', - itemdblclick: 'editDataStore', - }, -}); -- 2.20.1