From: Lorenz Stechauner <l.stechauner@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH manager 3/5] ui: refactor UploadToStorage.js
Date: Tue, 20 Jul 2021 13:51:45 +0200 [thread overview]
Message-ID: <20210720115147.1988565-7-l.stechauner@proxmox.com> (raw)
In-Reply-To: <20210720115147.1988565-1-l.stechauner@proxmox.com>
this also removes the "content" selector from the window.
as far as it seems, this selector was never able to select
more than one entry, so it was useless.
Signed-off-by: Lorenz Stechauner <l.stechauner@proxmox.com>
---
www/manager6/storage/ContentView.js | 2 +-
www/manager6/window/UploadToStorage.js | 359 +++++++++++++++----------
2 files changed, 213 insertions(+), 148 deletions(-)
diff --git a/www/manager6/storage/ContentView.js b/www/manager6/storage/ContentView.js
index ca0ad664..00a94f3c 100644
--- a/www/manager6/storage/ContentView.js
+++ b/www/manager6/storage/ContentView.js
@@ -69,7 +69,7 @@ Ext.define('PVE.storage.ContentView', {
Ext.create('PVE.window.UploadToStorage', {
nodename: nodename,
storage: storage,
- contents: [content],
+ content: content,
autoShow: true,
taskDone: () => reload(),
});
diff --git a/www/manager6/window/UploadToStorage.js b/www/manager6/window/UploadToStorage.js
index 3c35020a..75423b0f 100644
--- a/www/manager6/window/UploadToStorage.js
+++ b/www/manager6/window/UploadToStorage.js
@@ -1,191 +1,256 @@
Ext.define('PVE.window.UploadToStorage', {
extend: 'Ext.window.Window',
alias: 'widget.pveStorageUpload',
+ mixins: ['Proxmox.Mixin.CBind'],
resizable: false,
-
modal: true,
- initComponent: function() {
- var me = this;
+ title: gettext('Upload'),
- if (!me.nodename) {
- throw "no node name specified";
- }
- if (!me.storage) {
- throw "no storage ID specified";
- }
+ acceptedExtensions: {
+ iso: ['.img', '.iso'],
+ vztmpl: ['.tar.gz', '.tar.xz'],
+ },
- let baseurl = `/nodes/${me.nodename}/storage/${me.storage}/upload`;
+ cbindData: function(initialConfig) {
+ const me = this;
+ return {
+ nodename: me.nodename,
+ storage: me.storage,
+ content: me.content,
+ extensions: me.acceptedExtensions[me.content].join(', '),
+ };
+ },
- let pbar = Ext.create('Ext.ProgressBar', {
- text: 'Ready',
- hidden: true,
- });
+ cbind: {
+ url: `/nodes/{nodename}/storage/{storage}/upload`,
+ },
- let acceptedExtensions = {
- iso: ".img, .iso",
- vztmpl: ".tar.gz, .tar.xz",
- };
+ viewModel: {
+ data: {
+ size: '-',
+ mimetype: '-',
+ filename: '',
+ },
+ },
- let defaultContent = me.contents[0] || '';
+ controller: {
+ submit: function(button) {
+ const view = this.getView();
+ const form = Ext.getCmp('formPanel').getForm();
+ const abortBtn = Ext.getCmp('abortBtn');
+ const pbar = Ext.getCmp('progressBar');
- let fileField = Ext.create('Ext.form.field.File', {
- name: 'filename',
- buttonText: gettext('Select File...'),
- allowBlank: false,
- setAccept: function(content) {
- let acceptString = acceptedExtensions[content] || '';
- this.fileInputEl.set({
- accept: acceptString,
+ const doStandardSubmit = function() {
+ form.submit({
+ url: "/api2/htmljs" + view.url,
+ waitMsg: gettext('Uploading file...'),
+ success: function(f, action) {
+ view.close();
+ },
+ failure: function(f, action) {
+ const msg = PVE.Utils.extractFormActionError(action);
+ Ext.Msg.alert(gettext('Error'), msg);
+ },
});
- },
- listeners: {
- afterrender: function(cmp) {
- cmp.setAccept(defaultContent);
- },
- },
- });
+ };
+
+ const updateProgress = function(per, bytes) {
+ let text = (per * 100).toFixed(2) + '%';
+ if (bytes) {
+ text += " (" + Proxmox.Utils.format_size(bytes) + ')';
+ }
+ pbar.updateProgress(per, text);
+ };
+
+ let fd;
+ try {
+ fd = new FormData();
+ } catch (err) {
+ doStandardSubmit();
+ return;
+ }
+
+ button.setDisabled(true);
+ abortBtn.setDisabled(false);
+
+ let field = form.findField('content');
+ fd.append("content", field.getValue());
+ field.setDisabled(true);
+
+ field = form.findField('new-filename');
+ fd.append("new-filename", field.getValue());
+ field.setDisabled(true);
+
+ field = form.findField('filename');
+ const file = field.fileInputEl.dom;
+ fd.append("filename", file.files[0]);
+ field.setDisabled(true);
+
+ pbar.setVisible(true);
+ updateProgress(0);
+
+ const xhr = new XMLHttpRequest();
+ view.xhr = xhr;
+
+ xhr.addEventListener("load", function(e) {
+ if (xhr.status === 200) {
+ view.close();
+ return;
+ }
+ const err = Ext.htmlEncode(xhr.statusText);
+ let msg = `${gettext('Error')} ${xhr.status.toString()}: ${err}`;
+ if (xhr.responseText !== "") {
+ const result = Ext.decode(xhr.responseText);
+ result.message = msg;
+ msg = Proxmox.Utils.extractRequestError(result, true);
+ }
+ Ext.Msg.alert(gettext('Error'), msg, btn => view.close());
+ }, false);
+
+ xhr.addEventListener("error", function(e) {
+ const err = e.target.status.toString();
+ const msg = `Error '${err}' occurred while receiving the document.`;
+ Ext.Msg.alert(gettext('Error'), msg, btn => view.close());
+ });
+
+ xhr.upload.addEventListener("progress", function(evt) {
+ if (evt.lengthComputable) {
+ const percentComplete = evt.loaded / evt.total;
+ updateProgress(percentComplete, evt.loaded);
+ }
+ }, false);
+
+ xhr.open("POST", `/api2/json${view.url}`, true);
+ xhr.send(fd);
+ },
+
+ validitychange: function(f, valid) {
+ const submitBtn = Ext.getCmp('submitBtn');
+ submitBtn.setDisabled(!valid);
+ },
+
+ fileChange: function(input) {
+ const vm = this.getViewModel();
+ const name = input.value.replace(/^.*(\/|\\)/, '');
+ const fileInput = input.fileInputEl.dom;
+ vm.set('filename', name);
+ vm.set('size', (fileInput.files[0] && Proxmox.Utils.format_size(fileInput.files[0].size)) || '-');
+ vm.set('mimetype', (fileInput.files[0] && fileInput.files[0].type) || '-');
+ },
+ },
- me.formPanel = Ext.create('Ext.form.Panel', {
+ items: [
+ {
+ xtype: 'form',
+ id: 'formPanel',
method: 'POST',
waitMsgTarget: true,
bodyPadding: 10,
border: false,
- width: 300,
+ width: 400,
fieldDefaults: {
labelWidth: 100,
anchor: '100%',
},
items: [
{
- xtype: 'pveContentTypeSelector',
- cts: me.contents,
- fieldLabel: gettext('Content'),
- name: 'content',
- value: defaultContent,
+ xtype: 'filefield',
+ name: 'filename',
+ buttonText: gettext('Select File'),
allowBlank: false,
+ fieldLabel: gettext('File'),
+ cbind: {
+ accept: '{extensions}',
+ },
listeners: {
- change: function(cmp, newValue, oldValue) {
- fileField.setAccept(newValue);
- },
+ change: 'fileChange',
},
},
- fileField,
- pbar,
- ],
- });
-
- let form = me.formPanel.getForm();
-
- let doStandardSubmit = function() {
- form.submit({
- url: "/api2/htmljs" + baseurl,
- waitMsg: gettext('Uploading file...'),
- success: function(f, action) {
- me.close();
+ {
+ xtype: 'textfield',
+ name: 'new-filename',
+ allowBlank: false,
+ fieldLabel: gettext('File name'),
+ bind: {
+ value: '{filename}',
+ },
},
- failure: function(f, action) {
- var msg = PVE.Utils.extractFormActionError(action);
- Ext.Msg.alert(gettext('Error'), msg);
+ {
+ xtype: 'displayfield',
+ name: 'size',
+ fieldLabel: gettext('File size'),
+ bind: {
+ value: '{size}',
+ },
},
- });
- };
-
- let updateProgress = function(per, bytes) {
- var text = (per * 100).toFixed(2) + '%';
- if (bytes) {
- text += " (" + Proxmox.Utils.format_size(bytes) + ')';
- }
- pbar.updateProgress(per, text);
- };
+ {
+ xtype: 'displayfield',
+ name: 'mimetype',
+ fieldLabel: gettext('MIME type'),
+ bind: {
+ value: '{mimetype}',
+ },
+ },
+ {
+ xtype: 'progressbar',
+ text: 'Ready',
+ hidden: true,
+ id: 'progressBar',
+ },
+ {
+ xtype: 'hiddenfield',
+ name: 'content',
+ cbind: {
+ value: '{content}',
+ },
+ },
+ ],
+ listeners: {
+ validitychange: 'validitychange',
+ },
+ },
+ ],
- let abortBtn = Ext.create('Ext.Button', {
+ buttons: [
+ {
+ xtype: 'button',
text: gettext('Abort'),
+ id: 'abortBtn',
disabled: true,
handler: function() {
- me.close();
+ const me = this;
+ me.up('pveStorageUpload').close();
},
- });
-
- let submitBtn = Ext.create('Ext.Button', {
+ },
+ {
text: gettext('Upload'),
+ id: 'submitBtn',
disabled: true,
- handler: function(button) {
- var fd;
- try {
- fd = new FormData();
- } catch (err) {
- doStandardSubmit();
- return;
- }
+ handler: 'submit',
+ },
+ ],
- button.setDisabled(true);
- abortBtn.setDisabled(false);
-
- var field = form.findField('content');
- fd.append("content", field.getValue());
- field.setDisabled(true);
-
- field = form.findField('filename');
- var file = field.fileInputEl.dom;
- fd.append("filename", file.files[0]);
- field.setDisabled(true);
-
- pbar.setVisible(true);
- updateProgress(0);
-
- let xhr = new XMLHttpRequest();
- me.xhr = xhr;
-
- xhr.addEventListener("load", function(e) {
- if (xhr.status === 200) {
- me.close();
- return;
- }
- let err = Ext.htmlEncode(xhr.statusText);
- let msg = `${gettext('Error')} ${xhr.status.toString()}: ${err}`;
- if (xhr.responseText !== "") {
- let result = Ext.decode(xhr.responseText);
- result.message = msg;
- msg = Proxmox.Utils.extractRequestError(result, true);
- }
- Ext.Msg.alert(gettext('Error'), msg, btn => me.close());
- }, false);
-
- xhr.addEventListener("error", function(e) {
- let err = e.target.status.toString();
- let msg = `Error '${err}' occurred while receiving the document.`;
- Ext.Msg.alert(gettext('Error'), msg, btn => me.close());
- });
+ listeners: {
+ close: function() {
+ const me = this;
+ if (me.xhr) {
+ me.xhr.abort();
+ delete me.xhr;
+ }
+ },
+ },
- xhr.upload.addEventListener("progress", function(evt) {
- if (evt.lengthComputable) {
- let percentComplete = evt.loaded / evt.total;
- updateProgress(percentComplete, evt.loaded);
- }
- }, false);
+ initComponent: function() {
+ const me = this;
- xhr.open("POST", `/api2/json${baseurl}`, true);
- xhr.send(fd);
- },
- });
-
- form.on('validitychange', (f, valid) => submitBtn.setDisabled(!valid));
-
- Ext.apply(me, {
- title: gettext('Upload'),
- items: me.formPanel,
- buttons: [abortBtn, submitBtn],
- listeners: {
- close: function() {
- if (me.xhr) {
- me.xhr.abort();
- delete me.xhr;
- }
- },
- },
- });
+ if (!me.nodename) {
+ throw "no node name specified";
+ }
+ if (!me.storage) {
+ throw "no storage ID specified";
+ }
me.callParent();
},
--
2.30.2
next prev parent reply other threads:[~2021-07-20 11:53 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-20 11:51 [pve-devel] [PATCH-SERIES http-server/storage/manager] add checksum and algorithm to iso upload Lorenz Stechauner
2021-07-20 11:51 ` [pve-devel] [PATCH http-server] anyevent: move unlink from http-server to endpoint Lorenz Stechauner
2021-07-20 13:23 ` Thomas Lamprecht
2021-07-20 11:51 ` [pve-devel] [PATCH storage 1/3] status: " Lorenz Stechauner
2021-07-20 13:31 ` Thomas Lamprecht
2021-07-20 11:51 ` [pve-devel] [PATCH storage 2/3] status: add new-filename to upload Lorenz Stechauner
2021-07-20 13:27 ` Thomas Lamprecht
2021-07-20 19:15 ` Thomas Lamprecht
2021-07-20 11:51 ` [pve-devel] [PATCH storage 3/3] status: add checksum and algorithm to file upload Lorenz Stechauner
2021-07-20 13:40 ` Thomas Lamprecht
2021-07-20 11:51 ` [pve-devel] [PATCH manager 2/5] ui: move upload window into UploadToStorage.js Lorenz Stechauner
2021-07-20 11:51 ` Lorenz Stechauner [this message]
2021-07-20 11:51 ` [pve-devel] [PATCH manager 4/5] ui/UploadToStorage.js: add checksum and algorithm Lorenz Stechauner
2021-07-20 11:51 ` [pve-devel] [PATCH manager 5/5] ui/UploadToStorage.js: add TaskViewer Lorenz Stechauner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210720115147.1988565-7-l.stechauner@proxmox.com \
--to=l.stechauner@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox