From 290755fdfb283793171320e72f0ed39fdeb9f63d Mon Sep 17 00:00:00 2001 From: Wirachot Date: Wed, 11 Feb 2026 13:44:57 +0700 Subject: [PATCH 1/5] Migrate DataSelect --- AppBuilder/platform/plugins/included/index.js | 3 +- .../view_data-select/FNAbviewdataselect.js | 107 ++++++++++++++++++ .../FNAbviewdataselectComponent.js | 63 +++++++++++ 3 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 AppBuilder/platform/plugins/included/view_data-select/FNAbviewdataselect.js create mode 100644 AppBuilder/platform/plugins/included/view_data-select/FNAbviewdataselectComponent.js diff --git a/AppBuilder/platform/plugins/included/index.js b/AppBuilder/platform/plugins/included/index.js index 1d707c93..d70571c0 100644 --- a/AppBuilder/platform/plugins/included/index.js +++ b/AppBuilder/platform/plugins/included/index.js @@ -1,7 +1,8 @@ +import viewDataSelect from "./view_data-select/FNAbviewdataselect.js"; import viewList from "./view_list/FNAbviewlist.js"; import viewTab from "./view_tab/FNAbviewtab.js"; -const AllPlugins = [viewTab, viewList]; +const AllPlugins = [viewTab, viewList, viewDataSelect]; export default { load: (AB) => { diff --git a/AppBuilder/platform/plugins/included/view_data-select/FNAbviewdataselect.js b/AppBuilder/platform/plugins/included/view_data-select/FNAbviewdataselect.js new file mode 100644 index 00000000..86b4ce51 --- /dev/null +++ b/AppBuilder/platform/plugins/included/view_data-select/FNAbviewdataselect.js @@ -0,0 +1,107 @@ +import FNAbviewdataselectComponent from "./FNAbviewdataselectComponent.js"; + + +// FNAbviewdataselect Web +// A web side import for an ABView. +// +export default function FNAbviewdataselect({ + /*AB,*/ + ABViewWidgetPlugin, + ABViewComponentPlugin, + ABViewContainer +}) { + const ABAbviewdataselectComponent = FNAbviewdataselectComponent({ ABViewComponentPlugin }); + +const ABViewDataSelectPropertyComponentDefaults = { + dataviewID: null, // uuid of ABDatacollection +}; + +const ABViewDefaults = { + key: "data-select", // {string} unique key for this view + icon: "chevron-circle-down", // {string} fa-[icon] reference for this view + labelKey: "Data Select", // {string} the multilingual label key for the class label +}; + +class ABViewDataSelectCore extends ABViewWidgetPlugin { + constructor(values, application, parent, defaultValues) { + super(values, application, parent, defaultValues ?? ABViewDefaults); + } + + static common() { + return ABViewDefaults; + } + + static defaultValues() { + return ABViewDataSelectPropertyComponentDefaults; + } + + /// + /// Instance Methods + /// + + /** + * @method fromValues() + * + * initialze this object with the given set of values. + * @param {obj} values + */ + fromValues(values) { + super.fromValues(values); + } + + /** + * @method componentList + * return the list of components available on this view to display in the editor. + */ + componentList() { + return []; + } +}; + +return class ABViewDataSelect extends ABViewDataSelectCore { + +/** + * @method getPluginKey + * return the plugin key for this view. + * @return {string} plugin key + */ + static getPluginKey() { + return this.common().key; + } + +/** + * @method component() + * return a UI component based upon this view. + * @return {obj} UI component + */ + component(parentId) { + return new ABAbviewdataselectComponent(this, parentId); + } + + + + + warningsEval() { + super.warningsEval(); + + let DC = this.datacollection; + if (!DC) { + this.warningsMessage( + `can't resolve it's datacollection[${this.settings.dataviewID}]` + ); + } else { + if (this.settings.viewType == "connected") { + const object = DC.datasource; + const [field] = object.fields( + (f) => f.columnName === this.settings.field + ); + if (!field) { + this.warningsMessage(`can't resolve field reference`); + } + } + } + } +} + +} + diff --git a/AppBuilder/platform/plugins/included/view_data-select/FNAbviewdataselectComponent.js b/AppBuilder/platform/plugins/included/view_data-select/FNAbviewdataselectComponent.js new file mode 100644 index 00000000..b8748131 --- /dev/null +++ b/AppBuilder/platform/plugins/included/view_data-select/FNAbviewdataselectComponent.js @@ -0,0 +1,63 @@ +export default function FNAbviewdataselectComponent({ + /*AB,*/ + ABViewComponentPlugin, +}) { + return class ABAbviewdataselectComponent extends ABViewComponentPlugin { + + + constructor(baseView, idbase, ids) { + super( + baseView, + idbase || `ABViewDataSelect_${baseView.id}`, + Object.assign( + { + select: "", + }, + ids + ) + ); + } + + ui() { + const _ui = super.ui([ + { + view: "combo", + id: this.ids.select, + on: { + onChange: (n, o) => { + if (n !== o) this.cursorChange(n); + }, + }, + }, + ]); + delete _ui.type; + + return _ui; + } + + async onShow() { + super.onShow(); + const dc = this.datacollection; + if (!dc) return; + await dc.waitReady(); + const labelField = this.AB.definitionByID( + this.settings.labelField + )?.columnName; + const options = dc + .getData() + .map((o) => ({ id: o.id, value: o[labelField] })) + .sort((a, b) => (a.value > b.value ? 1 : -1)); + const $select = $$(this.ids.select); + $select.define("options", options); + $select.refresh(); + $select.setValue(dc.getCursor().id); + } + + cursorChange(n) { + this.datacollection.setCursor(n); + } + + + }; + +} From fd405941f0f50b510a8de140fa850dfa37b26b08 Mon Sep 17 00:00:00 2001 From: Wirachot Date: Wed, 18 Feb 2026 16:54:59 +0700 Subject: [PATCH 2/5] clean code --- .../view_data-select/FNAbviewdataselect.js | 131 +++++++++--------- .../FNAbviewdataselectComponent.js | 99 +++++++------ 2 files changed, 110 insertions(+), 120 deletions(-) diff --git a/AppBuilder/platform/plugins/included/view_data-select/FNAbviewdataselect.js b/AppBuilder/platform/plugins/included/view_data-select/FNAbviewdataselect.js index 86b4ce51..c62af4ee 100644 --- a/AppBuilder/platform/plugins/included/view_data-select/FNAbviewdataselect.js +++ b/AppBuilder/platform/plugins/included/view_data-select/FNAbviewdataselect.js @@ -1,6 +1,5 @@ import FNAbviewdataselectComponent from "./FNAbviewdataselectComponent.js"; - // FNAbviewdataselect Web // A web side import for an ABView. // @@ -8,59 +7,60 @@ export default function FNAbviewdataselect({ /*AB,*/ ABViewWidgetPlugin, ABViewComponentPlugin, - ABViewContainer + ABViewContainer, }) { - const ABAbviewdataselectComponent = FNAbviewdataselectComponent({ ABViewComponentPlugin }); - -const ABViewDataSelectPropertyComponentDefaults = { - dataviewID: null, // uuid of ABDatacollection -}; - -const ABViewDefaults = { - key: "data-select", // {string} unique key for this view - icon: "chevron-circle-down", // {string} fa-[icon] reference for this view - labelKey: "Data Select", // {string} the multilingual label key for the class label -}; - -class ABViewDataSelectCore extends ABViewWidgetPlugin { - constructor(values, application, parent, defaultValues) { - super(values, application, parent, defaultValues ?? ABViewDefaults); - } + const ABAbviewdataselectComponent = FNAbviewdataselectComponent({ + ABViewComponentPlugin, + }); + + const ABViewDataSelectPropertyComponentDefaults = { + dataviewID: null, // uuid of ABDatacollection + }; + + const ABViewDefaults = { + key: "data-select", // {string} unique key for this view + icon: "chevron-circle-down", // {string} fa-[icon] reference for this view + labelKey: "Data Select", // {string} the multilingual label key for the class label + }; + + class ABViewDataSelectCore extends ABViewWidgetPlugin { + constructor(values, application, parent, defaultValues) { + super(values, application, parent, defaultValues ?? ABViewDefaults); + } - static common() { - return ABViewDefaults; - } + static common() { + return ABViewDefaults; + } - static defaultValues() { - return ABViewDataSelectPropertyComponentDefaults; - } + static defaultValues() { + return ABViewDataSelectPropertyComponentDefaults; + } - /// - /// Instance Methods - /// + /// + /// Instance Methods + /// - /** - * @method fromValues() - * - * initialze this object with the given set of values. - * @param {obj} values - */ - fromValues(values) { - super.fromValues(values); - } + /** + * @method fromValues() + * + * initialze this object with the given set of values. + * @param {obj} values + */ + fromValues(values) { + super.fromValues(values); + } - /** - * @method componentList - * return the list of components available on this view to display in the editor. - */ - componentList() { - return []; + /** + * @method componentList + * return the list of components available on this view to display in the editor. + */ + componentList() { + return []; + } } -}; - -return class ABViewDataSelect extends ABViewDataSelectCore { -/** + return class ABViewDataSelect extends ABViewDataSelectCore { + /** * @method getPluginKey * return the plugin key for this view. * @return {string} plugin key @@ -69,7 +69,7 @@ return class ABViewDataSelect extends ABViewDataSelectCore { return this.common().key; } -/** + /** * @method component() * return a UI component based upon this view. * @return {obj} UI component @@ -78,30 +78,25 @@ return class ABViewDataSelect extends ABViewDataSelectCore { return new ABAbviewdataselectComponent(this, parentId); } + warningsEval() { + super.warningsEval(); - - - warningsEval() { - super.warningsEval(); - - let DC = this.datacollection; - if (!DC) { - this.warningsMessage( - `can't resolve it's datacollection[${this.settings.dataviewID}]` - ); - } else { - if (this.settings.viewType == "connected") { - const object = DC.datasource; - const [field] = object.fields( - (f) => f.columnName === this.settings.field + let DC = this.datacollection; + if (!DC) { + this.warningsMessage( + `can't resolve it's datacollection[${this.settings.dataviewID}]` ); - if (!field) { - this.warningsMessage(`can't resolve field reference`); + } else { + if (this.settings.viewType == "connected") { + const object = DC.datasource; + const [field] = object.fields( + (f) => f.columnName === this.settings.field + ); + if (!field) { + this.warningsMessage(`can't resolve field reference`); + } } } } - } + }; } - -} - diff --git a/AppBuilder/platform/plugins/included/view_data-select/FNAbviewdataselectComponent.js b/AppBuilder/platform/plugins/included/view_data-select/FNAbviewdataselectComponent.js index b8748131..3155e28a 100644 --- a/AppBuilder/platform/plugins/included/view_data-select/FNAbviewdataselectComponent.js +++ b/AppBuilder/platform/plugins/included/view_data-select/FNAbviewdataselectComponent.js @@ -3,61 +3,56 @@ export default function FNAbviewdataselectComponent({ ABViewComponentPlugin, }) { return class ABAbviewdataselectComponent extends ABViewComponentPlugin { + constructor(baseView, idbase, ids) { + super( + baseView, + idbase || `ABViewDataSelect_${baseView.id}`, + Object.assign( + { + select: "", + }, + ids + ) + ); + } - - constructor(baseView, idbase, ids) { - super( - baseView, - idbase || `ABViewDataSelect_${baseView.id}`, - Object.assign( + ui() { + const _ui = super.ui([ { - select: "", - }, - ids - ) - ); - } - - ui() { - const _ui = super.ui([ - { - view: "combo", - id: this.ids.select, - on: { - onChange: (n, o) => { - if (n !== o) this.cursorChange(n); + view: "combo", + id: this.ids.select, + on: { + onChange: (n, o) => { + if (n !== o) this.cursorChange(n); + }, }, }, - }, - ]); - delete _ui.type; - - return _ui; - } - - async onShow() { - super.onShow(); - const dc = this.datacollection; - if (!dc) return; - await dc.waitReady(); - const labelField = this.AB.definitionByID( - this.settings.labelField - )?.columnName; - const options = dc - .getData() - .map((o) => ({ id: o.id, value: o[labelField] })) - .sort((a, b) => (a.value > b.value ? 1 : -1)); - const $select = $$(this.ids.select); - $select.define("options", options); - $select.refresh(); - $select.setValue(dc.getCursor().id); - } - - cursorChange(n) { - this.datacollection.setCursor(n); - } - - + ]); + delete _ui.type; + + return _ui; + } + + async onShow() { + super.onShow(); + const dc = this.datacollection; + if (!dc) return; + await dc.waitReady(); + const labelField = this.AB.definitionByID( + this.settings.labelField + )?.columnName; + const options = dc + .getData() + .map((o) => ({ id: o.id, value: o[labelField] })) + .sort((a, b) => (a.value > b.value ? 1 : -1)); + const $select = $$(this.ids.select); + $select.define("options", options); + $select.refresh(); + $select.setValue(dc.getCursor().id); + } + + cursorChange(n) { + this.datacollection.setCursor(n); + } }; - } From 7bf0a7a9a86dc9d43f042f88f7b0d983c133a442 Mon Sep 17 00:00:00 2001 From: Wirachot Date: Wed, 18 Feb 2026 18:39:02 +0700 Subject: [PATCH 3/5] update --- AppBuilder/core | 2 +- package-lock.json | 18 +++++++++--------- package.json | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/AppBuilder/core b/AppBuilder/core index 033d062a..fcbb87a1 160000 --- a/AppBuilder/core +++ b/AppBuilder/core @@ -1 +1 @@ -Subproject commit 033d062ac13b1b720955016e10fe146d0523c759 +Subproject commit fcbb87a1c361495c61e0169c193de84a47efeec6 diff --git a/package-lock.json b/package-lock.json index d1b5abcd..a76e7a2a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ab_platform_web", - "version": "1.17.1+c20900", + "version": "1.17.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "ab_platform_web", - "version": "1.17.1+c20900", + "version": "1.17.7", "license": "ISC", "dependencies": { "@sentry/browser": "^7.69.0", @@ -22,7 +22,7 @@ "papaparse": "^5.5.2", "pdfjs-dist": "^4.2.67", "sails.io.js": "^1.2.1", - "semver": "^7.7.3", + "semver": "^7.7.4", "socket.io-client": "^2.5.0", "tinymce": "^5.10.6", "uuid": "^8.3.2" @@ -9404,9 +9404,9 @@ } }, "node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -17981,9 +17981,9 @@ } }, "semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==" + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==" }, "serialize-error": { "version": "8.1.0", diff --git a/package.json b/package.json index 40e0e81c..4dbad79d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ab_platform_web", - "version": "1.17.2+c20901", + "version": "1.17.8+c20904", "description": "AppBuilder runtime environment for the Web client.", "main": "index.js", "scripts": { @@ -58,7 +58,7 @@ "papaparse": "^5.5.2", "pdfjs-dist": "^4.2.67", "sails.io.js": "^1.2.1", - "semver": "^7.7.3", + "semver": "^7.7.4", "socket.io-client": "^2.5.0", "tinymce": "^5.10.6", "uuid": "^8.3.2" From 62923df9305da63435204552da037beb25a79ae0 Mon Sep 17 00:00:00 2001 From: Wirachot Date: Wed, 18 Feb 2026 18:42:07 +0700 Subject: [PATCH 4/5] Reset package.json, package-lock.json, and AppBuilder/core to master --- AppBuilder/core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppBuilder/core b/AppBuilder/core index fcbb87a1..9c645df2 160000 --- a/AppBuilder/core +++ b/AppBuilder/core @@ -1 +1 @@ -Subproject commit fcbb87a1c361495c61e0169c193de84a47efeec6 +Subproject commit 9c645df2f06fb745e3ea0e43e7fd3764da9cd82b From e89908aa32eddf674be275020b426de3bf4b5f31 Mon Sep 17 00:00:00 2001 From: Wirachot Date: Wed, 18 Feb 2026 18:47:46 +0700 Subject: [PATCH 5/5] Rearrange import --- AppBuilder/platform/plugins/included/index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/AppBuilder/platform/plugins/included/index.js b/AppBuilder/platform/plugins/included/index.js index 2e201259..da87f45b 100644 --- a/AppBuilder/platform/plugins/included/index.js +++ b/AppBuilder/platform/plugins/included/index.js @@ -1,10 +1,10 @@ -import viewImage from "./view_image/FNAbviewimage.js"; -import viewText from "./view_text/FNAbviewtext.js"; -import viewDataSelect from "./view_data-select/FNAbviewdataselect.js"; import viewList from "./view_list/FNAbviewlist.js"; import viewTab from "./view_tab/FNAbviewtab.js"; +import viewText from "./view_text/FNAbviewtext.js"; +import viewImage from "./view_image/FNAbviewimage.js"; +import viewDataSelect from "./view_data-select/FNAbviewdataselect.js"; -const AllPlugins = [viewTab, viewList, viewImage, viewText, viewDataSelect]; +const AllPlugins = [viewTab, viewList, viewText, viewImage, viewDataSelect]; export default { load: (AB) => {