luci-base: form.js: fix removing just created named GridSection
authorJo-Philipp Wich <jo@mein.io>
Fri, 22 Jul 2022 21:41:05 +0000 (23:41 +0200)
committerJo-Philipp Wich <jo@mein.io>
Fri, 22 Jul 2022 21:41:05 +0000 (23:41 +0200)
Since the `handleModalSave()` handler of the GridSection class invokes
`handleModalCancel()` after saving the data but before removing the
`addedSection` property, the `handleModalCancel` handler incorrectly
removed the uci section that has just been created.

This bug didn't affect anonymous GridSections because after saving the
id of the created section changes, causing the remove command to fail,
but for named ones with stable section IDs, the bug manifested.

Solve the issue by passing a flag to `handleModalCancel()` indicating
whether the method was called from a safe operation and use it do
decide whether to delete the new staged uci section or not.

Fixes: #5760
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
modules/luci-base/htdocs/luci-static/resources/form.js

index 90a15175712713891da34491de5dd43e6e7b7208..aae8b3684a0cce56518df5299bfbb9fa74b829c2 100644 (file)
@@ -3042,7 +3042,7 @@ var CBITableSection = CBITypedSection.extend(/** @lends LuCI.form.TableSection.p
                }
 
                return saveTasks
-                       .then(L.bind(this.handleModalCancel, this, modalMap, ev))
+                       .then(L.bind(this.handleModalCancel, this, modalMap, ev, true))
                        .catch(function() {});
        },
 
@@ -3365,20 +3365,19 @@ var CBIGridSection = CBITableSection.extend(/** @lends LuCI.form.GridSection.pro
                var mapNode = this.getPreviousModalMap(),
                    prevMap = mapNode ? dom.findClassInstance(mapNode) : this.map;
 
-               return this.super('handleModalSave', arguments)
-                       .then(function() { delete prevMap.addedSection });
+               return this.super('handleModalSave', arguments);
        },
 
        /** @private */
-       handleModalCancel: function(/* ... */) {
+       handleModalCancel: function(modalMap, ev, isSaving) {
                var config_name = this.uciconfig || this.map.config,
                    mapNode = this.getPreviousModalMap(),
                    prevMap = mapNode ? dom.findClassInstance(mapNode) : this.map;
 
-               if (prevMap.addedSection != null) {
+               if (prevMap.addedSection != null && !isSaving)
                        this.map.data.remove(config_name, prevMap.addedSection);
-                       delete prevMap.addedSection;
-               }
+
+               delete prevMap.addedSection;
 
                return this.super('handleModalCancel', arguments);
        },