From 7fb03038af59a3d2cecc339742344e20e8a532f6 Mon Sep 17 00:00:00 2001 From: BenWirachot Date: Thu, 26 Mar 2026 11:25:53 +0700 Subject: [PATCH 1/7] Form plugin --- src/plugins/index.js | 4 + src/plugins/web_view_form/FNAbviewform.js | 762 ++++++++++++++++++ .../web_view_form/FNAbviewformEditor.js | 63 ++ .../Designer/editors/EditorManager.js | 2 +- .../Designer/properties/PropertyManager.js | 2 +- 5 files changed, 831 insertions(+), 2 deletions(-) create mode 100644 src/plugins/web_view_form/FNAbviewform.js create mode 100644 src/plugins/web_view_form/FNAbviewformEditor.js diff --git a/src/plugins/index.js b/src/plugins/index.js index 02b8afe0..687dac3f 100644 --- a/src/plugins/index.js +++ b/src/plugins/index.js @@ -1,3 +1,5 @@ +import viewFormProperties from "./web_view_form/FNAbviewform.js"; +import viewFormEditor from "./web_view_form/FNAbviewformEditor.js"; import viewCarouselProperties from "./web_view_carousel/FNAbviewcarousel.js"; import viewCarouselEditor from "./web_view_carousel/FNAbviewcarouselEditor.js"; import viewCommentProperties from "./web_view_comment/FNAbviewcomment.js"; @@ -38,6 +40,8 @@ const AllPlugins = [ viewTabEditor, viewTextProperties, viewTextEditor, + viewFormProperties, + viewFormEditor, ]; export default { diff --git a/src/plugins/web_view_form/FNAbviewform.js b/src/plugins/web_view_form/FNAbviewform.js new file mode 100644 index 00000000..a2a9afc7 --- /dev/null +++ b/src/plugins/web_view_form/FNAbviewform.js @@ -0,0 +1,762 @@ +export default function FNAbviewformProperties({ + AB, + ABViewPropertiesPlugin, + // ABUIPlugin, +}) { + const FABViewContainer = + require("../../rootPages/Designer/properties/views/ABViewContainer").default; + const FABViewRuleListFormRecordRules = + require("../../rootPages/Designer/properties/rules/ABViewRuleListFormRecordRules").default; + const FABViewRuleListFormSubmitRules = + require("../../rootPages/Designer/properties/rules/ABViewRuleListFormSubmitRules").default; + + const ABViewContainer = FABViewContainer(AB); + const uiConfig = AB.Config.uiSettings(); + const L = ABViewContainer.L(); + + var ABViewFormPropertyComponentDefaults = {}; + + const base = "properties_abview_form"; + + const PopupRecordRule = FABViewRuleListFormRecordRules( + AB, + `${base}_popupRecordRule` + ); + + const PopupSubmitRule = FABViewRuleListFormSubmitRules( + AB, + `${base}_popupSubmitRule` + ); + + + +return class ABAbviewformProperties extends ABViewPropertiesPlugin { + +static getPluginKey() { + return this.key; + } + +static getPluginType() { + return "properties-view"; + // properties-view : will display in the properties panel of the ABDesigner + } + + + + + constructor(b = null, id = null) { + b = b || base; + id = Object.assign(id || {}, { + // Put our ids here + datacollection: "", + fields: "", + showLabel: "", + labelPosition: "", + labelWidth: "", + height: "", + clearOnLoad: "", + clearOnSave: "", + + buttonSubmitRules: "", + buttonRecordRules: "", + }); + super(b, id); + + this.AB = AB; + ABViewFormPropertyComponentDefaults = + this.AB.ClassManager.viewClass("form").defaultValues(); + } + + static get key() { + return "form"; + } + + ui(elements = null) { + let ids = this.ids; + + elements = elements || []; + + return super.ui( + [ + { + id: ids.datacollection, + view: "richselect", + name: "datacollection", + label: L("Datacollection"), + labelWidth: uiConfig.labelWidthLarge, + skipAutoSave: true, + on: { + onChange: (newId, oldId) => { + this.selectSource(newId, oldId); + }, + }, + }, + + { + view: "fieldset", + label: L("Form Fields:"), + labelWidth: uiConfig.labelWidthLarge, + body: { + type: "clean", + padding: 10, + rows: [ + { + id: ids.fields, + view: "list", + name: "fields", + + select: false, + minHeight: 200, + template: (...params) => { + return this.listTemplate(...params); + }, + type: { + markCheckbox: function (item) { + return ( + "" + ); + }, + }, + onClick: { + check: (...params) => { + return this.check(...params); + }, + }, + }, + ], + }, + }, + { + id: ids.showLabel, + name: "showLabel", + view: "checkbox", + label: L("Display Label"), + labelWidth: uiConfig.labelWidthLarge, + click: () => { + this.onChange(); + }, + }, + { + id: ids.labelPosition, + view: "richselect", + name: "labelPosition", + + label: L("Label Position"), + labelWidth: uiConfig.labelWidthLarge, + options: [ + { + id: "left", + value: L("Left"), + }, + { + id: "top", + value: L("Top"), + }, + ], + on: { + onChange: () => { + this.onChange(); + }, + }, + }, + { + id: ids.labelWidth, + view: "counter", + name: "labelWidth", + + label: L("Label Width"), + labelWidth: uiConfig.labelWidthLarge, + on: { + onChange: () => { + this.onChange(); + }, + }, + }, + { + id: ids.height, + view: "counter", + name: "height", + label: L("Height"), + labelWidth: uiConfig.labelWidthLarge, + on: { + onChange: () => { + this.onChange(); + }, + }, + }, + { + id: ids.clearOnLoad, + view: "checkbox", + name: "clearOnLoad", + + label: L("Clear on load"), + labelWidth: uiConfig.labelWidthLarge, + on: { + onChange: () => { + this.onChange(); + }, + }, + }, + { + id: ids.clearOnSave, + view: "checkbox", + name: "clearOnSave", + label: L("Clear on save"), + labelWidth: uiConfig.labelWidthLarge, + on: { + onChange: () => { + this.onChange(); + }, + }, + }, + { + view: "fieldset", + label: L("Rules:"), + labelWidth: uiConfig.labelWidthLarge, + body: { + type: "clean", + padding: 10, + rows: [ + { + cols: [ + { + view: "label", + label: L("Submit Rules:"), + width: uiConfig.labelWidthLarge, + }, + { + id: ids.buttonSubmitRules, + view: "button", + css: "webix_primary", + name: "buttonSubmitRules", + label: L("Settings"), + icon: "fa fa-gear", + type: "icon", + badge: 0, + click: () => { + this.submitRuleShow(); + }, + }, + ], + }, + // { + // cols: [ + // { + // view: "label", + // label: L("Display Rules:"), + // width: uiConfig.labelWidthLarge, + // }, + // { + // view: "button", + // name: "buttonDisplayRules", + // css: "webix_primary", + // label: L("Settings"), + // icon: "fa fa-gear", + // type: "icon", + // badge: 0, + // click: () => { + // this.displayRuleShow(); + // }, + // }, + // ], + // }, + { + cols: [ + { + view: "label", + label: L("Record Rules:"), + width: uiConfig.labelWidthLarge, + }, + { + id: ids.buttonRecordRules, + view: "button", + name: "buttonRecordRules", + css: "webix_primary", + label: L("Settings"), + icon: "fa fa-gear", + type: "icon", + badge: 0, + click: () => { + this.recordRuleShow(); + }, + }, + ], + }, + ], + }, + }, + ].concat(elements) + ); + } + + async init(AB) { + super.init(AB); + + webix.extend($$(this.ids.component), webix.ProgressBar); + + let allInits = []; + allInits.push(PopupRecordRule.init(AB)); + PopupRecordRule.on("save", () => { + this.onChange(); + this.populateBadgeNumber(); + }); + allInits.push(PopupSubmitRule.init(AB)); + PopupSubmitRule.on("save", (/* settings */) => { + this.onChange(); + this.populateBadgeNumber(); + }); + + return Promise.all(allInits); + } + + populate(view) { + super.populate(view); + let ids = this.ids; + if (!view) return; + + let formCom = view.parentFormComponent(); + let datacollectionId = formCom.settings.dataviewID + ? formCom.settings.dataviewID + : null; + var SourceSelector = $$(ids.datacollection); + + // Pull data collections to options + var dcOptions = view.application + .datacollectionsIncluded() + .filter((dc) => { + const obj = dc.datasource; + return ( + dc.sourceType == "object" && + !obj?.isImported && + !obj?.isReadOnly + ); + }) + .map((d) => { + let entry = { id: d.id, value: d.label }; + if (d.sourceType == "query") { + entry.icon = "fa fa-filter"; + } else { + entry.icon = "fa fa-database"; + } + return entry; + }); + SourceSelector.define("options", dcOptions); + SourceSelector.define("value", datacollectionId); + SourceSelector.refresh(); + + this.propertyUpdateFieldOptions(datacollectionId); + + // update properties when a field component is deleted + view.views().forEach((v) => { + if (v instanceof this.AB.Class.ABViewFormItem) + v.once("destroyed", () => this.populate(view)); + }); + + SourceSelector.enable(); + $$(ids.showLabel).setValue(view.settings.showLabel); + $$(ids.labelPosition).setValue( + view.settings.labelPosition || + ABViewFormPropertyComponentDefaults.labelPosition + ); + $$(ids.labelWidth).setValue( + view.settings.labelWidth || + ABViewFormPropertyComponentDefaults.labelWidth + ); + $$(ids.height).setValue( + view.settings.height || ABViewFormPropertyComponentDefaults.height + ); + $$(ids.clearOnLoad).setValue( + view.settings.clearOnLoad || + ABViewFormPropertyComponentDefaults.clearOnLoad + ); + $$(ids.clearOnSave).setValue( + view.settings.clearOnSave || + ABViewFormPropertyComponentDefaults.clearOnSave + ); + + // NOTE: load the object and view BEFORE the .fromSettings(); + PopupRecordRule.objectLoad(this.CurrentObject); + PopupRecordRule.viewLoad(view); + PopupRecordRule.fromSettings(view.settings.recordRules || []); + + PopupSubmitRule.objectLoad(this.CurrentObject); + PopupSubmitRule.viewLoad(view); + PopupSubmitRule.fromSettings(view.settings.submitRules || []); + + // this.propertyUpdateRules(ids, view, datacollectionId); + this.populateBadgeNumber(); + + // when a change is made in the properties the popups need to reflect the change + this.updateEventIds = this.updateEventIds || {}; // { viewId: boolean, ..., viewIdn: boolean } + if (!this.updateEventIds[view.id]) { + this.updateEventIds[view.id] = true; + + view.addListener("properties.updated", () => { + this.populateBadgeNumber(); + }); + } + } + + defaultValues() { + let values = {}; + var ViewClass = this.ViewClass(); + if (ViewClass) { + values = ViewClass.defaultValues(); + } + return values; + } + + /** + * @method values + * return the values for this form. + * @return {obj} + */ + values() { + let ids = this.ids; + let vals = super.values(); + + vals.settings = vals.settings || {}; + + vals.settings.dataviewID = $$(ids.datacollection).getValue(); + vals.settings.showLabel = $$(ids.showLabel).getValue(); + vals.settings.labelPosition = + $$(ids.labelPosition).getValue() || + ABViewFormPropertyComponentDefaults.labelPosition; + vals.settings.labelWidth = + $$(ids.labelWidth).getValue() || + ABViewFormPropertyComponentDefaults.labelWidth; + vals.settings.height = $$(ids.height).getValue(); + vals.settings.clearOnLoad = $$(ids.clearOnLoad).getValue(); + vals.settings.clearOnSave = $$(ids.clearOnSave).getValue(); + + vals.settings.recordRules = PopupRecordRule.toSettings(); + vals.settings.submitRules = PopupSubmitRule.toSettings(); + return vals; + } + + /** + * @method FieldClass() + * A method to return the proper ABViewXXX Definition. + * NOTE: Must be overwritten by the Child Class + */ + ViewClass() { + return super._ViewClass("carousel"); + } + + // + // + // + + busy() { + $$(this.ids.component)?.showProgress?.({ type: "icon" }); + } + + check(e, fieldId) { + const ids = this.ids; + let currView = this.CurrentView; + let formView = currView.parentFormComponent(); + + // update UI list + let item = $$(ids.fields).getItem(fieldId); + item.selected = item.selected ? 0 : 1; + $$(ids.fields).updateItem(fieldId, item); + + let doneFn = () => { + formView + .refreshDefaultButton(ids) + .save() + .then(() => { + // refresh UI + currView.emit("properties.updated", currView); + this.onChange(); + }); + + // // trigger a save() + // this.propertyEditorSave(ids, currView); + }; + + // add a field to the form + if (item.selected) { + let fieldView = currView.addFieldToForm(item); + if (fieldView) { + fieldView.save().then(() => { + fieldView.once("destroyed", () => this.populate(currView)); + currView.viewInsert(fieldView).then(() => { + doneFn(); + }); + }); + } + } + // remove field in the form + else { + let fieldView = formView + .fieldComponents() + .filter((c) => c.settings.fieldId == fieldId)[0]; + if (fieldView) { + // let remainingViews = formView.views(c => c.settings.fieldId != fieldId); + // formView._views = remainingViews; + + fieldView.destroy(); + currView.viewRemove(fieldView).then(() => { + doneFn(); + }); + } + } + } + + populateBadgeNumber(/* */) { + const ids = this.ids; + + let view = this.CurrentView; + + if (!view) return; + + if (view.settings.submitRules) { + $$(ids.buttonSubmitRules).define( + "badge", + view.settings.submitRules.length || null + ); + } else { + $$(ids.buttonSubmitRules).define("badge", null); + } + $$(ids.buttonSubmitRules).refresh(); + + // if (view.settings.displayRules) { + // $$(ids.buttonDisplayRules).define( + // "badge", + // view.settings.displayRules.length || null + // ); + // $$(ids.buttonDisplayRules).refresh(); + // } else { + // $$(ids.buttonDisplayRules).define("badge", null); + // $$(ids.buttonDisplayRules).refresh(); + // } + + if (view.settings.recordRules) { + $$(ids.buttonRecordRules).define( + "badge", + view.settings.recordRules.length || null + ); + } else { + $$(ids.buttonRecordRules).define("badge", null); + } + $$(ids.buttonRecordRules).refresh(); + } + + ready() { + $$(this.ids.component)?.hideProgress?.(); + } + + recordRuleShow() { + PopupRecordRule.fromSettings(this.CurrentView.settings.recordRules); + PopupRecordRule.show(); + } + + submitRuleShow() { + PopupSubmitRule.fromSettings(this.CurrentView.settings.submitRules); + PopupSubmitRule.show(); + } + + listTemplate(field, common) { + let currView = this.CurrentView; + + // disable in form + var fieldComponent = field.formComponent(); + if (fieldComponent == null) + return ` ${field.label}
Disable
`; + + var componentKey = fieldComponent.common().key; + var formComponent = currView.application.viewAll( + (v) => v.common().key == componentKey + )[0]; + + return `${common.markCheckbox(field)} ${ + field.label + }
${ + formComponent ? L(formComponent.common().labelKey) : "" + }
`; + } + + /** + * @method propertyUpdateFieldOptions + * Populate fields of object to select list in property + * + * @param {ABViewForm} view - the current component + * @param {string} dcId - id of ABDatacollection + */ + propertyUpdateFieldOptions(dcId) { + const ids = this.ids; + var formComponent = this.CurrentView.parentFormComponent(); + var existsFields = formComponent.fieldComponents(); + var datacollection = this.AB.datacollectionByID(dcId); + var object = datacollection ? datacollection.datasource : null; + + // Pull field list + var fieldOptions = []; + if (object != null) { + fieldOptions = object.fields().map((f) => { + f.selected = + existsFields.filter((com) => { + return f.id == com.settings.fieldId; + }).length > 0; + + return f; + }); + + this.objectLoad(object); + } + + $$(ids.fields).clearAll(); + $$(ids.fields).parse(fieldOptions); + } + + refreshDefaultButton() { + const ids = this.ids; + const ABViewFormButton = + this.AB.ClassManager.viewClass("button"); + + // If default button is not exists, then skip this + let defaultButton = this.views( + (v) => v instanceof ABViewFormButton && v.settings.isDefault + )[0]; + + // Add a default button + if (defaultButton == null) { + defaultButton = ABViewFormButton.newInstance( + this.application, + this + ); + defaultButton.settings.isDefault = true; + } + // Remove default button from array, then we will add it to be the last item later (.push) + else { + this._views = this.views( + (v) => !(v instanceof ABViewFormButton) && !v.settings.isDefault + ); + } + + // Calculate position Y of the default button + let yList = this.views().map((v) => (v.position.y || 0) + 1); + yList.push(this._views.length || 0); + yList.push($$(ids.fields).length || 0); + let posY = Math.max(...yList); + + // Update to be the last item + defaultButton.position.y = posY; + + // Keep the default button is always the last item of array + this._views.push(defaultButton); + + return defaultButton; + } + + selectSource(dcId /*, oldDcId */) { + // TODO : warning message + const ids = this.ids; + this.busy(); + + let currView = this.CurrentView; + let formView = currView.parentFormComponent(); + + currView.settings.dataviewID = dcId; + + // clear sub views + var viewsToRemove = currView._views; + currView._views = []; + + return ( + Promise.resolve() + .then(() => { + var allRemoves = []; + viewsToRemove.forEach((v) => { + allRemoves.push(v.destroy()); + }); + return Promise.all(allRemoves); + }) + // .then(() => { + // // remove all old components + // let destroyTasks = []; + // if (oldDcId != null) { + // let oldComps = formView.views(); + // oldComps.forEach(child => destroyTasks.push(() => child.destroy())); + // } + + // return destroyTasks.reduce((promiseChain, currTask) => { + // return promiseChain.then(currTask); + // }, Promise.resolve([])); + // }) + .then(() => { + // refresh UI + // formView.emit('properties.updated', currView); + + // Update field options in property + this.propertyUpdateFieldOptions(dcId); + + // add all fields to editor by default + if (currView._views.length > 0) return Promise.resolve(); + + let saveTasks = []; + let fields = $$(ids.fields).find({}); + fields.reverse(); + fields.forEach((f, index) => { + if (!f.selected) { + let yPosition = fields.length - index - 1; + + // Add new form field + let newFieldView = currView.addFieldToForm( + f, + yPosition + ); + if (newFieldView) { + newFieldView.once("destroyed", () => + this.populate(currView) + ); + + // // Call save API + saveTasks.push(newFieldView.save()); + } + + // update item to UI list + f.selected = 1; + $$(ids.fields).updateItem(f.id, f); + } + }); + + let defaultButton = formView.refreshDefaultButton(ids); + if (defaultButton) saveTasks.push(defaultButton.save()); + + return Promise.all(saveTasks); + }) + // Saving + .then(() => { + //// NOTE: the way the .addFieldToForm() works, it will prevent + //// the typical field.save() -> triggering the form.save() on a + //// new Field. So once all our field.saves() are finished, we + //// need to perform a form.save() to persist the changes. + return currView.save(); + }) + // Finally + .then(() => { + // refresh UI + formView.emit("properties.updated", currView); + + // Update field options in property + // this.propertyUpdateRules(ids, currView, dcId); + + this.ready(); + this.onChange(); + return Promise.resolve(); + }) + ); + } + } + + + + +} + diff --git a/src/plugins/web_view_form/FNAbviewformEditor.js b/src/plugins/web_view_form/FNAbviewformEditor.js new file mode 100644 index 00000000..eb55f29e --- /dev/null +++ b/src/plugins/web_view_form/FNAbviewformEditor.js @@ -0,0 +1,63 @@ +export default function FNAbviewformEditor({ AB, ABViewEditorPlugin }) { + const FABViewContainer = + require("../../rootPages/Designer/properties/views/ABViewContainer").default; + + const ABViewContainer = FABViewContainer(AB); + // var L = UIClass.L(); + // var L = ABViewContainer.L(); + +return class ABAbviewformEditor extends ABViewEditorPlugin { + +static getPluginKey() { + return this.key; + } + +/** + * @method getPluginType + * return the plugin type for this editor. + * plugin types are how our ClassManager knows how to store + * the plugin. + * @return {string} plugin type + */ + static getPluginType() { + return "editor-view"; + // editor-view : will display in the editor panel of the ABDesigner + } + + + + + static get key() { + return "form"; + } + + constructor(view, base = "interface_editor_viewform") { + // base: {string} unique base id reference + + super(view, base); + + // this.component = this.view.component(); + } + + ui() { + let _ui = super.ui(); + _ui.rows[0].cellHeight = 75; + return _ui; + } + + init(AB) { + this.AB = AB; + return super.init(AB); + } + + detatch() { + this.component?.detatch?.(); + } + + onShow() { + this.component?.onShow?.(); + } + }; + + +} diff --git a/src/rootPages/Designer/editors/EditorManager.js b/src/rootPages/Designer/editors/EditorManager.js index c81903b0..ec62b0e2 100644 --- a/src/rootPages/Designer/editors/EditorManager.js +++ b/src/rootPages/Designer/editors/EditorManager.js @@ -27,7 +27,7 @@ export default function (AB) { require("./views/ABViewDataview"), require("./views/ABViewDetail"), require("./views/ABViewDocxBuilder"), - require("./views/ABViewForm"), + // require("./views/ABViewForm"), require("./views/ABViewFormUrl"), require("./views/ABViewGantt"), require("./views/ABViewGrid"), diff --git a/src/rootPages/Designer/properties/PropertyManager.js b/src/rootPages/Designer/properties/PropertyManager.js index 2a0bee75..6bb78ff5 100644 --- a/src/rootPages/Designer/properties/PropertyManager.js +++ b/src/rootPages/Designer/properties/PropertyManager.js @@ -92,7 +92,7 @@ export default function (AB) { require("./views/ABViewDetailText"), require("./views/ABViewDetailTree"), require("./views/ABViewDocxBuilder"), - require("./views/ABViewForm"), + // require("./views/ABViewForm"), require("./views/ABViewFormButton"), require("./views/ABViewFormCheckbox"), require("./views/ABViewFormConnect"), From de979d8ec1053a9ac6a5c802896a4dbea66fb3ef Mon Sep 17 00:00:00 2001 From: BenWirachot Date: Mon, 20 Apr 2026 17:19:52 +0700 Subject: [PATCH 2/7] Improve form field management with busy states, duplicate prevention, and updated editor inheritance --- src/plugins/web_view_form/FNAbviewform.js | 31 ++++++-- .../web_view_form/FNAbviewformEditor.js | 74 +++++++++---------- ..._work_interface_workspace_editor_layout.js | 3 +- 3 files changed, 64 insertions(+), 44 deletions(-) diff --git a/src/plugins/web_view_form/FNAbviewform.js b/src/plugins/web_view_form/FNAbviewform.js index a2a9afc7..9f21dc7e 100644 --- a/src/plugins/web_view_form/FNAbviewform.js +++ b/src/plugins/web_view_form/FNAbviewform.js @@ -350,7 +350,7 @@ static getPluginType() { // update properties when a field component is deleted view.views().forEach((v) => { - if (v instanceof this.AB.Class.ABViewFormItem) + if (v.isFormField) v.once("destroyed", () => this.populate(view)); }); @@ -442,7 +442,7 @@ static getPluginType() { * NOTE: Must be overwritten by the Child Class */ ViewClass() { - return super._ViewClass("carousel"); + return super._ViewClass("form"); } // @@ -454,6 +454,9 @@ static getPluginType() { } check(e, fieldId) { + if (this._isBusy) return; + this._isBusy = true; + this.busy(); const ids = this.ids; let currView = this.CurrentView; let formView = currView.parentFormComponent(); @@ -464,6 +467,7 @@ static getPluginType() { $$(ids.fields).updateItem(fieldId, item); let doneFn = () => { + this._isBusy = false; formView .refreshDefaultButton(ids) .save() @@ -471,6 +475,7 @@ static getPluginType() { // refresh UI currView.emit("properties.updated", currView); this.onChange(); + this.ready(); }); // // trigger a save() @@ -479,14 +484,27 @@ static getPluginType() { // add a field to the form if (item.selected) { - let fieldView = currView.addFieldToForm(item); + // Check for duplication + let exists = formView + .fieldComponents() + .find((c) => c.settings.fieldId == fieldId); + if (exists) { + this._isBusy = false; + this.ready(); + return; + } + + let fieldView = formView.addFieldToForm(item); if (fieldView) { fieldView.save().then(() => { fieldView.once("destroyed", () => this.populate(currView)); - currView.viewInsert(fieldView).then(() => { + formView.viewInsert(fieldView).then(() => { doneFn(); }); }); + } else { + this._isBusy = false; + this.ready(); } } // remove field in the form @@ -499,9 +517,12 @@ static getPluginType() { // formView._views = remainingViews; fieldView.destroy(); - currView.viewRemove(fieldView).then(() => { + formView.viewRemove(fieldView).then(() => { doneFn(); }); + } else { + this._isBusy = false; + this.ready(); } } } diff --git a/src/plugins/web_view_form/FNAbviewformEditor.js b/src/plugins/web_view_form/FNAbviewformEditor.js index eb55f29e..688bfcff 100644 --- a/src/plugins/web_view_form/FNAbviewformEditor.js +++ b/src/plugins/web_view_form/FNAbviewformEditor.js @@ -1,24 +1,24 @@ export default function FNAbviewformEditor({ AB, ABViewEditorPlugin }) { const FABViewContainer = - require("../../rootPages/Designer/properties/views/ABViewContainer").default; + require("../../rootPages/Designer/editors/views/ABViewContainer").default; const ABViewContainer = FABViewContainer(AB); - // var L = UIClass.L(); - // var L = ABViewContainer.L(); + // var L = UIClass.L(); + // var L = ABViewContainer.L(); -return class ABAbviewformEditor extends ABViewEditorPlugin { + return class ABAbviewformEditor extends ABViewContainer { -static getPluginKey() { + static getPluginKey() { return this.key; } -/** - * @method getPluginType - * return the plugin type for this editor. - * plugin types are how our ClassManager knows how to store - * the plugin. - * @return {string} plugin type - */ + /** + * @method getPluginType + * return the plugin type for this editor. + * plugin types are how our ClassManager knows how to store + * the plugin. + * @return {string} plugin type + */ static getPluginType() { return "editor-view"; // editor-view : will display in the editor panel of the ABDesigner @@ -27,37 +27,35 @@ static getPluginKey() { - static get key() { - return "form"; - } - - constructor(view, base = "interface_editor_viewform") { - // base: {string} unique base id reference + static get key() { + return "form"; + } - super(view, base); + constructor(view, base = "interface_editor_viewform") { + // base: {string} unique base id reference - // this.component = this.view.component(); - } + super(view, base); - ui() { - let _ui = super.ui(); - _ui.rows[0].cellHeight = 75; - return _ui; - } + // this.component = this.view.component(); + } - init(AB) { - this.AB = AB; - return super.init(AB); - } + ui() { + let _ui = super.ui(); + _ui.rows[0].cellHeight = 75; + return _ui; + } - detatch() { - this.component?.detatch?.(); - } + init(AB) { + this.AB = AB; + return super.init(AB); + } - onShow() { - this.component?.onShow?.(); - } - }; - + detatch() { + this.component?.detatch?.(); + } + onShow() { + this.component?.onShow?.(); + } + }; } diff --git a/src/rootPages/Designer/ui_work_interface_workspace_editor_layout.js b/src/rootPages/Designer/ui_work_interface_workspace_editor_layout.js index 94586edc..0f797d72 100644 --- a/src/rootPages/Designer/ui_work_interface_workspace_editor_layout.js +++ b/src/rootPages/Designer/ui_work_interface_workspace_editor_layout.js @@ -287,7 +287,8 @@ export default function (AB) { } if (idDashboard) { const $dashboard = $$(idDashboard); - if ($dashboard) $dashboard.clearAll(); + if ($dashboard && typeof $dashboard.clearAll === "function") + $dashboard.clearAll(); } // add the editorUI if it is not already added From f9d1386934b1ba178a4ef58f86a99edffe198097 Mon Sep 17 00:00:00 2001 From: benthongtiang Date: Tue, 2 Jun 2026 15:07:47 +0700 Subject: [PATCH 3/7] Potential fix for pull request finding 'CodeQL / Semicolon insertion' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- src/plugins/web_view_form/FNAbviewform.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/web_view_form/FNAbviewform.js b/src/plugins/web_view_form/FNAbviewform.js index 9f21dc7e..ba388383 100644 --- a/src/plugins/web_view_form/FNAbviewform.js +++ b/src/plugins/web_view_form/FNAbviewform.js @@ -774,7 +774,7 @@ static getPluginType() { }) ); } - } + }; From b9c4f7967d190a1a52638f1c6a93bef56e1590d6 Mon Sep 17 00:00:00 2001 From: BenWirachot Date: Thu, 4 Jun 2026 13:37:48 +0700 Subject: [PATCH 4/7] Merge master plugins (Gantt, Kanban) into ben/FormPlugin index.js --- src/plugins/index.js | 76 ++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/src/plugins/index.js b/src/plugins/index.js index 5ba531a0..6265b1b1 100644 --- a/src/plugins/index.js +++ b/src/plugins/index.js @@ -1,63 +1,71 @@ -import viewFormProperties from "./web_view_form/FNAbviewform.js"; -import viewFormEditor from "./web_view_form/FNAbviewformEditor.js"; -import viewGridProperties from "./web_view_grid/FNAbviewgrid.js"; -import viewGridEditor from "./web_view_grid/FNAbviewgridEditor.js"; -import viewPivotProperties from "./web_view_pivot/FNAbviewpivot.js"; -import viewPivotEditor from "./web_view_pivot/FNAbviewpivotEditor.js"; -import viewCarouselProperties from "./web_view_carousel/FNAbviewcarousel.js"; import viewCarouselEditor from "./web_view_carousel/FNAbviewcarouselEditor.js"; -import viewCommentProperties from "./web_view_comment/FNAbviewcomment.js"; +import viewCarouselProperties from "./web_view_carousel/FNAbviewcarousel.js"; import viewCommentEditor from "./web_view_comment/FNAbviewcommentEditor.js"; -import viewDataSelectProperties from "./web_view_data-select/FNAbviewdataselect.js"; +import viewCommentProperties from "./web_view_comment/FNAbviewcomment.js"; import viewDataSelectEditor from "./web_view_data-select/FNAbviewdataselectEditor.js"; -import viewDataviewProperties from "./web_view_dataview/FNAbviewdataview.js"; +import viewDataSelectProperties from "./web_view_data-select/FNAbviewdataselect.js"; import viewDataviewEditor from "./web_view_dataview/FNAbviewdataviewEditor.js"; -import viewDetailProperties from "./web_view_detail/FNAbviewdetail.js"; +import viewDataviewProperties from "./web_view_dataview/FNAbviewdataview.js"; import viewDetailEditor from "./web_view_detail/FNAbviewdetailEditor.js"; -import viewImageProperties from "./web_view_image/FNAbviewimage.js"; +import viewDetailProperties from "./web_view_detail/FNAbviewdetail.js"; +import viewFormEditor from "./web_view_form/FNAbviewformEditor.js"; +import viewFormProperties from "./web_view_form/FNAbviewform.js"; +import viewGanttEditor from "./web_view_gantt/FNAbviewganttEditor.js"; +import viewGanttProperties from "./web_view_gantt/FNAbviewgantt.js"; +import viewGridEditor from "./web_view_grid/FNAbviewgridEditor.js"; +import viewGridProperties from "./web_view_grid/FNAbviewgrid.js"; import viewImageEditor from "./web_view_image/FNAbviewimageEditor.js"; -import viewLabelProperties from "./web_view_label/FNAbviewLabel.js"; +import viewImageProperties from "./web_view_image/FNAbviewimage.js"; +import viewKanbanEditor from "./web_view_kanban/FNAbviewkanbanEditor.js"; +import viewKanbanProperties from "./web_view_kanban/FNAbviewkanban.js"; import viewLabelEditor from "./web_view_label/FNAbviewLabelEditor.js"; -import viewLayoutProperties from "./web_view_layout/FNAbviewlayout.js"; +import viewLabelProperties from "./web_view_label/FNAbviewLabel.js"; import viewLayoutEditor from "./web_view_layout/FNAbviewlayoutEditor.js"; +import viewLayoutProperties from "./web_view_layout/FNAbviewlayout.js"; import viewListProperties from "./web_view_list/FNAbviewlist.js"; -import viewPdfImporterProperties from "./web_view_pdfImporter/FNAbviewpdfimporter.js"; import viewPdfImporterEditor from "./web_view_pdfImporter/FNAbviewpdfimporterEditor.js"; -import viewTabProperties from "./web_view_tab/FNAbviewtab.js"; +import viewPdfImporterProperties from "./web_view_pdfImporter/FNAbviewpdfimporter.js"; +import viewPivotEditor from "./web_view_pivot/FNAbviewpivotEditor.js"; +import viewPivotProperties from "./web_view_pivot/FNAbviewpivot.js"; import viewTabEditor from "./web_view_tab/FNAbviewtabEditor.js"; -import viewTextProperties from "./web_view_text/FNAbviewtext.js"; +import viewTabProperties from "./web_view_tab/FNAbviewtab.js"; import viewTextEditor from "./web_view_text/FNAbviewtextEditor.js"; +import viewTextProperties from "./web_view_text/FNAbviewtext.js"; const AllPlugins = [ - viewCarouselProperties, viewCarouselEditor, - viewCommentProperties, + viewCarouselProperties, viewCommentEditor, - viewDataSelectProperties, + viewCommentProperties, viewDataSelectEditor, - viewDataviewProperties, + viewDataSelectProperties, viewDataviewEditor, - viewDetailProperties, + viewDataviewProperties, viewDetailEditor, - viewImageProperties, + viewDetailProperties, + viewFormEditor, + viewFormProperties, + viewGanttEditor, + viewGanttProperties, + viewGridEditor, + viewGridProperties, viewImageEditor, - viewLabelProperties, + viewImageProperties, + viewKanbanEditor, + viewKanbanProperties, viewLabelEditor, - viewLayoutProperties, + viewLabelProperties, viewLayoutEditor, + viewLayoutProperties, viewListProperties, - viewPdfImporterProperties, viewPdfImporterEditor, - viewTabProperties, + viewPdfImporterProperties, + viewPivotEditor, + viewPivotProperties, viewTabEditor, - viewTextProperties, + viewTabProperties, viewTextEditor, - viewFormProperties, - viewFormEditor, - viewGridProperties, - viewGridEditor, - viewPivotProperties, - viewPivotEditor, + viewTextProperties, ]; export default { From df2ecee217f2001b5a14fe43ba521fdebc9e55f4 Mon Sep 17 00:00:00 2001 From: BenWirachot Date: Wed, 17 Jun 2026 16:13:47 +0700 Subject: [PATCH 5/7] Form view properties and introduce dynamic editor registration for form elements. --- src/plugins/web_view_form/FNAbviewform.js | 32 +- .../web_view_form/FNAbviewformEditor.js | 7 + .../editors/FNAbviewFormUrlEditor.js | 67 +++ .../properties/FNAbviewFormButton.js | 288 ++++++++++ .../properties/FNAbviewFormCheckbox.js | 40 ++ .../properties/FNAbviewFormConnect.js | 534 ++++++++++++++++++ .../properties/FNAbviewFormCustom.js | 40 ++ .../properties/FNAbviewFormDatepicker.js | 40 ++ .../properties/FNAbviewFormItem.js | 126 +++++ .../properties/FNAbviewFormJson.js | 160 ++++++ .../properties/FNAbviewFormNumber.js | 107 ++++ .../properties/FNAbviewFormSelectMultiple.js | 115 ++++ .../properties/FNAbviewFormSelectSingle.js | 115 ++++ .../properties/FNAbviewFormTextbox.js | 120 ++++ .../properties/FNAbviewFormTree.js | 40 ++ .../properties/FNAbviewFormUrl.js | 168 ++++++ .../Designer/editors/EditorManager.js | 3 +- .../Designer/properties/PropertyManager.js | 24 +- 18 files changed, 2008 insertions(+), 18 deletions(-) create mode 100644 src/plugins/web_view_form/editors/FNAbviewFormUrlEditor.js create mode 100644 src/plugins/web_view_form/properties/FNAbviewFormButton.js create mode 100644 src/plugins/web_view_form/properties/FNAbviewFormCheckbox.js create mode 100644 src/plugins/web_view_form/properties/FNAbviewFormConnect.js create mode 100644 src/plugins/web_view_form/properties/FNAbviewFormCustom.js create mode 100644 src/plugins/web_view_form/properties/FNAbviewFormDatepicker.js create mode 100644 src/plugins/web_view_form/properties/FNAbviewFormItem.js create mode 100644 src/plugins/web_view_form/properties/FNAbviewFormJson.js create mode 100644 src/plugins/web_view_form/properties/FNAbviewFormNumber.js create mode 100644 src/plugins/web_view_form/properties/FNAbviewFormSelectMultiple.js create mode 100644 src/plugins/web_view_form/properties/FNAbviewFormSelectSingle.js create mode 100644 src/plugins/web_view_form/properties/FNAbviewFormTextbox.js create mode 100644 src/plugins/web_view_form/properties/FNAbviewFormTree.js create mode 100644 src/plugins/web_view_form/properties/FNAbviewFormUrl.js diff --git a/src/plugins/web_view_form/FNAbviewform.js b/src/plugins/web_view_form/FNAbviewform.js index ba388383..b79b04d9 100644 --- a/src/plugins/web_view_form/FNAbviewform.js +++ b/src/plugins/web_view_form/FNAbviewform.js @@ -1,3 +1,16 @@ +import FNAbviewFormButtonProperties from "./properties/FNAbviewFormButton.js"; +import FNAbviewFormCheckboxProperties from "./properties/FNAbviewFormCheckbox.js"; +import FNAbviewFormConnectProperties from "./properties/FNAbviewFormConnect.js"; +import FNAbviewFormCustomProperties from "./properties/FNAbviewFormCustom.js"; +import FNAbviewFormDatepickerProperties from "./properties/FNAbviewFormDatepicker.js"; +import FNAbviewFormJsonProperties from "./properties/FNAbviewFormJson.js"; +import FNAbviewFormNumberProperties from "./properties/FNAbviewFormNumber.js"; +import FNAbviewFormSelectMultipleProperties from "./properties/FNAbviewFormSelectMultiple.js"; +import FNAbviewFormSelectSingleProperties from "./properties/FNAbviewFormSelectSingle.js"; +import FNAbviewFormTextboxProperties from "./properties/FNAbviewFormTextbox.js"; +import FNAbviewFormTreeProperties from "./properties/FNAbviewFormTree.js"; +import FNAbviewFormUrlProperties from "./properties/FNAbviewFormUrl.js"; + export default function FNAbviewformProperties({ AB, ABViewPropertiesPlugin, @@ -776,8 +789,19 @@ static getPluginType() { } }; - - - + return [ + ABAbviewformProperties, + FNAbviewFormButtonProperties({ AB, ABViewPropertiesPlugin }), + FNAbviewFormCheckboxProperties({ AB, ABViewPropertiesPlugin }), + FNAbviewFormConnectProperties({ AB, ABViewPropertiesPlugin }), + FNAbviewFormCustomProperties({ AB, ABViewPropertiesPlugin }), + FNAbviewFormDatepickerProperties({ AB, ABViewPropertiesPlugin }), + FNAbviewFormJsonProperties({ AB, ABViewPropertiesPlugin }), + FNAbviewFormNumberProperties({ AB, ABViewPropertiesPlugin }), + FNAbviewFormSelectMultipleProperties({ AB, ABViewPropertiesPlugin }), + FNAbviewFormSelectSingleProperties({ AB, ABViewPropertiesPlugin }), + FNAbviewFormTextboxProperties({ AB, ABViewPropertiesPlugin }), + FNAbviewFormTreeProperties({ AB, ABViewPropertiesPlugin }), + FNAbviewFormUrlProperties({ AB, ABViewPropertiesPlugin }), + ]; } - diff --git a/src/plugins/web_view_form/FNAbviewformEditor.js b/src/plugins/web_view_form/FNAbviewformEditor.js index 688bfcff..1cc28b07 100644 --- a/src/plugins/web_view_form/FNAbviewformEditor.js +++ b/src/plugins/web_view_form/FNAbviewformEditor.js @@ -1,3 +1,5 @@ +import FNAbviewFormUrlEditor from "./editors/FNAbviewFormUrlEditor.js"; + export default function FNAbviewformEditor({ AB, ABViewEditorPlugin }) { const FABViewContainer = require("../../rootPages/Designer/editors/views/ABViewContainer").default; @@ -58,4 +60,9 @@ export default function FNAbviewformEditor({ AB, ABViewEditorPlugin }) { this.component?.onShow?.(); } }; + + return [ + ABAbviewformEditor, + FNAbviewFormUrlEditor({ ABViewEditorPlugin }) + ]; } diff --git a/src/plugins/web_view_form/editors/FNAbviewFormUrlEditor.js b/src/plugins/web_view_form/editors/FNAbviewFormUrlEditor.js new file mode 100644 index 00000000..8ace3b25 --- /dev/null +++ b/src/plugins/web_view_form/editors/FNAbviewFormUrlEditor.js @@ -0,0 +1,67 @@ +import FNAbviewformEditor from "../FNAbviewformEditor.js"; + +/** + * ABViewFormEditor + * The widget that displays the UI Editor Component on the screen + * when designing the UI. + */ +var myClass = null; +// {singleton} +// we will want to call this factory fn() repeatedly in our imports, +// but we only want to define 1 Class reference. + + + +export default function FNAbviewFormUrlEditor({ + ABViewEditorPlugin, +}) { + const ABViewForm = FNAbviewformEditor({ ABViewEditorPlugin }); + + if (!myClass) { + + // var L = UIClass.L(); + // var L = ABViewContainer.L(); + + myClass = class ABViewFormEditor extends ABViewForm { + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "editor-view"; + } + static get key() { + return "form-url"; + } + + // constructor(view, base = "interface_editor_viewform") { + // // base: {string} unique base id reference + + // super(view, base); + + // // this.component = this.view.component(); + // } + + // ui() { + // let _ui = super.ui(); + // _ui.rows[0].cellHeight = 75; + // return _ui; + // } + + // init(AB) { + // this.AB = AB; + // return super.init(AB); + // } + + // detatch() { + // this.component?.detatch?.(); + // } + + // onShow() { + // this.component?.onShow?.(); + // } + }; + } + + return myClass; +} diff --git a/src/plugins/web_view_form/properties/FNAbviewFormButton.js b/src/plugins/web_view_form/properties/FNAbviewFormButton.js new file mode 100644 index 00000000..ff47a515 --- /dev/null +++ b/src/plugins/web_view_form/properties/FNAbviewFormButton.js @@ -0,0 +1,288 @@ + + +/* + * ABViewButton + * A Property manager for our ABViewButton definitions + */ + + + +export default function FNAbviewFormButtonProperties({ + AB, + ABViewPropertiesPlugin, +}) { + + const BASE_ID = "properties_abview_button"; + + + const L = AB.Label(); + + class ABViewButtonProperty extends ABViewPropertiesPlugin { + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } + constructor() { + super(BASE_ID, { + // Put our ids here + includeSave: "", + saveLabel: "", + includeCancel: "", + cancelLabel: "", + includeReset: "", + resetLabel: "", + includeDelete: "", + deleteLabel: "", + afterCancel: "", + alignment: "", + }); + + this.AB = AB; + } + + static get key() { + return "button"; + } + + ui() { + const ids = this.ids; + const uiConfig = this.AB.UISettings.config(); + + return super.ui([ + { + id: ids.includeSave, + name: "includeSave", + view: "checkbox", + label: L("Save"), + click: () => this.onChange(), + }, + { + id: ids.saveLabel, + name: "saveLabel", + view: "text", + labelWidth: uiConfig.labelWidthLarge, + label: L("Save Label"), + placeholder: L("Save Placeholder"), + on: { + onChange: () => this.onChange(), + }, + }, + { + id: ids.includeCancel, + name: "includeCancel", + view: "checkbox", + label: L("Cancel"), + click: () => this.onChange(), + }, + { + id: ids.cancelLabel, + name: "cancelLabel", + view: "text", + labelWidth: uiConfig.labelWidthLarge, + label: L("Cancel Label"), + placeholder: L("Cancel Placeholder"), + on: { + onChange: () => this.onChange(), + }, + }, + { + id: ids.includeReset, + name: "includeReset", + view: "checkbox", + label: L("Reset"), + click: () => this.onChange(), + }, + { + id: ids.resetLabel, + name: "resetLabel", + view: "text", + labelWidth: uiConfig.labelWidthLarge, + label: L("Reset Label"), + placeholder: L("Reset Placeholder"), + on: { + onChange: () => this.onChange(), + }, + }, + { + id: ids.includeDelete, + name: "includeDelete", + view: "checkbox", + label: L("Delete"), + click: () => this.onChange(), + }, + { + id: ids.deleteLabel, + name: "deleteLabel", + view: "text", + labelWidth: uiConfig.labelWidthLarge, + label: L("Delete Label"), + placeholder: L("Delete Placeholder"), + on: { + onChange: () => this.onChange(), + }, + }, + { + id: ids.afterCancel, + name: "afterCancel", + view: "richselect", + labelWidth: uiConfig.labelWidthLarge, + label: L("After Cancel"), + on: { + onChange: () => this.onChange(), + }, + // options: [] + }, + { + id: ids.alignment, + name: "alignment", + view: "richselect", + labelWidth: uiConfig.labelWidthLarge, + label: L("Alignment"), + options: [ + { + id: "left", + value: L("Left"), + }, + { + id: "center", + value: L("Center"), + }, + { + id: "right", + value: L("Right"), + }, + ], + on: { + onChange: () => this.onChange(), + }, + }, + ]); + } + + async init(AB) { + this.AB = AB; + + await super.init(AB); + } + + populate(view) { + super.populate(view); + + const ids = this.ids; + const ABViewFormButtonPropertyComponentDefaults = this.defaultValues(); + + const pagesList = []; + this.addPagesToList(pagesList, view.application, view.pageRoot().id); + + const opts = pagesList.map((opt) => { + return { + id: opt.id, + value: opt.value, + }; + }); + $$(ids.afterCancel).define("options", opts); + + $$(ids.includeSave).setValue( + view.settings.includeSave != null + ? view.settings.includeSave + : ABViewFormButtonPropertyComponentDefaults.includeSave + ); + $$(ids.includeCancel).setValue( + view.settings.includeCancel != null + ? view.settings.includeCancel + : ABViewFormButtonPropertyComponentDefaults.includeCancel + ); + $$(ids.includeReset).setValue( + view.settings.includeReset != null + ? view.settings.includeReset + : ABViewFormButtonPropertyComponentDefaults.includeReset + ); + $$(ids.includeDelete).setValue( + view.settings.includeDelete != null + ? view.settings.includeDelete + : ABViewFormButtonPropertyComponentDefaults.includeDelete + ); + + $$(ids.saveLabel).setValue(view.settings.saveLabel ?? ""); + $$(ids.cancelLabel).setValue(view.settings.cancelLabel ?? ""); + $$(ids.resetLabel).setValue(view.settings.resetLabel ?? ""); + $$(ids.deleteLabel).setValue(view.settings.deleteLabel ?? ""); + + $$(ids.afterCancel).setValue( + view.settings.afterCancel ?? + ABViewFormButtonPropertyComponentDefaults.afterCancel + ); + $$(ids.alignment).setValue( + view.settings.alignment ?? + ABViewFormButtonPropertyComponentDefaults.alignment + ); + } + + defaultValues() { + const ViewClass = this.ViewClass(); + + let values = null; + + if (ViewClass) { + values = ViewClass.defaultValues(); + } + + return values; + } + + /** + * @method values + * return the values for this form. + * @return {obj} + */ + values() { + const ids = this.ids; + + const $component = $$(ids.component); + + const values = super.values() ?? {}; + values.settings = $component.getValues() ?? {}; + values.settings.includeSave = $$(ids.includeSave).getValue(); + values.settings.saveLabel = $$(ids.saveLabel).getValue(); + values.settings.includeCancel = $$(ids.includeCancel).getValue(); + values.settings.cancelLabel = $$(ids.cancelLabel).getValue(); + values.settings.includeReset = $$(ids.includeReset).getValue(); + values.settings.resetLabel = $$(ids.resetLabel).getValue(); + values.settings.includeDelete = $$(ids.includeDelete).getValue(); + values.settings.deleteLabel = $$(ids.deleteLabel).getValue(); + values.settings.afterCancel = $$(ids.afterCancel).getValue(); + values.settings.alignment = $$(ids.alignment).getValue(); + + return values; + } + + /** + * @method FieldClass() + * A method to return the proper ABViewXXX Definition. + * NOTE: Must be overwritten by the Child Class + */ + ViewClass() { + return super._ViewClass("button"); + } + + addPagesToList(pagesList, parent, rootPageId) { + if (!parent || !parent.pages || !pagesList) return; + + (parent.pages() ?? []).forEach((page) => { + if (page.parent != null || page.id == rootPageId) { + pagesList.push({ + id: page.id, + value: page.label, + }); + + this.addPagesToList(pagesList, page, page.id); + } + }); + } + } + + return ABViewButtonProperty; +} diff --git a/src/plugins/web_view_form/properties/FNAbviewFormCheckbox.js b/src/plugins/web_view_form/properties/FNAbviewFormCheckbox.js new file mode 100644 index 00000000..579cf1f7 --- /dev/null +++ b/src/plugins/web_view_form/properties/FNAbviewFormCheckbox.js @@ -0,0 +1,40 @@ +import FNAbviewformItem from "./FNAbviewformItem.js"; + +/* + * ABViewFormCheckbox + * A Property manager for our ABViewFormCheckbox definitions + */ + + + +export default function FNAbviewFormCheckboxProperties({ + AB, + ABViewPropertiesPlugin, +}) { + const ABViewFormItem = FNAbviewformItem({ AB, ABViewPropertiesPlugin }); + + const BASE_ID = "properties_abview_form_checkbox"; + + + + class ABViewFormCheckboxProperty extends ABViewFormItem { + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } + constructor() { + super(BASE_ID, {}); + + this.AB = AB; + } + + static get key() { + return "checkbox"; + } + } + + return ABViewFormCheckboxProperty; +} diff --git a/src/plugins/web_view_form/properties/FNAbviewFormConnect.js b/src/plugins/web_view_form/properties/FNAbviewFormConnect.js new file mode 100644 index 00000000..8f47fa73 --- /dev/null +++ b/src/plugins/web_view_form/properties/FNAbviewFormConnect.js @@ -0,0 +1,534 @@ +import FNAbviewformItem from "./FNAbviewformItem.js"; +import ABPopupSort from "../../../rootPages/Designer/ui_work_object_workspace_popupSortFields"; +import ABViewPropertyAddPage from "../../../rootPages/Designer/properties/views/viewProperties/ABViewPropertyAddPage"; +import ABViewPropertyEditPage from "../../../rootPages/Designer/properties/views/viewProperties/ABViewPropertyEditPage"; + +/* + * ABViewConnect + * A Property manager for our ABViewConnect definitions + */ + + + + + + +export default function FNAbviewFormConnectProperties({ + AB, + ABViewPropertiesPlugin, +}) { + const ABViewFormItem = FNAbviewformItem({ AB, ABViewPropertiesPlugin }); + + const BASE_ID = "properties_abview_connect"; + + + const ABAddPage = ABViewPropertyAddPage(AB, BASE_ID); + const ABEditPage = ABViewPropertyEditPage(AB, BASE_ID); + const L = AB.Label(); + + let FilterComponent = null; + let SortComponent = null; + + class ABViewConnectProperty extends ABViewFormItem { + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } + constructor() { + super(BASE_ID, { + // Put our ids here + addNewSettings: "", + popupWidth: "", + popupHeight: "", + advancedOption: "", + buttonFilter: "", + filterConnectedValue: "", + buttonSort: "", + }); + + this.AB = AB; + FilterComponent = this.AB.filterComplexNew(`${BASE_ID}_filter`); + FilterComponent.on("save", () => this.onChange()); + SortComponent = ABPopupSort(this.AB, `${BASE_ID}_sort`); + SortComponent.on("changed", () => this.onChange()); + } + + static get key() { + return "connect"; + } + + ui() { + const self = this; + const ids = this.ids; + const uiConfig = this.AB.UISettings.config(); + + return super.ui([ + this.addPageProperty.ui(), + this.editPageProperty.ui(), + { + id: ids.addNewSettings, + view: "fieldset", + name: "addNewSettings", + label: L("Add New Popup Settings:"), + labelWidth: uiConfig.labelWidthLarge, + body: { + type: "clean", + padding: 10, + rows: [ + { + id: ids.popupWidth, + view: "text", + name: "popupWidth", + placeholder: L("Set popup width"), + label: L("Width:"), + labelWidth: uiConfig.labelWidthLarge, + validate: this.AB.Webix.rules.isNumber, + on: { + onChange: () => this.onChange(), + }, + }, + { + id: ids.popupHeight, + view: "text", + name: "popupHeight", + placeholder: L("Set popup height"), + label: L("Height:"), + labelWidth: uiConfig.labelWidthLarge, + validate: this.AB.Webix.rules.isNumber, + on: { + onChange: () => this.onChange(), + }, + }, + ], + }, + }, + { + id: ids.advancedOption, + view: "fieldset", + name: "advancedOption", + label: L("Advanced Options:"), + labelWidth: uiConfig.labelWidthLarge, + body: { + type: "clean", + padding: 10, + rows: [ + { + cols: [ + { + view: "label", + label: L("Filter Options:"), + width: uiConfig.labelWidthLarge, + }, + { + id: ids.buttonFilter, + view: "button", + name: "buttonFilter", + css: "webix_primary", + label: L("Settings"), + icon: "fa fa-gear", + type: "icon", + badge: 0, + click: function () { + self.showFilterPopup(this.$view); + }, + }, + ], + }, + { + rows: [ + { + view: "label", + label: L("Filter by Connected Field Value:"), + }, + { + id: ids.filterConnectedValue, + view: "combo", + name: "filterConnectedValue", + options: [], // we will add these in propertyEditorPopulate + on: { + onChange: () => this.onChange(), + }, + }, + ], + }, + { + height: 30, + }, + { + rows: [ + { + cols: [ + { + view: "label", + label: L("Sort Options:"), + width: uiConfig.labelWidthLarge, + }, + { + id: ids.buttonSort, + view: "button", + name: "buttonSort", + css: "webix_primary", + label: L("Settings"), + icon: "fa fa-gear", + type: "icon", + badge: 0, + click: function () { + self.showSortPopup(this.$view); + }, + }, + ], + }, + ], + }, + ], + }, + }, + ]); + } + + async init(AB) { + this.AB = AB; + + await super.init(AB); + + FilterComponent.init(); + // when we make a change in the popups we want to make sure we save the new workspace to the properties to do so just fire an onChange event + // FilterComponent.on("change", (val) => { + // this.onChange(); + // }); + + SortComponent.init(AB); + + this.addPageProperty.on("change", () => { + this.onChange(); + }); + + this.editPageProperty.on("change", () => { + this.onChange(); + }); + } + + populate(view) { + super.populate(view); + + this.populateFilterByConnectedFieldValue(view); + + const ids = this.ids; + const ABViewFormConnectPropertyComponentDefaults = + this.defaultValues(); + + // Default set of options for filter connected combo + const filterConnectedOptions = [{ id: null, value: "" }]; + + // get the definitions for the connected field + const fieldDefs = this.AB.definitionByID(view.settings.fieldId); + + // get the definition for the object that the field is related to + const objectDefs = this.AB.definitionByID( + fieldDefs.settings.linkObject + ); + + // we need these definitions later as we check to find out which field + // we are filtering by so push them into an array for later + const fieldsDefs = []; + objectDefs.fieldIDs.forEach((fld) => { + fieldsDefs.push(this.AB.definitionByID(fld)); + }); + + // find out what connected objects this field has + const connectedObjs = view.application.connectedObjects( + fieldDefs.settings.linkObject + ); + + // loop through the form's elements (need to ensure that just looking at parent is okay in all cases) + view.parent.views().forEach((element) => { + // identify if element is a connected field + if (element.key == "connect") { + // we need to get the fields defs to find out what it is connected to + const formElementsDefs = this.AB.definitionByID( + element.settings.fieldId + ); + + // loop through the connected objects discovered above + connectedObjs.forEach((connObj) => { + // see if the connected object matches the connected object of the form element + if (connObj.id == formElementsDefs.settings.linkObject) { + // get the ui id of this component that matches the link Object + let fieldToCheck; + fieldsDefs.forEach((fdefs) => { + // if the field has a custom foreign key we need to store it + // so selectivity later can know what value to get, otherwise + // we just get the uuid of the record + if ( + fdefs.settings.isCustomFK && + fdefs.settings.indexField != "" && + fdefs.settings.linkObject && + fdefs.settings.linkType == "one" && + fdefs.settings.linkObject == + formElementsDefs.settings.linkObject + ) { + fieldToCheck = fdefs.id; + let customFK = this.AB.definitionByID( + fdefs.settings.indexField + ); + + // if the index definitions were found + if (customFK) { + fieldToCheck = `${fdefs.id}:${customFK.columnName}`; + } + } else if ( + fdefs.settings.linkObject && + fdefs.settings.linkType == "one" && + fdefs.settings.linkObject == + formElementsDefs.settings.linkObject + ) { + fieldToCheck = `${fdefs.id}:uuid`; + } + }); + + // only add optinos that have a fieldToCheck + if (fieldToCheck) { + // get the component we are referencing so we can display its label + const formComponent = + view.parent.viewComponents[element.id]; // need to ensure that just looking at parent is okay in all cases + + const uiComp = formComponent.ui(); + const uiInput = uiComp.rows[0] ?? uiComp; + + filterConnectedOptions.push({ + id: `${uiInput.name}:${fieldToCheck}`, // store the columnName name because the ui id changes on each load + value: uiInput.label, // should be the translated field label + }); + } + } + }); + } + }); + + // Set the options of the possible edit forms + this.addPageProperty.setSettings(view, { + formView: view.settings.formView, + }); + this.editPageProperty.setSettings(view, { + editForm: view.settings.editForm, + }); + $$(ids.filterConnectedValue).define("options", filterConnectedOptions); + $$(ids.filterConnectedValue).setValue( + view.settings.filterConnectedValue + ); + + $$(ids.popupWidth).setValue( + view.settings.popupWidth || + ABViewFormConnectPropertyComponentDefaults.popupWidth + ); + $$(ids.popupHeight).setValue( + view.settings.popupHeight || + ABViewFormConnectPropertyComponentDefaults.popupHeight + ); + + // initial populate of popups + this.populatePopupEditors(view); + + // inform the user that some advanced settings have been set + this.populateBadgeNumber(ids, view); + } + + _filterCondition(view) { + if (view?.options?.filters?.rules?.length) { + return view.options.filters; + } else if (view?.settings?.filterConditions?.rules?.length) { + return view.settings.filterConditions; + } else { + return null; + } + } + + populatePopupEditors(view) { + const filterConditions = + this._filterCondition(view) ?? + this.defaultValues().filterConditions; + + // Populate data to popups + // FilterComponent.objectLoad(objectCopy); + let linkedObj; + const field = view.field(); + if (field) { + linkedObj = field.datasourceLink; + if (linkedObj) + FilterComponent.fieldsLoad(linkedObj.fields(), linkedObj); + } + + FilterComponent.setValue(filterConditions); + + if (linkedObj) SortComponent.objectLoad(linkedObj); + SortComponent.setSettings(view.settings.sortFields); + } + + populateBadgeNumber(ids, view) { + const $buttonFilter = $$(ids.buttonFilter); + const filterCondition = this._filterCondition(view); + if (filterCondition?.rules) { + $buttonFilter.define("badge", filterCondition.rules.length || null); + $buttonFilter.refresh(); + } else { + $buttonFilter.define("badge", null); + $buttonFilter.refresh(); + } + + const $buttonSort = $$(ids.buttonSort); + if (view?.settings?.sortFields?.length) { + $buttonSort.define( + "badge", + view.settings.sortFields.length || null + ); + $buttonSort.refresh(); + } else { + $buttonSort.define("badge", null); + $buttonSort.refresh(); + } + } + + populateFilterByConnectedFieldValue(view) { + const fieldDef = this.AB.definitionByID(view.settings.fieldId); + + // Support only 1:M and 1:1 relation type of the connect field + if ( + // 1:M + (fieldDef.settings.linkType == "one" && + fieldDef.settings.linkViaType == "many") || + // 1:1 isSource = true + (fieldDef.settings.linkType == "one" && + fieldDef.settings.linkViaType == "one" && + fieldDef.settings.isSource) + ) { + // Pull link object + const linkObject = this.AB.objectByID(fieldDef.settings.linkObject); + if (!linkObject) return; + + let connectFields = linkObject.fields( + (f) => f.key == "connectObject" + ); + if (!connectFields || !connectFields.length) return; + + connectFields.forEach((f) => { + let connectFieldOptions = view.parent + .views((element) => { + let linkFieldDef = this.AB.definitionByID( + element.settings.fieldId + ); + + // Pull other connected field input elements + return ( + element.key == "connect" && + element.id != view.id && + f.settings.linkObject == + linkFieldDef.settings.linkObject + ); + }) + .map((element) => { + const formComponent = + view.parent.viewComponents[element.id]; + + const uiComp = formComponent.ui(); + const uiInput = uiComp.rows[0] ?? uiComp; + + return { + id: uiInput.name, + value: uiInput.label, + }; + }); + + if (connectFieldOptions && connectFieldOptions.length) { + FilterComponent.addCustomOption(f.id, { + conditions: [ + { + id: "filterByConnectValue", + value: L("Filter by Connected Field Value:"), + batch: "FilterByConnectedFieldValue", + handler: () => true, + }, + ], + values: [ + { + batch: "FilterByConnectedFieldValue", + view: "combo", + options: connectFieldOptions, + }, + ], + }); + } + }); + } + } + + /** + * @method values + * return the values for this form. + * @return {obj} + */ + values() { + const ids = this.ids; + const view = this.CurrentView; + + const $component = $$(ids.component); + + const values = super.values() ?? {}; + values.settings = $component.getValues() ?? {}; + values.settings.popupWidth = $$(ids.popupWidth).getValue(); + values.settings.popupHeight = $$(ids.popupHeight).getValue(); + values.settings.filterConnectedValue = $$( + ids.filterConnectedValue + ).getValue(); + values.settings.filterConditions = FilterComponent.getValue(); + values.settings.sortFields = SortComponent.getSettings(); + + const settingsAddPage = this.addPageProperty.getSettings(view) ?? {}; + const settingsEditPage = this.editPageProperty.getSettings(view) ?? {}; + values.settings.formView = settingsAddPage.formView; + values.settings.editForm = settingsEditPage.editForm; + + // refresh settings of app page tool + // this.addPageProperty.setSettings(view, values.settingsAddPage); + // this.editPageProperty.setSettings(view, values.settingsEditPage); + + return values; + } + + /** + * @method FieldClass() + * A method to return the proper ABViewXXX Definition. + * NOTE: Must be overwritten by the Child Class + */ + ViewClass() { + return super._ViewClass("connect"); + } + + get addPageProperty() { + if (!this._addPage) this._addPage = new ABAddPage(); + + return this._addPage; + } + + get editPageProperty() { + if (!this._editPage) this._editPage = new ABEditPage(); + + return this._editPage; + } + + showFilterPopup($view) { + FilterComponent.popUp($view, null, { pos: "top" }); + } + + showSortPopup($button) { + SortComponent.show($button, null, { + pos: "top", + }); + } + } + + return ABViewConnectProperty; +} + diff --git a/src/plugins/web_view_form/properties/FNAbviewFormCustom.js b/src/plugins/web_view_form/properties/FNAbviewFormCustom.js new file mode 100644 index 00000000..fc92fc86 --- /dev/null +++ b/src/plugins/web_view_form/properties/FNAbviewFormCustom.js @@ -0,0 +1,40 @@ +import FNAbviewformItem from "./FNAbviewformItem.js"; + +/* + * ABViewFormCustom + * A Property manager for our ABViewFormCustom definitions + */ + + + +export default function FNAbviewFormCustomProperties({ + AB, + ABViewPropertiesPlugin, +}) { + const ABViewFormItem = FNAbviewformItem({ AB, ABViewPropertiesPlugin }); + + const BASE_ID = "properties_abview_form_custom"; + + + + class ABViewFormCustomProperty extends ABViewFormItem { + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } + constructor() { + super(BASE_ID, {}); + + this.AB = AB; + } + + static get key() { + return "fieldcustom"; + } + } + + return ABViewFormCustomProperty; +} diff --git a/src/plugins/web_view_form/properties/FNAbviewFormDatepicker.js b/src/plugins/web_view_form/properties/FNAbviewFormDatepicker.js new file mode 100644 index 00000000..0dedaf42 --- /dev/null +++ b/src/plugins/web_view_form/properties/FNAbviewFormDatepicker.js @@ -0,0 +1,40 @@ +import FNAbviewformItem from "./FNAbviewformItem.js"; + +/* + * ABViewFormDatepicker + * A Property manager for our ABViewFormDatepicker definitions + */ + + + +export default function FNAbviewFormDatepickerProperties({ + AB, + ABViewPropertiesPlugin, +}) { + const ABViewFormItem = FNAbviewformItem({ AB, ABViewPropertiesPlugin }); + + const BASE_ID = "properties_abview_form_datepicker"; + + + + class ABViewFormDatepickerProperty extends ABViewFormItem { + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } + constructor() { + super(BASE_ID, {}); + + this.AB = AB; + } + + static get key() { + return "datepicker"; + } + } + + return ABViewFormDatepickerProperty; +} diff --git a/src/plugins/web_view_form/properties/FNAbviewFormItem.js b/src/plugins/web_view_form/properties/FNAbviewFormItem.js new file mode 100644 index 00000000..2b4b7c27 --- /dev/null +++ b/src/plugins/web_view_form/properties/FNAbviewFormItem.js @@ -0,0 +1,126 @@ + + +/* + * ABViewFormItem + * A Property manager for our ABViewFormItem definitions + */ + + + +export default function FNAbviewFormItemProperties({ + AB, + ABViewPropertiesPlugin, +}) { + + + const L = AB.Label(); + const DEFAULT_VALUES = { + required: 0, + disable: 0, + }; + + class ABViewFormItemProperty extends ABViewPropertiesPlugin { + constructor(BASE_ID, ids = {}) { + super( + BASE_ID, + Object.assign(ids, { + // Put our ids here + field: "", + required: "", + disable: "", + }) + ); + + this.AB = AB; + } + + ui(elements = [], rules = {}) { + const ids = this.ids; + const uiSettings = this.AB.UISettings.config(); + const _ui = [ + { + id: ids.field, + name: "fieldLabel", + view: "text", + disabled: true, + label: L("Field"), + }, + { + id: ids.required, + name: "required", + view: "checkbox", + labelWidth: uiSettings.labelWidthCheckbox, + labelRight: L("Required"), + click: () => this.onChange(), + }, + { + id: ids.disable, + name: "disable", + view: "checkbox", + labelWidth: uiSettings.labelWidthCheckbox, + labelRight: L("Disable"), + click: () => this.onChange(), + }, + ].concat(elements); + + return super.ui(_ui, rules); + } + + populate(view) { + super.populate(view); + + const ids = this.ids; + const ABViewFormItemPropertyDefaults = this.defaultValues(); + const field = view.field(); + + $$(ids.field).setValue(field ? field.label : ""); + + if (field?.settings?.required == 1) { + $$(ids.required).setValue(field.settings.required); + $$(ids.required).disable(); + } else { + $$(ids.required).setValue( + view.settings?.required != null + ? view.settings.required + : ABViewFormItemPropertyDefaults.required + ); + } + + if (view.settings?.disable == 1) { + $$(ids.disable).setValue(view.settings.disable); + } else { + $$(ids.disable).setValue(ABViewFormItemPropertyDefaults.disable); + } + } + + defaultValues() { + const ViewClass = this.ViewClass(); + + let values = {}; + + if (ViewClass) { + values = ViewClass.defaultValues(); + } + + return Object.assign(DEFAULT_VALUES, values); + } + + /** + * @method values + * return the values for this form. + * @return {obj} + */ + values() { + const ids = this.ids; + + const values = super.values() ?? {}; + values.settings = values.settings ?? {}; + values.settings.required = $$(ids.required).getValue(); + values.settings.disable = $$(ids.disable).getValue(); + + return values; + } + } + + return ABViewFormItemProperty; +} diff --git a/src/plugins/web_view_form/properties/FNAbviewFormJson.js b/src/plugins/web_view_form/properties/FNAbviewFormJson.js new file mode 100644 index 00000000..accebcfd --- /dev/null +++ b/src/plugins/web_view_form/properties/FNAbviewFormJson.js @@ -0,0 +1,160 @@ +import FNAbviewformItem from "./FNAbviewformItem.js"; + +/* + * ABViewFormJson + * A Property manager for our ABViewFormJson definitions + */ + + + +export default function FNAbviewFormJsonProperties({ + AB, + ABViewPropertiesPlugin, +}) { + const ABViewFormItem = FNAbviewformItem({ AB, ABViewPropertiesPlugin }); + + const BASE_ID = "properties_abview_form_json"; + + + const L = AB.Label(); + + class ABViewFormJsonProperty extends ABViewFormItem { + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } + constructor() { + super(BASE_ID, { + // Put our ids here + type: "", + filterField: "", + }); + + this.AB = AB; + } + + static get key() { + return "json"; + } + + ui() { + const ids = this.ids; + + return super.ui([ + { + id: ids.type, + name: "type", + view: "radio", + label: L("Type"), + vertical: true, + options: [ + { + id: "string", + value: L("JSON String"), + }, + { + id: "systemObject", + value: L("System Object Chooser UI"), + }, + { + id: "filter", + value: L("Filter UI"), + }, + ], + on: { + onChange: (newValue) => { + if (newValue == "filter") { + $$(ids.filterField).show(); + } else { + $$(ids.filterField).hide(); + } + this.onChange(); + }, + }, + }, + { + id: ids.filterField, + name: "filterField", + view: "combo", + hidden: true, + label: L("Object Field to Filter"), + labelPosition: "top", + placeholder: L("Select a field to filter by"), + // options: look at populate + on: { + onChange: (/* newValue */) => { + this.onChange(); + }, + }, + }, + ]); + } + + async init(AB) { + this.AB = AB; + + await super.init(AB); + } + + populate(view) { + super.populate(view); + + const ids = this.ids; + const ABViewFormJsonPropertyComponentDefaults = this.defaultValues(); + + // set the options for the filterField + let filterFieldOptions = [{ id: "", value: "" }]; + view.parent.views().forEach((element) => { + if ( + element.key == "json" && + element.settings.type == "systemObject" + ) { + let formComponent = view.parent.viewComponents[element.id]; + filterFieldOptions.push({ + id: element.settings.fieldId, + value: formComponent.settings.fieldLabel, + }); + } + }); + $$(ids.filterField).define("options", filterFieldOptions); + + if (view.settings.filterField) + $$(ids.filterField).setValue(view.settings.filterField); + + $$(ids.type).setValue( + view.settings.type || ABViewFormJsonPropertyComponentDefaults.type + ); + } + + /** + * @method values + * return the values for this form. + * @return {obj} + */ + values() { + const ids = this.ids; + + const $component = $$(ids.component); + + const values = super.values() ?? {}; + values.settings = $component.getValues() ?? {}; + values.settings.type = $$(ids.type).getValue(); + + return values; + } + + /** + * @method FieldClass() + * A method to return the proper ABViewXXX Definition. + * NOTE: Must be overwritten by the Child Class + */ + ViewClass() { + return super._ViewClass("json"); + } + } + + return ABViewFormJsonProperty; +} diff --git a/src/plugins/web_view_form/properties/FNAbviewFormNumber.js b/src/plugins/web_view_form/properties/FNAbviewFormNumber.js new file mode 100644 index 00000000..dd8549be --- /dev/null +++ b/src/plugins/web_view_form/properties/FNAbviewFormNumber.js @@ -0,0 +1,107 @@ +import FNAbviewformItem from "./FNAbviewformItem.js"; + +/* + * ABViewFormNumber + * A Property manager for our ABViewFormNumber definitions + */ + + + +export default function FNAbviewFormNumberProperties({ + AB, + ABViewPropertiesPlugin, +}) { + const ABViewFormItem = FNAbviewformItem({ AB, ABViewPropertiesPlugin }); + + const BASE_ID = "properties_abview_form_number"; + + + const L = AB.Label(); + + class ABViewFormNumberProperty extends ABViewFormItem { + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } + constructor() { + super(BASE_ID, { + // Put our ids here + isStepper: "", + }); + + this.AB = AB; + } + + static get key() { + return "numberbox"; + } + + ui() { + const ids = this.ids; + const uiConfig = this.AB.UISettings.config(); + + return super.ui([ + { + id: ids.isStepper, + name: "isStepper", + view: "checkbox", + labelWidth: uiConfig.labelWidthCheckbox, + labelRight: L("Plus/Minus Buttons"), + on: { + onChange: () => this.onChange(), + }, + }, + ]); + } + + async init(AB) { + this.AB = AB; + + await super.init(AB); + } + + populate(view) { + super.populate(view); + + const ids = this.ids; + const ABViewFormNumberPropertyComponentDefaults = this.defaultValues(); + + $$(ids.isStepper).setValue( + view.settings.isStepper != null + ? view.settings.isStepper + : ABViewFormNumberPropertyComponentDefaults.isStepper + ); + } + + /** + * @method values + * return the values for this form. + * @return {obj} + */ + values() { + const ids = this.ids; + + const $component = $$(ids.component); + + const values = super.values() ?? {}; + values.settings = $component.getValues() ?? {}; + values.settings.isStepper = $$(ids.isStepper).getValue(); + + return values; + } + + /** + * @method FieldClass() + * A method to return the proper ABViewXXX Definition. + * NOTE: Must be overwritten by the Child Class + */ + ViewClass() { + return super._ViewClass("numberbox"); + } + } + + return ABViewFormNumberProperty; +} diff --git a/src/plugins/web_view_form/properties/FNAbviewFormSelectMultiple.js b/src/plugins/web_view_form/properties/FNAbviewFormSelectMultiple.js new file mode 100644 index 00000000..f9e0acc3 --- /dev/null +++ b/src/plugins/web_view_form/properties/FNAbviewFormSelectMultiple.js @@ -0,0 +1,115 @@ +import FNAbviewformItem from "./FNAbviewformItem.js"; + +/* + * ABViewFormSelectMultiple + * A Property manager for our ABViewFormSelectMultiple definitions + */ + + + +export default function FNAbviewFormSelectMultipleProperties({ + AB, + ABViewPropertiesPlugin, +}) { + const ABViewFormItem = FNAbviewformItem({ AB, ABViewPropertiesPlugin }); + + const BASE_ID = "properties_abview_form_select_multiple"; + + + const L = AB.Label(); + + class ABViewFormSelectMultipleProperty extends ABViewFormItem { + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } + constructor() { + super(BASE_ID, { + // Put our ids here + type: "", + }); + + this.AB = AB; + } + + static get key() { + return "selectmultiple"; + } + + ui() { + const ids = this.ids; + + return super.ui([ + { + id: ids.type, + name: "type", + view: "richselect", + label: L("Type"), + options: [ + { + id: "multicombo", + value: L("Multi Combo"), + }, + { + id: "checkbox", + value: L("Checkboxes"), + }, + ], + on: { + onChange: () => this.onChange(), + }, + }, + ]); + } + + async init(AB) { + this.AB = AB; + + await super.init(AB); + } + + populate(view) { + super.populate(view); + + const ids = this.ids; + const ABViewFormSelectMultiplePropertyComponentDefaults = + this.defaultValues(); + + $$(ids.type).setValue( + view.settings.type || + ABViewFormSelectMultiplePropertyComponentDefaults.type + ); + } + + /** + * @method values + * return the values for this form. + * @return {obj} + */ + values() { + const ids = this.ids; + + const $component = $$(ids.component); + + const values = super.values() ?? {}; + values.settings = $component.getValues() ?? {}; + values.settings.type = $$(ids.type).getValue(); + + return values; + } + + /** + * @method FieldClass() + * A method to return the proper ABViewXXX Definition. + * NOTE: Must be overwritten by the Child Class + */ + ViewClass() { + return super._ViewClass("selectmultiple"); + } + } + + return ABViewFormSelectMultipleProperty; +} diff --git a/src/plugins/web_view_form/properties/FNAbviewFormSelectSingle.js b/src/plugins/web_view_form/properties/FNAbviewFormSelectSingle.js new file mode 100644 index 00000000..64b10cbb --- /dev/null +++ b/src/plugins/web_view_form/properties/FNAbviewFormSelectSingle.js @@ -0,0 +1,115 @@ +import FNAbviewformItem from "./FNAbviewformItem.js"; + +/* + * ABViewFormSelectSingle + * A Property manager for our ABViewFormSelectSingle definitions + */ + + + +export default function FNAbviewFormSelectSingleProperties({ + AB, + ABViewPropertiesPlugin, +}) { + const ABViewFormItem = FNAbviewformItem({ AB, ABViewPropertiesPlugin }); + + const BASE_ID = "properties_abview_form_select_single"; + + + const L = AB.Label(); + + class ABViewFormSelectSingleProperty extends ABViewFormItem { + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } + constructor() { + super(BASE_ID, { + // Put our ids here + type: "", + }); + + this.AB = AB; + } + + static get key() { + return "selectsingle"; + } + + ui() { + const ids = this.ids; + + return super.ui([ + { + id: ids.type, + name: "type", + view: "richselect", + label: L("Type"), + options: [ + { + id: "richselect", + value: L("Select list"), + }, + { + id: "radio", + value: L("Radio"), + }, + ], + on: { + onChange: () => this.onChange(), + }, + }, + ]); + } + + async init(AB) { + this.AB = AB; + + await super.init(AB); + } + + populate(view) { + super.populate(view); + + const ids = this.ids; + const ABViewFormSelectSinglePropertyComponentDefaults = + this.defaultValues(); + + $$(ids.type).setValue( + view.settings.type || + ABViewFormSelectSinglePropertyComponentDefaults.type + ); + } + + /** + * @method values + * return the values for this form. + * @return {obj} + */ + values() { + const ids = this.ids; + + const $component = $$(ids.component); + + const values = super.values() ?? {}; + values.settings = $component.getValues() ?? {}; + values.settings.type = $$(ids.type).getValue(); + + return values; + } + + /** + * @method FieldClass() + * A method to return the proper ABViewXXX Definition. + * NOTE: Must be overwritten by the Child Class + */ + ViewClass() { + return super._ViewClass("selectsingle"); + } + } + + return ABViewFormSelectSingleProperty; +} diff --git a/src/plugins/web_view_form/properties/FNAbviewFormTextbox.js b/src/plugins/web_view_form/properties/FNAbviewFormTextbox.js new file mode 100644 index 00000000..21bb5c38 --- /dev/null +++ b/src/plugins/web_view_form/properties/FNAbviewFormTextbox.js @@ -0,0 +1,120 @@ +import FNAbviewformItem from "./FNAbviewformItem.js"; + +/* + * ABViewFormTextbox + * A Property manager for our ABViewFormTextbox definitions + */ + + + +export default function FNAbviewFormTextboxProperties({ + AB, + ABViewPropertiesPlugin, +}) { + const ABViewFormItem = FNAbviewformItem({ AB, ABViewPropertiesPlugin }); + + const BASE_ID = "properties_abview_form_textbox"; + + + const L = AB.Label(); + + class ABViewFormTextboxProperty extends ABViewFormItem { + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } + constructor() { + super(BASE_ID, { + // Put our ids here + type: "", + }); + + this.AB = AB; + } + + static get key() { + return "textbox"; + } + + ui() { + const ids = this.ids; + + return super.ui([ + { + id: ids.type, + name: "type", + view: "radio", + label: L("Type"), + vertical: true, + options: [ + { + id: "single", + value: L("Single line"), + }, + { + id: "multiple", + value: L("Multiple lines"), + }, + { + id: "rich", + value: L("Rich editor"), + }, + ], + on: { + onChange: () => this.onChange(), + }, + }, + ]); + } + + async init(AB) { + this.AB = AB; + + await super.init(AB); + } + + populate(view) { + super.populate(view); + + const ids = this.ids; + const ABViewFormTextboxPropertyComponentDefaults = + this.defaultValues(); + + $$(ids.type).setValue( + view.settings.type || + ABViewFormTextboxPropertyComponentDefaults.type + ); + } + + /** + * @method values + * return the values for this form. + * @return {obj} + */ + values() { + const ids = this.ids; + + const $component = $$(ids.component); + + const values = super.values() ?? {}; + values.settings = $component.getValues() ?? {}; + values.settings.type = $$(ids.type).getValue(); + + return values; + } + + /** + * @method FieldClass() + * A method to return the proper ABViewXXX Definition. + * NOTE: Must be overwritten by the Child Class + */ + ViewClass() { + return super._ViewClass("textbox"); + } + } + + return ABViewFormTextboxProperty; +} diff --git a/src/plugins/web_view_form/properties/FNAbviewFormTree.js b/src/plugins/web_view_form/properties/FNAbviewFormTree.js new file mode 100644 index 00000000..2cce6c41 --- /dev/null +++ b/src/plugins/web_view_form/properties/FNAbviewFormTree.js @@ -0,0 +1,40 @@ +import FNAbviewformItem from "./FNAbviewformItem.js"; + +/* + * ABViewFormTree + * A Property manager for our ABViewFormTree definitions + */ + + + +export default function FNAbviewFormTreeProperties({ + AB, + ABViewPropertiesPlugin, +}) { + const ABViewFormItem = FNAbviewformItem({ AB, ABViewPropertiesPlugin }); + + const BASE_ID = "properties_abview_form_tree"; + + + + class ABViewFormTreeProperty extends ABViewFormItem { + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } + constructor() { + super(BASE_ID, {}); + + this.AB = AB; + } + + static get key() { + return "formtree"; + } + } + + return ABViewFormTreeProperty; +} diff --git a/src/plugins/web_view_form/properties/FNAbviewFormUrl.js b/src/plugins/web_view_form/properties/FNAbviewFormUrl.js new file mode 100644 index 00000000..e45a42ca --- /dev/null +++ b/src/plugins/web_view_form/properties/FNAbviewFormUrl.js @@ -0,0 +1,168 @@ +import FCommonKeyValue from "../../../rootPages/Designer/ui_common_key_value"; +import FNAbviewformProperties from "../FNAbviewform.js"; + +/* + * ABViewForm + * A Property manager for our ABViewForm definitions + */ + + + +export default function FNAbviewFormUrlProperties({ + AB, + ABViewPropertiesPlugin, +}) { + const ABViewForm = FNAbviewformProperties({ AB, ABViewPropertiesPlugin }); + + const UIClassCommonKeyValue = FCommonKeyValue(AB); + const uiConfig = AB.Config.uiSettings(); + const L = AB.Label(); + + const base = "properties_abview_form_url"; + + class ABViewFormUrlProperty extends ABViewForm { + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } + constructor() { + super(base, { + method: "", + url: "", + headers: "", + }); + + this.AB = AB; + + this.UIKeyValues = new UIClassCommonKeyValue({ + title: L("Headers"), + keyTitle: L("Key"), + valueTitle: L("Value"), + // contextID: base || randomID(), + }); + } + + static get key() { + return "form-url"; + } + + ui() { + let ids = this.ids; + + return super.ui([ + { + view: "fieldset", + label: L("URL:"), + labelWidth: uiConfig.labelWidthLarge, + body: { + type: "clean", + padding: 10, + rows: [ + { + id: ids.method, + view: "richselect", + name: "urlMethod", + + label: L("Method"), + labelWidth: uiConfig.labelWidthLarge, + options: [ + { + id: "get", + value: L("GET"), + }, + { + id: "post", + value: L("POST"), + }, + + { + id: "put", + value: L("PUT"), + }, + { + id: "delete", + value: L("DELETE"), + }, + ], + on: { + onChange: () => { + this.onChange(); + }, + }, + }, + { + id: ids.url, + view: "text", + label: L("URL"), + name: "url", + value: "", + on: { + onChange: () => { + this.onChange(); + }, + }, + }, + this.UIKeyValues.ui(), + ], + }, + }, + ]); + } + + populate(view) { + super.populate(view); + let ids = this.ids; + if (!view) return; + + var methodSelector = $$(ids.method); + methodSelector.define("value", view.settings?.method || "get"); + methodSelector.refresh(); + methodSelector.enable(); + + $$(ids.url).setValue(view.settings.url); + + this.UIKeyValues.populate(view.settings?.headers || []); + } + + defaultValues() { + let values = {}; + var ViewClass = this.ViewClass(); + if (ViewClass) { + values = ViewClass.defaultValues(); + } + return values; + } + + /** + * @method values + * return the values for this form. + * @return {obj} + */ + values() { + let ids = this.ids; + let vals = super.values(); + + vals.settings = vals.settings || {}; + + vals.settings.method = $$(ids.method).getValue(); + vals.settings.url = $$(ids.url).getValue(); + + vals.headers = this.UIKeyValues.getValues(); + return vals; + } + + /** + * @method FieldClass() + * A method to return the proper ABViewXXX Definition. + * NOTE: Must be overwritten by the Child Class + */ + ViewClass() { + return super._ViewClass("form-url"); + } + } + + return ABViewFormUrlProperty; +} diff --git a/src/rootPages/Designer/editors/EditorManager.js b/src/rootPages/Designer/editors/EditorManager.js index 659078f0..d6f74609 100644 --- a/src/rootPages/Designer/editors/EditorManager.js +++ b/src/rootPages/Designer/editors/EditorManager.js @@ -25,8 +25,7 @@ export default function (AB) { // require("./views/ABViewDataview"), // require("./views/ABViewDetail"), // require("./views/ABViewDocxBuilder"), - // require("./views/ABViewForm"), - require("./views/ABViewFormUrl"), + // require("./views/ABViewFormUrl"), // require("./views/ABViewGantt"), // require("./views/ABViewKanban"), // require("./views/ABViewGrid"), diff --git a/src/rootPages/Designer/properties/PropertyManager.js b/src/rootPages/Designer/properties/PropertyManager.js index 9b3556a1..27cf0588 100644 --- a/src/rootPages/Designer/properties/PropertyManager.js +++ b/src/rootPages/Designer/properties/PropertyManager.js @@ -91,18 +91,18 @@ export default function (AB) { require("./views/ABViewDetailTree"), // require("./views/ABViewDocxBuilder"), // require("./views/ABViewForm"), - require("./views/ABViewFormButton"), - require("./views/ABViewFormCheckbox"), - require("./views/ABViewFormConnect"), - require("./views/ABViewFormCustom"), - require("./views/ABViewFormDatepicker"), - require("./views/ABViewFormJson"), - require("./views/ABViewFormNumber"), - require("./views/ABViewFormSelectMultiple"), - require("./views/ABViewFormSelectSingle"), - require("./views/ABViewFormTextbox"), - require("./views/ABViewFormTree"), - require("./views/ABViewFormUrl"), + // require("./views/ABViewFormButton"), + // require("./views/ABViewFormCheckbox"), + // require("./views/ABViewFormConnect"), + // require("./views/ABViewFormCustom"), + // require("./views/ABViewFormDatepicker"), + // require("./views/ABViewFormJson"), + // require("./views/ABViewFormNumber"), + // require("./views/ABViewFormSelectMultiple"), + // require("./views/ABViewFormSelectSingle"), + // require("./views/ABViewFormTextbox"), + // require("./views/ABViewFormTree"), + // require("./views/ABViewFormUrl"), // require("./views/ABViewGantt"), // require("./views/ABViewGrid"), // require("./views/ABViewImage"), From dc9154662457b226f77b47d5d84b697d4e51e7ba Mon Sep 17 00:00:00 2001 From: BenWirachot Date: Wed, 17 Jun 2026 17:22:40 +0700 Subject: [PATCH 6/7] Standardize indentation and remove redundant whitespace across form property plugins --- src/plugins/web_view_form/FNAbviewform.js | 18 ++++----------- .../web_view_form/FNAbviewformEditor.js | 23 +++++++------------ .../editors/FNAbviewFormUrlEditor.js | 19 ++++++--------- .../properties/FNAbviewFormButton.js | 20 ++++++---------- .../properties/FNAbviewFormCheckbox.js | 18 ++++++--------- .../properties/FNAbviewFormConnect.js | 21 ++++++----------- .../properties/FNAbviewFormCustom.js | 18 ++++++--------- .../properties/FNAbviewFormDatepicker.js | 18 ++++++--------- .../properties/FNAbviewFormItem.js | 6 ----- .../properties/FNAbviewFormJson.js | 17 ++++++-------- .../properties/FNAbviewFormNumber.js | 17 ++++++-------- .../properties/FNAbviewFormSelectMultiple.js | 17 ++++++-------- .../properties/FNAbviewFormSelectSingle.js | 17 ++++++-------- .../properties/FNAbviewFormTextbox.js | 17 ++++++-------- .../properties/FNAbviewFormTree.js | 18 ++++++--------- .../properties/FNAbviewFormUrl.js | 18 +++++++-------- 16 files changed, 105 insertions(+), 177 deletions(-) diff --git a/src/plugins/web_view_form/FNAbviewform.js b/src/plugins/web_view_form/FNAbviewform.js index b79b04d9..1ba128a1 100644 --- a/src/plugins/web_view_form/FNAbviewform.js +++ b/src/plugins/web_view_form/FNAbviewform.js @@ -41,22 +41,16 @@ export default function FNAbviewformProperties({ `${base}_popupSubmitRule` ); - - -return class ABAbviewformProperties extends ABViewPropertiesPlugin { - -static getPluginKey() { + const ABAbviewformProperties = class ABAbviewformProperties extends ABViewPropertiesPlugin { + static getPluginKey() { return this.key; } -static getPluginType() { + static getPluginType() { return "properties-view"; // properties-view : will display in the properties panel of the ABDesigner } - - - constructor(b = null, id = null) { b = b || base; id = Object.assign(id || {}, { @@ -363,8 +357,7 @@ static getPluginType() { // update properties when a field component is deleted view.views().forEach((v) => { - if (v.isFormField) - v.once("destroyed", () => this.populate(view)); + if (v.isFormField) v.once("destroyed", () => this.populate(view)); }); SourceSelector.enable(); @@ -650,8 +643,7 @@ static getPluginType() { refreshDefaultButton() { const ids = this.ids; - const ABViewFormButton = - this.AB.ClassManager.viewClass("button"); + const ABViewFormButton = this.AB.ClassManager.viewClass("button"); // If default button is not exists, then skip this let defaultButton = this.views( diff --git a/src/plugins/web_view_form/FNAbviewformEditor.js b/src/plugins/web_view_form/FNAbviewformEditor.js index 1cc28b07..43e3a9cd 100644 --- a/src/plugins/web_view_form/FNAbviewformEditor.js +++ b/src/plugins/web_view_form/FNAbviewformEditor.js @@ -8,27 +8,23 @@ export default function FNAbviewformEditor({ AB, ABViewEditorPlugin }) { // var L = UIClass.L(); // var L = ABViewContainer.L(); - return class ABAbviewformEditor extends ABViewContainer { - + const ABAbviewformEditor = class ABAbviewformEditor extends ABViewContainer { static getPluginKey() { return this.key; } /** - * @method getPluginType - * return the plugin type for this editor. - * plugin types are how our ClassManager knows how to store - * the plugin. - * @return {string} plugin type - */ + * @method getPluginType + * return the plugin type for this editor. + * plugin types are how our ClassManager knows how to store + * the plugin. + * @return {string} plugin type + */ static getPluginType() { return "editor-view"; // editor-view : will display in the editor panel of the ABDesigner } - - - static get key() { return "form"; } @@ -61,8 +57,5 @@ export default function FNAbviewformEditor({ AB, ABViewEditorPlugin }) { } }; - return [ - ABAbviewformEditor, - FNAbviewFormUrlEditor({ ABViewEditorPlugin }) - ]; + return [ABAbviewformEditor, FNAbviewFormUrlEditor({ ABViewEditorPlugin })]; } diff --git a/src/plugins/web_view_form/editors/FNAbviewFormUrlEditor.js b/src/plugins/web_view_form/editors/FNAbviewFormUrlEditor.js index 8ace3b25..d719d12a 100644 --- a/src/plugins/web_view_form/editors/FNAbviewFormUrlEditor.js +++ b/src/plugins/web_view_form/editors/FNAbviewFormUrlEditor.js @@ -10,26 +10,21 @@ var myClass = null; // we will want to call this factory fn() repeatedly in our imports, // but we only want to define 1 Class reference. - - -export default function FNAbviewFormUrlEditor({ - ABViewEditorPlugin, -}) { +export default function FNAbviewFormUrlEditor({ ABViewEditorPlugin }) { const ABViewForm = FNAbviewformEditor({ ABViewEditorPlugin }); if (!myClass) { - // var L = UIClass.L(); // var L = ABViewContainer.L(); myClass = class ABViewFormEditor extends ABViewForm { - static getPluginKey() { - return this.key; - } + static getPluginKey() { + return this.key; + } - static getPluginType() { - return "editor-view"; - } + static getPluginType() { + return "editor-view"; + } static get key() { return "form-url"; } diff --git a/src/plugins/web_view_form/properties/FNAbviewFormButton.js b/src/plugins/web_view_form/properties/FNAbviewFormButton.js index ff47a515..087d34b9 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormButton.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormButton.js @@ -1,30 +1,24 @@ - - /* * ABViewButton * A Property manager for our ABViewButton definitions */ - - export default function FNAbviewFormButtonProperties({ AB, ABViewPropertiesPlugin, }) { - const BASE_ID = "properties_abview_button"; - const L = AB.Label(); class ABViewButtonProperty extends ABViewPropertiesPlugin { - static getPluginKey() { - return this.key; - } - - static getPluginType() { - return "properties-view"; - } + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } constructor() { super(BASE_ID, { // Put our ids here diff --git a/src/plugins/web_view_form/properties/FNAbviewFormCheckbox.js b/src/plugins/web_view_form/properties/FNAbviewFormCheckbox.js index 579cf1f7..1be1de29 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormCheckbox.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormCheckbox.js @@ -5,8 +5,6 @@ import FNAbviewformItem from "./FNAbviewformItem.js"; * A Property manager for our ABViewFormCheckbox definitions */ - - export default function FNAbviewFormCheckboxProperties({ AB, ABViewPropertiesPlugin, @@ -15,16 +13,14 @@ export default function FNAbviewFormCheckboxProperties({ const BASE_ID = "properties_abview_form_checkbox"; - - class ABViewFormCheckboxProperty extends ABViewFormItem { - static getPluginKey() { - return this.key; - } - - static getPluginType() { - return "properties-view"; - } + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } constructor() { super(BASE_ID, {}); diff --git a/src/plugins/web_view_form/properties/FNAbviewFormConnect.js b/src/plugins/web_view_form/properties/FNAbviewFormConnect.js index 8f47fa73..8ecb3f33 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormConnect.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormConnect.js @@ -8,11 +8,6 @@ import ABViewPropertyEditPage from "../../../rootPages/Designer/properties/views * A Property manager for our ABViewConnect definitions */ - - - - - export default function FNAbviewFormConnectProperties({ AB, ABViewPropertiesPlugin, @@ -21,7 +16,6 @@ export default function FNAbviewFormConnectProperties({ const BASE_ID = "properties_abview_connect"; - const ABAddPage = ABViewPropertyAddPage(AB, BASE_ID); const ABEditPage = ABViewPropertyEditPage(AB, BASE_ID); const L = AB.Label(); @@ -30,13 +24,13 @@ export default function FNAbviewFormConnectProperties({ let SortComponent = null; class ABViewConnectProperty extends ABViewFormItem { - static getPluginKey() { - return this.key; - } - - static getPluginType() { - return "properties-view"; - } + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } constructor() { super(BASE_ID, { // Put our ids here @@ -531,4 +525,3 @@ export default function FNAbviewFormConnectProperties({ return ABViewConnectProperty; } - diff --git a/src/plugins/web_view_form/properties/FNAbviewFormCustom.js b/src/plugins/web_view_form/properties/FNAbviewFormCustom.js index fc92fc86..487fc406 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormCustom.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormCustom.js @@ -5,8 +5,6 @@ import FNAbviewformItem from "./FNAbviewformItem.js"; * A Property manager for our ABViewFormCustom definitions */ - - export default function FNAbviewFormCustomProperties({ AB, ABViewPropertiesPlugin, @@ -15,16 +13,14 @@ export default function FNAbviewFormCustomProperties({ const BASE_ID = "properties_abview_form_custom"; - - class ABViewFormCustomProperty extends ABViewFormItem { - static getPluginKey() { - return this.key; - } - - static getPluginType() { - return "properties-view"; - } + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } constructor() { super(BASE_ID, {}); diff --git a/src/plugins/web_view_form/properties/FNAbviewFormDatepicker.js b/src/plugins/web_view_form/properties/FNAbviewFormDatepicker.js index 0dedaf42..be6b6b5e 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormDatepicker.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormDatepicker.js @@ -5,8 +5,6 @@ import FNAbviewformItem from "./FNAbviewformItem.js"; * A Property manager for our ABViewFormDatepicker definitions */ - - export default function FNAbviewFormDatepickerProperties({ AB, ABViewPropertiesPlugin, @@ -15,16 +13,14 @@ export default function FNAbviewFormDatepickerProperties({ const BASE_ID = "properties_abview_form_datepicker"; - - class ABViewFormDatepickerProperty extends ABViewFormItem { - static getPluginKey() { - return this.key; - } - - static getPluginType() { - return "properties-view"; - } + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } constructor() { super(BASE_ID, {}); diff --git a/src/plugins/web_view_form/properties/FNAbviewFormItem.js b/src/plugins/web_view_form/properties/FNAbviewFormItem.js index 2b4b7c27..f1388fbb 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormItem.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormItem.js @@ -1,18 +1,12 @@ - - /* * ABViewFormItem * A Property manager for our ABViewFormItem definitions */ - - export default function FNAbviewFormItemProperties({ AB, ABViewPropertiesPlugin, }) { - - const L = AB.Label(); const DEFAULT_VALUES = { required: 0, diff --git a/src/plugins/web_view_form/properties/FNAbviewFormJson.js b/src/plugins/web_view_form/properties/FNAbviewFormJson.js index accebcfd..728c6d2f 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormJson.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormJson.js @@ -5,8 +5,6 @@ import FNAbviewformItem from "./FNAbviewformItem.js"; * A Property manager for our ABViewFormJson definitions */ - - export default function FNAbviewFormJsonProperties({ AB, ABViewPropertiesPlugin, @@ -15,17 +13,16 @@ export default function FNAbviewFormJsonProperties({ const BASE_ID = "properties_abview_form_json"; - const L = AB.Label(); class ABViewFormJsonProperty extends ABViewFormItem { - static getPluginKey() { - return this.key; - } - - static getPluginType() { - return "properties-view"; - } + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } constructor() { super(BASE_ID, { // Put our ids here diff --git a/src/plugins/web_view_form/properties/FNAbviewFormNumber.js b/src/plugins/web_view_form/properties/FNAbviewFormNumber.js index dd8549be..6e6eb9d3 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormNumber.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormNumber.js @@ -5,8 +5,6 @@ import FNAbviewformItem from "./FNAbviewformItem.js"; * A Property manager for our ABViewFormNumber definitions */ - - export default function FNAbviewFormNumberProperties({ AB, ABViewPropertiesPlugin, @@ -15,17 +13,16 @@ export default function FNAbviewFormNumberProperties({ const BASE_ID = "properties_abview_form_number"; - const L = AB.Label(); class ABViewFormNumberProperty extends ABViewFormItem { - static getPluginKey() { - return this.key; - } - - static getPluginType() { - return "properties-view"; - } + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } constructor() { super(BASE_ID, { // Put our ids here diff --git a/src/plugins/web_view_form/properties/FNAbviewFormSelectMultiple.js b/src/plugins/web_view_form/properties/FNAbviewFormSelectMultiple.js index f9e0acc3..77b4bdae 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormSelectMultiple.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormSelectMultiple.js @@ -5,8 +5,6 @@ import FNAbviewformItem from "./FNAbviewformItem.js"; * A Property manager for our ABViewFormSelectMultiple definitions */ - - export default function FNAbviewFormSelectMultipleProperties({ AB, ABViewPropertiesPlugin, @@ -15,17 +13,16 @@ export default function FNAbviewFormSelectMultipleProperties({ const BASE_ID = "properties_abview_form_select_multiple"; - const L = AB.Label(); class ABViewFormSelectMultipleProperty extends ABViewFormItem { - static getPluginKey() { - return this.key; - } - - static getPluginType() { - return "properties-view"; - } + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } constructor() { super(BASE_ID, { // Put our ids here diff --git a/src/plugins/web_view_form/properties/FNAbviewFormSelectSingle.js b/src/plugins/web_view_form/properties/FNAbviewFormSelectSingle.js index 64b10cbb..6f600d50 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormSelectSingle.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormSelectSingle.js @@ -5,8 +5,6 @@ import FNAbviewformItem from "./FNAbviewformItem.js"; * A Property manager for our ABViewFormSelectSingle definitions */ - - export default function FNAbviewFormSelectSingleProperties({ AB, ABViewPropertiesPlugin, @@ -15,17 +13,16 @@ export default function FNAbviewFormSelectSingleProperties({ const BASE_ID = "properties_abview_form_select_single"; - const L = AB.Label(); class ABViewFormSelectSingleProperty extends ABViewFormItem { - static getPluginKey() { - return this.key; - } - - static getPluginType() { - return "properties-view"; - } + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } constructor() { super(BASE_ID, { // Put our ids here diff --git a/src/plugins/web_view_form/properties/FNAbviewFormTextbox.js b/src/plugins/web_view_form/properties/FNAbviewFormTextbox.js index 21bb5c38..3febd9ba 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormTextbox.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormTextbox.js @@ -5,8 +5,6 @@ import FNAbviewformItem from "./FNAbviewformItem.js"; * A Property manager for our ABViewFormTextbox definitions */ - - export default function FNAbviewFormTextboxProperties({ AB, ABViewPropertiesPlugin, @@ -15,17 +13,16 @@ export default function FNAbviewFormTextboxProperties({ const BASE_ID = "properties_abview_form_textbox"; - const L = AB.Label(); class ABViewFormTextboxProperty extends ABViewFormItem { - static getPluginKey() { - return this.key; - } - - static getPluginType() { - return "properties-view"; - } + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } constructor() { super(BASE_ID, { // Put our ids here diff --git a/src/plugins/web_view_form/properties/FNAbviewFormTree.js b/src/plugins/web_view_form/properties/FNAbviewFormTree.js index 2cce6c41..15a093ba 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormTree.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormTree.js @@ -5,8 +5,6 @@ import FNAbviewformItem from "./FNAbviewformItem.js"; * A Property manager for our ABViewFormTree definitions */ - - export default function FNAbviewFormTreeProperties({ AB, ABViewPropertiesPlugin, @@ -15,16 +13,14 @@ export default function FNAbviewFormTreeProperties({ const BASE_ID = "properties_abview_form_tree"; - - class ABViewFormTreeProperty extends ABViewFormItem { - static getPluginKey() { - return this.key; - } - - static getPluginType() { - return "properties-view"; - } + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } constructor() { super(BASE_ID, {}); diff --git a/src/plugins/web_view_form/properties/FNAbviewFormUrl.js b/src/plugins/web_view_form/properties/FNAbviewFormUrl.js index e45a42ca..a2666de0 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormUrl.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormUrl.js @@ -6,8 +6,6 @@ import FNAbviewformProperties from "../FNAbviewform.js"; * A Property manager for our ABViewForm definitions */ - - export default function FNAbviewFormUrlProperties({ AB, ABViewPropertiesPlugin, @@ -15,19 +13,19 @@ export default function FNAbviewFormUrlProperties({ const ABViewForm = FNAbviewformProperties({ AB, ABViewPropertiesPlugin }); const UIClassCommonKeyValue = FCommonKeyValue(AB); - const uiConfig = AB.Config.uiSettings(); + const uiConfig = AB.Config.uiSettings(); const L = AB.Label(); const base = "properties_abview_form_url"; class ABViewFormUrlProperty extends ABViewForm { - static getPluginKey() { - return this.key; - } - - static getPluginType() { - return "properties-view"; - } + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + } constructor() { super(base, { method: "", From 0625ef7afd61c503e4930421773f299b6b1c9d8e Mon Sep 17 00:00:00 2001 From: BenWirachot Date: Wed, 17 Jun 2026 17:31:02 +0700 Subject: [PATCH 7/7] Correct casing of FNAbviewFormItem import across form property plugins --- src/plugins/web_view_form/properties/FNAbviewFormCheckbox.js | 2 +- src/plugins/web_view_form/properties/FNAbviewFormConnect.js | 2 +- src/plugins/web_view_form/properties/FNAbviewFormCustom.js | 2 +- src/plugins/web_view_form/properties/FNAbviewFormDatepicker.js | 2 +- src/plugins/web_view_form/properties/FNAbviewFormJson.js | 2 +- src/plugins/web_view_form/properties/FNAbviewFormNumber.js | 2 +- .../web_view_form/properties/FNAbviewFormSelectMultiple.js | 2 +- .../web_view_form/properties/FNAbviewFormSelectSingle.js | 2 +- src/plugins/web_view_form/properties/FNAbviewFormTextbox.js | 2 +- src/plugins/web_view_form/properties/FNAbviewFormTree.js | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/plugins/web_view_form/properties/FNAbviewFormCheckbox.js b/src/plugins/web_view_form/properties/FNAbviewFormCheckbox.js index 1be1de29..0a07b5e7 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormCheckbox.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormCheckbox.js @@ -1,4 +1,4 @@ -import FNAbviewformItem from "./FNAbviewformItem.js"; +import FNAbviewformItem from "./FNAbviewFormItem.js"; /* * ABViewFormCheckbox diff --git a/src/plugins/web_view_form/properties/FNAbviewFormConnect.js b/src/plugins/web_view_form/properties/FNAbviewFormConnect.js index 8ecb3f33..d0c4b1d0 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormConnect.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormConnect.js @@ -1,4 +1,4 @@ -import FNAbviewformItem from "./FNAbviewformItem.js"; +import FNAbviewformItem from "./FNAbviewFormItem.js"; import ABPopupSort from "../../../rootPages/Designer/ui_work_object_workspace_popupSortFields"; import ABViewPropertyAddPage from "../../../rootPages/Designer/properties/views/viewProperties/ABViewPropertyAddPage"; import ABViewPropertyEditPage from "../../../rootPages/Designer/properties/views/viewProperties/ABViewPropertyEditPage"; diff --git a/src/plugins/web_view_form/properties/FNAbviewFormCustom.js b/src/plugins/web_view_form/properties/FNAbviewFormCustom.js index 487fc406..4e933fc0 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormCustom.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormCustom.js @@ -1,4 +1,4 @@ -import FNAbviewformItem from "./FNAbviewformItem.js"; +import FNAbviewformItem from "./FNAbviewFormItem.js"; /* * ABViewFormCustom diff --git a/src/plugins/web_view_form/properties/FNAbviewFormDatepicker.js b/src/plugins/web_view_form/properties/FNAbviewFormDatepicker.js index be6b6b5e..c3d666de 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormDatepicker.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormDatepicker.js @@ -1,4 +1,4 @@ -import FNAbviewformItem from "./FNAbviewformItem.js"; +import FNAbviewformItem from "./FNAbviewFormItem.js"; /* * ABViewFormDatepicker diff --git a/src/plugins/web_view_form/properties/FNAbviewFormJson.js b/src/plugins/web_view_form/properties/FNAbviewFormJson.js index 728c6d2f..a10ddb0c 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormJson.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormJson.js @@ -1,4 +1,4 @@ -import FNAbviewformItem from "./FNAbviewformItem.js"; +import FNAbviewformItem from "./FNAbviewFormItem.js"; /* * ABViewFormJson diff --git a/src/plugins/web_view_form/properties/FNAbviewFormNumber.js b/src/plugins/web_view_form/properties/FNAbviewFormNumber.js index 6e6eb9d3..da831146 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormNumber.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormNumber.js @@ -1,4 +1,4 @@ -import FNAbviewformItem from "./FNAbviewformItem.js"; +import FNAbviewformItem from "./FNAbviewFormItem.js"; /* * ABViewFormNumber diff --git a/src/plugins/web_view_form/properties/FNAbviewFormSelectMultiple.js b/src/plugins/web_view_form/properties/FNAbviewFormSelectMultiple.js index 77b4bdae..adc1e15d 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormSelectMultiple.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormSelectMultiple.js @@ -1,4 +1,4 @@ -import FNAbviewformItem from "./FNAbviewformItem.js"; +import FNAbviewformItem from "./FNAbviewFormItem.js"; /* * ABViewFormSelectMultiple diff --git a/src/plugins/web_view_form/properties/FNAbviewFormSelectSingle.js b/src/plugins/web_view_form/properties/FNAbviewFormSelectSingle.js index 6f600d50..bd3a7f00 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormSelectSingle.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormSelectSingle.js @@ -1,4 +1,4 @@ -import FNAbviewformItem from "./FNAbviewformItem.js"; +import FNAbviewformItem from "./FNAbviewFormItem.js"; /* * ABViewFormSelectSingle diff --git a/src/plugins/web_view_form/properties/FNAbviewFormTextbox.js b/src/plugins/web_view_form/properties/FNAbviewFormTextbox.js index 3febd9ba..5083da97 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormTextbox.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormTextbox.js @@ -1,4 +1,4 @@ -import FNAbviewformItem from "./FNAbviewformItem.js"; +import FNAbviewformItem from "./FNAbviewFormItem.js"; /* * ABViewFormTextbox diff --git a/src/plugins/web_view_form/properties/FNAbviewFormTree.js b/src/plugins/web_view_form/properties/FNAbviewFormTree.js index 15a093ba..3017e28c 100644 --- a/src/plugins/web_view_form/properties/FNAbviewFormTree.js +++ b/src/plugins/web_view_form/properties/FNAbviewFormTree.js @@ -1,4 +1,4 @@ -import FNAbviewformItem from "./FNAbviewformItem.js"; +import FNAbviewformItem from "./FNAbviewFormItem.js"; /* * ABViewFormTree