* [pbs-devel] [PATCH proxmox-widget-toolkit 1/3] window: add FileBrowser
2021-04-01 15:34 [pbs-devel] [PATCH 0/3] Move FileBrowser to widget-toolkit Stefan Reiter
@ 2021-04-01 15:34 ` Stefan Reiter
2021-04-13 6:00 ` [pbs-devel] applied: " Thomas Lamprecht
2021-04-01 15:34 ` [pbs-devel] [PATCH proxmox-widget-toolkit 2/3] FileBrowser: remove PBS dependencies Stefan Reiter
2021-04-01 15:34 ` [pbs-devel] [PATCH proxmox-backup 3/3] use FileBrowser from proxmox-widget-toolkit Stefan Reiter
2 siblings, 1 reply; 7+ messages in thread
From: Stefan Reiter @ 2021-04-01 15:34 UTC (permalink / raw)
To: pve-devel, pbs-devel
from proxmox-backup, only names changed
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
---
src/Makefile | 1 +
src/window/FileBrowser.js | 248 ++++++++++++++++++++++++++++++++++++++
2 files changed, 249 insertions(+)
create mode 100644 src/window/FileBrowser.js
diff --git a/src/Makefile b/src/Makefile
index 44c11ea..f97c74a 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -64,6 +64,7 @@ JSSRC= \
window/ACMEAccount.js \
window/ACMEPluginEdit.js \
window/ACMEDomains.js \
+ window/FileBrowser.js \
node/APT.js \
node/NetworkEdit.js \
node/NetworkView.js \
diff --git a/src/window/FileBrowser.js b/src/window/FileBrowser.js
new file mode 100644
index 0000000..82fd1b2
--- /dev/null
+++ b/src/window/FileBrowser.js
@@ -0,0 +1,248 @@
+Ext.define('proxmox-file-tree', {
+ extend: 'Ext.data.Model',
+
+ fields: ['filepath', 'text', 'type', 'size',
+ {
+ name: 'mtime',
+ type: 'date',
+ dateFormat: 'timestamp',
+ },
+ {
+ name: 'iconCls',
+ calculate: function(data) {
+ let icon = 'file-o';
+ switch (data.type) {
+ case 'b': // block device
+ icon = 'cube';
+ break;
+ case 'c': // char device
+ icon = 'tty';
+ break;
+ case 'd':
+ icon = data.expanded ? 'folder-open-o' : 'folder-o';
+ break;
+ case 'f': //regular file
+ icon = 'file-text-o';
+ break;
+ case 'h': // hardlink
+ icon = 'file-o';
+ break;
+ case 'l': // softlink
+ icon = 'link';
+ break;
+ case 'p': // pipe/fifo
+ icon = 'exchange';
+ break;
+ case 's': // socket
+ icon = 'plug';
+ break;
+ default:
+ icon = 'file-o';
+ break;
+ }
+
+ return `fa fa-${icon}`;
+ },
+ },
+ ],
+ idProperty: 'filepath',
+});
+
+Ext.define("Proxmox.window.FileBrowser", {
+ extend: "Ext.window.Window",
+
+ width: 800,
+ height: 600,
+
+ modal: true,
+
+ controller: {
+ xclass: 'Ext.app.ViewController',
+
+ buildUrl: function(baseurl, params) {
+ let url = new URL(baseurl, window.location.origin);
+ for (const [key, value] of Object.entries(params)) {
+ url.searchParams.append(key, value);
+ }
+
+ return url.href;
+ },
+
+ downloadFile: function() {
+ let me = this;
+ let view = me.getView();
+ let tree = me.lookup('tree');
+ let selection = tree.getSelection();
+ if (!selection || selection.length < 1) return;
+
+ let data = selection[0].data;
+
+ let atag = document.createElement('a');
+
+ atag.download = data.text;
+ let params = {
+ 'backup-id': view['backup-id'],
+ 'backup-type': view['backup-type'],
+ 'backup-time': view['backup-time'],
+ };
+ params.filepath = data.filepath;
+ atag.download = data.text;
+ if (data.type === 'd') {
+ atag.download += ".zip";
+ }
+ atag.href = me
+ .buildUrl(`/api2/json/admin/datastore/${view.datastore}/pxar-file-download`, params);
+ atag.click();
+ },
+
+ fileChanged: function() {
+ let me = this;
+ let tree = me.lookup('tree');
+ let selection = tree.getSelection();
+ if (!selection || selection.length < 1) return;
+
+ let data = selection[0].data;
+
+ let canDownload = false;
+ switch (data.type) {
+ case 'h':
+ case 'f':
+ canDownload = true;
+ break;
+ case 'd':
+ if (data.depth > 1) {
+ canDownload = true;
+ }
+ break;
+ default: break;
+ }
+
+ me.lookup('downloadBtn').setDisabled(!canDownload);
+ },
+
+ init: function(view) {
+ let me = this;
+ let tree = me.lookup('tree');
+
+ if (!view['backup-id']) {
+ throw "no backup-id given";
+ }
+
+ if (!view['backup-type']) {
+ throw "no backup-id given";
+ }
+
+ if (!view['backup-time']) {
+ throw "no backup-id given";
+ }
+
+ let store = tree.getStore();
+ let proxy = store.getProxy();
+
+ Proxmox.Utils.monStoreErrors(tree, store, true);
+ proxy.setUrl(`/api2/json/admin/datastore/${view.datastore}/catalog`);
+ proxy.setExtraParams({
+ 'backup-id': view['backup-id'],
+ 'backup-type': view['backup-type'],
+ 'backup-time': view['backup-time'],
+ });
+ store.load(() => {
+ let root = store.getRoot();
+ root.expand(); // always expand invisible root node
+ if (view.archive) {
+ let child = root.findChild('text', view.archive);
+ if (child) {
+ child.expand();
+ setTimeout(function() {
+ tree.setSelection(child);
+ tree.getView().focusRow(child);
+ }, 10);
+ }
+ } else if (root.childNodes.length === 1) {
+ root.firstChild.expand();
+ }
+ });
+ },
+
+ control: {
+ 'treepanel': {
+ selectionchange: 'fileChanged',
+ },
+ },
+ },
+
+ layout: 'fit',
+ items: [
+ {
+ xtype: 'treepanel',
+ scrollable: true,
+ rootVisible: false,
+ reference: 'tree',
+ store: {
+ autoLoad: false,
+ model: 'proxmox-file-tree',
+ defaultRootId: '/',
+ nodeParam: 'filepath',
+ sorters: 'text',
+ proxy: {
+ appendId: false,
+ type: 'proxmox',
+ },
+ },
+
+ columns: [
+ {
+ text: gettext('Name'),
+ xtype: 'treecolumn',
+ flex: 1,
+ dataIndex: 'text',
+ renderer: Ext.String.htmlEncode,
+ },
+ {
+ text: gettext('Size'),
+ dataIndex: 'size',
+ renderer: value => value === undefined ? '' : Proxmox.Utils.format_size(value),
+ sorter: {
+ sorterFn: function(a, b) {
+ let asize = a.data.size || 0;
+ let bsize = b.data.size || 0;
+
+ return asize - bsize;
+ },
+ },
+ },
+ {
+ text: gettext('Modified'),
+ dataIndex: 'mtime',
+ minWidth: 200,
+ },
+ {
+ text: gettext('Type'),
+ dataIndex: 'type',
+ renderer: function(value) {
+ switch (value) {
+ case 'b': return gettext('Block Device');
+ case 'c': return gettext('Character Device');
+ case 'd': return gettext('Directory');
+ case 'f': return gettext('File');
+ case 'h': return gettext('Hardlink');
+ case 'l': return gettext('Softlink');
+ case 'p': return gettext('Pipe/Fifo');
+ case 's': return gettext('Socket');
+ default: return Proxmox.Utils.unknownText;
+ }
+ },
+ },
+ ],
+ },
+ ],
+
+ buttons: [
+ {
+ text: gettext('Download'),
+ handler: 'downloadFile',
+ reference: 'downloadBtn',
+ disabled: true,
+ },
+ ],
+});
--
2.20.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [pbs-devel] [PATCH proxmox-widget-toolkit 2/3] FileBrowser: remove PBS dependencies
2021-04-01 15:34 [pbs-devel] [PATCH 0/3] Move FileBrowser to widget-toolkit Stefan Reiter
2021-04-01 15:34 ` [pbs-devel] [PATCH proxmox-widget-toolkit 1/3] window: add FileBrowser Stefan Reiter
@ 2021-04-01 15:34 ` Stefan Reiter
2021-04-13 6:00 ` [pbs-devel] applied: " Thomas Lamprecht
2021-04-01 15:34 ` [pbs-devel] [PATCH proxmox-backup 3/3] use FileBrowser from proxmox-widget-toolkit Stefan Reiter
2 siblings, 1 reply; 7+ messages in thread
From: Stefan Reiter @ 2021-04-01 15:34 UTC (permalink / raw)
To: pve-devel, pbs-devel
Don't construct any URLs locally, instead have them (and their static
parameters) be passed in. This removes the need to have the datastore.
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
---
src/window/FileBrowser.js | 52 ++++++++++++++-------------------------
1 file changed, 19 insertions(+), 33 deletions(-)
diff --git a/src/window/FileBrowser.js b/src/window/FileBrowser.js
index 82fd1b2..d8e75f4 100644
--- a/src/window/FileBrowser.js
+++ b/src/window/FileBrowser.js
@@ -80,23 +80,19 @@ Ext.define("Proxmox.window.FileBrowser", {
let atag = document.createElement('a');
atag.download = data.text;
- let params = {
- 'backup-id': view['backup-id'],
- 'backup-type': view['backup-type'],
- 'backup-time': view['backup-time'],
- };
+ let params = { ...view.extraParams };
params.filepath = data.filepath;
atag.download = data.text;
if (data.type === 'd') {
atag.download += ".zip";
}
- atag.href = me
- .buildUrl(`/api2/json/admin/datastore/${view.datastore}/pxar-file-download`, params);
+ atag.href = me.buildUrl(view.downloadUrl, params);
atag.click();
},
fileChanged: function() {
let me = this;
+ let view = me.getView();
let tree = me.lookup('tree');
let selection = tree.getSelection();
if (!selection || selection.length < 1) return;
@@ -104,17 +100,19 @@ Ext.define("Proxmox.window.FileBrowser", {
let data = selection[0].data;
let canDownload = false;
- switch (data.type) {
- case 'h':
- case 'f':
- canDownload = true;
- break;
- case 'd':
- if (data.depth > 1) {
+ if (view.downloadUrl) {
+ switch (data.type) {
+ case 'h':
+ case 'f':
canDownload = true;
- }
- break;
- default: break;
+ break;
+ case 'd':
+ if (data.depth > 1) {
+ canDownload = true;
+ }
+ break;
+ default: break;
+ }
}
me.lookup('downloadBtn').setDisabled(!canDownload);
@@ -124,28 +122,16 @@ Ext.define("Proxmox.window.FileBrowser", {
let me = this;
let tree = me.lookup('tree');
- if (!view['backup-id']) {
- throw "no backup-id given";
- }
-
- if (!view['backup-type']) {
- throw "no backup-id given";
- }
-
- if (!view['backup-time']) {
- throw "no backup-id given";
+ if (!view.listUrl) {
+ throw "no list URL given";
}
let store = tree.getStore();
let proxy = store.getProxy();
Proxmox.Utils.monStoreErrors(tree, store, true);
- proxy.setUrl(`/api2/json/admin/datastore/${view.datastore}/catalog`);
- proxy.setExtraParams({
- 'backup-id': view['backup-id'],
- 'backup-type': view['backup-type'],
- 'backup-time': view['backup-time'],
- });
+ proxy.setUrl(view.listUrl);
+ proxy.setExtraParams(view.extraParams);
store.load(() => {
let root = store.getRoot();
root.expand(); // always expand invisible root node
--
2.20.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [pbs-devel] [PATCH proxmox-backup 3/3] use FileBrowser from proxmox-widget-toolkit
2021-04-01 15:34 [pbs-devel] [PATCH 0/3] Move FileBrowser to widget-toolkit Stefan Reiter
2021-04-01 15:34 ` [pbs-devel] [PATCH proxmox-widget-toolkit 1/3] window: add FileBrowser Stefan Reiter
2021-04-01 15:34 ` [pbs-devel] [PATCH proxmox-widget-toolkit 2/3] FileBrowser: remove PBS dependencies Stefan Reiter
@ 2021-04-01 15:34 ` Stefan Reiter
2021-04-13 7:15 ` [pbs-devel] applied: " Thomas Lamprecht
2 siblings, 1 reply; 7+ messages in thread
From: Stefan Reiter @ 2021-04-01 15:34 UTC (permalink / raw)
To: pve-devel, pbs-devel
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
---
Requires bumped proxmox-widget-toolkit of course.
www/Makefile | 1 -
www/datastore/Content.js | 13 +-
www/window/FileBrowser.js | 252 --------------------------------------
3 files changed, 8 insertions(+), 258 deletions(-)
delete mode 100644 www/window/FileBrowser.js
diff --git a/www/Makefile b/www/Makefile
index 1790273f..2b847e74 100644
--- a/www/Makefile
+++ b/www/Makefile
@@ -61,7 +61,6 @@ JSSRC= \
window/BackupGroupChangeOwner.js \
window/CreateDirectory.js \
window/DataStoreEdit.js \
- window/FileBrowser.js \
window/NotesEdit.js \
window/RemoteEdit.js \
window/NotifyOptions.js \
diff --git a/www/datastore/Content.js b/www/datastore/Content.js
index d0cf3e0b..a6c77f63 100644
--- a/www/datastore/Content.js
+++ b/www/datastore/Content.js
@@ -452,12 +452,15 @@ Ext.define('PBS.DataStoreContent', {
let type = data['backup-type'];
let timetext = PBS.Utils.render_datetime_utc(data["backup-time"]);
- Ext.create('PBS.window.FileBrowser', {
+ Ext.create('Proxmox.window.FileBrowser', {
title: `${type}/${id}/${timetext}`,
- datastore: view.datastore,
- 'backup-id': id,
- 'backup-time': (time.getTime()/1000).toFixed(0),
- 'backup-type': type,
+ listUrl: `/api2/json/admin/datastore/${view.datastore}/catalog`,
+ downloadUrl: `/api2/json/admin/datastore/${view.datastore}/pxar-file-download`,
+ extraParams: {
+ 'backup-id': id,
+ 'backup-time': (time.getTime()/1000).toFixed(0),
+ 'backup-type': type,
+ },
archive: rec.data.filename,
}).show();
},
diff --git a/www/window/FileBrowser.js b/www/window/FileBrowser.js
deleted file mode 100644
index 724e1791..00000000
--- a/www/window/FileBrowser.js
+++ /dev/null
@@ -1,252 +0,0 @@
-Ext.define('pbs-file-tree', {
- extend: 'Ext.data.Model',
-
- fields: ['filepath', 'text', 'type', 'size',
- {
- name: 'mtime',
- type: 'date',
- dateFormat: 'timestamp',
- },
- {
- name: 'iconCls',
- calculate: function(data) {
- let icon = 'file-o';
- switch (data.type) {
- case 'b': // block device
- icon = 'cube';
- break;
- case 'c': // char device
- icon = 'tty';
- break;
- case 'd':
- icon = data.expanded ? 'folder-open-o' : 'folder-o';
- break;
- case 'f': //regular file
- icon = 'file-text-o';
- break;
- case 'h': // hardlink
- icon = 'file-o';
- break;
- case 'l': // softlink
- icon = 'link';
- break;
- case 'p': // pipe/fifo
- icon = 'exchange';
- break;
- case 's': // socket
- icon = 'plug';
- break;
- default:
- icon = 'file-o';
- break;
- }
-
- return `fa fa-${icon}`;
- },
- },
- ],
- idProperty: 'filepath',
-});
-
-Ext.define("PBS.window.FileBrowser", {
- extend: "Ext.window.Window",
-
- width: 800,
- height: 600,
-
- modal: true,
-
- controller: {
- xclass: 'Ext.app.ViewController',
-
- buildUrl: function(baseurl, params) {
- let url = new URL(baseurl, window.location.origin);
- for (const [key, value] of Object.entries(params)) {
- url.searchParams.append(key, value);
- }
-
- return url.href;
- },
-
- downloadFile: function() {
- let me = this;
- let view = me.getView();
- let tree = me.lookup('tree');
- let selection = tree.getSelection();
- if (!selection || selection.length < 1) return;
-
- let data = selection[0].data;
-
- let atag = document.createElement('a');
-
- atag.download = data.text;
- let params = {
- 'backup-id': view['backup-id'],
- 'backup-type': view['backup-type'],
- 'backup-time': view['backup-time'],
- };
- params.filepath = data.filepath;
- atag.download = data.text;
- if (data.type === 'd') {
- atag.download += ".zip";
- }
- atag.href = me
- .buildUrl(`/api2/json/admin/datastore/${view.datastore}/pxar-file-download`, params);
- atag.click();
- },
-
- fileChanged: function() {
- let me = this;
- let tree = me.lookup('tree');
- let selection = tree.getSelection();
- if (!selection || selection.length < 1) return;
-
- let data = selection[0].data;
-
- let canDownload = false;
- switch (data.type) {
- case 'h':
- case 'f':
- canDownload = true;
- break;
- case 'd':
- if (data.depth > 1) {
- canDownload = true;
- }
- break;
- default: break;
- }
-
- me.lookup('downloadBtn').setDisabled(!canDownload);
- },
-
- init: function(view) {
- let me = this;
- let tree = me.lookup('tree');
-
- if (!view['backup-id']) {
- throw "no backup-id given";
- }
-
- if (!view['backup-type']) {
- throw "no backup-id given";
- }
-
- if (!view['backup-time']) {
- throw "no backup-id given";
- }
-
- if (!view.datastore) {
- throw "no datastore given";
- }
-
- let store = tree.getStore();
- let proxy = store.getProxy();
-
- Proxmox.Utils.monStoreErrors(tree, store, true);
- proxy.setUrl(`/api2/json/admin/datastore/${view.datastore}/catalog`);
- proxy.setExtraParams({
- 'backup-id': view['backup-id'],
- 'backup-type': view['backup-type'],
- 'backup-time': view['backup-time'],
- });
- store.load(() => {
- let root = store.getRoot();
- root.expand(); // always expand invisible root node
- if (view.archive) {
- let child = root.findChild('text', view.archive);
- if (child) {
- child.expand();
- setTimeout(function() {
- tree.setSelection(child);
- tree.getView().focusRow(child);
- }, 10);
- }
- } else if (root.childNodes.length === 1) {
- root.firstChild.expand();
- }
- });
- },
-
- control: {
- 'treepanel': {
- selectionchange: 'fileChanged',
- },
- },
- },
-
- layout: 'fit',
- items: [
- {
- xtype: 'treepanel',
- scrollable: true,
- rootVisible: false,
- reference: 'tree',
- store: {
- autoLoad: false,
- model: 'pbs-file-tree',
- defaultRootId: '/',
- nodeParam: 'filepath',
- sorters: 'text',
- proxy: {
- appendId: false,
- type: 'proxmox',
- },
- },
-
- columns: [
- {
- text: gettext('Name'),
- xtype: 'treecolumn',
- flex: 1,
- dataIndex: 'text',
- renderer: Ext.String.htmlEncode,
- },
- {
- text: gettext('Size'),
- dataIndex: 'size',
- renderer: value => value === undefined ? '' : Proxmox.Utils.format_size(value),
- sorter: {
- sorterFn: function(a, b) {
- let asize = a.data.size || 0;
- let bsize = b.data.size || 0;
-
- return asize - bsize;
- },
- },
- },
- {
- text: gettext('Modified'),
- dataIndex: 'mtime',
- minWidth: 200,
- },
- {
- text: gettext('Type'),
- dataIndex: 'type',
- renderer: function(value) {
- switch (value) {
- case 'b': return gettext('Block Device');
- case 'c': return gettext('Character Device');
- case 'd': return gettext('Directory');
- case 'f': return gettext('File');
- case 'h': return gettext('Hardlink');
- case 'l': return gettext('Softlink');
- case 'p': return gettext('Pipe/Fifo');
- case 's': return gettext('Socket');
- default: return Proxmox.Utils.unknownText;
- }
- },
- },
- ],
- },
- ],
-
- buttons: [
- {
- text: gettext('Download'),
- handler: 'downloadFile',
- reference: 'downloadBtn',
- disabled: true,
- },
- ],
-});
--
2.20.1
^ permalink raw reply [flat|nested] 7+ messages in thread