]> git.proxmox.com Git - proxmox-widget-toolkit.git/blobdiff - src/window/Edit.js
edit window: make response handling code path more robust
[proxmox-widget-toolkit.git] / src / window / Edit.js
index c165141129f7e725d18a04a17a0b02ed8f683be8..488642de7abd3b5a110fb15137b77a3f5bea6740 100644 (file)
@@ -1,39 +1,53 @@
-// fixme: how can we avoid those lint errors?
 Ext.define('Proxmox.window.Edit', {
     extend: 'Ext.window.Window',
     alias: 'widget.proxmoxWindowEdit',
 
     // autoLoad trigger a load() after component creation
     autoLoad: false,
+    // set extra options like params for the load request
+    autoLoadOptions: undefined,
+
+    // to submit extra params on load and submit, useful, e.g., if not all ID
+    // parameters are included in the URL
+    extraRequestParams: {},
 
     resizable: false,
 
-    // use this tio atimatically generate a title like
-    // Create: <subject>
+    // use this to automatically generate a title like `Create: <subject>`
     subject: undefined,
 
-    // set isCreate to true if you want a Create button (instead
-    // OK and RESET)
+    // set isCreate to true if you want a Create button (instead OK and RESET)
     isCreate: false,
 
     // set to true if you want an Add button (instead of Create)
     isAdd: false,
 
-    // set to true if you want an Remove button (instead of Create)
+    // set to true if you want a Remove button (instead of Create)
     isRemove: false,
 
+    // set to false, if you don't want the reset button present
+    showReset: true,
+
     // custom submitText
     submitText: undefined,
 
     backgroundDelay: 0,
 
+    // string or function, called as (url, values) - useful if the ID of the
+    // new object is part of the URL, or that URL differs from GET/PUT URL
+    submitUrl: Ext.identityFn,
+
+    // string or function, called as (url, initialConfig) - mostly for
+    // consistency with submitUrl existing. If both are set `url` gets optional
+    loadUrl: Ext.identityFn,
+
     // needed for finding the reference to submitbutton
     // because we do not have a controller
     referenceHolder: true,
     defaultButton: 'submitbutton',
 
     // finds the first form field
-    defaultFocus: 'field[disabled=false][hidden=false]',
+    defaultFocus: 'field:focusable[disabled=false][hidden=false]',
 
     showProgress: false,
 
@@ -62,15 +76,16 @@ Ext.define('Proxmox.window.Edit', {
     getValues: function(dirtyOnly) {
        let me = this;
 
-        let values = {};
+       let values = {};
+       Ext.apply(values, me.extraRequestParams);
 
        let form = me.formPanel.getForm();
 
-        form.getFields().each(function(field) {
-            if (!field.up('inputpanel') && (!dirtyOnly || field.isDirty())) {
-                Proxmox.Utils.assemble_field_data(values, field.getSubmitData());
-            }
-        });
+       form.getFields().each(function(field) {
+           if (!field.up('inputpanel') && (!dirtyOnly || field.isDirty())) {
+               Proxmox.Utils.assemble_field_data(values, field.getSubmitData());
+           }
+       });
 
        Ext.Array.each(me.query('inputpanel'), function(panel) {
            Proxmox.Utils.assemble_field_data(values, panel.getValues(dirtyOnly));
@@ -128,7 +143,9 @@ Ext.define('Proxmox.window.Edit', {
            values.background_delay = me.backgroundDelay;
        }
 
-       let url = me.url;
+       let url = Ext.isFunction(me.submitUrl)
+           ? me.submitUrl(me.url, values)
+           : me.submitUrl || me.url;
        if (me.method === 'DELETE') {
            url = url + "?" + Ext.Object.toQueryString(values);
            values = undefined;
@@ -189,13 +206,23 @@ Ext.define('Proxmox.window.Edit', {
            waitMsgTarget: me,
        }, options);
 
+       if (Object.keys(me.extraRequestParams).length > 0) {
+           let params = newopts.params || {};
+           Ext.applyIf(params, me.extraRequestParams);
+           newopts.params = params;
+       }
+
+       let url = Ext.isFunction(me.loadUrl)
+           ? me.loadUrl(me.url, me.initialConfig)
+           : me.loadUrl || me.url;
+
        let createWrapper = function(successFn) {
            Ext.apply(newopts, {
-               url: me.url,
+               url: url,
                method: 'GET',
                success: function(response, opts) {
                    form.clearInvalid();
-                   me.digest = response.result.digest || response.result.data.digest;
+                   me.digest = response.result?.digest || response.result?.data?.digest;
                    if (successFn) {
                        successFn(response, opts);
                    } else {
@@ -222,8 +249,12 @@ Ext.define('Proxmox.window.Edit', {
     initComponent: function() {
        let me = this;
 
-       if (!me.url) {
-           throw "no url specified";
+       if (!me.url && (
+               !me.submitUrl || !me.loadUrl || me.submitUrl === Ext.identityFn ||
+               me.loadUrl === Ext.identityFn
+           )
+       ) {
+           throw "neither 'url' nor both, submitUrl and loadUrl specified";
        }
 
        if (me.create) {throw "deprecated parameter, use isCreate";}
@@ -233,7 +264,7 @@ Ext.define('Proxmox.window.Edit', {
        me.items = undefined;
 
        me.formPanel = Ext.create('Ext.form.Panel', {
-           url: me.url,
+           url: me.url, // FIXME: not in 'form' class, safe to remove??
            method: me.method || 'PUT',
            trackResetOnLoad: true,
            bodyPadding: me.bodyPadding !== undefined ? me.bodyPadding : 10,
@@ -291,8 +322,7 @@ Ext.define('Proxmox.window.Edit', {
            resetBtn.setDisabled(!dirty);
 
            if (inputPanel && inputPanel.hasAdvanced) {
-               // we want to show the advanced options
-               // as soon as some of it is not valid
+               // we want to show the advanced options as soon as some of it is not valid
                let advancedItems = me.down('#advancedContainer').query('field');
                let allAdvancedValid = true;
                advancedItems.forEach(function(field) {
@@ -303,7 +333,6 @@ Ext.define('Proxmox.window.Edit', {
 
                if (!allAdvancedValid) {
                    inputPanel.setAdvancedVisible(true);
-                   me.down('#advancedcb').setValue(true);
                }
            }
        };
@@ -322,7 +351,7 @@ Ext.define('Proxmox.window.Edit', {
            me.title = Proxmox.Utils.dialog_title(me.subject, me.isCreate, me.isAdd);
        }
 
-       if (me.isCreate) {
+       if (me.isCreate || !me.showReset) {
                me.buttons = [submitBtn];
        } else {
                me.buttons = [submitBtn, resetBtn];
@@ -332,22 +361,20 @@ Ext.define('Proxmox.window.Edit', {
            let sp = Ext.state.Manager.getProvider();
            let advchecked = sp.get('proxmox-advanced-cb');
            inputPanel.setAdvancedVisible(advchecked);
-           me.buttons.unshift(
-              {
-                  xtype: 'proxmoxcheckbox',
-                  itemId: 'advancedcb',
-                  boxLabelAlign: 'before',
-                  boxLabel: gettext('Advanced'),
-                  stateId: 'proxmox-advanced-cb',
-                  value: advchecked,
-                  listeners: {
-                      change: function(cb, val) {
-                          inputPanel.setAdvancedVisible(val);
-                          sp.set('proxmox-advanced-cb', val);
-                      },
-                  },
-              },
-           );
+           me.buttons.unshift({
+               xtype: 'proxmoxcheckbox',
+               itemId: 'advancedcb',
+               boxLabelAlign: 'before',
+               boxLabel: gettext('Advanced'),
+               stateId: 'proxmox-advanced-cb',
+               value: advchecked,
+               listeners: {
+                   change: function(cb, val) {
+                       inputPanel.setAdvancedVisible(val);
+                       sp.set('proxmox-advanced-cb', val);
+                   },
+               },
+           });
        }
 
        let onlineHelp = me.onlineHelp;
@@ -383,7 +410,7 @@ Ext.define('Proxmox.window.Edit', {
        });
 
        if (me.autoLoad) {
-           me.load();
+           me.load(me.autoLoadOptions);
        }
     },
 });