From f3e10d68d8c6cefa4b00606479462e565f4fd434 Mon Sep 17 00:00:00 2001 From: BenWirachot Date: Thu, 11 Jun 2026 12:55:02 +0700 Subject: [PATCH 1/2] Migrate docxBuilder view to plugin --- src/plugins/index.js | 4 + .../FNAbviewdocxbuilder.js | 428 ++++++++++++++++++ .../FNAbviewdocxbuilderEditor.js | 10 + .../Designer/editors/EditorManager.js | 2 +- .../Designer/properties/PropertyManager.js | 2 +- 5 files changed, 444 insertions(+), 2 deletions(-) create mode 100644 src/plugins/web_view_docxBuilder/FNAbviewdocxbuilder.js create mode 100644 src/plugins/web_view_docxBuilder/FNAbviewdocxbuilderEditor.js diff --git a/src/plugins/index.js b/src/plugins/index.js index a5631ca..3f295b6 100644 --- a/src/plugins/index.js +++ b/src/plugins/index.js @@ -1,3 +1,5 @@ +import viewDocxBuilderProperties from "./web_view_docxBuilder/FNAbviewdocxbuilder.js"; +import viewDocxBuilderEditor from "./web_view_docxBuilder/FNAbviewdocxbuilderEditor.js"; import CsvExporterEditor from "./web_view_csvExporter/FNAbviewcsvexporterEditor.js"; import CsvExporterProperties from "./web_view_csvExporter/FNAbviewcsvexporter.js"; import CsvImporterEditor from "./web_view_csvImporter/FNAbviewcsvimporterEditor.js"; @@ -70,6 +72,8 @@ const AllPlugins = [ viewTabProperties, viewTextEditor, viewTextProperties, + viewDocxBuilderProperties, + viewDocxBuilderEditor ]; export default { diff --git a/src/plugins/web_view_docxBuilder/FNAbviewdocxbuilder.js b/src/plugins/web_view_docxBuilder/FNAbviewdocxbuilder.js new file mode 100644 index 0000000..b05932e --- /dev/null +++ b/src/plugins/web_view_docxBuilder/FNAbviewdocxbuilder.js @@ -0,0 +1,428 @@ +// FNAbviewdocxbuilder Properties +// A properties side import for an ABView. +// +export default function FNAbviewdocxbuilderProperties({ + AB, + ABViewPropertiesPlugin, + // ABUIPlugin, +}) { + const uiConfig = AB.Config.uiSettings(); + const L = AB.Label(); + + let ABViewDocxBuilderPropertyComponentDefaults = {}; + + const base = "properties_abview_docxBuilder"; + + return class ABAbviewdocxbuilderProperties extends ABViewPropertiesPlugin { + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + // properties-view : will display in the properties panel of the ABDesigner + } + + constructor() { + super(base, { + // Put our ids here + buttonlabel: "", + buttonPosition: "", + datacollection: "", + docxFile: "", + docxDownload: "", + filelabel: "", + language: "", + toolbarBackground: "", + width: 0, + }); + + this.AB = AB; + ABViewDocxBuilderPropertyComponentDefaults = + this.AB.ClassManager.viewClass("docxBuilder").defaultValues(); + } + + static get key() { + return "docxBuilder"; + } + + ui() { + // const ids = this.ids; + + // Populate language options + const langOptions = this.AB.Multilingual.languages().map((lang) => { + return { + id: lang.language_code, + value: lang.language_label, + }; + }); + + // docxFile: "", + // docxDownload: "", + // toolbarBackground: "", + // width: 0, + + return super.ui([ + { + view: "fieldset", + label: L("Data:"), + labelWidth: uiConfig.labelWidthLarge, + body: { + type: "clean", + padding: 10, + rows: [ + { + id: this.ids.datacollection, + name: "datacollection", + view: "multiselect", + label: L("Data Source"), + labelWidth: uiConfig.labelWidthLarge, + on: { + onChange: () => { + if ($$(this.ids.datacollection).getValue()) { + $$(this.ids.docxFile).enable(); + } else { + $$(this.ids.docxFile).disable(); + } + + this.onChange(); + }, + }, + }, + ], + }, + }, + + { + view: "fieldset", + label: L("Template file:"), + labelWidth: uiConfig.labelWidthLarge, + body: { + type: "clean", + padding: 10, + rows: [ + { + cols: [ + { + view: "label", + label: L("DOCX file:"), + css: "ab-text-bold", + width: uiConfig.labelWidthXLarge, + }, + { + id: this.ids.docxFile, + view: "uploader", + value: L("Upload"), + name: "docxFile", + apiOnly: true, + inputName: "file", + multiple: false, + on: { + onBeforeFileAdd: (item) => { + return this.validateType(item); + }, + + onFileUpload: (file) => { + this.uploadedFile(file); + }, + + onFileUploadError: () => {}, + onViewShow: () => { + if ( + $$(this.ids.datacollection).getValue() + ) { + $$(this.ids.docxFile).enable(); + } else { + $$(this.ids.docxFile).disable(); + } + }, + }, + }, + ], + }, + { + id: this.ids.filelabel, + name: "filelabel", + view: "text", + label: L("Filename"), + labelWidth: uiConfig.labelWidthLarge, + on: { + onChange: () => { + this.onChange(); + }, + }, + }, + { + id: this.ids.docxDownload, + name: "docxDownload", + view: "button", + type: "icon", + css: "webix_primary", + icon: "fa fa-file-word-o", + label: L("Download Template File"), + click: () => { + this.downloadFile(); + }, + }, + ], + }, + }, + + { + view: "fieldset", + label: L("Language:"), + labelWidth: uiConfig.labelWidthLarge, + body: { + type: "clean", + padding: 10, + rows: [ + { + id: this.ids.language, + name: "language", + view: "richselect", + label: L("Language"), + labelWidth: uiConfig.labelWidthLarge, + options: langOptions, + on: { + onChange: () => { + this.onChange(); + }, + }, + }, + ], + }, + }, + + { + view: "fieldset", + label: L("Customize Display:"), + labelWidth: uiConfig.labelWidthLarge, + body: { + type: "clean", + padding: 10, + rows: [ + { + id: this.ids.buttonlabel, + name: "buttonlabel", + view: "text", + label: L("Label"), + labelWidth: uiConfig.labelWidthXLarge, + on: { + onChange: () => { + this.onChange(); + }, + }, + }, + + { + id: this.ids.width, + view: "counter", + name: "width", + label: L("Width:"), + labelWidth: uiConfig.labelWidthXLarge, + on: { + onChange: () => { + this.onChange(); + }, + }, + }, + { + id: this.ids.toolbarBackground, + view: "richselect", + name: "toolbarBackground", + label: L("Page background:"), + labelWidth: uiConfig.labelWidthXLarge, + options: [ + { + id: "ab-background-default", + value: L("White (default)"), + }, + { + id: "webix_dark", + value: L("Dark"), + }, + { + id: "ab-background-lightgray", + value: L("Gray"), + }, + ], + on: { + onChange: () => { + this.onChange(); + }, + }, + }, + + { + id: this.ids.buttonPosition, + view: "richselect", + name: "buttonPosition", + label: L("Button Position:"), + labelWidth: uiConfig.labelWidthXLarge, + options: [ + { + id: "left", + value: L("Left (default)"), + }, + { + id: "center", + value: L("Centered"), + }, + { + id: "right", + value: L("Right"), + }, + ], + on: { + onChange: () => { + this.onChange(); + }, + }, + }, + ], + }, + }, + ]); + } + + populate(view) { + super.populate(view); + if (!view) return; + + const ids = this.ids; + + const $DcSelector = $$(ids.datacollection); + + const selectedDvId = view.settings.dataviewID ?? null; + + $$(ids.toolbarBackground).setValue( + view.settings.toolbarBackground ?? + ABViewDocxBuilderPropertyComponentDefaults.toolbarBackground + ); + $$(ids.buttonPosition).setValue( + view.settings.buttonPosition ?? + ABViewDocxBuilderPropertyComponentDefaults.buttonPosition + ); + + // Pull data views to options + const dcOptions = view.application + .datacollectionsIncluded() + .map((dc) => { + return { + id: dc.id, + value: dc.label, + icon: + dc.sourceType === "query" + ? "fa fa-filter" + : "fa fa-database", + }; + }); + + $DcSelector.define("options", dcOptions); + $DcSelector.define("value", selectedDvId); + $DcSelector.refresh(); + + $$(ids.language).setValue( + view.settings.language ?? + ABViewDocxBuilderPropertyComponentDefaults.language + ); + + $$(ids.filelabel).setValue(view.filelabel ?? view.settings.filelabel); + $$(ids.buttonlabel).setValue( + view.buttonlabel ?? view.settings.buttonlabel + ); + $$(ids.width).setValue(view.settings.width); + + if (view.settings.filename) { + $$(ids.docxDownload).show(); + } else { + $$(ids.docxDownload).hide(); + } + } + + defaultValues() { + let values = {}; + const ViewClass = this.ViewClass(); + if (ViewClass) { + values = ViewClass.defaultValues(); + } + return values; + } + + /** + * @method values + * return the values for this form. + * @return {obj} + */ + values() { + const ids = this.ids; + let vals = super.values(); + + vals.settings = vals.settings ?? {}; + vals.settings.buttonlabel = $$(ids.buttonlabel).getValue(); + vals.settings.dataviewID = $$(ids.datacollection).getValue(); + vals.settings.width = $$(ids.width).getValue(); + vals.filelabel = $$(ids.filelabel).getValue(); + vals.settings.language = $$(ids.language).getValue(); + vals.settings.toolbarBackground = $$(ids.toolbarBackground).getValue(); + vals.settings.buttonPosition = $$(ids.buttonPosition).getValue(); + + return vals; + } + + /** + * @method ViewClass() + * A method to return the proper ABViewXXX Definition. + * NOTE: Must be overwritten by the Child Class + */ + ViewClass() { + return super._ViewClass("docxBuilder"); + } + + validateType(item) { + const ids = this.ids; + + // verify file type + const acceptableTypes = ["docx"]; + const type = item.type.toLowerCase(); + if (acceptableTypes.indexOf(type) == -1) { + this.AB.Webix.message( + L(`Only [${acceptableTypes.join(", ")}] files are supported`) + ); + return false; + } else { + // set upload url to uploader + const currView = this.CurrentView; + const uploadUrl = currView.uploadUrl(); + + $$(ids.docxFile).define("upload", uploadUrl); + $$(ids.docxFile).refresh(); + + return true; + } + } + + uploadedFile(fileInfo) { + if (!fileInfo || !fileInfo.data) return; + + const ids = this.ids; + let currView = this.CurrentView; + currView.settings.filename = fileInfo.data.uuid; + currView.filelabel = fileInfo.name; + + $$(ids.filelabel).setValue(currView.filelabel); + $$(ids.docxDownload).show(); + } + + downloadFile() { + const currView = this.CurrentView; + const url = currView.downloadUrl(); + + fetch(url) + .then((response) => response.blob()) + .then((blob) => { + currView.letUserDownload(blob, currView.filelabel); + }); + } + }; +} diff --git a/src/plugins/web_view_docxBuilder/FNAbviewdocxbuilderEditor.js b/src/plugins/web_view_docxBuilder/FNAbviewdocxbuilderEditor.js new file mode 100644 index 0000000..eff0f30 --- /dev/null +++ b/src/plugins/web_view_docxBuilder/FNAbviewdocxbuilderEditor.js @@ -0,0 +1,10 @@ +// FNAbviewdocxbuilder Editor +// An Editor wrapper for the ABView Component. +// The Editor is displayed in the ABDesigner as a view is worked on. +// The Editor allows a widget to be moved and placed on the canvas. +// +export default function FNAbviewdocxbuilderEditor({ ABViewEditorPlugin }) { + return class ABAbviewdocxbuilderEditor extends ABViewEditorPlugin { + // Insert Here // + }; +} diff --git a/src/rootPages/Designer/editors/EditorManager.js b/src/rootPages/Designer/editors/EditorManager.js index 759e2ee..5d02be7 100644 --- a/src/rootPages/Designer/editors/EditorManager.js +++ b/src/rootPages/Designer/editors/EditorManager.js @@ -24,7 +24,7 @@ export default function (AB) { // require("./views/ABViewDataSelect"), // require("./views/ABViewDataview"), // require("./views/ABViewDetail"), - require("./views/ABViewDocxBuilder"), + // require("./views/ABViewDocxBuilder"), require("./views/ABViewForm"), require("./views/ABViewFormUrl"), // require("./views/ABViewGantt"), diff --git a/src/rootPages/Designer/properties/PropertyManager.js b/src/rootPages/Designer/properties/PropertyManager.js index 046d891..27505aa 100644 --- a/src/rootPages/Designer/properties/PropertyManager.js +++ b/src/rootPages/Designer/properties/PropertyManager.js @@ -89,7 +89,7 @@ export default function (AB) { require("./views/ABViewDetailItem"), require("./views/ABViewDetailText"), require("./views/ABViewDetailTree"), - require("./views/ABViewDocxBuilder"), + // require("./views/ABViewDocxBuilder"), require("./views/ABViewForm"), require("./views/ABViewFormButton"), require("./views/ABViewFormCheckbox"), From 582741ddcbfc206b43c558595301de25a30debc5 Mon Sep 17 00:00:00 2001 From: BenWirachot Date: Tue, 16 Jun 2026 16:08:36 +0700 Subject: [PATCH 2/2] Plugin lifecycle methods and key definitions in FNAbviewdocxbuilderEditor --- .../FNAbviewdocxbuilderEditor.js | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/plugins/web_view_docxBuilder/FNAbviewdocxbuilderEditor.js b/src/plugins/web_view_docxBuilder/FNAbviewdocxbuilderEditor.js index eff0f30..4e267da 100644 --- a/src/plugins/web_view_docxBuilder/FNAbviewdocxbuilderEditor.js +++ b/src/plugins/web_view_docxBuilder/FNAbviewdocxbuilderEditor.js @@ -5,6 +5,37 @@ // export default function FNAbviewdocxbuilderEditor({ ABViewEditorPlugin }) { return class ABAbviewdocxbuilderEditor extends ABViewEditorPlugin { - // Insert Here // + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "editor-view"; + } + + static get key() { + return "docxBuilder"; + } + + constructor(view, base = "interface_editor_docxBuilder") { + super(view, base); + } + + ui() { + return super.ui(); + } + + async init(AB) { + this.AB = AB; + await super.init(AB); + } + + detatch() { + super.detatch(); + } + + onShow() { + super.onShow(); + } }; }