From f24606b1ffd59cc82c7251243a18f4cfdc4f78d5 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Mon, 16 May 2022 11:55:11 +0200 Subject: [PATCH] luci-base: form.js: handle SectionValue objects in GridSection modals The existing logic for cloning section options into the modal form section container did not properly handle SectionValue objects. Introduce a new `cloneOptions()` helper to recursively traverse and properly clowning such nested sections. Signed-off-by: Jo-Philipp Wich --- .../htdocs/luci-static/resources/form.js | 74 +++++++++++++------ 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/modules/luci-base/htdocs/luci-static/resources/form.js b/modules/luci-base/htdocs/luci-static/resources/form.js index 6786d3d234..3b2e89eccd 100644 --- a/modules/luci-base/htdocs/luci-static/resources/form.js +++ b/modules/luci-base/htdocs/luci-static/resources/form.js @@ -3150,34 +3150,38 @@ 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); + cloneOptions: function(src_section, dest_section) { + for (var i = 0; i < src_section.children.length; i++) { + var o1 = src_section.children[i]; - m.parent = parent; - m.section = section_id; - m.readonly = parent.readonly; + if (o1.modalonly === false && src_section === this) + continue; - s.tabs = this.tabs; - s.tab_names = this.tab_names; + var o2; - 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 (o1.subsection) { + o2 = dest_section.option(o1.constructor, o1.option, o1.subsection.constructor, o1.subsection.sectiontype, o1.subsection.title, o1.subsection.description); - for (var i = 0; i < this.children.length; i++) { - var o1 = this.children[i]; + for (var k in o1.subsection) { + if (!o1.subsection.hasOwnProperty(k)) + continue; - if (o1.modalonly === false) - continue; + switch (k) { + case 'map': + case 'children': + case 'parentoption': + continue; - var o2 = s.option(o1.constructor, o1.option, o1.title, o1.description); + default: + o2.subsection[k] = o1.subsection[k]; + } + } + + this.cloneOptions(o1.subsection, o2.subsection); + } + else { + o2 = dest_section.option(o1.constructor, o1.option, o1.title, o1.description); + } for (var k in o1) { if (!o1.hasOwnProperty(k)) @@ -3189,6 +3193,7 @@ var CBITableSection = CBITypedSection.extend(/** @lends LuCI.form.TableSection.p case 'option': case 'title': case 'description': + case 'subsection': continue; default: @@ -3196,6 +3201,31 @@ 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); + + m.parent = parent; + m.section = section_id; + m.readonly = parent.readonly; + + s.tabs = this.tabs; + s.tab_names = this.tab_names; + + 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); + + this.cloneOptions(this, s); return Promise.resolve(this.addModalOptions(s, section_id, ev)).then(L.bind(m.render, m)).then(L.bind(function(nodes) { var mapNode = this.getActiveModalMap(), -- 2.30.2