diff --git a/index.js b/index.js index b9ec7472..24f8fdb2 100644 --- a/index.js +++ b/index.js @@ -19,6 +19,7 @@ import definitions from "./src/definitions.js"; import ApplicationFactory from "./src/application.js"; import Labels from "./src/labels/labels.js"; +import LocalPlugins from "./src/plugins/index.js"; // pull in our css we defined for our plugin // eslint-disable-next-line no-unused-vars @@ -40,6 +41,9 @@ window.__AB_Plugins.push({ AB.scriptLoadAll(this.scripts()); AB.cssLoadAll(this.stylesheets()); + // load any included plugins + LocalPlugins.load(AB); + // At this point, the Plugin should already have loaded all it's definitions // into the AB Factory AB.pluginLoad(ApplicationFactory(AB)); diff --git a/src/plugins/index.js b/src/plugins/index.js new file mode 100644 index 00000000..a8b0b552 --- /dev/null +++ b/src/plugins/index.js @@ -0,0 +1,13 @@ +import viewListProperties from "./web_view_list/FNAbviewlist.js"; +import TabProperties from "./web_view_tab/FNAbviewtab.js"; +import TabEditor from "./web_view_tab/FNAbviewtabEditor.js"; + +const AllPlugins = [TabProperties, TabEditor, viewListProperties]; + +export default { + load: (AB) => { + AllPlugins.forEach((plugin) => { + AB.pluginRegister(plugin); + }); + }, +}; diff --git a/src/rootPages/Designer/properties/views/ABViewList.js b/src/plugins/web_view_list/FNAbviewlist.js similarity index 88% rename from src/rootPages/Designer/properties/views/ABViewList.js rename to src/plugins/web_view_list/FNAbviewlist.js index f031cbb8..aa2cf13f 100644 --- a/src/rootPages/Designer/properties/views/ABViewList.js +++ b/src/plugins/web_view_list/FNAbviewlist.js @@ -1,24 +1,33 @@ -/* - * ABViewList - * A Property manager for our ABViewList definitions - */ - -import FABView from "./ABView"; - -export default function (AB) { +// FNAbviewlist Properties +// A properties side import for an ABView. +// +export default function FNAbviewlistProperties({ + AB, + ABViewPropertiesPlugin, + // ABUIPlugin, +}) { const BASE_ID = "properties_abview_list"; - const ABView = FABView(AB); - const L = ABView.L(); const uiConfig = AB.UISettings.config(); + const L = AB.Label(); + + return class ABAbviewlistProperties extends ABViewPropertiesPlugin { + static getPluginKey() { + return this.key; + } + + static getPluginType() { + return "properties-view"; + // properties-view : will display in the properties panel of the ABDesigner + } - class ABViewListProperty extends ABView { constructor() { super(BASE_ID, { datacollection: "", field: "", height: "", }); + this.AB = AB; } static get key() { @@ -168,7 +177,5 @@ export default function (AB) { ViewClass() { return super._ViewClass("list"); } - } - - return ABViewListProperty; + }; } diff --git a/src/rootPages/Designer/properties/views/ABViewTab.js b/src/plugins/web_view_tab/FNAbviewtab.js similarity index 90% rename from src/rootPages/Designer/properties/views/ABViewTab.js rename to src/plugins/web_view_tab/FNAbviewtab.js index 6dd9bd2f..1f614b1e 100644 --- a/src/rootPages/Designer/properties/views/ABViewTab.js +++ b/src/plugins/web_view_tab/FNAbviewtab.js @@ -1,21 +1,30 @@ -/* - * ABViewTab - * A Property manager for our ABViewTab definitions - */ - -import FABView from "./ABView"; -import FTabPopup from "../../interface_common/ui_tab_form_popup"; - -export default function (AB) { +// FNAbviewtab Properties +// A properties side import for an ABView. +// +import FTabPopup from "../../rootPages/Designer/interface_common/ui_tab_form_popup"; + +export default function FNAbviewtabProperties({ + AB, + ABViewPropertiesPlugin, + // ABUIPlugin, +}) { const BASE_ID = "properties_abview_tab"; - const ABView = FABView(AB); const uiConfig = AB.Config.uiSettings(); - const L = ABView.L(); + const L = AB.Label(); const TabPopup = FTabPopup(AB); - class ABViewTabProperty extends ABView { + return class ABAbviewtabProperties 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_ID, { sidebarWidth: "", @@ -26,6 +35,7 @@ export default function (AB) { stackTabs: "", darkTheme: "", }); + this.AB = AB; } static get key() { @@ -209,7 +219,5 @@ export default function (AB) { ViewClass() { return super._ViewClass("tab"); } - } - - return ABViewTabProperty; + }; } diff --git a/src/plugins/web_view_tab/FNAbviewtabEditor.js b/src/plugins/web_view_tab/FNAbviewtabEditor.js new file mode 100644 index 00000000..47858f6a --- /dev/null +++ b/src/plugins/web_view_tab/FNAbviewtabEditor.js @@ -0,0 +1,357 @@ +// FNAbviewtab 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. +// + +import FTabPopup from "../../rootPages/Designer/interface_common/ui_tab_form_popup"; + +export default function FNAbviewtabEditor({ AB, ABViewEditorPlugin }) { + const BASE_ID = "interface_editor_viewtab"; + + const L = AB.Label(); + + const TabPopup = FTabPopup(AB); + + return class ABAbviewtabEditor extends ABViewEditorPlugin { + /** + * @method getPluginKey + * return the plugin key for this editor. + * @return {string} plugin key + */ + 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 "tab"; + } + + constructor(view, base = BASE_ID) { + // base: {string} unique base id reference + super(base, { + view: "", + }); + + this.AB = AB; + this.view = view; + this.component = this.view.component(); + } + + ui() { + const ids = this.ids; + const baseView = this.view; + const component = this.component; + const componentUI = this.component.ui()?.rows[0]; + + if (componentUI.rows) { + componentUI.rows[0].id = ids.component; + componentUI.rows[0].tabbar = { + height: 60, + type: "bottom", + css: baseView.settings.darkTheme ? "webix_dark" : "", + on: { + onItemClick: (id, e) => { + const tabID = $$(ids.component).getValue(); + const tab = baseView.views((view) => view.id === tabID)[0]; + const currIndex = baseView._views.findIndex( + (view) => view.id === tabID + ); + + // Rename + if (e.target.classList.contains("rename")) { + baseView.tabPopup.show(tab); + } + // Reorder back + else if (e.target.classList.contains("move-back")) { + baseView.viewReorder(tabID, currIndex - 1); + + // refresh editor view + baseView.emit("properties.updated", baseView); + } + // Reorder next + else if (e.target.classList.contains("move-next")) { + baseView.viewReorder(tabID, currIndex + 1); + + // refresh editor view + baseView.emit("properties.updated", baseView); + } + }, + }, + }; + + // Add action buttons + for ( + let i = 0; + i < (componentUI.rows[0]?.cells ?? []).length; + i++ + ) { + let _cell = componentUI.rows[0].cells[i]; + // Add 'move back' icon + _cell.header = `${componentUI.rows[0]?.cells[i].header}`; + + let currView = baseView.views((v) => v.id == _cell.body.id)[0]; + if (!currView || (currView.warningsAll() || []).length > 0) { + // Add warnings icon + _cell.header += this.WARNING_ICON; + } + + // Add 'edit' icon + _cell.header += + ' '; + + // Add 'move next' icon + _cell.header += + ' '; + } + } else if (componentUI.cols) { + // if we detect colums we are using sidebar and need to format the onItemClick event differently + let viewIndex = 1; + let tabIndex = 0; + + if (baseView.settings.sidebarPos === "right") { + // the sidebar is in the second column now so we need to reference it properly + viewIndex = 0; + tabIndex = 1; + } + + componentUI.cols[viewIndex].id = ids.component; + componentUI.cols[tabIndex].on = { + onItemClick: (id, e) => { + const tabID = id.replace("_menu", ""); + const tab = baseView.views((view) => view.id == tabID)[0]; + const currIndex = baseView._views.findIndex( + (view) => view.id === tabID + ); + + component.onShow(tabID); + + // Rename + if (e.target.classList.contains("rename")) + baseView.tabPopup.show(tab); + // Reorder back + else if (e.target.classList.contains("move-back")) { + baseView.viewReorder(tabID, currIndex - 1); + + // refresh editor view + baseView.emit("properties.updated", baseView); + } + // Reorder next + else if (e.target.classList.contains("move-next")) { + baseView.viewReorder(tabID, currIndex + 1); + + // refresh editor view + baseView.emit("properties.updated", baseView); + } + }, + }; + + // Add action buttons + for ( + let i = 0; + i < (componentUI.cols[tabIndex].data ?? []).length; + i++ + ) { + // Add 'edit' icon + componentUI.cols[tabIndex].data[i].value = + componentUI.cols[tabIndex].data[i].value + + ' '; + // Add 'move up' icon + componentUI.cols[tabIndex].data[i].value += + ''; + // Add 'move down' icon + componentUI.cols[tabIndex].data[i].value += + ' '; + } + } + + return { + _dashboardID: ids.component, + rows: [componentUI], + }; + } + + async init(AB) { + this.AB = AB; + + const ids = this.ids; + + await this.component.init(this.AB); + + const $component = $$(ids.component); + + if ($component) { + const tabID = $component.getValue(); + const tab = this.view.views((v) => v.id === tabID)[0]; + + let warnText = ""; + if (!tab || (tab.warningsAll() || []).length > 0) { + warnText = this.WARNING_ICON; + } + + // Add actions buttons - Edit , Delete + if ($component.config.view === "tabview") { + webix.ui({ + container: $component.getMultiview().$view, + view: "template", + autoheight: false, + height: 1, + width: 0, + template: [ + '