One comment inline.

On 4/3/25 12:34, Markus Frank wrote:
Signed-off-by: Markus Frank <m.fr...@proxmox.com>
---
v15:
* removed announce-submounts

  www/manager6/Makefile             |   1 +
  www/manager6/window/DirMapEdit.js | 202 ++++++++++++++++++++++++++++++
  2 files changed, 203 insertions(+)
  create mode 100644 www/manager6/window/DirMapEdit.js

diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index c94a5cdf..4b8677e3 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -138,6 +138,7 @@ JSSRC=                                                      
\
        window/TreeSettingsEdit.js                      \
        window/PCIMapEdit.js                            \
        window/USBMapEdit.js                            \
+       window/DirMapEdit.js                            \
        window/GuestImport.js                           \
        ha/Fencing.js                                   \
        ha/GroupEdit.js                                 \
diff --git a/www/manager6/window/DirMapEdit.js 
b/www/manager6/window/DirMapEdit.js
new file mode 100644
index 00000000..b635f34d
--- /dev/null
+++ b/www/manager6/window/DirMapEdit.js
@@ -0,0 +1,202 @@
+Ext.define('PVE.window.DirMapEditWindow', {
+    extend: 'Proxmox.window.Edit',
+
+    mixins: ['Proxmox.Mixin.CBind'],
+
+    cbindData: function(initialConfig) {
+       let me = this;
+       me.isCreate = !me.name;
+       me.method = me.isCreate ? 'POST' : 'PUT';
+       me.hideMapping = !!me.entryOnly;
+       me.hideComment = me.name && !me.entryOnly;
+       me.hideNodeSelector = me.nodename || me.entryOnly;
+       me.hideNode = !me.nodename || !me.hideNodeSelector;
+       return {
+           name: me.name,
+           nodename: me.nodename,
+       };
+    },
+
+    submitUrl: function(_url, data) {
+       let me = this;
+       let name = me.isCreate ? '' : me.name;
+       return `/cluster/mapping/dir/${name}`;
+    },
+
+    title: gettext('Add Dir mapping'),
+
+    onlineHelp: 'resource_mapping',
+
+    method: 'POST',
+
+    controller: {
+       xclass: 'Ext.app.ViewController',
+
+       onGetValues: function(values) {
+           let me = this;
+           let view = me.getView();
+           values.node ??= view.nodename;
+
+           let name = values.name;
+           let description = values.description;
+           let deletes = values.delete;
+
+           delete values.description;
+           delete values.name;
+           delete values.delete;
+
+           let map = [];
+           if (me.originalMap) {
+               map = PVE.Parser.filterPropertyStringList(me.originalMap, (e) 
=> e.node !== values.node);
+           }
+           if (values.path) {
+               // TODO: Remove this when property string supports quotation of 
properties
+               if (!/^\/[^;,=()]+/.test(values.path)) {
+                   let errMsg = 'these symbols are currently not allowed in 
path: ;,=()';
This error message duplicates the one in the verify_path in the backend and should also be capitalized at the start. Couldn't we verify this in the API handler and return the error from there to not duplicate this code (esp. if it gets out of sync)?

On another note, this should also tell the user that the path must be a absolute path (which it does in the regex but doesn't say so in the error message).

+                   Ext.Msg.alert(gettext('Error'), errMsg);
+                   throw errMsg;
+               }
+               map.push(PVE.Parser.printPropertyString(values));
+           }
+           values = { map };
+
+           if (description) {
+               values.description = description;
+           }
+           if (deletes && !view.isCreate) {
+               values.delete = deletes;
+           }
+           if (view.isCreate) {
+               values.id = name;
+           }
+
+           return values;
+       },
+
+       onSetValues: function(values) {
+           let me = this;
+           let view = me.getView();
+           me.originalMap = [...values.map];
+           let configuredNodes = [];
+           PVE.Parser.filterPropertyStringList(values.map, (e) => {
+               configuredNodes.push(e.node);
+               if (e.node === view.nodename) {
+                   values = e;
+               }
+               return false;
+           });
+
+           me.lookup('nodeselector').disallowedNodes = configuredNodes;
+
+           return values;
+       },
+
+       init: function(view) {
+           let me = this;
+
+           if (!view.nodename) {
+               //throw "no nodename given";
+           }
+       },
+    },
+
+    items: [
+       {
+           xtype: 'inputpanel',
+           onGetValues: function(values) {
+               return this.up('window').getController().onGetValues(values);
+           },
+
+           onSetValues: function(values) {
+               return this.up('window').getController().onSetValues(values);
+           },
+
+           columnT: [
+               {
+                   xtype: 'displayfield',
+                   reference: 'directory-hint',
+                   columnWidth: 1,
+                   value: 'Make sure the directory exists.',
+                   cbind: {
+                       disabled: '{hideMapping}',
+                       hidden: '{hideMapping}',
+                   },
+                   userCls: 'pmx-hint',
+               },
+           ],
+
+           column1: [
+               {
+                   xtype: 'pmxDisplayEditField',
+                   fieldLabel: gettext('Name'),
+                   cbind: {
+                       editable: '{!name}',
+                       value: '{name}',
+                       submitValue: '{isCreate}',
+                   },
+                   name: 'name',
+                   allowBlank: false,
+               },
+               {
+                   xtype: 'pveNodeSelector',
+                   reference: 'nodeselector',
+                   fieldLabel: gettext('Node'),
+                   name: 'node',
+                   cbind: {
+                       disabled: '{hideNodeSelector}',
+                       hidden: '{hideNodeSelector}',
+                   },
+                   allowBlank: false,
+               },
+           ],
+
+           column2: [
+               {
+                   xtype: 'fieldcontainer',
+                   defaultType: 'radiofield',
+                   layout: 'fit',
+                   cbind: {
+                       disabled: '{hideMapping}',
+                       hidden: '{hideMapping}',
+                   },
+                   items: [
+                       {
+                           xtype: 'textfield',
+                           name: 'path',
+                           reference: 'path',
+                           value: '',
+                           emptyText: gettext('/some/path'),
+                           cbind: {
+                               nodename: '{nodename}',
+                               disabled: '{hideMapping}',
+                           },
+                           allowBlank: false,
+                           fieldLabel: gettext('Path'),
+                       },
+                   ],
+               },
+           ],
+
+           columnB: [
+               {
+                   xtype: 'fieldcontainer',
+                   defaultType: 'radiofield',
+                   layout: 'fit',
+                   cbind: {
+                       disabled: '{hideComment}',
+                       hidden: '{hideComment}',
+                   },
+                   items: [
+                       {
+                           xtype: 'proxmoxtextfield',
+                           fieldLabel: gettext('Comment'),
+                           submitValue: true,
+                           name: 'description',
+                           deleteEmpty: true,
+                       },
+                   ],
+               },
+           ],
+       },
+    ],
+});



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to