diff --git a/index.js b/index.js index 6ea0bcf..b9ec747 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,27 @@ +/** + * @fileoverview This file registers the ABDesigner plugin with the global `__AB_Plugins` array. + * The plugin includes definitions, labels, scripts, and stylesheets required for the ABDesigner functionality. + * + * @module ABDesigner + */ + +/** + * @typedef {Object} Plugin + * @property {string} version - The version of the plugin. + * @property {string} key - The unique key identifier for the plugin. + * @property {function} apply - Function to apply the plugin to the AB instance. + * @property {function} definitions - Function to return the plugin definitions. + * @property {function} labels - Function to return the labels for the specified language. + * @property {function} scripts - Function to return the array of script URLs required by the plugin. + * @property {function} stylesheets - Function to return the array of stylesheet URLs required by the plugin. + */ + import definitions from "./src/definitions.js"; import ApplicationFactory from "./src/application.js"; import Labels from "./src/labels/labels.js"; +// pull in our css we defined for our plugin +// eslint-disable-next-line no-unused-vars import designerCSS from "./styles/Designer.css"; window.__AB_Plugins = window.__AB_Plugins || []; @@ -9,7 +29,17 @@ window.__AB_Plugins = window.__AB_Plugins || []; window.__AB_Plugins.push({ version: "0.0.0", key: "ABDesigner", + + /** + * @function apply + * @description Applies the ABDesigner plugin to the AB instance. + * @param {Object} AB - The AB instance. + */ apply: function (AB) { + // load any custom js or css + AB.scriptLoadAll(this.scripts()); + AB.cssLoadAll(this.stylesheets()); + // At this point, the Plugin should already have loaded all it's definitions // into the AB Factory AB.pluginLoad(ApplicationFactory(AB)); @@ -22,10 +52,49 @@ window.__AB_Plugins.push({ // } // AB.pluginLabelLoad("ABDesigner", labels); }, + + /** + * @function definitions + * @description Returns the definitions required by the ABDesigner plugin. + * @returns {Object} The definitions object. + */ definitions: function () { return definitions; }, + + /** + * @function labels + * @description Returns the labels for the specified language. + * @param {string} lang - The language code. + * @returns {Object} The labels object for the specified language. + */ labels: function (lang) { return Labels[lang] || Labels.en; }, + + /** + * @function scripts + * @description Returns the array of script URLs required by the ABDesigner plugin. + * these are required by any 3rd party libraries or other scripts that the plugin needs to run. + * @returns {string[]} The array of script URLs. + */ + scripts: function () { + return [ + // "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/codemirror.min.js", + // "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/mode/javascript/javascript.min.js", + ]; + }, + + /** + * @function stylesheets + * @description Returns the array of stylesheet URLs required by the ABDesigner plugin. + * these are required by any 3rd party libraries or other stylesheets that the plugin needs to run. + * @returns {string[]} The array of stylesheet URLs. + */ + stylesheets: function () { + return [ + // "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/codemirror.min.css", + // "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/theme/material.min.css", + ]; + }, }); diff --git a/package.json b/package.json index 42fbe20..fea5776 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,9 @@ "webpack-merge": "^5.8.0" }, "dependencies": { + "@codemirror/lang-javascript": "^6.2.3", "bpmn-js": "^9.0.3", + "codemirror": "^6.0.1", "path": "^0.12.7", "semver": "^7.7.1" } diff --git a/src/rootPages/Designer/properties/PropertyManager.js b/src/rootPages/Designer/properties/PropertyManager.js index 2ecaf3e..54b11fc 100644 --- a/src/rootPages/Designer/properties/PropertyManager.js +++ b/src/rootPages/Designer/properties/PropertyManager.js @@ -131,6 +131,7 @@ export default function (AB) { // All the ABMobileViewXXX Property Interfaces Available. [ require("./mobile/ABMobilePage"), + require("./mobile/ABMobileViewCustom"), require("./mobile/ABMobileViewForm"), require("./mobile/ABMobileViewFormButton"), require("./mobile/ABMobileViewFormCheckbox"), diff --git a/src/rootPages/Designer/properties/mobile/ABMobileViewCustom.js b/src/rootPages/Designer/properties/mobile/ABMobileViewCustom.js new file mode 100644 index 0000000..c504fc8 --- /dev/null +++ b/src/rootPages/Designer/properties/mobile/ABMobileViewCustom.js @@ -0,0 +1,381 @@ +/* + * ABViewCustom + * A Property manager for our ABViewCustom definitions + */ + +import FABMobileView from "./ABMobileView"; +import { EditorState } from "@codemirror/state"; +import { basicSetup } from "codemirror"; +import { EditorView } from "@codemirror/view"; +import { javascript } from "@codemirror/lang-javascript"; + +export default function (AB) { + const BASE_ID = "properties_abmobileview_custom"; + + const ABMobileView = FABMobileView(AB); + // const L = ABMobileView.L(); + const uiConfig = AB.UISettings.config(); + + class ABViewCustomProperty extends ABMobileView { + constructor() { + super(BASE_ID, { + dataCollectionList: "", + dataCollectionForm: "", + dataCollection: "", + initCodeTemplate: "", + initCode: "", + htmlCodeTemplate: "", + htmlCode: "", + }); + } + + static get key() { + return "mobile-custom"; + } + + ui() { + const ids = this.ids; + + return super.ui([ + { + view: "tabview", + cells: [ + { + header: "DataCollections", + body: { + rows: [ + { + view: "list", + id: ids.dataCollectionList, + template: + "#name# - #dataCollection# ", + autoheight: true, + onClick: { + "wxi-trash": (e, id) => { + this.removeDataCollection(id); + return false; + }, + }, + }, + { + view: "form", + id: ids.dataCollectionForm, + elements: [ + { + cols: [ + { + view: "text", + name: "name", + label: "Name", + labelWidth: uiConfig.labelWidthSmall, + labelPosition: "top", + }, + { + id: ids.dataCollection, + view: "richselect", + name: "id", + label: "Data Collection", + labelWidth: uiConfig.labelWidthLarge, + labelPosition: "top", + options: [], + }, + { + view: "button", + value: "Add", + click: () => { + this.addDataCollection(); + }, + }, + ], + }, + ], + }, + ], + }, + }, + { + header: "init", + body: { + id: ids.initCodeTemplate, + view: "form", + elements: [ + { + view: "template", + labelWidth: uiConfig.labelWidthLarge, + // height: 200, + template: "
", + }, + ], + }, + }, + { + header: "html", + body: { + id: ids.htmlCodeTemplate, + view: "form", + elements: [ + { + view: "template", + labelWidth: uiConfig.labelWidthLarge, + // height: 200, + template: "", + }, + ], + }, + }, + ], + multiview: { + keepViews: true, + }, + tabbar: { + on: { + onAfterTabClick: (id) => { + if ( + id === ids.initCodeTemplate || + id === ids.htmlCodeTemplate + ) { + this.initTab(id); + } + this.onChange(); + }, + }, + }, + }, + ]); + } + + /** + * Initializes the editor views for the specified tab. + * + * @param {string} tab - The identifier of the tab to initialize. + * + * Initializes the CodeMirror editor for the `initCodeTemplate` tab if it hasn't been initialized yet. + * The editor is configured with JavaScript syntax highlighting and a basic setup. + * + * Initializes the CodeMirror editor for the `htmlCodeTemplate` tab if it hasn't been initialized yet. + * The editor is configured with JavaScript syntax highlighting and a basic setup. + * + * The editors are set up with initial content based on the current view's settings or default template code. + * + * @property {Object} ids - The identifiers for the different tabs and elements. + * @property {Object} CurrentView - The current view settings. + * @property {Object} initView - The CodeMirror editor instance for the init code. + * @property {Object} htmlView - The CodeMirror editor instance for the HTML code. + * @property {Function} onChange - The function to call when the editor content changes. + */ + initTab(tab) { + const ids = this.ids; + + if (tab == ids.initCodeTemplate && !this.initView) { + this.initView = new EditorView({ + state: EditorState.create({ + doc: + this.CurrentView.settings?.initCode ?? + `// init code here\n// the following variables are available:\n// $AB: the ABFactory\n// $DC[