diff --git a/src/plugins/index.js b/src/plugins/index.js index 02b8afe..687dac3 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 0000000..9f21dc7 --- /dev/null +++ b/src/plugins/web_view_form/FNAbviewform.js @@ -0,0 +1,783 @@ +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.isFormField) + 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("form"); + } + + // + // + // + + busy() { + $$(this.ids.component)?.showProgress?.({ type: "icon" }); + } + + check(e, fieldId) { + if (this._isBusy) return; + this._isBusy = true; + this.busy(); + 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 = () => { + this._isBusy = false; + formView + .refreshDefaultButton(ids) + .save() + .then(() => { + // refresh UI + currView.emit("properties.updated", currView); + this.onChange(); + this.ready(); + }); + + // // trigger a save() + // this.propertyEditorSave(ids, currView); + }; + + // add a field to the form + if (item.selected) { + // 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)); + formView.viewInsert(fieldView).then(() => { + doneFn(); + }); + }); + } else { + this._isBusy = false; + this.ready(); + } + } + // 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(); + formView.viewRemove(fieldView).then(() => { + doneFn(); + }); + } else { + this._isBusy = false; + this.ready(); + } + } + } + + 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}