diff --git a/src/rootPages/Designer/editors/EditorManager.js b/src/rootPages/Designer/editors/EditorManager.js
index 9b6c1f57..fa036320 100644
--- a/src/rootPages/Designer/editors/EditorManager.js
+++ b/src/rootPages/Designer/editors/EditorManager.js
@@ -6,7 +6,7 @@
*/
import _ABViewDefault from "./views/_ABViewDefault";
-export default function(AB) {
+export default function (AB) {
const Editors = [];
// {array}
// All the ABField Component Inerfaces available.
@@ -28,6 +28,7 @@ export default function(AB) {
require("./views/ABViewDetail"),
require("./views/ABViewDocxBuilder"),
require("./views/ABViewForm"),
+ require("./views/ABViewFormUrl"),
require("./views/ABViewGantt"),
require("./views/ABViewGrid"),
require("./views/ABViewKanban"),
@@ -50,6 +51,13 @@ export default function(AB) {
if (p.editor) Editors.push(p.editor(AB, _ABViewDefault));
});
+ // Load editors from ClassManager
+ if (AB.ClassManager && AB.ClassManager.viewEditorAll) {
+ AB.ClassManager.viewEditorAll()?.forEach((EditorClass) => {
+ Editors.push(EditorClass);
+ });
+ }
+
return {
/*
* @function editors
@@ -58,7 +66,7 @@ export default function(AB) {
* A filter for limiting which editor you want.
* @return [{ClassUI(Editor1)}, {ClassUI(Editor2)}, ...]
*/
- editors: function(f = () => true) {
+ editors: function (f = () => true) {
return Editors.filter(f);
},
};
diff --git a/src/rootPages/Designer/editors/views/ABViewContainer.js b/src/rootPages/Designer/editors/views/ABViewContainer.js
index 5d7a9e54..15c53710 100644
--- a/src/rootPages/Designer/editors/views/ABViewContainer.js
+++ b/src/rootPages/Designer/editors/views/ABViewContainer.js
@@ -66,6 +66,7 @@ export default function (AB) {
let Defaults =
AB.Class.ABViewManager.viewClass(key).defaultValues();
return {
+ _dashboardID: this.ids.component,
rows: [
{
id: this.ids.component,
@@ -93,7 +94,7 @@ export default function (AB) {
// NOTE: need to sorting before .addView because there is a render position bug in webix 5.1.7
// https://webix.com/snippet/404cf0c7
- var childViews = this.CurrentView.viewsSortByPosition();
+ var childViews = this.CurrentView?.viewsSortByPosition() || [];
// attach all the .UI views:
childViews.forEach((child) => {
@@ -225,7 +226,7 @@ export default function (AB) {
var allViewUpdates = [];
// save view position state to views
- this.CurrentView.views().forEach((v) => {
+ (this.CurrentView?.views() || []).forEach((v) => {
var state = viewState.filter((vs) => vs.name == v.id)[0];
if (state) {
v.position.x = state.x;
@@ -244,13 +245,17 @@ export default function (AB) {
// this.saveReorder()
await Promise.all(allViewUpdates);
- await this.CurrentView.save();
+ if (this.CurrentView) {
+ await this.CurrentView.save();
+ }
this.ready();
} catch (err) {
this.AB.notify.developer(err, {
message: "Error trying to save selected View:",
- view: this.CurrentView.toObj(),
+ view: this.CurrentView?.toObj() || {
+ currentView: "not found",
+ },
});
this.ready();
}
@@ -258,17 +263,19 @@ export default function (AB) {
onShow() {
let hasTextComponent = false;
- this.CurrentView.views().forEach((v) => {
- if (v.key === "text") hasTextComponent = true;
- var component = this.subComponents[v.id];
- component?.onShow?.();
- });
- if (hasTextComponent) this.initTinyMCE();
+ if (this.CurrentView) {
+ this.CurrentView.views().forEach((v) => {
+ if (v.key === "text") hasTextComponent = true;
+ var component = this.subComponents[v.id];
+ component?.onShow?.();
+ });
+ if (hasTextComponent) this.initTinyMCE();
- let dc = this.CurrentView.datacollection;
- if (dc && dc.dataStatus == dc.dataStatusFlag.notInitial) {
- // load data when a widget is showing
- dc.loadData();
+ let dc = this.CurrentView.datacollection;
+ if (dc && dc.dataStatus == dc.dataStatusFlag.notInitial) {
+ // load data when a widget is showing
+ dc.loadData();
+ }
}
}
@@ -344,7 +351,8 @@ export default function (AB) {
* @param {obj} trg Webix provided object
*/
viewDelete(e, id /*, trg */) {
- var deletedView = this.CurrentView.views((v) => v.id == id)[0];
+ var deletedView =
+ this.CurrentView?.views((v) => v.id == id)[0] || null;
if (!deletedView) return false;
webix.confirm({
@@ -383,11 +391,13 @@ export default function (AB) {
let Dashboard = $$(this.ids.component);
// Update UI
- var deletedElem = Dashboard.queryView({ name: id });
- if (deletedElem) {
- Dashboard.blockEvent();
- Dashboard.removeView(deletedElem);
- Dashboard.unblockEvent();
+ if (Dashboard) {
+ var deletedElem = Dashboard.queryView({ name: id });
+ if (deletedElem) {
+ Dashboard.blockEvent();
+ Dashboard.removeView(deletedElem);
+ Dashboard.unblockEvent();
+ }
}
this.showEmptyPlaceholder();
@@ -412,7 +422,7 @@ export default function (AB) {
* @param {obj} trg Webix provided object
*/
viewEdit(e, id /*, trg */) {
- var view = this.CurrentView.views((v) => v.id == id)[0];
+ var view = this.CurrentView?.views((v) => v.id == id)[0] || null;
if (!view) return false;
diff --git a/src/rootPages/Designer/editors/views/ABViewFormUrl.js b/src/rootPages/Designer/editors/views/ABViewFormUrl.js
new file mode 100644
index 00000000..89934f04
--- /dev/null
+++ b/src/rootPages/Designer/editors/views/ABViewFormUrl.js
@@ -0,0 +1,54 @@
+/**
+ * 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.
+
+import FABViewForm from "./ABViewForm";
+
+export default function (AB) {
+ if (!myClass) {
+ const ABViewForm = FABViewForm(AB);
+ // var L = UIClass.L();
+ // var L = ABViewContainer.L();
+
+ myClass = class ABViewFormEditor extends ABViewForm {
+ 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/rootPages/Designer/editors/views/ABViewPivot.js b/src/rootPages/Designer/editors/views/ABViewPivot.js
index 6cf87dea..b99668e3 100644
--- a/src/rootPages/Designer/editors/views/ABViewPivot.js
+++ b/src/rootPages/Designer/editors/views/ABViewPivot.js
@@ -36,7 +36,9 @@ export default function (AB) {
pivot.readonly = false;
- return pivot;
+ // NOTE: ui_work_interface_workspace_editor_layout is expecting a { rows:[] }
+ // type of response from this.
+ return pivotContainer;
}
init(AB) {
@@ -44,7 +46,7 @@ export default function (AB) {
this.component?.init?.();
- const pivotId = this.ui().id;
+ const pivotId = this.ui().rows[0].id;
const $pivot = $$(pivotId);
$pivot.getState().$observe("structure", (structure) => {
this._saveStructure(structure);
diff --git a/src/rootPages/Designer/editors/views/ABViewTab.js b/src/rootPages/Designer/editors/views/ABViewTab.js
index b7c94b36..29eb0df5 100644
--- a/src/rootPages/Designer/editors/views/ABViewTab.js
+++ b/src/rootPages/Designer/editors/views/ABViewTab.js
@@ -168,6 +168,7 @@ export default function (AB) {
}
return {
+ _dashboardID: ids.component,
rows: [componentUI],
};
}
diff --git a/src/rootPages/Designer/editors/views/ABViewText.js b/src/rootPages/Designer/editors/views/ABViewText.js
index b56ddea9..eff61510 100644
--- a/src/rootPages/Designer/editors/views/ABViewText.js
+++ b/src/rootPages/Designer/editors/views/ABViewText.js
@@ -35,6 +35,7 @@ export default function (AB) {
const baseView = this.view;
return {
+ _dashboardID: ids.component,
rows: [
{
id: ids.component,
diff --git a/src/rootPages/Designer/properties/PropertyManager.js b/src/rootPages/Designer/properties/PropertyManager.js
index f59651b7..3e4c86d4 100644
--- a/src/rootPages/Designer/properties/PropertyManager.js
+++ b/src/rootPages/Designer/properties/PropertyManager.js
@@ -104,6 +104,7 @@ export default function (AB) {
require("./views/ABViewFormSelectSingle"),
require("./views/ABViewFormTextbox"),
require("./views/ABViewFormTree"),
+ require("./views/ABViewFormUrl"),
require("./views/ABViewGantt"),
require("./views/ABViewGrid"),
require("./views/ABViewImage"),
@@ -127,6 +128,15 @@ export default function (AB) {
if (p.viewProperty) Views.push(p.viewProperty(AB, ABView));
});
+ // Include view properties from ClassManager
+ const Plugins = [];
+ if (AB.ClassManager && AB.ClassManager.viewPropertiesAll) {
+ const classManagerViewProperties = AB.ClassManager.viewPropertiesAll();
+ classManagerViewProperties.forEach((ViewPropertyClass) => {
+ Plugins.push(ViewPropertyClass);
+ });
+ }
+
var MobileViews = [];
// {array}
// All the ABMobileViewXXX Property Interfaces Available.
@@ -168,11 +178,11 @@ export default function (AB) {
},
processElements: function (f = () => true) {
- return Processes.filter(f);
+ return Plugins.concat(Processes).filter(f);
},
views: function (v = () => true) {
- return Views.filter(v);
+ return Plugins.concat(Views).filter(v);
},
mobileViews: function (v = () => true) {
diff --git a/src/rootPages/Designer/properties/dataFields/ABField.js b/src/rootPages/Designer/properties/dataFields/ABField.js
index fc3368c0..513ef12f 100644
--- a/src/rootPages/Designer/properties/dataFields/ABField.js
+++ b/src/rootPages/Designer/properties/dataFields/ABField.js
@@ -75,6 +75,7 @@ export default function (AB) {
{
cols: [
{
+ id: `${this.base}_name`,
view: "label",
label: L("Field Name:"),
align: "left",
diff --git a/src/rootPages/Designer/properties/dataFields/ABFieldList.js b/src/rootPages/Designer/properties/dataFields/ABFieldList.js
index 42abc47b..b657bbcb 100644
--- a/src/rootPages/Designer/properties/dataFields/ABFieldList.js
+++ b/src/rootPages/Designer/properties/dataFields/ABFieldList.js
@@ -272,7 +272,10 @@ export default function (AB) {
}
clear() {
+ // NOTE: don't call super.clear() here
+
const ids = this.ids;
+ $$(ids.label).setValue("");
$$(ids.isMultiple).setValue(0);
$$(ids.hasColors).setValue(0);
$$(ids.options).clearAll();
diff --git a/src/rootPages/Designer/properties/views/ABViewForm.js b/src/rootPages/Designer/properties/views/ABViewForm.js
index 494acd2f..989d8702 100644
--- a/src/rootPages/Designer/properties/views/ABViewForm.js
+++ b/src/rootPages/Designer/properties/views/ABViewForm.js
@@ -27,8 +27,9 @@ export default function (AB) {
);
class ABViewFormProperty extends ABViewContainer {
- constructor() {
- super(base, {
+ constructor(b = null, id = null) {
+ b = b || base;
+ id = Object.assign(id || {}, {
// Put our ids here
datacollection: "",
fields: "",
@@ -42,6 +43,7 @@ export default function (AB) {
buttonSubmitRules: "",
buttonRecordRules: "",
});
+ super(b, id);
this.AB = AB;
ABViewFormPropertyComponentDefaults =
@@ -52,220 +54,224 @@ export default function (AB) {
return "form";
}
- ui() {
+ ui(elements = null) {
let ids = this.ids;
- 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);
+ 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 (
- ""
- );
+
+ {
+ 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);
},
- },
- onClick: {
- check: (...params) => {
- return this.check(...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: () => {
+ },
+ {
+ id: ids.showLabel,
+ name: "showLabel",
+ view: "checkbox",
+ label: L("Display Label"),
+ labelWidth: uiConfig.labelWidthLarge,
+ click: () => {
this.onChange();
},
},
- },
- {
- id: ids.labelWidth,
- view: "counter",
- name: "labelWidth",
-
- label: L("Label Width"),
- labelWidth: uiConfig.labelWidthLarge,
- on: {
- onChange: () => {
- 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.height,
- view: "counter",
- name: "height",
- label: L("Height"),
- labelWidth: uiConfig.labelWidthLarge,
- on: {
- onChange: () => {
- this.onChange();
+ {
+ id: ids.labelWidth,
+ view: "counter",
+ name: "labelWidth",
+
+ label: L("Label Width"),
+ 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.height,
+ view: "counter",
+ name: "height",
+ label: L("Height"),
+ 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();
+ {
+ id: ids.clearOnLoad,
+ view: "checkbox",
+ name: "clearOnLoad",
+
+ label: L("Clear on load"),
+ 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();
- },
- },
- ],
+ {
+ id: ids.clearOnSave,
+ view: "checkbox",
+ name: "clearOnSave",
+ label: L("Clear on save"),
+ labelWidth: uiConfig.labelWidthLarge,
+ on: {
+ onChange: () => {
+ this.onChange();
},
- // {
- // 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();
+ },
+ },
+ {
+ 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) {
diff --git a/src/rootPages/Designer/properties/views/ABViewFormJson.js b/src/rootPages/Designer/properties/views/ABViewFormJson.js
index c2a43ad0..8a7485c2 100644
--- a/src/rootPages/Designer/properties/views/ABViewFormJson.js
+++ b/src/rootPages/Designer/properties/views/ABViewFormJson.js
@@ -71,7 +71,7 @@ export default function (AB) {
placeholder: L("Select a field to filter by"),
// options: look at populate
on: {
- onChange: (newValue) => {
+ onChange: (/* newValue */) => {
this.onChange();
},
},
diff --git a/src/rootPages/Designer/properties/views/ABViewFormUrl.js b/src/rootPages/Designer/properties/views/ABViewFormUrl.js
new file mode 100644
index 00000000..07ba1ac7
--- /dev/null
+++ b/src/rootPages/Designer/properties/views/ABViewFormUrl.js
@@ -0,0 +1,154 @@
+/*
+ * ABViewForm
+ * A Property manager for our ABViewForm definitions
+ */
+import FCommonKeyValue from "../../ui_common_key_value";
+import FABViewForm from "./ABViewForm";
+
+export default function (AB) {
+ const UIClassCommonKeyValue = FCommonKeyValue(AB);
+ const ABViewForm = FABViewForm(AB);
+ const uiConfig = AB.Config.uiSettings();
+ const L = ABViewForm.L();
+
+ const base = "properties_abview_form_url";
+
+ class ABViewFormUrlProperty extends ABViewForm {
+ 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/ui_common_key_value.js b/src/rootPages/Designer/ui_common_key_value.js
new file mode 100644
index 00000000..562ef750
--- /dev/null
+++ b/src/rootPages/Designer/ui_common_key_value.js
@@ -0,0 +1,176 @@
+/*
+ * ui_common_key_value
+ *
+ * A common UI element for entering key/value pairs.
+ *
+ */
+import UI_Class from "./ui_class";
+
+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 (AB) {
+ if (!myClass) {
+ const UIClass = UI_Class(AB);
+ var L = UIClass.L();
+
+ myClass = class ABCommonKeyValue extends UIClass {
+ constructor({ title, keyTitle, valueTitle, contextID = null }) {
+ var idBase = "abd_common_key_value";
+ if (contextID) {
+ idBase += `_${contextID}`;
+ }
+ super(idBase, {
+ kvlist: "",
+ });
+
+ this.title = title || L("Key/Value Pairs");
+ this.keyTitle = keyTitle || L("Key");
+ this.valueTitle = valueTitle || L("Value");
+ }
+
+ ui() {
+ return {
+ id: this.ids.component,
+ view: "layout",
+ padding: 10,
+ rows: [
+ {
+ padding: 0,
+ cols: [
+ {
+ label: this.title,
+ view: "label",
+ padding: 0,
+ height: 0,
+ },
+ {
+ icon: "wxi-plus",
+ view: "icon",
+ padding: 0,
+ width: 38,
+ click: () => {
+ this._addHeaderItem($$(this.ids.kvlist));
+ },
+ },
+ ],
+ },
+ {
+ view: "scrollview",
+ scroll: "y",
+ borderless: true,
+ padding: 0,
+ margin: 0,
+ body: {
+ id: this.ids.kvlist,
+ view: "layout",
+ padding: 0,
+ margin: 0,
+ rows: [],
+ },
+ },
+ ],
+ };
+ }
+
+ async init(/*AB, options */) {
+ // options = options || {};
+ }
+
+ _addHeaderItem($container) {
+ const uiItem = this._headerItem($container);
+ $container.addView(uiItem);
+ }
+
+ _headerItem($container, key, value) {
+ return {
+ cols: [
+ {
+ placeholder: this.keyTitle,
+ view: "text",
+ value: key,
+ },
+ {
+ placeholder: this.valueTitle,
+ view: "text",
+ suggest: this._getSecretValues().map(
+ (secret) => `SECRET:${secret.name}`
+ ),
+ value: value,
+ },
+ {
+ icon: "wxi-trash",
+ view: "icon",
+ width: 38,
+ click: function () {
+ const $item = this.getParentView();
+ $container.removeView($item);
+ },
+ },
+ ],
+ };
+ }
+
+ show() {
+ $$(this.ids.component)?.show();
+ }
+
+ hide() {
+ $$(this.ids.component)?.hide();
+ }
+
+ populate(values) {
+ this.formClear();
+
+ if (!values || !Array.isArray(values)) {
+ return;
+ }
+
+ const $kvlist = $$(this.ids.kvlist);
+ values.forEach((item) => {
+ if (item.key && item.value) {
+ const uiItem = this._headerItem(
+ $kvlist,
+ item.key,
+ item.value
+ );
+ $kvlist.addView(uiItem);
+ }
+ });
+ }
+
+ formClear() {
+ const $kvlist = $$(this.ids.kvlist);
+ this.AB.Webix.ui([], $kvlist);
+ }
+
+ getValues() {
+ const values = [];
+
+ // Request's headers
+ const $kvlist = $$(this.ids.kvlist);
+ values.headers = values.headers ?? [];
+ $kvlist?.getChildViews().forEach((item) => {
+ let children = item.getChildViews();
+ const $key = children[0];
+ const $value = children[1];
+ const key = $key.getValue();
+ const value = $value.getValue();
+
+ if (key != null && value != null)
+ values.push({
+ key,
+ value,
+ });
+ });
+
+ return values;
+ }
+ };
+ }
+
+ // NOTE: return JUST the class definition.
+ return myClass;
+}
diff --git a/src/rootPages/Designer/ui_work_interface_workspace_editor_components.js b/src/rootPages/Designer/ui_work_interface_workspace_editor_components.js
index 5da058e8..757255e9 100644
--- a/src/rootPages/Designer/ui_work_interface_workspace_editor_components.js
+++ b/src/rootPages/Designer/ui_work_interface_workspace_editor_components.js
@@ -91,8 +91,8 @@ export default function (AB) {
},
on: {
onItemClick: function (id /*, e, node */) {
- var component = this.getItem(id);
- _this.addWidget(component);
+ var item = this.getItem(id);
+ _this.addWidget(item.component || item);
},
},
},
@@ -160,6 +160,8 @@ export default function (AB) {
* compile the template for each item in the list.
*/
template(obj /* , common */) {
+ return `
${obj.label}
`;
+ /*
// if this is one of our ABViews:
if (obj.common) {
// see if a .label field is present
@@ -177,6 +179,7 @@ export default function (AB) {
// maybe this is simply the "No Components" placeholder
return obj.label;
}
+ */
}
/*
@@ -194,6 +197,16 @@ export default function (AB) {
var components = this.CurrentView.componentList();
+ components = components.map((c) => {
+ let label = c.name;
+ let icon = "cubes";
+ if (c.common) {
+ label = c.common().label || L(c.common().labelKey);
+ icon = c.common().icon || "cubes";
+ }
+ // preserve the original component so its methods (e.g., .newInstance()) remain available
+ return { label, icon, component: c };
+ });
List.clearAll();
if (components && components.length > 0) {
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 50ba9fa1..94586edc 100644
--- a/src/rootPages/Designer/ui_work_interface_workspace_editor_layout.js
+++ b/src/rootPages/Designer/ui_work_interface_workspace_editor_layout.js
@@ -132,11 +132,17 @@ export default function (AB) {
let ids = this.ids;
// clear edit area
- $$(ids.editArea)
- .getChildViews()
- .forEach((childView) => {
- $$(ids.editArea)?.removeView(childView);
- });
+ $$(ids.editArea).define("rows", []);
+ $$(ids.editArea).define("cols", []);
+ $$(ids.editArea).reconstruct();
+ // let removeViews = $$(ids.editArea).getChildViews();
+ // while (removeViews.length > 0) {
+ // let childView = removeViews.shift();
+ // $$(ids.editArea)?.removeView(childView);
+ // }
+ // // removeViews.forEach((childView) => {
+ // // $$(ids.editArea)?.removeView(childView);
+ // // });
// load the component's editor in our editArea
var editorComponent;
@@ -261,20 +267,28 @@ export default function (AB) {
editorUI.id = `${ids.editArea}_dashboard_layout`;
// clear out widgets in our dashboard area
- var subWidgets = editorUI.rows ?? editorUI.cols;
- if (!subWidgets || subWidgets.length === 0) {
- if (editorUI.body) {
- subWidgets = editorUI.body.rows ?? editorUI.body.cols;
- }
+
+ let idDashboard = editorUI._dashboardID;
+ if (!idDashboard) {
+ var subWidgets = editorUI.rows ?? editorUI.cols;
if (!subWidgets || subWidgets.length === 0) {
- console.error("Tell Johnny: No sub widgets found in editor UI");
- console.error(editorUI);
- return;
+ if (editorUI.body) {
+ subWidgets = editorUI.body.rows ?? editorUI.body.cols;
+ }
+ if (!subWidgets || subWidgets.length === 0) {
+ console.error(
+ "Tell Johnny: No sub widgets found in editor UI"
+ );
+ console.error(editorUI);
+ return;
+ }
}
+ idDashboard = subWidgets[0].id;
+ }
+ if (idDashboard) {
+ const $dashboard = $$(idDashboard);
+ if ($dashboard) $dashboard.clearAll();
}
- const idDashboard = subWidgets[0].id;
- const $dashboard = $$(idDashboard);
- if ($dashboard) $dashboard.clearAll();
// add the editorUI if it is not already added
if ($$(ids.editArea).queryView({ id: editorUI.id }) == null)
diff --git a/src/rootPages/Designer/ui_work_object_list_newObject.js b/src/rootPages/Designer/ui_work_object_list_newObject.js
index 94b870fa..279960b4 100644
--- a/src/rootPages/Designer/ui_work_object_list_newObject.js
+++ b/src/rootPages/Designer/ui_work_object_list_newObject.js
@@ -22,7 +22,6 @@ import UIBlankObject from "./ui_work_object_list_newObject_blank";
import UICsvObject from "./ui_work_object_list_newObject_csv";
import UIApiObject from "./ui_work_object_list_newObject_api";
import UIImportObject from "./ui_work_object_list_newObject_import";
-import UINetsuiteObject from "./ui_work_object_list_newObject_netsuite";
// const ABImportExternal = require("./ab_work_object_list_newObject_external");
export default function (AB) {
const UIClass = UI_Class(AB);
@@ -43,7 +42,16 @@ export default function (AB) {
this.CsvTab = UICsvObject(AB);
this.ApiTab = UIApiObject(AB);
this.ImportTab = UIImportObject(AB);
- this.NetsuiteTab = UINetsuiteObject(AB);
+
+ // Find any Plugin Properties for Objects:
+ this._plugins = {};
+ this.AB.ClassManager.allObjectProperties().forEach((plugin) => {
+ this._plugins[plugin.getPluginKey()] = new plugin(
+ null,
+ {},
+ this.AB
+ );
+ });
/*
this.ExternalTab = new ABImportExternal(AB);
*/
@@ -51,7 +59,7 @@ export default function (AB) {
ui() {
// Our webix UI definition:
- return {
+ let myUI = {
view: "window",
id: this.ids.component,
// width: 400,
@@ -92,7 +100,6 @@ export default function (AB) {
this.CsvTab.ui(),
this.ApiTab.ui(),
this.ImportTab.ui(),
- this.NetsuiteTab.ui(),
],
tabbar: {
on: {
@@ -117,6 +124,16 @@ export default function (AB) {
},
},
};
+
+ // load any Plugin Properties for Objects:
+ Object.keys(this._plugins).forEach((key) => {
+ var plugin = this._plugins[key];
+ if (plugin.ui) {
+ myUI.body.cells.push(plugin.ui());
+ }
+ });
+
+ return myUI;
}
async init(AB) {
@@ -133,7 +150,6 @@ export default function (AB) {
"CsvTab",
"ApiTab",
"ImportTab",
- "NetsuiteTab",
/*, "ExternalTab"*/
].forEach((k) => {
allInits.push(this[k].init(AB));
@@ -145,6 +161,18 @@ export default function (AB) {
});
});
+ // load any Plugin Properties for Objects:
+ Object.keys(this._plugins).forEach((key) => {
+ var plugin = this._plugins[key];
+ allInits.push(plugin.init(AB));
+ plugin.on("cancel", () => {
+ this.emit("cancel");
+ });
+ plugin.on("save", (values) => {
+ this.save(values, key);
+ });
+ });
+
// ImportTab doesn't save, but "imported"
this.ImportTab.on("imported", (obj) => {
this.done(obj);
@@ -166,7 +194,11 @@ export default function (AB) {
this.CsvTab.applicationLoad(application);
this.ApiTab.applicationLoad(application);
this.ImportTab.applicationLoad(application);
- this.NetsuiteTab.applicationLoad(application);
+
+ Object.keys(this._plugins).forEach((key) => {
+ let plugin = this._plugins[key];
+ plugin.applicationLoad(application);
+ });
}
/**
@@ -203,6 +235,20 @@ export default function (AB) {
this.emit("save", obj, this.selectNew);
}
+ getTab(tabKey) {
+ if (this[tabKey]) {
+ return this[tabKey];
+ }
+ if (this._plugins[tabKey]) {
+ return this._plugins[tabKey];
+ }
+ webix.message({
+ type: "error",
+ text: L("Tab not found: {0}", tabKey),
+ });
+ return null;
+ }
+
/**
* @method save
* take the data gathered by our child creation tabs, and
@@ -213,13 +259,22 @@ export default function (AB) {
* @return {Promise}
*/
async save(values, tabKey) {
+ let tab = this.getTab(tabKey);
+ if (!tab) {
+ webix.message({
+ type: "error",
+ text: L("Tab not found: {0}", tabKey),
+ });
+ return false;
+ }
+
// must have an application set.
if (!this.CurrentApplicationID) {
webix.alert({
title: L("Shoot!"),
test: L("No Application Set! Why?"),
});
- this[tabKey].emit("save.error", true);
+ tab.emit("save.error", true);
return false;
}
@@ -229,7 +284,7 @@ export default function (AB) {
// have newObject validate it's values.
var validator = newObject.isValid();
if (validator.fail()) {
- this[tabKey].emit("save.error", validator);
+ tab.emit("save.error", validator);
// cb(validator); // tell current Tab component the errors
return false; // stop here.
}
@@ -247,7 +302,7 @@ export default function (AB) {
try {
var obj = await newObject.save();
await application.objectInsert(obj);
- this[tabKey].emit("save.successful", obj);
+ tab.emit("save.successful", obj);
this.done(obj);
} catch (err) {
// hide progress
@@ -259,7 +314,7 @@ export default function (AB) {
await application.objectRemove(newObject);
// tell current Tab component there was an error
- this[tabKey].emit("save.error", err);
+ tab.emit("save.error", err);
}
}
@@ -291,8 +346,14 @@ export default function (AB) {
case this.ExternalTab?.ids.form:
this.ExternalTab?.onShow?.(this.CurrentApplicationID);
break;
- case this.NetsuiteTab?.ids.form:
- this.NetsuiteTab?.onShow?.(this.CurrentApplicationID);
+
+ default:
+ Object.keys(this._plugins).forEach((key) => {
+ let plugin = this._plugins[key];
+ if (plugin.ids.form == tabId) {
+ plugin.onShow?.(this.CurrentApplicationID);
+ }
+ });
break;
}
}
diff --git a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js
deleted file mode 100644
index 32018fb8..00000000
--- a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * ui_work_object_list_newObject_netsuite
- *
- * Display the form for creating a new ABObject that connects to a Netsuite
- * instance.
- */
-import UI_Class from "./ui_class";
-import UI_Credentials from "./ui_work_object_list_newObject_netsuite_credentials";
-import UI_Tables from "./ui_work_object_list_newObject_netsuite_tables";
-import UI_Fields from "./ui_work_object_list_newObject_netsuite_fields";
-import UI_Connections from "./ui_work_object_list_newObject_netsuite_connections";
-import UI_FieldTest from "./ui_work_object_list_newObject_netsuite_dataTest";
-
-export default function (AB) {
- const UIClass = UI_Class(AB);
- const L = UIClass.L();
-
- class UI_Work_Object_List_NewObject_Netsuite extends UIClass {
- constructor() {
- super("ui_work_object_list_newObject_netsuite", {
- // component: base,
-
- form: "",
- buttonSave: "",
- buttonCancel: "",
- });
-
- this.UI_Credentials = UI_Credentials(AB);
- this.UI_Tables = UI_Tables(AB);
- this.UI_Fields = UI_Fields(AB);
- this.UI_FieldTest = UI_FieldTest(AB);
- this.UI_Connections = UI_Connections(AB);
- }
-
- ui() {
- // Our webix UI definition:
- return {
- id: this.ids.component,
- header: L("Netsuite"),
- body: {
- view: "form",
- id: this.ids.form,
- width: 820,
- height: 650,
- rules: {
- // TODO:
- // name: inputValidator.rules.validateObjectName
- },
- elements: [
- {
- rows: [
- {
- view: "text",
- label: L("Name"),
- name: "name",
- required: true,
- placeholder: L("Object name"),
- labelWidth: 70,
- },
- {
- view: "checkbox",
- label: L("Read Only"),
- name: "readonly",
- value: 0,
- // disabled: true,
- },
- ],
- },
- {
- view: "tabview",
- cells: [
- this.UI_Credentials.ui(),
- this.UI_Tables.ui(),
- this.UI_Fields.ui(),
- this.UI_Connections.ui(),
- this.UI_FieldTest.ui(),
- ],
- },
- { fillspace: true },
- {
- cols: [
- { fillspace: true },
- {
- view: "button",
- id: this.ids.buttonCancel,
- value: L("Cancel"),
- css: "ab-cancel-button",
- autowidth: true,
- click: () => {
- this.cancel();
- },
- },
- {
- view: "button",
- id: this.ids.buttonSave,
- css: "webix_primary",
- value: L("Save"),
- autowidth: true,
- type: "form",
- click: () => {
- return this.save();
- },
- disabled: true,
- },
- ],
- },
- ],
- },
- };
- }
-
- async init(AB) {
- this.AB = AB;
-
- this.$form = $$(this.ids.form);
- AB.Webix.extend(this.$form, webix.ProgressBar);
-
- this.UI_Credentials.init(AB);
- this.UI_Tables.init(AB);
- this.UI_Fields.init(AB);
- this.UI_Connections.init(AB);
- this.UI_FieldTest.init(AB);
-
- this.UI_Credentials.show();
- this.UI_Tables.disable();
- this.UI_Fields.disable();
- this.UI_Connections.disable();
- this.UI_FieldTest.disable();
-
- // "verified" is triggered on the credentials tab once we verify
- // the entered data is successful.
- this.UI_Credentials.on("verified", () => {
- this.UI_Tables.enable();
- let creds = this.UI_Credentials.credentials();
- this.UI_Tables.setCredentials(creds);
- this.UI_Fields.setCredentials(creds);
- this.UI_FieldTest.setCredentials(creds);
- this.UI_Connections.setCredentials(creds);
- this.UI_Tables.show();
- });
-
- this.UI_Credentials.on("notverified", () => {
- this.UI_Tables.disable();
- });
-
- this.UI_Tables.on("tables", (tables) => {
- this.UI_Connections.setAllTables(tables);
- });
-
- this.UI_Tables.on("table.selected", (table) => {
- this.UI_Fields.enable();
- this.UI_Fields.loadFields(table);
- this.UI_Fields.show();
-
- this.UI_Connections.setTable(table);
- this.UI_FieldTest.setTable(table);
- });
-
- this.UI_Fields.on("connections", (list) => {
- this.UI_Connections.loadConnections(list);
- this.UI_Connections.enable();
- });
-
- this.UI_Fields.on("fields.ready", (config) => {
- this.UI_FieldTest.enable();
- this.UI_FieldTest.loadConfig(config);
- });
-
- this.UI_FieldTest.on("data.verfied", () => {
- $$(this.ids.buttonSave).enable();
- });
-
- // "save.error" is triggered by the ui_work_object_list_newObject
- // if there was an error saving the values from our form.
- this.on("save.error", (err) => {
- this.onError(err);
- });
-
- // "save.successful" is triggered by the ui_work_object_list_newObject
- // if the values we provided were successfully saved.
- this.on("save.successful", async (obj) => {
- this.onSuccess();
-
- // try {
- // await obj.fetchData();
-
- // webix.message({
- // type: "success",
- // text: L("Successfully fetching data."),
- // });
- // } catch (err) {
- // webix.message({
- // type: "error",
- // text: L("Error fetching data."),
- // });
- // this.AB.notify.developer(err, {
- // context: "ABObjectAPI.fetchData()",
- // object: obj.toObj(),
- // });
- // }
- });
-
- // init() routines are always considered async so:
- return Promise.resolve();
- }
-
- cancel() {
- this.formClear();
- this.emit("cancel");
- }
-
- formClear() {
- this.$form.clearValidation();
- this.$form.clear();
-
- this.UI_Credentials.formClear();
- this.UI_Tables.formClear();
- this.UI_Fields.formClear();
- this.UI_Connections.formClear();
- this.UI_FieldTest.formClear();
-
- $$(this.ids.buttonSave).disable();
- }
-
- /**
- * @method onError()
- * Our Error handler when the data we provided our parent
- * ui_work_object_list_newObject object had an error saving
- * the values.
- * @param {Error|ABValidation|other} err
- * The error information returned. This can be several
- * different types of objects:
- * - A javascript Error() object
- * - An ABValidation object returned from our .isValid()
- * method
- * - An error response from our API call.
- */
- onError(err) {
- if (err) {
- console.error(err);
- let message = L("the entered data is invalid");
- // if this was our Validation() object:
- if (err.updateForm) {
- err.updateForm(this.$form);
- } else {
- if (err.code && err.data) {
- message = err.data?.sqlMessage ?? message;
- } else {
- message = err?.message ?? message;
- }
- }
-
- const values = this.$form.getValues();
- webix.alert({
- title: L("Error creating Object: {0}", [values.name]),
- ok: L("fix it"),
- text: message,
- type: "alert-error",
- });
- }
- // get notified if there was an error saving.
- $$(this.ids.buttonSave).enable();
- }
-
- /**
- * @method onSuccess()
- * Our success handler when the data we provided our parent
- * ui_work_object_list_newObject successfully saved the values.
- */
- onSuccess() {
- this.formClear();
- $$(this.ids.buttonSave).enable();
- }
-
- /**
- * @function save
- *
- * verify the current info is ok, package it, and return it to be
- * added to the application.createModel() method.
- */
- async save() {
- this.busy();
-
- const Form = this.$form;
-
- Form.clearValidation();
-
- // if it doesn't pass the basic form validation, return:
- if (!Form.validate()) {
- this.ready();
- return false;
- }
-
- let values = Form.getValues();
-
- values.credentials = this.UI_Credentials.getValues();
- values.tableName = this.UI_Tables.getValues();
-
- let allFields = this.UI_Fields.getValues();
-
- // Pick out our special columns: pk, created_at, updated_at
- let pkField = allFields.find((f) => f.pk);
- if (!pkField) {
- webix.alert({
- title: L("Error creating Object: {0}", [values.name]),
- ok: L("fix it"),
- text: L("No primary key specified."),
- type: "alert-error",
- });
- return;
- }
- values.primaryColumnName = pkField.column;
-
- values.columnRef = { created_at: null, updated_at: null };
-
- ["created_at", "updated_at"].forEach((field) => {
- let foundField = allFields.find((f) => f[field]);
- if (foundField) {
- values.columnRef[field] = foundField.column;
- }
- });
-
- // Create a new Object
- const object = AB.objectNew(
- Object.assign({ isNetsuite: true }, values)
- );
-
- try {
- // Add fields
-
- for (const f of allFields) {
- let def = {
- name: f.title,
- label: f.title,
- columnName: f.column,
- key: f.abType,
- };
- if (f.default) {
- def.settings = {};
- def.settings.default = f.default;
- }
- const field = AB.fieldNew(def, object);
- await field.save(true);
-
- // values.fieldIDs.push(field.id);
- }
- // values.id = object.id;
- } catch (err) {
- console.error(err);
- }
-
- let allConnectFields = this.UI_Connections.getValues();
- for (var i = 0; i < allConnectFields.length; i++) {
- let f = allConnectFields[i];
- /* f =
- {
- "thisField": "_this_object_",
- "thatObject": "b7c7cca2-b919-4a90-b199-650a7a4693c1",
- "thatObjectField": "custrecord_whq_teams_strategy_strtgy_cod",
- "linkType": "many:one"
- }
- */
-
- let linkObject = this.AB.objectByID(f.thatObject);
- if (!linkObject) continue;
-
- let linkType = f.linkType;
- let parts = linkType.split(":");
- let link = parts[0];
- let linkVia = parts[1];
-
- let thisField = {
- key: "connectObject",
- // columnName: f.thisField,
- label: linkObject.label,
- settings: {
- showIcon: "1",
-
- linkObject: linkObject.id,
- linkType: link,
- linkViaType: linkVia,
- isCustomFK: 0,
- indexField: "",
- indexField2: "",
- isSource: 0,
- width: 100,
- },
- };
-
- let linkField = this.AB.cloneDeep(thisField);
- // linkField.columnName = f.thatObjectField;
- linkField.label = object.label || object.name;
- linkField.settings.linkObject = object.id;
- linkField.settings.linkType = linkVia;
- linkField.settings.linkViaType = link;
-
- switch (linkType) {
- case "one:one":
- if (f.whichSource == "_this_") {
- thisField.settings.isSource = 1;
- } else {
- linkField.settings.isSource = 1;
- }
- thisField.columnName = f.sourceField;
- linkField.columnName = f.sourceField;
- break;
-
- case "one:many":
- case "many:one":
- thisField.columnName = f.thatField;
- linkField.columnName = f.thatField;
- break;
-
- case "many:many":
- thisField.settings.joinTable = f.joinTable;
- linkField.settings.joinTable = f.joinTable;
-
- thisField.settings.joinTableReference = f.thisObjReference;
- linkField.settings.joinTableReference = f.thatObjReference;
-
- thisField.settings.joinTablePK = f.joinTablePK;
- linkField.settings.joinTablePK = f.joinTablePK;
-
- thisField.settings.joinTableEntity = f.joinTableEntity;
- linkField.settings.joinTableEntity = f.joinTableEntity;
-
- if (f.joinActiveField != "_none_") {
- thisField.settings.joinActiveField = f.joinActiveField;
- thisField.settings.joinActiveValue = f.joinActiveValue;
- thisField.settings.joinInActiveValue = f.joinInActiveValue;
-
- linkField.settings.joinActiveField = f.joinActiveField;
- linkField.settings.joinActiveValue = f.joinActiveValue;
- linkField.settings.joinInActiveValue = f.joinInActiveValue;
- }
- break;
- }
-
- // create an initial LinkColumn
- let fieldLink = linkObject.fieldNew(linkField);
- await fieldLink.save(true); // should get an .id now
-
- // make sure I can reference field => linkColumn
- thisField.settings.linkColumn = fieldLink.id;
- let field = object.fieldNew(thisField);
- await field.save();
-
- // now update reference linkColumn => field
- fieldLink.settings.linkColumn = field.id;
- await fieldLink.save();
- }
-
- this.emit("save", object.toObj());
-
- this.ready();
- }
-
- /**
- * @function show()
- *
- * Show this component.
- */
- show() {
- $$(this.ids.component)?.show();
- }
-
- busy() {
- const $form = $$(this.ids.form);
- const $saveButton = $$(this.ids.buttonSave);
-
- $form.showProgress({ type: "icon" });
- $saveButton.disable();
- }
-
- ready() {
- const $form = $$(this.ids.form);
- const $saveButton = $$(this.ids.buttonSave);
-
- $form.hideProgress();
- $saveButton.enable();
- }
- }
- return new UI_Work_Object_List_NewObject_Netsuite();
-}
diff --git a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_connections.js b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_connections.js
deleted file mode 100644
index bdae1a56..00000000
--- a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_connections.js
+++ /dev/null
@@ -1,907 +0,0 @@
-/*
- * ui_work_object_list_newObject_netsuite_connections
- *
- * Display the tab/form for selecting which of the available conections we
- * want to create for this table.
- */
-import UI_Class from "./ui_class";
-
-export default function (AB) {
- const UIClass = UI_Class(AB);
- const L = UIClass.L();
- const uiConfig = AB.Config.uiSettings();
-
- class UI_Work_Object_List_NewObject_Netsuite_Connections extends UIClass {
- constructor() {
- super("ui_work_object_list_newObject_netsuite_connections", {
- // component: base,
-
- form: "",
-
- // fieldSelector: "",
- connections: "",
- displayConnections: "",
- displayNoConnections: "",
-
- fieldGrid: "",
- buttonVerify: "",
- buttonLookup: "",
- tableName: "",
- });
-
- this.allTables = [];
- // [ { id, name }, ... ]
- // A list of all the available tables. This is used for identifying the
- // join tables in many:many connections.
- // We get this list from the Tables interface tab.
-
- this.credentials = {};
- // { CRED_KEY : CRED_VAL }
- // The entered credential references necessary to perform our Netsuite
- // operations.
-
- this.connectionList = null;
- // {array}
- // Holds an array of connection descriptions
-
- this.connections = null;
- // {array}
- // Holds the array of chosen/verified connections
- }
-
- ui() {
- // Our webix UI definition:
- return {
- id: this.ids.component,
- header: L("Connections"),
- body: {
- view: "form",
- id: this.ids.form,
- width: 800,
- height: 450,
- rules: {
- // TODO:
- // name: inputValidator.rules.validateObjectName
- },
- elements: [
- {
- view: "layout",
- padding: 10,
- rows: [
- {
- id: this.ids.tableName,
- label: L("Selected Table: {0}", [this.table]),
- view: "label",
- height: 40,
- },
- ],
- },
-
- // Field Selector
- {
- view: "multiview",
- animate: false,
- borderless: true,
- rows: [
- {
- id: this.ids.displayNoConnections,
- rows: [
- {
- maxHeight: uiConfig.xxxLargeSpacer,
- hidden: uiConfig.hideMobile,
- },
- {
- view: "label",
- align: "center",
- height: 200,
- label: "",
- },
- {
- // id: ids.error_msg,
- view: "label",
- align: "center",
- label: L(
- "You have no other Netwuite Objects imported"
- ),
- },
- {
- // id: ids.error_msg,
- view: "label",
- align: "center",
- label: L(
- "Continue creating this object now, then create the connections on the other objects you import."
- ),
- },
- {
- maxHeight: uiConfig.xxxLargeSpacer,
- hidden: uiConfig.hideMobile,
- },
- ],
- },
- {
- id: this.ids.displayConnections,
- rows: [
- {
- // id: ids.tabFields,
- view: "layout",
- padding: 10,
- rows: [
- {
- cols: [
- {
- label: L("Connections"),
- view: "label",
- },
- {
- icon: "wxi-plus",
- view: "icon",
- width: 38,
- click: () => {
- this._addConnection();
- },
- },
- ],
- },
- {
- view: "scrollview",
- scroll: "y",
- borderless: true,
- padding: 0,
- margin: 0,
- body: {
- id: this.ids.connections,
- view: "layout",
- padding: 0,
- margin: 0,
- rows: [],
- },
- },
- ],
- },
- ],
- },
- ],
- },
- ],
- },
- };
- }
-
- async init(AB) {
- this.AB = AB;
-
- this.$form = $$(this.ids.form);
-
- AB.Webix.extend(this.$form, webix.ProgressBar);
-
- // this.$fieldSelector = $$(this.ids.fieldSelector);
- // if (this.$fieldSelector)
- // AB.Webix.extend(this.$fieldSelector, webix.ProgressBar);
-
- // init() routines are always considered async so:
- return Promise.resolve();
- }
-
- disable() {
- $$(this.ids.form).disable();
- }
-
- enable() {
- $$(this.ids.form).enable();
- }
-
- formClear() {
- this.$form.clearValidation();
- this.$form.clear();
- this.disable();
- }
-
- getValues() {
- return []; // TODO:
- }
-
- setTable(table) {
- this.table = table;
- $$(this.ids.tableName).setValue(
- `${this.table}`
- );
- }
-
- loadConnections(allConnections) {
- this.connectionList = allConnections;
- // refresh more often than on init();
- this.listNetsuiteObjects = this.AB.objects((o) => o.isNetsuite);
- if (this.listNetsuiteObjects.length == 0) {
- $$(this.ids.displayNoConnections)?.show();
- } else {
- $$(this.ids.displayConnections)?.show();
- }
- }
-
- _fieldItem(key, type) {
- const self = this;
- const fieldTypes = this.AB.Class.ABFieldManager.allFields();
- const fieldKeys = ["string", "LongText", "number", "date", "boolean"];
-
- const linkTypes = ["one:one", "one:many", "many:one", "many:many"];
- const linkOptions = linkTypes.map((l) => {
- return { id: l, value: l };
- });
- linkOptions.unshift({ id: "_choose", value: L("choose link type") });
-
- // For the Base Object, let's include all fields that are clearly
- // objects.
- let fieldOptions = this.connectionList.map((conn) => {
- return {
- id: conn.column,
- value: conn.column,
- };
- });
-
- let thisObjectFields = fieldOptions;
- let thatObjectFields = [];
-
- let listOtherObjects = this.listNetsuiteObjects.map((nObj) => {
- return {
- id: nObj.id,
- value: nObj.label,
- };
- });
- listOtherObjects.unshift({ id: "_choose", value: L("Choose Object") });
-
- return {
- view: "form",
- elements: [
- {
- cols: [
- // object and type
- {
- rows: [
- {
- placeholder: L("Existing Netsuite Object"),
- options: listOtherObjects,
- view: "select",
- name: "thatObject",
- label: L("To:"),
- // value: type,
- on: {
- onChange: async function (
- newVal,
- oldVal,
- config
- ) {
- let connObj = self.AB.objectByID(newVal);
- if (connObj) {
- let result = await self.AB.Network.get({
- url: `/netsuite/table/${connObj.tableName}`,
- params: {
- credentials: JSON.stringify(
- self.credentials
- ),
- },
- });
- let fields = result.filter(
- (r) => r.type == "object"
- );
- let options = fields.map((f) => {
- return {
- id: f.column,
- value: f.column,
- };
- });
-
- // include a "_that_object_" incase this is a one:xxx
- // connection.
- // options.unshift({
- // id: "_that_object_",
- // value: L("That Object"),
- // });
-
- thatObjectFields = options;
- /*
- let $linkColumn =
- this.getParentView().getChildViews()[1];
-
- $linkColumn.define("options", options);
- $linkColumn.refresh();
- */
- let $rowsFieldsets = this.getParentView()
- .getParentView()
- .getChildViews()[1];
-
- // update one:one ThatObject:
- let whichOptions = $rowsFieldsets
- .getChildViews()[0]
- .getChildViews()[0]
- .getChildViews()[1];
- let newOptions = [
- { id: "_choose", value: L("Choose") },
- {
- id: "_this_",
- value: L("This Object"),
- },
- ];
- newOptions.push({
- id: connObj.id,
- value: connObj.label,
- });
- whichOptions.define(
- "options",
- newOptions
- );
- whichOptions.refresh();
- }
- },
- },
- },
- {
- placeholder: "Link Type",
- options: linkOptions,
- view: "select",
- name: "linkType",
- label: L("link type"),
- on: {
- onChange: async function (
- newVal,
- oldVal,
- config
- ) {
- let $toObj =
- this.getParentView().getChildViews()[0];
- let $linkColumn =
- this.getParentView().getChildViews()[1];
-
- let objID = $toObj.getValue();
- let Obj = self.AB.objectByID(objID);
-
- let linkVal = $linkColumn.getValue();
- let links = linkVal.split(":");
- let messageA = self.message(
- L("This object"),
- links[0],
- Obj.label
- );
-
- let messageB = self.message(
- Obj.label,
- links[1],
- L("This object")
- );
-
- if (newVal == "_choose") {
- messageA = messageB = "";
- }
-
- let $linkTextA =
- this.getParentView().getChildViews()[2];
- let $linkTextB =
- this.getParentView().getChildViews()[3];
-
- $linkTextA.define("label", messageA);
- $linkTextA.refresh();
-
- $linkTextB.define("label", messageB);
- $linkTextB.refresh();
-
- let $rowsFieldsets = this.getParentView()
- .getParentView()
- .getChildViews()[1];
-
- let $thatFieldOptions;
-
- switch (linkVal) {
- case "one:one":
- $rowsFieldsets
- .getChildViews()[0]
- .show();
- break;
-
- case "one:many":
- // This Object's fields must be in field picker:
- $thatFieldOptions = $rowsFieldsets
- .getChildViews()[1]
- .getChildViews()[0]
- .getChildViews()[1];
- $thatFieldOptions.define(
- "options",
- thisObjectFields
- );
- $thatFieldOptions.refresh();
- $rowsFieldsets
- .getChildViews()[1]
- .show();
- break;
-
- case "many:one":
- // This Object's fields must be in field picker:
- $thatFieldOptions = $rowsFieldsets
- .getChildViews()[1]
- .getChildViews()[0]
- .getChildViews()[1];
- $thatFieldOptions.define(
- "options",
- thatObjectFields
- );
- $thatFieldOptions.refresh();
- $rowsFieldsets
- .getChildViews()[1]
- .show();
- break;
-
- case "many:many":
- $rowsFieldsets
- .getChildViews()[2]
- .show();
- break;
- }
- },
- },
- // value: type,
- },
- {
- // this to that
- // id: ids.fieldLink2,
- view: "label",
- // width: 200,
- },
- {
- // that to this
- view: "label",
- // width: 200,
- },
- ],
- },
- {
- rows: [
- {
- view: "fieldset",
- label: L("one to one"),
- hidden: true,
- body: {
- rows: [
- {
- view: "label",
- label: L(
- "which object holds the connection value?"
- ),
- },
- {
- view: "select",
- options: [
- {
- id: "_choose",
- value: L("Choose Object"),
- },
- {
- id: "_this_",
- value: L("This Object"),
- },
- {
- id: "_that_",
- value: L("That Object"),
- },
- ],
- name: "whichSource",
- on: {
- onChange: async function (
- newVal,
- oldVal,
- config
- ) {
- if (newVal == "_choose") return;
-
- let $fieldPicker =
- this.getParentView().getChildViews()[2];
-
- if (newVal == "_this_") {
- $fieldPicker.define(
- "options",
- thisObjectFields
- );
- } else {
- $fieldPicker.define(
- "options",
- thatObjectFields
- );
- }
- $fieldPicker.refresh();
- $fieldPicker.show();
- },
- },
- },
- {
- view: "select",
- label: L("which field"),
- name: "sourceField",
- options: [],
- hidden: true,
- },
- ],
- },
- },
- {
- view: "fieldset",
- label: L("one:X"),
- hidden: true,
- body: {
- rows: [
- {
- view: "label",
- label: L(
- "which field defines the connection?"
- ),
- },
- {
- view: "select",
- // label: L("which field"),
- name: "thatField",
- options: [],
- // hidden: false,
- },
- ],
- },
- },
- {
- view: "fieldset",
- label: L("many:many"),
- hidden: true,
- body: {
- rows: [
- {
- view: "label",
- label: L(
- "which table is the join table?"
- ),
- },
- {
- view: "combo",
- name: "joinTable",
- options: {
- filter: (item, value) => {
- return (
- item.value
- .toLowerCase()
- .indexOf(
- value.toLowerCase()
- ) > -1
- );
- },
- body: {
- // template: "#value#",
- data: this.allTables,
- },
- },
- on: {
- onChange: async function (
- newVal,
- oldVal,
- config
- ) {
- let result =
- await self.AB.Network.get({
- url: `/netsuite/table/${newVal}`,
- params: {
- credentials:
- JSON.stringify(
- self.credentials
- ),
- },
- });
- // let fields = result.filter(
- // (r) => r.type == "object"
- // );
- let options = result.map((f) => {
- return {
- id: f.column,
- value: f.column,
- };
- });
-
- let $thisObjRef =
- this.getParentView().getChildViews()[2];
- $thisObjRef.define(
- "options",
- options
- );
- $thisObjRef.refresh();
- $thisObjRef.show();
-
- let $thatObjRef =
- this.getParentView().getChildViews()[3];
- $thatObjRef.define(
- "options",
- options
- );
- $thatObjRef.refresh();
- $thatObjRef.show();
-
- let $objectPK =
- this.getParentView().getChildViews()[4];
- $objectPK.define(
- "options",
- options
- );
-
- let pkField = result.find(
- (r) => r.title == "Internal ID"
- );
- if (pkField) {
- $objectPK.setValue(
- pkField.column
- );
- }
- $objectPK.refresh();
- $objectPK.show();
-
- let $entityField =
- this.getParentView().getChildViews()[5];
- $entityField.define(
- "options",
- options
- );
-
- let fieldEntity = result.find(
- (r) => {
- if (!r.column) return false;
-
- return (
- r.column.indexOf(
- "entity"
- ) > -1
- );
- }
- );
- if (fieldEntity) {
- $entityField.setValue(
- fieldEntity.column
- );
- }
- $entityField.refresh();
- $entityField.show();
-
- let fOptions =
- self.AB.cloneDeep(options);
- fOptions.unshift({
- id: "_none_",
- value: "",
- });
- let $activeField =
- this.getParentView().getChildViews()[6];
- $activeField.define(
- "options",
- fOptions
- );
- $activeField.refresh();
- $activeField.show();
- },
- },
- },
-
- {
- view: "select",
- label: L("This Object's reference"),
- labelPosition: "top",
- options: [],
- name: "thisObjReference",
- hidden: true,
- },
- {
- view: "select",
- label: L("That Object's reference"),
- labelPosition: "top",
- options: [],
- name: "thatObjReference",
- hidden: true,
- },
- {
- view: "select",
- label: L("Join Table Primary Key:"),
- labelPosition: "top",
- options: [],
- name: "joinTablePK",
- hidden: true,
- },
- {
- view: "select",
- label: L(
- "Which field holds the Entity:"
- ),
- labelPosition: "top",
- options: [],
- name: "joinTableEntity",
- hidden: true,
- },
- {
- view: "select",
- label: L("Join Table isActive Field:"),
- labelPosition: "top",
- options: [],
- name: "joinActiveField",
- hidden: true,
- on: {
- onChange: async function (
- newVal,
- oldVal,
- config
- ) {
- if (newVal != "_none_") {
- // show the active/inactive value
- let siblings =
- this.getParentView().getChildViews();
- siblings[
- siblings.length - 2
- ].show();
- siblings[
- siblings.length - 1
- ].show();
- }
- },
- },
- },
- {
- view: "text",
- label: L("Active Value"),
- name: "joinActiveValue",
- hidden: true,
- value: "",
- },
- {
- view: "text",
- label: L("InActive Value"),
- name: "joinInActiveValue",
- hidden: true,
- value: "",
- },
- ],
- },
- },
- ],
- },
- {
- // Delete Column
- rows: [
- {},
- {
- icon: "wxi-trash",
- view: "icon",
- width: 38,
- click: function () {
- const $item = this.getParentView()
- .getParentView()
- .getParentView();
- $$(self.ids.connections).removeView($item);
- },
- },
- {},
- ],
- // delete Row Icon
- },
- ],
- },
- ],
- };
- }
-
- _addConnection(key, type) {
- const uiItem = this._fieldItem(key, type);
- $$(this.ids.connections).addView(uiItem);
- }
-
- _clearFieldItems() {
- const $connections = $$(this.ids.connections);
- AB.Webix.ui([], $connections);
- }
-
- message(a, link, b) {
- let msg;
- if (link == "many") {
- msg = L("{0} has many {1} entities", [a, b]);
- } else {
- msg = L("{0} has one {1} entity", [a, b]);
- }
-
- return msg;
- }
-
- /**
- * @method onError()
- * Our Error handler when the data we provided our parent
- * ui_work_object_list_newObject object had an error saving
- * the values.
- * @param {Error|ABValidation|other} err
- * The error information returned. This can be several
- * different types of objects:
- * - A javascript Error() object
- * - An ABValidation object returned from our .isValid()
- * method
- * - An error response from our API call.
- */
- onError(err) {
- if (err) {
- console.error(err);
- let message = L("the entered data is invalid");
- // if this was our Validation() object:
- if (err.updateForm) {
- err.updateForm(this.$form);
- } else {
- if (err.code && err.data) {
- message = err.data?.sqlMessage ?? message;
- } else {
- message = err?.message ?? message;
- }
- }
-
- const values = this.$form.getValues();
- webix.alert({
- title: L("Error creating Object: {0}", [values.name]),
- ok: L("fix it"),
- text: message,
- type: "alert-error",
- });
- }
- // get notified if there was an error saving.
- $$(this.ids.buttonVerify).enable();
- }
-
- /**
- * @method onSuccess()
- * Our success handler when the data we provided our parent
- * ui_work_object_list_newObject successfully saved the values.
- */
- onSuccess() {
- this.formClear();
- $$(this.ids.buttonVerify).enable();
- }
-
- /**
- * @function show()
- *
- * Show this component.
- */
- show() {
- $$(this.ids.component)?.show();
- }
-
- busy() {
- const $verifyButton = $$(this.ids.buttonVerify);
-
- // this.$fieldSelector.showProgress({ type: "icon" });
- $verifyButton.disable();
- }
-
- ready() {
- const $verifyButton = $$(this.ids.buttonVerify);
-
- // this.$fieldSelector.hideProgress();
- $verifyButton.enable();
- }
-
- setCredentials(creds) {
- this.credentials = creds;
- }
-
- setAllTables(tables) {
- this.allTables = this.AB.cloneDeep(tables);
- this.allTables.unshift({ id: "_choose", value: L("Choose") });
- }
-
- getValues() {
- let values = [];
- $$(this.ids.connections)
- .getChildViews()
- .forEach(($row) => {
- values.push($row.getValues());
- });
- return values;
- }
-
- // verify() {
- // this.emit("fields.ready", {
- // credentials: this.credentials,
- // table: this.table,
- // fieldList: this.fieldList,
- // });
- // }
- }
- return new UI_Work_Object_List_NewObject_Netsuite_Connections();
-}
diff --git a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_credentials.js b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_credentials.js
deleted file mode 100644
index e4fbf138..00000000
--- a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_credentials.js
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * ui_work_object_list_newObject_netsuite_credentials
- *
- * Display the tab/form for entering the Netsuite credentials for our
- * connection.
- */
-import UI_Class from "./ui_class";
-
-const KeysCredentials = [
- "NETSUITE_CONSUMER_KEY",
- "NETSUITE_CONSUMER_SECRET",
- "NETSUITE_TOKEN_KEY",
- "NETSUITE_TOKEN_SECRET",
-];
-const KeysAPI = [
- "NETSUITE_REALM",
- "NETSUITE_BASE_URL",
- "NETSUITE_QUERY_BASE_URL",
-];
-
-const KeysALL = KeysCredentials.concat(KeysAPI);
-
-export default function (AB) {
- const UIClass = UI_Class(AB);
- const L = UIClass.L();
-
- class UI_Work_Object_List_NewObject_Netsuite_Credentials extends UIClass {
- constructor() {
- super("ui_work_object_list_newObject_netsuite_credentials", {
- // component: base,
-
- form: "",
- buttonVerify: "",
- labelVerified: "",
- });
-
- this.entries = {};
- }
-
- ui() {
- // Our webix UI definition:
- let ui = {
- id: this.ids.component,
- header: L("Credentials"),
- body: {
- view: "form",
- id: this.ids.form,
- width: 820,
- height: 700,
- rules: {
- // TODO:
- // name: inputValidator.rules.validateObjectName
- },
- elements: [
- {
- rows: [],
- },
- {
- cols: [
- { fillspace: true },
- // {
- // view: "button",
- // id: this.ids.buttonCancel,
- // value: L("Cancel"),
- // css: "ab-cancel-button",
- // autowidth: true,
- // click: () => {
- // this.cancel();
- // },
- // },
- {
- view: "button",
- id: this.ids.buttonVerify,
- css: "webix_primary",
- value: L("Verify"),
- autowidth: true,
- type: "form",
- click: () => {
- return this.verify();
- },
- },
- ],
- },
- {
- cols: [
- { fillspace: true },
- {
- id: this.ids.labelVerified,
- view: "label",
- label: L(
- "All parameters are valid. Continue on to select a Table to work with."
- ),
- hidden: true,
- },
- ],
- },
- ],
- },
- };
-
- let rows = ui.body.elements[0].rows;
- let fsOauth = {
- view: "fieldset",
- label: L("Netsuite OAuth 1.0 Credentials"),
- body: {
- rows: [],
- },
- };
-
- let EnvInput = (k) => {
- return {
- cols: [
- {
- id: k,
- view: "text",
- label: k,
- name: k,
- required: true,
- placeholder: `ENV:${k}`,
- value: `ENV:${k}`,
- labelWidth: 230,
- on: {
- onChange: (nV, oV) => {
- this.envVerify(k, nV);
- },
- },
- },
- {
- id: `${k}_verified`,
- view: "label",
- width: 20,
- label: '',
- hidden: true,
- },
- ],
- };
- };
-
- KeysCredentials.forEach((k) => {
- fsOauth.body.rows.push(EnvInput(k));
- });
- rows.push(fsOauth);
- rows.push({ height: 15 });
-
- let fsAPI = {
- view: "fieldset",
- label: L("Netsuite API Config"),
- body: {
- rows: [],
- },
- };
-
- KeysAPI.forEach((k) => {
- fsAPI.body.rows.push(EnvInput(k));
- });
- rows.push(fsAPI);
-
- return ui;
- }
-
- async init(AB) {
- this.AB = AB;
-
- this.$form = $$(this.ids.form);
- AB.Webix.extend(this.$form, webix.ProgressBar);
-
- // init() routines are always considered async so:
- return Promise.resolve();
- }
-
- formClear() {
- this.$form.clearValidation();
- this.$form.clear();
-
- KeysALL.forEach((k) => {
- $$(k).setValue(`ENV:${k}`);
- });
- }
-
- getValues() {
- return this.credentials();
- }
-
- /**
- * @method onError()
- * Our Error handler when the data we provided our parent
- * ui_work_object_list_newObject object had an error saving
- * the values.
- * @param {Error|ABValidation|other} err
- * The error information returned. This can be several
- * different types of objects:
- * - A javascript Error() object
- * - An ABValidation object returned from our .isValid()
- * method
- * - An error response from our API call.
- */
- onError(err) {
- if (err) {
- console.error(err);
- let message = L("the entered data is invalid");
- // if this was our Validation() object:
- if (err.updateForm) {
- err.updateForm(this.$form);
- } else {
- if (err.code && err.data) {
- message = err.data?.sqlMessage ?? message;
- } else {
- message = err?.message ?? message;
- }
- }
-
- const values = this.$form.getValues();
- webix.alert({
- title: L("Error creating Object: {0}", [values.name]),
- ok: L("fix it"),
- text: message,
- type: "alert-error",
- });
- }
- // get notified if there was an error saving.
- $$(this.ids.buttonVerify).enable();
- }
-
- /**
- * @method onSuccess()
- * Our success handler when the data we provided our parent
- * ui_work_object_list_newObject successfully saved the values.
- */
- onSuccess() {
- this.formClear();
- $$(this.ids.buttonVerify).enable();
- }
-
- /**
- * @function show()
- *
- * Show this component.
- */
- show() {
- $$(this.ids.component)?.show();
- console.log("SHOW, Baby! SHOW!");
- }
-
- busy() {
- const $form = $$(this.ids.form);
- const $saveButton = $$(this.ids.buttonVerify);
-
- $form.showProgress({ type: "icon" });
- $saveButton.disable();
- }
-
- credentials() {
- let creds = {};
- KeysALL.forEach((k) => {
- let $input = $$(k);
- if ($input) {
- creds[k] = $input.getValue();
- }
- });
-
- return creds;
- }
-
- envVerify(k, nV) {
- let envKey = nV.replace("ENV:", "");
- return this.AB.Network.get({
- url: `/env/verify/${envKey}`,
- })
- .then((result) => {
- console.log(result);
- if (result.status == "success") {
- $$(`${k}_verified`).show();
- this.entries[k] = true;
- } else {
- $$(`${k}_verified`).hide();
- this.entries[k] = false;
- }
- })
- .catch((err) => {
- console.error(err);
- $$(`${k}_verified`).hide();
- this.entries[k] = false;
- });
- }
-
- ready() {
- const $form = $$(this.ids.form);
- const $saveButton = $$(this.ids.buttonVerify);
-
- $form.hideProgress();
- $saveButton.enable();
- }
-
- async verify() {
- let isVerified = true;
- let AllVerifies = [];
- KeysALL.forEach((k) => {
- let nV = $$(k).getValue();
- AllVerifies.push(this.envVerify(k, nV));
- });
- await Promise.all(AllVerifies);
-
- KeysALL.forEach((k) => {
- isVerified = isVerified && this.entries[k];
- });
-
- if (isVerified) {
- this.emit("verified");
- $$(this.ids.labelVerified)?.show();
- } else {
- this.emit("notverified");
- $$(this.ids.labelVerified)?.hide();
- }
- }
- }
- return new UI_Work_Object_List_NewObject_Netsuite_Credentials();
-}
diff --git a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_dataTest.js b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_dataTest.js
deleted file mode 100644
index a258d31f..00000000
--- a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_dataTest.js
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * ui_work_object_list_newObject_netsuite_dataTest
- *
- * Display the tab/form to review what the current Definitions look like
- * working with the data from Netsuite.
- */
-import UI_Class from "./ui_class";
-
-export default function (AB) {
- const UIClass = UI_Class(AB);
- const L = UIClass.L();
-
- class UI_Work_Object_List_NewObject_Netsuite_DataTest extends UIClass {
- constructor() {
- super("ui_work_object_list_newObject_netsuite_dataTest", {
- // component: base,
- form: "",
- network: "",
- dataView: "",
-
- buttonVerify: "",
- tableName: "",
- });
-
- this.credentials = {};
- // { CRED_KEY : CRED_VAL }
- // The entered credential references necessary to perform our Netsuite
- // operations.
-
- this.fieldKeys = [
- "string",
- "LongText",
- "number",
- "date",
- "boolean",
- "json",
- "list",
- ];
- // {array} of types of ABFields we can translate into.
-
- this.fieldList = null;
- // {array}
- // Holds an array of field descriptions
-
- this.table = null;
- // {string}
- // name of the table we are working with
- }
-
- ui() {
- // Our webix UI definition:
- return {
- id: this.ids.component,
- header: L("Data Verification"),
- body: {
- view: "form",
- id: this.ids.form,
- width: 800,
- height: 400,
- rules: {
- // TODO:
- // name: inputValidator.rules.validateObjectName
- },
- elements: [
- // Field Selector
- {
- view: "layout",
- padding: 10,
- rows: [
- {
- cols: [
- {
- id: this.ids.tableName,
- label: L("Selected Table: {0}", [this.table]),
- view: "label",
- height: 40,
- },
- {},
- ],
- },
- {
- view: "multiview",
- // keepViews: true,
- cells: [
- // Select Table indicator
- {
- id: this.ids.network,
- rows: [
- {},
- {
- view: "label",
- align: "center",
- height: 200,
- label: "",
- },
- {
- view: "label",
- align: "center",
- label: L(
- "Gathering data from Netsuite."
- ),
- },
- {},
- ],
- },
- {
- id: this.ids.dataView,
- rows: [
- {},
- {
- view: "label",
- label: "Waiting for response",
- },
- {},
- ],
- // hidden: true,
- },
- ],
- },
-
- // {
- // id: this.ids.fieldGrid,
- // view: "datatable",
- // resizeColumn: true,
- // height: 300,
- // columns: [
- // {
- // id: "title",
- // header: L("title"),
- // editor: "text",
- // },
- // { id: "column", header: L("column") },
-
- // { id: "nullable", header: L("nullable") },
- // { id: "readOnly", header: L("read only") },
- // {
- // id: "pk",
- // header: L("is primary key"),
- // template: "{common.radio()}",
- // },
- // // {
- // // id: "description",
- // // header: L("description"),
- // // fillspace: true,
- // // },
- // {
- // id: "abType",
- // header: L("AB Field Type"),
- // editor: "select",
- // options: [" "].concat(this.fieldKeys),
- // },
- // {
- // id: "delme",
- // header: "",
- // template: "{common.trashIcon()}",
- // },
- // ],
- // editable: true,
- // scroll: "y",
- // onClick: {
- // "wxi-trash": (e, id) => {
- // debugger;
- // $$(this.ids.fieldGrid).remove(id);
- // },
- // },
- // },
- ],
- },
-
- {
- cols: [
- { fillspace: true },
- // {
- // view: "button",
- // id: this.ids.buttonCancel,
- // value: L("Cancel"),
- // css: "ab-cancel-button",
- // autowidth: true,
- // click: () => {
- // this.cancel();
- // },
- // },
- {
- view: "button",
- id: this.ids.buttonVerify,
- css: "webix_primary",
- value: L("Verify"),
- autowidth: true,
- type: "form",
- click: () => {
- return this.verify();
- },
- },
- ],
- },
- ],
- },
- };
- }
-
- async init(AB) {
- this.AB = AB;
-
- this.$form = $$(this.ids.form);
- AB.Webix.extend(this.$form, webix.ProgressBar);
-
- // init() routines are always considered async so:
- return Promise.resolve();
- }
-
- disable() {
- $$(this.ids.form).disable();
- }
-
- enable() {
- $$(this.ids.form).enable();
- }
-
- formClear() {
- this.$form.clearValidation();
- this.$form.clear();
-
- // reset the data view to blank
- let table = {
- id: this.ids.dataView,
- rows: [
- {},
- {
- view: "label",
- label: "Waiting for response",
- },
- {},
- ],
- // hidden: true,
- };
- webix.ui(table, $$(this.ids.dataView));
- this.disable();
- }
- setTableName() {
- $$(this.ids.tableName).setValue(
- `${this.table}`
- );
- }
-
- setTable(table) {
- this.table = table;
- this.setTableName();
-
- // this is called when a table name has been selected.
- // but we need to be disabled until they have verified the
- // fields.
- this.formClear();
- }
-
- async loadConfig(config) {
- this.credentials = config.credentials;
- this.setTable(config.table);
- this.fieldList = config.fieldList;
-
- $$(this.ids.network).show();
- this.busy();
-
- let result = await this.AB.Network.get({
- url: `/netsuite/dataVerify/${this.table}`,
- params: {
- credentials: JSON.stringify(this.credentials),
- },
- });
-
- this.data = result;
- // this.ids.dataView,
-
- // convert all the json types to strings for display:
- this.fieldList
- .filter((f) => f.abType == "json")
- .forEach((f) => {
- this.data.forEach((d) => {
- try {
- d[f.column] = JSON.stringify(d[f.column]);
- } catch (e) {
- console.log(e);
- }
- });
- });
-
- this.showTable();
- this.enable();
- this.ready();
- }
-
- showTable() {
- let table = {
- id: this.ids.dataView,
- view: "datatable",
- columns: this.fieldList.map((f) => {
- return {
- id: f.column,
- header: f.title,
- };
- }),
- data: this.data,
- };
-
- webix.ui(table, $$(this.ids.dataView));
- $$(this.ids.dataView).show();
- }
-
- /**
- * @method onError()
- * Our Error handler when the data we provided our parent
- * ui_work_object_list_newObject object had an error saving
- * the values.
- * @param {Error|ABValidation|other} err
- * The error information returned. This can be several
- * different types of objects:
- * - A javascript Error() object
- * - An ABValidation object returned from our .isValid()
- * method
- * - An error response from our API call.
- */
- // onError(err) {
- // if (err) {
- // console.error(err);
- // let message = L("the entered data is invalid");
- // // if this was our Validation() object:
- // if (err.updateForm) {
- // err.updateForm(this.$form);
- // } else {
- // if (err.code && err.data) {
- // message = err.data?.sqlMessage ?? message;
- // } else {
- // message = err?.message ?? message;
- // }
- // }
-
- // const values = this.$form.getValues();
- // webix.alert({
- // title: L("Error creating Object: {0}", [values.name]),
- // ok: L("fix it"),
- // text: message,
- // type: "alert-error",
- // });
- // }
- // // get notified if there was an error saving.
- // $$(this.ids.buttonVerify).enable();
- // }
-
- /**
- * @method onSuccess()
- * Our success handler when the data we provided our parent
- * ui_work_object_list_newObject successfully saved the values.
- */
- // onSuccess() {
- // this.formClear();
- // $$(this.ids.buttonVerify).enable();
- // }
-
- verify() {
- this.emit("data.verfied");
- }
-
- /**
- * @function show()
- *
- * Show this component.
- */
- show() {
- $$(this.ids.component)?.show();
- }
-
- busy() {
- const $verifyButton = $$(this.ids.buttonVerify);
-
- this.$form.showProgress({ type: "icon" });
- $verifyButton.disable();
- }
-
- ready() {
- const $verifyButton = $$(this.ids.buttonVerify);
-
- this.$form.hideProgress();
- $verifyButton.enable();
- }
-
- setCredentials(creds) {
- this.credentials = creds;
- }
- }
- return new UI_Work_Object_List_NewObject_Netsuite_DataTest();
-}
diff --git a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_fields.js b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_fields.js
deleted file mode 100644
index 08caf392..00000000
--- a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_fields.js
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * ui_work_object_list_newObject_netsuite_fields
- *
- * Display the tab/form for selecting which of the available tables we are
- * working with.
- */
-import UI_Class from "./ui_class";
-
-export default function (AB) {
- const UIClass = UI_Class(AB);
- const L = UIClass.L();
-
- class UI_Work_Object_List_NewObject_Netsuite_Fields extends UIClass {
- constructor() {
- super("ui_work_object_list_newObject_netsuite_fields", {
- // component: base,
-
- form: "",
-
- tableName: "",
- // tableList: "",
- fieldSelector: "",
- // fields: "",
- fieldGrid: "",
- buttonVerify: "",
- // buttonLookup: "",
- });
-
- this.credentials = {};
- // { CRED_KEY : CRED_VAL }
- // The entered credential references necessary to perform our Netsuite
- // operations.
-
- this.fieldKeys = [
- "string",
- "LongText",
- "number",
- "date",
- "datetime",
- "boolean",
- "json",
- "list",
- // "connectObject",
- ];
- // {array} of types of ABFields we can translate into.
-
- this.fieldList = null;
- // {array}
- // Holds an array of field descriptions
-
- this.fields = null;
- // {array}
- // Holds the array of chosen/verified fields
- }
-
- ui() {
- // Our webix UI definition:
- return {
- id: this.ids.component,
- header: L("Fields"),
- body: {
- view: "form",
- id: this.ids.form,
- width: 800,
- height: 450,
- rules: {
- // TODO:
- // name: inputValidator.rules.validateObjectName
- },
- elements: [
- // Field Selector
- {
- id: this.ids.fieldSelector,
- view: "layout",
- padding: 10,
- rows: [
- {
- rows: [
- {
- id: this.ids.tableName,
- label: L("Selected Table: {0}", [this.table]),
- view: "label",
- height: 40,
- },
- {},
- ],
- },
- // {
- // view: "scrollview",
- // scroll: "y",
- // borderless: true,
- // padding: 0,
- // margin: 0,
- // body: {
- // id: this.ids.fields,
- // view: "layout",
- // padding: 0,
- // margin: 0,
- // rows: [],
- // },
- // },
- {
- id: this.ids.fieldGrid,
- view: "datatable",
- resizeColumn: true,
- height: 300,
- columns: [
- {
- id: "title",
- header: L("title"),
- editor: "text",
- },
- { id: "column", header: L("column") },
-
- { id: "nullable", header: L("nullable") },
- { id: "readOnly", header: L("read only") },
- {
- id: "default",
- header: L("Default Value"),
- editor: "text",
- },
- {
- id: "pk",
- header: L("is primary key"),
- template: "{common.radio()}",
- },
- {
- id: "created_at",
- header: L("Created At"),
- template: "{common.radio()}",
- },
- {
- id: "updated_at",
- header: L("Updated At"),
- template: "{common.radio()}",
- },
- // {
- // id: "description",
- // header: L("description"),
- // fillspace: true,
- // },
- {
- id: "abType",
- header: L("AB Field Type"),
- editor: "select",
- options: [" "].concat(this.fieldKeys),
- on: {
- onChange: (newValue, oldValue) => {
- debugger;
- },
- },
- },
- {
- id: "delme",
- header: "",
- template: "{common.trashIcon()}",
- },
- ],
- editable: true,
- scroll: "xy",
- onClick: {
- "wxi-trash": (e, id) => {
- $$(this.ids.fieldGrid).remove(id);
- this.fields = this.fields.filter(
- (f) => f.id != id.row
- );
- },
- },
- },
- {
- cols: [
- { fillspace: true },
- // {
- // view: "button",
- // id: this.ids.buttonCancel,
- // value: L("Cancel"),
- // css: "ab-cancel-button",
- // autowidth: true,
- // click: () => {
- // this.cancel();
- // },
- // },
- {
- view: "button",
- id: this.ids.buttonVerify,
- css: "webix_primary",
- value: L("Verify"),
- autowidth: true,
- type: "form",
- click: () => {
- return this.verify();
- },
- },
- ],
- },
- ],
- },
- ],
- },
- };
- }
-
- async init(AB) {
- this.AB = AB;
-
- this.$form = $$(this.ids.form);
-
- this.$fieldSelector = $$(this.ids.fieldSelector);
- AB.Webix.extend(this.$form, webix.ProgressBar);
- AB.Webix.extend(this.$fieldSelector, webix.ProgressBar);
-
- // init() routines are always considered async so:
- return Promise.resolve();
- }
-
- disable() {
- $$(this.ids.form).disable();
- }
-
- enable() {
- $$(this.ids.form).enable();
- }
-
- formClear() {
- this.$form.clearValidation();
- this.$form.clear();
-
- $$(this.ids.fieldGrid)?.clearAll();
- this.disable();
- $$(this.ids.buttonVerify).disable();
- }
-
- addABType(f) {
- switch (f.type) {
- case "array":
- // this is most likely a MANY:x connection.
- // Q:what do we default this to?
- f.abType = "json";
- break;
-
- case "object":
- // this is most likely a ONE:X[ONE,MANY] connection.
- // // lets scan the properties of the dest obj,
- // // find a property with title = "Internal Identifier"
- // // and make this ABType == that property.type
-
- // if (f.properties) {
- // Object.keys(f.properties).forEach((k) => {
- // if (f.properties[k].title == "Internal Identifier") {
- // f.abType = f.properties[k].type;
- // }
- // });
- // }
- // // default to "string" if an Internal Identifier isn't found.
- // if (!f.abType) {
- // f.abType = "string";
- // }
- f.abType = "connectObject";
- break;
-
- case "boolean":
- f.abType = "boolean";
- break;
-
- default:
- f.abType = "string";
- }
-
- // just in case:
- // lets see if this looks like a date field instead
-
- if (f.abType == "string") {
- let lcTitle = f.title?.toLowerCase();
- if (lcTitle) {
- let indxDate = lcTitle.indexOf("date") > -1;
- let indxDay = lcTitle.indexOf("day") > -1;
- if (indxDate || indxDay) {
- f.abType = "date";
- }
- }
-
- if (f.format == "date-time") {
- f.abType = "datetime";
- }
- }
-
- // Seems like the PKs have title == "Internal ID"
- if (f.title == "Internal ID") {
- f.pk = true;
- }
- }
-
- getValues() {
- return this.fields;
- }
-
- setTableName() {
- $$(this.ids.tableName).setValue(
- `${this.table}`
- );
- }
- async loadFields(table) {
- $$(this.ids.fieldGrid)?.clearAll();
- this.table = table;
- $$(this.ids.fieldSelector).show();
- this.busy();
- this.setTableName();
-
- let result = await this.AB.Network.get({
- url: `/netsuite/table/${table}`,
- params: { credentials: JSON.stringify(this.credentials) },
- });
-
- this.fieldList = result;
- (result || []).forEach((f) => {
- this.addABType(f);
- });
-
- // ok, in this pane, we are just looking at the base fields
- // leave the connections to the next pane:
- this.fields = result.filter((r) => r.type != "object");
-
- // let our other pane know about it's connections
- this.emit(
- "connections",
- result.filter((r) => r.type == "object")
- );
-
- $$(this.ids.fieldGrid).parse(this.fields);
- this.ready();
- }
-
- /**
- * @method onError()
- * Our Error handler when the data we provided our parent
- * ui_work_object_list_newObject object had an error saving
- * the values.
- * @param {Error|ABValidation|other} err
- * The error information returned. This can be several
- * different types of objects:
- * - A javascript Error() object
- * - An ABValidation object returned from our .isValid()
- * method
- * - An error response from our API call.
- */
- onError(err) {
- if (err) {
- console.error(err);
- let message = L("the entered data is invalid");
- // if this was our Validation() object:
- if (err.updateForm) {
- err.updateForm(this.$form);
- } else {
- if (err.code && err.data) {
- message = err.data?.sqlMessage ?? message;
- } else {
- message = err?.message ?? message;
- }
- }
-
- const values = this.$form.getValues();
- webix.alert({
- title: L("Error creating Object: {0}", [values.name]),
- ok: L("fix it"),
- text: message,
- type: "alert-error",
- });
- }
- // get notified if there was an error saving.
- $$(this.ids.buttonVerify).enable();
- }
-
- /**
- * @method onSuccess()
- * Our success handler when the data we provided our parent
- * ui_work_object_list_newObject successfully saved the values.
- */
- onSuccess() {
- this.formClear();
- $$(this.ids.buttonVerify).enable();
- }
-
- /**
- * @function show()
- *
- * Show this component.
- */
- show() {
- $$(this.ids.component)?.show();
- }
-
- busy() {
- const $verifyButton = $$(this.ids.buttonVerify);
-
- this.$fieldSelector.showProgress({ type: "icon" });
- $verifyButton.disable();
- }
-
- ready() {
- const $verifyButton = $$(this.ids.buttonVerify);
-
- this.$fieldSelector.hideProgress();
- $verifyButton.enable();
- }
-
- setCredentials(creds) {
- this.credentials = creds;
- }
-
- verify() {
- this.emit("fields.ready", {
- credentials: this.credentials,
- table: this.table,
- fieldList: this.fields,
- });
- }
- }
- return new UI_Work_Object_List_NewObject_Netsuite_Fields();
-}
diff --git a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_tables.js b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_tables.js
deleted file mode 100644
index e3a62781..00000000
--- a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_tables.js
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * ui_work_object_list_newObject_netsuite_tables
- *
- * Display the tab/form for selecting which of the available tables we are
- * working with.
- */
-import UI_Class from "./ui_class";
-
-export default function (AB) {
- const UIClass = UI_Class(AB);
- const L = UIClass.L();
-
- class UI_Work_Object_List_NewObject_Netsuite_Tables extends UIClass {
- constructor() {
- super("ui_work_object_list_newObject_netsuite_tables", {
- // component: base,
-
- form: "",
-
- searchText: "",
- tableList: "",
- // fieldSelector: "",
- fields: "",
- buttonVerify: "",
- buttonLookup: "",
- });
-
- this.credentials = {};
- // { CRED_KEY : CRED_VAL }
- // The entered credential references necessary to perform our Netsuite
- // operations.
-
- this.lastSelectedTable = null;
- // {string}
- // the table name of the last selected table.
- }
-
- ui() {
- // Our webix UI definition:
- return {
- id: this.ids.component,
- header: L("Tables"),
- body: {
- view: "form",
- id: this.ids.form,
- width: 800,
- height: 700,
- rules: {
- // TODO:
- // name: inputValidator.rules.validateObjectName
- },
- elements: [
- {
- cols: [
- // The Table Selector Column
- {
- rows: [
- {
- cols: [
- {
- view: "label",
- align: "left",
- label: L(
- "Use the provided credentials to request a list of tables to work with."
- ),
- },
- {
- view: "button",
- id: this.ids.buttonLookup,
- value: L("Load Catalog"),
- // css: "ab-cancel-button",
- autowidth: true,
- click: () => {
- this.loadCatalog();
- },
- },
- ],
- },
- {
- id: this.ids.searchText,
- view: "search",
- icon: "fa fa-search",
- label: L("Search"),
- labelWidth: 80,
- placeholder: L("tablename"),
- height: 35,
- keyPressTimeout: 100,
- on: {
- onAfterRender() {
- AB.ClassUI.CYPRESS_REF(this);
- },
- onTimedKeyPress: () => {
- let searchText = $$(this.ids.searchText)
- .getValue()
- .toLowerCase();
-
- this.$list.filter(function (item) {
- return (
- !item.value ||
- item.value
- .toLowerCase()
- .indexOf(searchText) > -1
- );
- });
- },
- },
- },
- {
- id: this.ids.tableList,
- view: "list",
- select: 1,
- height: 400,
- on: {
- onItemClick: (id, e) => {
- if (id != this.lastSelectedTable) {
- this.lastSelectedTable = id;
- this.emit("table.selected", id);
- }
- },
- },
- },
- ],
- },
-
- // Select Table indicator
- {
- rows: [
- {},
- {
- view: "label",
- align: "center",
- height: 200,
- label: "",
- },
- {
- view: "label",
- align: "center",
- label: L("Select an table to work with."),
- },
- {},
- ],
- },
- ],
- },
- // {
- // cols: [
- // { fillspace: true },
- // // {
- // // view: "button",
- // // id: this.ids.buttonCancel,
- // // value: L("Cancel"),
- // // css: "ab-cancel-button",
- // // autowidth: true,
- // // click: () => {
- // // this.cancel();
- // // },
- // // },
- // {
- // view: "button",
- // id: this.ids.buttonVerify,
- // css: "webix_primary",
- // value: L("Verify"),
- // autowidth: true,
- // type: "form",
- // click: () => {
- // return this.verify();
- // },
- // },
- // ],
- // },
- ],
- },
- };
- }
-
- async init(AB) {
- this.AB = AB;
-
- this.$form = $$(this.ids.form);
- this.$list = $$(this.ids.tableList);
- // this.$fieldSelector = $$(this.ids.fieldSelector);
- AB.Webix.extend(this.$form, webix.ProgressBar);
- AB.Webix.extend(this.$list, webix.ProgressBar);
- // AB.Webix.extend(this.$fieldSelector, webix.ProgressBar);
-
- // init() routines are always considered async so:
- return Promise.resolve();
- }
-
- disable() {
- $$(this.ids.form).disable();
- }
-
- enable() {
- $$(this.ids.form).enable();
- }
-
- formClear() {
- this.$form.clearValidation();
- this.$form.clear();
-
- $$(this.ids.searchText).setValue("");
- this.$list.filter(() => true);
- this.lastSelectedTable = null;
- }
- getValues() {
- return this.lastSelectedTable;
- }
-
- async loadCatalog() {
- this.busy();
- let result = await this.AB.Network.get({
- url: "/netsuite/metadata",
- params: { credentials: JSON.stringify(this.credentials) },
- });
-
- let data = [];
- result.forEach((r) => {
- data.push({ id: r, value: r });
- });
- let $table = $$(this.ids.tableList);
- $table.clearAll();
- $table.parse(data);
-
- // console.error(data);
- this.emit("tables", data);
- }
-
- _fieldItem(def) {
- const self = this;
- const fieldTypes = this.AB.Class.ABFieldManager.allFields();
- const fieldKeys = ["string", "LongText", "number", "date", "boolean"];
-
- let key = def.column || def.title;
- let type = def.type;
-
- return {
- cols: [
- {
- view: "text",
- value: key,
- placeholder: "key",
- },
- {
- placeholder: "Type",
- options: fieldKeys.map((fKey) => {
- return {
- id: fKey,
- value: fieldTypes
- .filter((f) => f.defaults().key == fKey)[0]
- ?.defaults().menuName,
- };
- }),
- view: "select",
- value: type,
- },
- {
- icon: "wxi-trash",
- view: "icon",
- width: 38,
- click: function () {
- const $item = this.getParentView();
- $$(self.ids.fields).removeView($item);
- },
- },
- ],
- };
- }
-
- async loadFields(table) {
- // $$(this.ids.fieldSelector).show();
- this.busyFields();
-
- let result = await this.AB.Network.get({
- url: `/netsuite/table/${table}`,
- params: { credentials: JSON.stringify(this.credentials) },
- });
-
- this.fieldList = result;
- (result || []).forEach((f) => {
- const uiItem = this._fieldItem(f);
- $$(this.ids.fields).addView(uiItem);
- });
- this.readyFields();
- }
-
- /**
- * @method onError()
- * Our Error handler when the data we provided our parent
- * ui_work_object_list_newObject object had an error saving
- * the values.
- * @param {Error|ABValidation|other} err
- * The error information returned. This can be several
- * different types of objects:
- * - A javascript Error() object
- * - An ABValidation object returned from our .isValid()
- * method
- * - An error response from our API call.
- */
- onError(err) {
- if (err) {
- console.error(err);
- let message = L("the entered data is invalid");
- // if this was our Validation() object:
- if (err.updateForm) {
- err.updateForm(this.$form);
- } else {
- if (err.code && err.data) {
- message = err.data?.sqlMessage ?? message;
- } else {
- message = err?.message ?? message;
- }
- }
-
- const values = this.$form.getValues();
- webix.alert({
- title: L("Error creating Object: {0}", [values.name]),
- ok: L("fix it"),
- text: message,
- type: "alert-error",
- });
- }
- // get notified if there was an error saving.
- $$(this.ids.buttonVerify).enable();
- }
-
- /**
- * @method onSuccess()
- * Our success handler when the data we provided our parent
- * ui_work_object_list_newObject successfully saved the values.
- */
- onSuccess() {
- this.formClear();
- $$(this.ids.buttonVerify).enable();
- }
-
- /**
- * @function show()
- *
- * Show this component.
- */
- show() {
- $$(this.ids.component)?.show();
- }
-
- busy() {
- const $list = $$(this.ids.tableList);
- // const $verifyButton = $$(this.ids.buttonVerify);
-
- $list.showProgress({ type: "icon" });
- // $verifyButton.disable();
- }
-
- // busyFields() {
- // this.$fieldSelector.showProgress({ type: "icon" });
- // }
-
- ready() {
- const $form = $$(this.ids.form);
- // const $verifyButton = $$(this.ids.buttonVerify);
-
- $form.hideProgress();
- // $verifyButton.enable();
- }
-
- // readyFields() {
- // this.$fieldSelector.hideProgress();
- // }
-
- setCredentials(creds) {
- this.credentials = creds;
- }
- }
- return new UI_Work_Object_List_NewObject_Netsuite_Tables();
-}
diff --git a/webpack.common.js b/webpack.common.js
index eea1212e..8b4da236 100644
--- a/webpack.common.js
+++ b/webpack.common.js
@@ -25,7 +25,7 @@ module.exports = {
},
},
{
- test: /\.(eot|woff|woff2|svg|ttf)([\?]?.*)$/,
+ test: /\.(eot|woff|woff2|svg|ttf)([?]?.*)$/,
use: ["url-loader?limit=10000000"],
},
],