From ee5a7c6fc5cbc7671cf7c440ec3044b166db6104 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Mon, 16 May 2022 13:10:20 +0200 Subject: [PATCH] luci-base: form.js: save parent map on opening nested modal map Before opening (rendering) a nested modal map, make sure to save the parent modal map in order to persist any structural uci changes, such as newly added anonymous sections to prevent the nested map from operating on stale values or ephemeral config section IDs. Signed-off-by: Jo-Philipp Wich (cherry picked from commit 3be479446bdeaf446468c5e7ac3b9bc49da023da) --- .../htdocs/luci-static/resources/form.js | 101 ++++++++++-------- 1 file changed, 54 insertions(+), 47 deletions(-) diff --git a/modules/luci-base/htdocs/luci-static/resources/form.js b/modules/luci-base/htdocs/luci-static/resources/form.js index 9f45d3b2b2..aae8b3684a 100644 --- a/modules/luci-base/htdocs/luci-static/resources/form.js +++ b/modules/luci-base/htdocs/luci-static/resources/form.js @@ -3207,63 +3207,70 @@ var CBITableSection = CBITypedSection.extend(/** @lends LuCI.form.TableSection.p /** @private */ renderMoreOptionsModal: function(section_id, ev) { var parent = this.map, - title = parent.title, - name = null, - m = new CBIMap(this.map.config, null, null), - s = m.section(CBINamedSection, section_id, this.sectiontype); + sref = parent.data.get(parent.config, section_id), + mapNode = this.getActiveModalMap(), + activeMap = mapNode ? dom.findClassInstance(mapNode) : null, + stackedMap = activeMap && (activeMap.parent !== parent || activeMap.section !== section_id); - m.parent = parent; - m.section = section_id; - m.readonly = parent.readonly; + return (stackedMap ? activeMap.save(null, true) : Promise.resolve()).then(L.bind(function() { + section_id = sref['.name']; - s.tabs = this.tabs; - s.tab_names = this.tab_names; + var m = new CBIMap(parent.config, null, null), + s = m.section(CBINamedSection, section_id, this.sectiontype); - if ((name = this.titleFn('modaltitle', section_id)) != null) - title = name; - else if ((name = this.titleFn('sectiontitle', section_id)) != null) - title = '%s - %s'.format(parent.title, name); - else if (!this.anonymous) - title = '%s - %s'.format(parent.title, section_id); + m.parent = parent; + m.section = section_id; + m.readonly = parent.readonly; - this.cloneOptions(this, s); + s.tabs = this.tabs; + s.tab_names = this.tab_names; - return Promise.resolve(this.addModalOptions(s, section_id, ev)).then(L.bind(m.render, m)).then(L.bind(function(nodes) { - var mapNode = this.getActiveModalMap(), - activeMap = mapNode ? dom.findClassInstance(mapNode) : null; + this.cloneOptions(this, s); - if (activeMap && (activeMap.parent !== parent || activeMap.section !== section_id)) { - mapNode.parentNode - .querySelector('h4') - .appendChild(E('span', title ? ' » ' + title : '')); + return Promise.resolve(this.addModalOptions(s, section_id, ev)).then(function() { + return m.render(); + }).then(L.bind(function(nodes) { + var title = parent.title, + name = null; - mapNode.parentNode - .querySelector('div.right > button') - .firstChild.data = _('Back'); + if ((name = this.titleFn('modaltitle', section_id)) != null) + title = name; + else if ((name = this.titleFn('sectiontitle', section_id)) != null) + title = '%s - %s'.format(parent.title, name); + else if (!this.anonymous) + title = '%s - %s'.format(parent.title, section_id); + + if (stackedMap) { + mapNode.parentNode + .querySelector('h4') + .appendChild(E('span', title ? ' » ' + title : '')); - mapNode.classList.add('hidden'); - mapNode.parentNode.insertBefore(nodes, mapNode.nextElementSibling); + mapNode.parentNode + .querySelector('div.right > button') + .firstChild.data = _('Back'); + + mapNode.classList.add('hidden'); + mapNode.parentNode.insertBefore(nodes, mapNode.nextElementSibling); - return activeMap.save(null, true).then(function() { nodes.classList.add('flash'); - }, function() {}); - } - else { - ui.showModal(title, [ - nodes, - E('div', { 'class': 'right' }, [ - E('button', { - 'class': 'cbi-button', - 'click': ui.createHandlerFn(this, 'handleModalCancel', m) - }, [ _('Dismiss') ]), ' ', - E('button', { - 'class': 'cbi-button cbi-button-positive important', - 'click': ui.createHandlerFn(this, 'handleModalSave', m), - 'disabled': m.readonly || null - }, [ _('Save') ]) - ]) - ], 'cbi-modal'); - } + } + else { + ui.showModal(title, [ + nodes, + E('div', { 'class': 'right' }, [ + E('button', { + 'class': 'cbi-button', + 'click': ui.createHandlerFn(this, 'handleModalCancel', m) + }, [ _('Dismiss') ]), ' ', + E('button', { + 'class': 'cbi-button cbi-button-positive important', + 'click': ui.createHandlerFn(this, 'handleModalSave', m), + 'disabled': m.readonly || null + }, [ _('Save') ]) + ]) + ], 'cbi-modal'); + } + }, this)); }, this)).catch(L.error); } }); -- 2.30.2