From 3569bcebe7c045f344a0248c0659510ef51e9b59 Mon Sep 17 00:00:00 2001
From: nh758 <7259@pm.me>
Date: Mon, 9 Sep 2024 13:06:49 +0700
Subject: [PATCH 01/16] add complex teams widget
---
.../Designer/editors/EditorManager.js | 1 +
.../editors/views/ABViewOrgChartTeams.js | 53 +++
.../Designer/properties/PropertyManager.js | 1 +
.../properties/views/ABViewOrgChartTeams.js | 359 ++++++++++++++++++
4 files changed, 414 insertions(+)
create mode 100644 src/rootPages/Designer/editors/views/ABViewOrgChartTeams.js
create mode 100644 src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
diff --git a/src/rootPages/Designer/editors/EditorManager.js b/src/rootPages/Designer/editors/EditorManager.js
index 6afb1ef0..f7b82266 100644
--- a/src/rootPages/Designer/editors/EditorManager.js
+++ b/src/rootPages/Designer/editors/EditorManager.js
@@ -32,6 +32,7 @@ export default function (AB) {
require("./views/ABViewLayout"),
require("./views/ABViewMenu"),
require("./views/ABViewOrgChart"),
+ require("./views/ABViewOrgChartTeams"),
require("./views/ABViewPage"),
require("./views/ABViewPDFImporter"),
require("./views/ABViewPivot"),
diff --git a/src/rootPages/Designer/editors/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/editors/views/ABViewOrgChartTeams.js
new file mode 100644
index 00000000..5a568fb4
--- /dev/null
+++ b/src/rootPages/Designer/editors/views/ABViewOrgChartTeams.js
@@ -0,0 +1,53 @@
+/**
+ * ABViewOrgChartEditor
+ * 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 FABViewDefault from "./_ABViewDefault";
+
+export default function (AB) {
+ if (!myClass) {
+ const ABViewDefault = FABViewDefault(AB);
+ // var L = UIClass.L();
+ // var L = ABViewContainer.L();
+
+ myClass = class ABViewOrgChartTeamsEditor extends ABViewDefault {
+ static get key() {
+ return "orgchart_teams";
+ }
+
+ constructor(view, base = "interface_editor_viewOrgChartTeans") {
+ // base: {string} unique base id reference
+
+ super(view, base);
+
+ // this.component = this.view.component();
+ }
+
+ ui() {
+ let _ui = super.ui();
+ 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/properties/PropertyManager.js b/src/rootPages/Designer/properties/PropertyManager.js
index 8608b548..b497faaa 100644
--- a/src/rootPages/Designer/properties/PropertyManager.js
+++ b/src/rootPages/Designer/properties/PropertyManager.js
@@ -109,6 +109,7 @@ export default function (AB) {
require("./views/ABViewList"),
require("./views/ABViewMenu"),
require("./views/ABViewOrgChart"),
+ require("./views/ABViewOrgChartTeams"),
require("./views/ABViewPage"),
require("./views/ABViewPDFImporter"),
require("./views/ABViewPivot"),
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
new file mode 100644
index 00000000..891acda6
--- /dev/null
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -0,0 +1,359 @@
+/*
+ * ABViewChartTeams
+ * A Property manager for our ABViewChartTeams definitions
+ */
+
+import FABView from "./ABView";
+
+export default function (AB) {
+ const BASE_ID = "properties_abview_org_chart_teams";
+
+ const ABView = FABView(AB);
+ const uiConfig = AB.Config.uiSettings();
+ const L = ABView.L();
+
+ class ABViewOrgChartTeamsProperty extends ABView {
+ constructor() {
+ super(BASE_ID, {
+ datacollectionID: "",
+ fields: "",
+ direction: "",
+ depth: "",
+ color: "",
+ pan: "",
+ zoom: "",
+ height: "",
+ export: "",
+ exportFilename: "",
+ });
+
+ this.AB = AB;
+ }
+
+ static get key() {
+ return "orgchart_teams";
+ }
+
+ ui() {
+ const ids = this.ids;
+
+ return super.ui([
+ {
+ id: ids.datacollectionID,
+ name: "datacollectionID",
+ view: "richselect",
+ label: L("Data Collection"),
+ labelWidth: uiConfig.labelWidthLarge,
+ options: [],
+ on: {
+ onChange: (value) => {
+ this.CurrentView.settings.datacollectionID = value;
+ this.populateSubValueFieldOptions(
+ this.CurrentView?.datacollection?.datasource
+ );
+ this.onChange();
+ },
+ },
+ },
+ {
+ cols: [
+ {
+ view: "label",
+ label: "Fields",
+ width: uiConfig.labelWidthLarge,
+ },
+ {
+ id: ids.fields,
+ name: "fields",
+ view: "tree",
+ template:
+ "{common.icon()} {common.checkbox()} #value#",
+ select: false,
+ height: 200,
+ data: [],
+ on: {
+ onItemCheck: () => {
+ const fieldValues = $$(this.ids.fields).getChecked();
+ this.refreshValueFieldOptions(fieldValues);
+ this.onChange();
+ },
+ },
+ },
+ ],
+ },
+ {
+ id: ids.direction,
+ name: "direction",
+ view: "richselect",
+ label: L("Direction"),
+ labelWidth: uiConfig.labelWidthLarge,
+ options: [
+ { id: "t2b", value: L("Top to Bottom") },
+ { id: "b2t", value: L("Bottom to Top") },
+ { id: "l2r", value: L("Left to Right") },
+ { id: "r2l", value: L("Right to Left") },
+ ],
+ on: {
+ onChange: () => {
+ this.onChange();
+ },
+ },
+ },
+ {
+ id: ids.depth,
+ name: "depth",
+ hidden: true, // NOTE: use choose Connect Fields option
+ view: "counter",
+ label: L("Depth"),
+ labelWidth: uiConfig.labelWidthLarge,
+ value: 0,
+ on: {
+ onChange: () => {
+ this.onChange();
+ },
+ },
+ },
+ {
+ id: ids.color,
+ name: "color",
+ view: "colorpicker",
+ label: L("Color"),
+ labelWidth: uiConfig.labelWidthLarge,
+ on: {
+ onChange: () => {
+ this.onChange();
+ },
+ },
+ },
+ {
+ hidden: true, // NOTE: does not support
+ id: ids.pan,
+ name: "pan",
+ view: "checkbox",
+ label: L("Pan"),
+ labelWidth: uiConfig.labelWidthLarge,
+ value: 0,
+ on: {
+ onChange: () => {
+ this.onChange();
+ },
+ },
+ },
+ {
+ hidden: true, // NOTE: does not support
+ id: ids.zoom,
+ name: "zoom",
+ view: "checkbox",
+ label: L("Zoom"),
+ labelWidth: uiConfig.labelWidthLarge,
+ value: 0,
+ on: {
+ onChange: () => {
+ this.onChange();
+ },
+ },
+ },
+ {
+ id: ids.height,
+ view: "counter",
+ name: "height",
+ label: L("Height"),
+ labelWidth: uiConfig.labelWidthLarge,
+ on: {
+ onChange: () => {
+ this.onChange();
+ },
+ },
+ },
+ {
+ hidden: true, // NOTE: does not support
+ view: "fieldset",
+ label: L("Export"),
+ body: {
+ view: "layout",
+ borderless: true,
+ rows: [
+ {
+ id: ids.export,
+ name: "export",
+ view: "checkbox",
+ label: L("Is Exportable"),
+ labelWidth: uiConfig.labelWidthLarge,
+ value: 0,
+ on: {
+ onChange: () => {
+ this.onChange();
+ },
+ },
+ },
+ {
+ id: ids.exportFilename,
+ view: "text",
+ name: "exportFilename",
+ label: L("File name"),
+ placeholder: L("Enter file name"),
+ labelWidth: uiConfig.labelWidthLarge,
+ },
+ ],
+ },
+ },
+ ]);
+ }
+
+ async init(AB) {
+ this.AB = AB;
+
+ await super.init(AB);
+
+ webix.extend($$(this.ids.component), webix.ProgressBar);
+ }
+
+ populate(view) {
+ super.populate(view);
+
+ const ids = this.ids;
+ const $component = $$(ids.component);
+ const defaultValues = this.defaultValues();
+ const values = Object.assign(
+ $component.getValues(),
+ Object.assign(defaultValues, view.settings)
+ );
+
+ const $fieldList = $$(ids.fields);
+ $fieldList.clearAll();
+
+ this.populateDatacollection(values.datacollectionId);
+ // this.populateDescriptionFieldOptions(values.columnDescription);
+
+ const fieldValues = (view.settings?.fields ?? "").split(",");
+ this.refreshValueFieldOptions(fieldValues);
+
+ $component.setValues(values);
+ }
+
+ populateDatacollection(datacollectionId) {
+ const $dataCollection = $$(this.ids.datacollectionID);
+
+ // Pull data collections to options
+ const dcOptions = this.CurrentView.application
+ .datacollectionsIncluded()
+ .map((d) => {
+ return { id: d.id, value: d.label };
+ });
+ $dataCollection.define("options", dcOptions);
+ $dataCollection.define("value", datacollectionId);
+ $dataCollection.refresh();
+ }
+
+ refreshValueFieldOptions(fieldValues = []) {
+ const ids = this.ids;
+ const view = this.CurrentView;
+ const $fieldList = $$(ids.fields);
+
+ $fieldList.clearAll();
+
+ // Populate 1:M fields option of the root object
+ this.populateSubValueFieldOptions(view.datacollection?.datasource);
+
+ // Populate sub 1:M fields option of each fields
+ fieldValues.forEach((fId) => {
+ if (!fId) return;
+
+ const $fieldItem = $fieldList.getItem(fId);
+ if ($fieldItem) {
+ const abField = $fieldItem.field;
+ this.populateSubValueFieldOptions(abField.datasourceLink, fId);
+ }
+ });
+
+ // Set check items
+ $fieldList.blockEvent();
+ fieldValues.forEach((fId) => {
+ if ($fieldList.exists(fId)) $fieldList.checkItem(fId);
+ });
+ $fieldList.unblockEvent();
+ }
+
+ populateSubValueFieldOptions(object, parentFieldId) {
+ const view = this.CurrentView;
+ const $fields = $$(this.ids.fields);
+
+ view.getValueFields(object).forEach((f, index) => {
+ if ($fields.exists(f.id)) return;
+ $fields.add(
+ {
+ id: f.id,
+ value: f.label,
+ field: f,
+ },
+ index,
+ parentFieldId
+ );
+ });
+
+ $fields.openAll();
+ }
+
+ // populateDescriptionFieldOptions(fieldId) {
+ // const valueField = this.CurrentView.valueField();
+ // const $columnDescription = $$(this.ids.columnDescription);
+
+ // const connectFieldOpts =
+ // valueField?.datasourceLink
+ // ?.fields?.((f) => f.key != "connectObject")
+ // .map?.((f) => {
+ // return {
+ // id: f.id,
+ // value: f.label,
+ // };
+ // }) ?? [];
+ // $columnDescription.define("options", connectFieldOpts);
+ // $columnDescription.define("value", fieldId);
+ // $columnDescription.refresh();
+ // }
+
+ defaultValues() {
+ const ViewClass = this.ViewClass();
+
+ let values = null;
+
+ if (ViewClass) {
+ values = ViewClass.defaultValues();
+ }
+
+ return values;
+ }
+
+ /**
+ * @method values
+ * return the values for this form.
+ * @return {obj}
+ */
+ values() {
+ const values = super.values();
+ const ids = this.ids;
+ const $component = $$(ids.component);
+
+ values.settings = Object.assign(
+ $component.getValues(),
+ values.settings
+ );
+
+ // Retrive the values of your properties from Webix and store them in the view
+ values.settings.fields = $$(ids.fields).getChecked().join(",");
+
+ return values;
+ }
+
+ /**
+ * @method FieldClass()
+ * A method to return the proper ABViewXXX Definition.
+ * NOTE: Must be overwritten by the Child Class
+ */
+ ViewClass() {
+ return super._ViewClass("orgchart");
+ }
+ }
+
+ return ABViewOrgChartTeamsProperty;
+}
From 1e4f0e26e3989c2033e173e47e91c6b80b384d92 Mon Sep 17 00:00:00 2001
From: nh758 <7259@pm.me>
Date: Tue, 10 Sep 2024 11:10:27 +0700
Subject: [PATCH 02/16] add options for node name and top node selection
---
.../properties/views/ABViewOrgChartTeams.js | 131 +++++++++++-------
1 file changed, 78 insertions(+), 53 deletions(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index 891acda6..8f682101 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -16,6 +16,9 @@ export default function (AB) {
constructor() {
super(BASE_ID, {
datacollectionID: "",
+ teamLink: "",
+ teamName: "",
+ topTeam: "",
fields: "",
direction: "",
depth: "",
@@ -42,44 +45,47 @@ export default function (AB) {
id: ids.datacollectionID,
name: "datacollectionID",
view: "richselect",
- label: L("Data Collection"),
+ label: L("Team Data"),
labelWidth: uiConfig.labelWidthLarge,
options: [],
on: {
onChange: (value) => {
this.CurrentView.settings.datacollectionID = value;
- this.populateSubValueFieldOptions(
- this.CurrentView?.datacollection?.datasource
- );
+ const obj = this.CurrentView?.datacollection?.datasource;
+ this.populateTeamFieldOptions(obj);
this.onChange();
},
},
},
{
- cols: [
- {
- view: "label",
- label: "Fields",
- width: uiConfig.labelWidthLarge,
- },
- {
- id: ids.fields,
- name: "fields",
- view: "tree",
- template:
- "{common.icon()} {common.checkbox()} #value#",
- select: false,
- height: 200,
- data: [],
- on: {
- onItemCheck: () => {
- const fieldValues = $$(this.ids.fields).getChecked();
- this.refreshValueFieldOptions(fieldValues);
- this.onChange();
- },
- },
- },
- ],
+ id: ids.teamLink,
+ view: "richselect",
+ label: L("Team Link"),
+ labelWidth: uiConfig.labelWidthLarge,
+ options: [],
+ on: {
+ onChange: () => this.onChange(),
+ },
+ },
+ {
+ id: ids.teamName,
+ view: "richselect",
+ label: L("Team Name"),
+ labelWidth: uiConfig.labelWidthLarge,
+ options: [],
+ on: {
+ onChange: () => this.onChange(),
+ },
+ },
+ {
+ id: ids.topTeam,
+ view: "richselect",
+ label: L("Top Team"),
+ labelWidth: uiConfig.labelWidthLarge,
+ options: [],
+ on: {
+ onChange: () => this.onChange(),
+ },
},
{
id: ids.direction,
@@ -219,14 +225,16 @@ export default function (AB) {
Object.assign(defaultValues, view.settings)
);
- const $fieldList = $$(ids.fields);
- $fieldList.clearAll();
-
+ // const $fieldList = $$(ids.fields);
+ // $fieldList.clearAll();
this.populateDatacollection(values.datacollectionId);
- // this.populateDescriptionFieldOptions(values.columnDescription);
-
- const fieldValues = (view.settings?.fields ?? "").split(",");
- this.refreshValueFieldOptions(fieldValues);
+ const teamObj = this.CurrentView?.datacollection?.datasource;
+ if (teamObj) {
+ this.populateTeamFieldOptions(teamObj);
+ $$(this.ids.teamLink).setValue(values.teamLink);
+ $$(this.ids.teamName).setValue(values.teamName);
+ $$(this.ids.topTeam).setValue(values.topTeam);
+ }
$component.setValues(values);
}
@@ -274,24 +282,40 @@ export default function (AB) {
$fieldList.unblockEvent();
}
- populateSubValueFieldOptions(object, parentFieldId) {
+ populateTeamFieldOptions(object) {
const view = this.CurrentView;
- const $fields = $$(this.ids.fields);
+ const linkFields = view.getValueFields(object).map((f) => {
+ return {
+ id: f.id,
+ value: f.label,
+ field: f,
+ };
+ });
+ $$(this.ids.teamLink).define("options", linkFields);
- view.getValueFields(object).forEach((f, index) => {
- if ($fields.exists(f.id)) return;
- $fields.add(
- {
+ const textFields = object
+ ?.fields((f) => f.key === "string")
+ .map((f) => {
+ return {
id: f.id,
value: f.label,
field: f,
- },
- index,
- parentFieldId
- );
- });
+ };
+ });
+ $$(this.ids.teamName).define("options", textFields);
- $fields.openAll();
+ const booleanFields = object
+ ?.fields((f) => f.key === "boolean")
+ .map((f) => {
+ return {
+ id: f.id,
+ value: f.label,
+ field: f,
+ };
+ });
+ // Add an empty option as this is an optional setting.
+ booleanFields.unshift({ id: "", value: "", $empty: true });
+ $$(this.ids.topTeam).define("options", booleanFields);
}
// populateDescriptionFieldOptions(fieldId) {
@@ -332,15 +356,16 @@ export default function (AB) {
values() {
const values = super.values();
const ids = this.ids;
- const $component = $$(ids.component);
-
+ // values.settings = values.setttings ?? {};
values.settings = Object.assign(
- $component.getValues(),
+ $$(ids.component).getValues(),
values.settings
);
-
// Retrive the values of your properties from Webix and store them in the view
- values.settings.fields = $$(ids.fields).getChecked().join(",");
+ values.settings.teamLink = $$(ids.teamLink).getValue();
+ values.settings.teamName = $$(ids.teamName).getValue();
+ values.settings.topTeam = $$(ids.topTeam).getValue();
+ values.settings.dataCollectionId = $$(ids.datacollectionID).getValue();
return values;
}
@@ -351,7 +376,7 @@ export default function (AB) {
* NOTE: Must be overwritten by the Child Class
*/
ViewClass() {
- return super._ViewClass("orgchart");
+ return super._ViewClass("orgchart_teams");
}
}
From dc09c403025e93e86c7d502d6f2b85aaf96dce41 Mon Sep 17 00:00:00 2001
From: nh758 <7259@pm.me>
Date: Tue, 10 Sep 2024 12:46:21 +0700
Subject: [PATCH 03/16] add drag & drop setting
---
.../properties/views/ABViewOrgChartTeams.js | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index 8f682101..6e0c0bb9 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -22,6 +22,7 @@ export default function (AB) {
fields: "",
direction: "",
depth: "",
+ draggable: "",
color: "",
pan: "",
zoom: "",
@@ -87,6 +88,19 @@ export default function (AB) {
onChange: () => this.onChange(),
},
},
+ {
+ id: ids.draggable,
+ name: "draggable",
+ view: "checkbox",
+ label: L("Drag & Drop"),
+ labelWidth: uiConfig.labelWidthLarge,
+ value: 0,
+ on: {
+ onChange: () => {
+ this.onChange();
+ },
+ },
+ },
{
id: ids.direction,
name: "direction",
From 91ee7389c410d7d3aa8de39bc1324f877b038227 Mon Sep 17 00:00:00 2001
From: nh758 <7259@pm.me>
Date: Thu, 3 Oct 2024 13:39:03 +0700
Subject: [PATCH 04/16] add setting fields for inactive, canInactivate
---
.../properties/views/ABViewOrgChartTeams.js | 76 ++++++++-----------
1 file changed, 32 insertions(+), 44 deletions(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index 6e0c0bb9..ff111fb9 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -16,6 +16,8 @@ export default function (AB) {
constructor() {
super(BASE_ID, {
datacollectionID: "",
+ teamInactive: "",
+ teamCanInactivate: "",
teamLink: "",
teamName: "",
topTeam: "",
@@ -64,9 +66,7 @@ export default function (AB) {
label: L("Team Link"),
labelWidth: uiConfig.labelWidthLarge,
options: [],
- on: {
- onChange: () => this.onChange(),
- },
+ on: { onChange: () => this.onChange() },
},
{
id: ids.teamName,
@@ -74,9 +74,7 @@ export default function (AB) {
label: L("Team Name"),
labelWidth: uiConfig.labelWidthLarge,
options: [],
- on: {
- onChange: () => this.onChange(),
- },
+ on: { onChange: () => this.onChange() },
},
{
id: ids.topTeam,
@@ -84,9 +82,23 @@ export default function (AB) {
label: L("Top Team"),
labelWidth: uiConfig.labelWidthLarge,
options: [],
- on: {
- onChange: () => this.onChange(),
- },
+ on: { onChange: () => this.onChange() },
+ },
+ {
+ id: ids.teamInactive,
+ view: "richselect",
+ label: L("Team Inactive"),
+ labelWidth: uiConfig.labelWidthLarge,
+ options: [],
+ on: { onChange: () => this.onChange() },
+ },
+ {
+ id: ids.teamCanInactivate,
+ view: "richselect",
+ label: L("Can Inactivate"),
+ labelWidth: uiConfig.labelWidthLarge,
+ options: [],
+ on: { onChange: () => this.onChange() },
},
{
id: ids.draggable,
@@ -95,11 +107,7 @@ export default function (AB) {
label: L("Drag & Drop"),
labelWidth: uiConfig.labelWidthLarge,
value: 0,
- on: {
- onChange: () => {
- this.onChange();
- },
- },
+ on: { onChange: () => this.onChange() },
},
{
id: ids.direction,
@@ -113,11 +121,7 @@ export default function (AB) {
{ id: "l2r", value: L("Left to Right") },
{ id: "r2l", value: L("Right to Left") },
],
- on: {
- onChange: () => {
- this.onChange();
- },
- },
+ on: { onChange: () => this.onChange() },
},
{
id: ids.depth,
@@ -127,11 +131,7 @@ export default function (AB) {
label: L("Depth"),
labelWidth: uiConfig.labelWidthLarge,
value: 0,
- on: {
- onChange: () => {
- this.onChange();
- },
- },
+ on: { onChange: () => this.onChange() },
},
{
id: ids.color,
@@ -139,11 +139,7 @@ export default function (AB) {
view: "colorpicker",
label: L("Color"),
labelWidth: uiConfig.labelWidthLarge,
- on: {
- onChange: () => {
- this.onChange();
- },
- },
+ on: { onChange: () => this.onChange() },
},
{
hidden: true, // NOTE: does not support
@@ -153,11 +149,7 @@ export default function (AB) {
label: L("Pan"),
labelWidth: uiConfig.labelWidthLarge,
value: 0,
- on: {
- onChange: () => {
- this.onChange();
- },
- },
+ on: { onChange: () => this.onChange() },
},
{
hidden: true, // NOTE: does not support
@@ -167,11 +159,7 @@ export default function (AB) {
label: L("Zoom"),
labelWidth: uiConfig.labelWidthLarge,
value: 0,
- on: {
- onChange: () => {
- this.onChange();
- },
- },
+ on: { onChange: () => this.onChange() },
},
{
id: ids.height,
@@ -179,11 +167,7 @@ export default function (AB) {
name: "height",
label: L("Height"),
labelWidth: uiConfig.labelWidthLarge,
- on: {
- onChange: () => {
- this.onChange();
- },
- },
+ on: { onChange: () => this.onChange() },
},
{
hidden: true, // NOTE: does not support
@@ -330,6 +314,8 @@ export default function (AB) {
// Add an empty option as this is an optional setting.
booleanFields.unshift({ id: "", value: "", $empty: true });
$$(this.ids.topTeam).define("options", booleanFields);
+ $$(this.ids.teamInactive).define("options", booleanFields);
+ $$(this.ids.teamCanInactivate).define("options", booleanFields);
}
// populateDescriptionFieldOptions(fieldId) {
@@ -379,6 +365,8 @@ export default function (AB) {
values.settings.teamLink = $$(ids.teamLink).getValue();
values.settings.teamName = $$(ids.teamName).getValue();
values.settings.topTeam = $$(ids.topTeam).getValue();
+ values.settings.teamInactive = $$(ids.teamInactive).getValue();
+ values.settings.teamCanInactivate = $$(ids.teamCanInactivate).getValue();
values.settings.dataCollectionId = $$(ids.datacollectionID).getValue();
return values;
From 1f0abaa6bf545fec1b2cb403823ffd70d3bd1942 Mon Sep 17 00:00:00 2001
From: Johnny
Date: Fri, 11 Oct 2024 15:42:33 -0500
Subject: [PATCH 05/16] [wip] initial Netsuite object definitions
---
.../Designer/ui_work_object_list_newObject.js | 13 +-
...object_list_newObject_api_read_response.js | 8 +-
.../ui_work_object_list_newObject_netsuite.js | 404 +++++++++++++++++
...ect_list_newObject_netsuite_connections.js | 409 +++++++++++++++++
...ect_list_newObject_netsuite_credentials.js | 317 +++++++++++++
...object_list_newObject_netsuite_dataTest.js | 390 ++++++++++++++++
...k_object_list_newObject_netsuite_fields.js | 419 ++++++++++++++++++
...k_object_list_newObject_netsuite_tables.js | 374 ++++++++++++++++
8 files changed, 2328 insertions(+), 6 deletions(-)
create mode 100644 src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js
create mode 100644 src/rootPages/Designer/ui_work_object_list_newObject_netsuite_connections.js
create mode 100644 src/rootPages/Designer/ui_work_object_list_newObject_netsuite_credentials.js
create mode 100644 src/rootPages/Designer/ui_work_object_list_newObject_netsuite_dataTest.js
create mode 100644 src/rootPages/Designer/ui_work_object_list_newObject_netsuite_fields.js
create mode 100644 src/rootPages/Designer/ui_work_object_list_newObject_netsuite_tables.js
diff --git a/src/rootPages/Designer/ui_work_object_list_newObject.js b/src/rootPages/Designer/ui_work_object_list_newObject.js
index 16a6cc11..94b870fa 100644
--- a/src/rootPages/Designer/ui_work_object_list_newObject.js
+++ b/src/rootPages/Designer/ui_work_object_list_newObject.js
@@ -22,6 +22,7 @@ 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);
@@ -42,6 +43,7 @@ export default function (AB) {
this.CsvTab = UICsvObject(AB);
this.ApiTab = UIApiObject(AB);
this.ImportTab = UIImportObject(AB);
+ this.NetsuiteTab = UINetsuiteObject(AB);
/*
this.ExternalTab = new ABImportExternal(AB);
*/
@@ -86,10 +88,11 @@ export default function (AB) {
view: "tabview",
id: this.ids.tab,
cells: [
- this.BlankTab.ui() /*, this.ImportTab.ui(), this.ExternalTab.ui() */,
+ this.BlankTab.ui() /* this.ExternalTab.ui() */,
this.CsvTab.ui(),
this.ApiTab.ui(),
this.ImportTab.ui(),
+ this.NetsuiteTab.ui(),
],
tabbar: {
on: {
@@ -129,7 +132,9 @@ export default function (AB) {
"BlankTab",
"CsvTab",
"ApiTab",
- "ImportTab" /*, "ExternalTab"*/,
+ "ImportTab",
+ "NetsuiteTab",
+ /*, "ExternalTab"*/
].forEach((k) => {
allInits.push(this[k].init(AB));
this[k].on("cancel", () => {
@@ -161,6 +166,7 @@ export default function (AB) {
this.CsvTab.applicationLoad(application);
this.ApiTab.applicationLoad(application);
this.ImportTab.applicationLoad(application);
+ this.NetsuiteTab.applicationLoad(application);
}
/**
@@ -285,6 +291,9 @@ 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);
+ break;
}
}
}
diff --git a/src/rootPages/Designer/ui_work_object_list_newObject_api_read_response.js b/src/rootPages/Designer/ui_work_object_list_newObject_api_read_response.js
index 2d0275d0..147f9e85 100644
--- a/src/rootPages/Designer/ui_work_object_list_newObject_api_read_response.js
+++ b/src/rootPages/Designer/ui_work_object_list_newObject_api_read_response.js
@@ -79,7 +79,7 @@ export default function (AB) {
label: L("Data Key"),
placeholder: "data.example",
bottomLabel: L(
- "* JSON key containing the relevant data from the resonse object. Can be left blank to use the root level data."
+ "* JSON key containing the relevant data from the response object. Can be left blank to use the root level data."
),
suggest: [],
on: {
@@ -261,12 +261,12 @@ export default function (AB) {
_addFieldItem(key, type) {
const uiItem = this._fieldItem(key, type);
- $$(this.ids.fields).addView(uiItem);
+ $$(this.ids.connections).addView(uiItem);
}
_clearFieldItems() {
- const $fields = $$(this.ids.fields);
- AB.Webix.ui([], $fields);
+ const $connections = $$(this.ids.connections);
+ AB.Webix.ui([], $connections);
}
_populateDataKeys() {
diff --git a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js
new file mode 100644
index 00000000..377a49b6
--- /dev/null
+++ b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js
@@ -0,0 +1,404 @@
+/*
+ * 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_Tables.loadTables();
+ this.UI_Tables.show();
+ });
+
+ this.UI_Credentials.on("notverified", () => {
+ this.UI_Tables.disable();
+ });
+
+ 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();
+
+ // allConnectFields = allFields.concat(this.UI_Connections.getValues());
+ /*
+ linkCol = linkObject.fieldNew({
+ // id: OP.Util.uuid(),
+
+ key: field.key,
+
+ columnName: linkColumnName,
+ label: this.CurrentObject.label,
+
+ settings: {
+ showIcon: field.settings.showIcon,
+
+ linkObject: field.object.id,
+ linkType: field.settings.linkViaType,
+ linkViaType: field.settings.linkType,
+ isCustomFK: field.settings.isCustomFK,
+ indexField: field.settings.indexField,
+ indexField2: field.settings.indexField2,
+ isSource: 0,
+ width: width,
+ },
+ });
+ */
+
+ // 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;
+
+ this.emit("save", object.toObj());
+
+ this.ready();
+ } catch (err) {
+ console.error(err);
+ }
+ }
+
+ /**
+ * @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
new file mode 100644
index 00000000..eb811400
--- /dev/null
+++ b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_connections.js
@@ -0,0 +1,409 @@
+/*
+ * 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.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: [],
+ },
+ },
+ ],
+ },
+
+ {
+ 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.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"];
+ return {
+ cols: [
+ {
+ rows: [
+ {
+ label: L("Field"),
+ view: "label",
+ },
+ {
+ placeholder: "Type",
+ options: this.connectionList.map((conn) => {
+ return {
+ id: conn.column,
+ value: conn.column,
+ };
+ }),
+ view: "select",
+ // value: type,
+ },
+ ],
+ },
+ {
+ rows: [
+ {
+ placeholder: "Existing Netsuite Object",
+ options: this.listNetsuiteObjects.map((nObj) => {
+ return {
+ id: nObj.id,
+ value: nObj.label,
+ };
+ }),
+ view: "select",
+ // value: type,
+ },
+ {
+ placeholder: "Link Column",
+ options: [],
+ view: "select",
+ // value: type,
+ },
+ {
+ placeholder: "Link Type",
+ options: linkTypes.map((l) => {
+ return {
+ id: l,
+ value: l,
+ };
+ }),
+ view: "select",
+ // value: type,
+ },
+ ],
+ },
+
+ {
+ icon: "wxi-trash",
+ view: "icon",
+ width: 38,
+ click: function () {
+ const $item = this.getParentView();
+ $$(self.ids.fields).removeView($item);
+ },
+ },
+ ],
+ };
+ }
+
+ _addConnection(key, type) {
+ const uiItem = this._fieldItem(key, type);
+ $$(this.ids.connections).addView(uiItem);
+ }
+
+ _clearFieldItems() {
+ const $connections = $$(this.ids.connections);
+ AB.Webix.ui([], $connections);
+ }
+
+ /**
+ * @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.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
new file mode 100644
index 00000000..e4fbf138
--- /dev/null
+++ b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_credentials.js
@@ -0,0 +1,317 @@
+/*
+ * 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
new file mode 100644
index 00000000..a258d31f
--- /dev/null
+++ b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_dataTest.js
@@ -0,0 +1,390 @@
+/*
+ * 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
new file mode 100644
index 00000000..08caf392
--- /dev/null
+++ b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_fields.js
@@ -0,0 +1,419 @@
+/*
+ * 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
new file mode 100644
index 00000000..f5481169
--- /dev/null
+++ b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_tables.js
@@ -0,0 +1,374 @@
+/*
+ * 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: 400,
+ 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);
+ }
+
+ _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();
+}
From e3540da4b24be1fc0c9bdedcc96bf2b4f4bc40d2 Mon Sep 17 00:00:00 2001
From: guyyoo
Date: Tue, 15 Oct 2024 15:05:13 +0700
Subject: [PATCH 06/16] Add node content and display
---
.../properties/views/ABViewOrgChartTeams.js | 411 +++++++++++++++++-
1 file changed, 388 insertions(+), 23 deletions(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index 6e0c0bb9..1e3398b9 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -29,18 +29,143 @@ export default function (AB) {
height: "",
export: "",
exportFilename: "",
+ groupByField: "",
+ contentField: "",
+ contentFieldFilter: "",
+ contentFieldFilterButton: "",
+ contentGroupByField: "",
+ contentDisplayedFields: "",
+ contentDisplayedFieldsAdd: "",
});
-
this.AB = AB;
+ const contentFieldFilter = (this.contentFieldFilter =
+ AB.filterComplexNew(this.ids.contentFieldFilter));
+ contentFieldFilter.on("save", () => {
+ if (
+ !contentFieldFilter.isConditionComplete(
+ contentFieldFilter.getValue()
+ )
+ )
+ contentFieldFilter.setValue({ glue: "and", rules: [] });
+ this.onChange();
+ });
}
static get key() {
return "orgchart_teams";
}
+ _uiContentDisplayedField(fieldID = "", obj, atDisplay) {
+ const self = this;
+ const ids = self.ids;
+ const datasource = this.CurrentView.datacollection.datasource;
+ const datasourceID = datasource.id;
+ const parentObj = datasource.fieldByID(
+ $$(ids.contentField).getValue()
+ ).datasourceLink;
+ const parentObjID = parentObj.id;
+ const objID = obj?.id || parentObjID;
+ const $contentDisplayedFields = $$(ids.contentDisplayedFields);
+ const filterFields = (f) => {
+ const linkedObjID = f.datasourceLink?.id;
+ return linkedObjID !== datasourceID && linkedObjID !== parentObjID;
+ };
+ const mapFields = (f) => ({
+ id: f.id,
+ value: f.label,
+ field: f,
+ });
+ const getOnSelectChangeFn =
+ (currentObj, currentAtDisplay) => (newValue) => {
+ const field = currentObj.fieldByID(newValue);
+ if (field.key === "connectObject") {
+ $contentDisplayedFields.addView(
+ this._uiContentDisplayedField(
+ "",
+ field.datasourceLink,
+ currentAtDisplay
+ )
+ );
+ }
+ this.populateContentDisplayedFields(
+ $contentDisplayedFields.getValues()
+ );
+ this.onChange();
+ };
+ if (objID === parentObjID) {
+ const rootAtDisplay = Object.keys(
+ $contentDisplayedFields.elements
+ ).filter((key) => key.includes(objID)).length;
+ return {
+ cols: [
+ {
+ view: "richselect",
+ name: `${rootAtDisplay}.${parentObjID}`,
+ label: `${L("Display")} ${rootAtDisplay + 1}`,
+ labelWidth: uiConfig.labelWidthMedium,
+ options:
+ parentObj.fields(filterFields).map(mapFields) || [],
+ value: fieldID,
+ on: {
+ onChange: getOnSelectChangeFn(parentObj, rootAtDisplay),
+ },
+ },
+ {
+ view: "button",
+ css: "webix_danger",
+ type: "icon",
+ icon: "wxi-close",
+ width: uiConfig.buttonWidthExtraSmall,
+ click() {
+ self.deleteContentDisplayedField(
+ this.getParentView().getChildViews()[0].config.id
+ );
+ self.onChange();
+ },
+ },
+ ],
+ };
+ }
+ return {
+ cols: [
+ {
+ view: "richselect",
+ name: `${atDisplay}.${objID}`,
+ label: "->",
+ labelWidth: uiConfig.labelWidthMedium,
+ options: obj.fields(filterFields).map(mapFields) || [],
+ value: fieldID,
+ on: {
+ onChange: getOnSelectChangeFn(obj, atDisplay),
+ },
+ },
+ {
+ view: "button",
+ css: "webix_danger",
+ type: "icon",
+ icon: "wxi-close",
+ width: uiConfig.buttonWidthExtraSmall,
+ click() {
+ self.deleteContentDisplayedField(
+ this.getParentView().getChildViews()[0].config.id
+ );
+ self.onChange();
+ },
+ },
+ ],
+ };
+ }
+
ui() {
const ids = this.ids;
-
+ const contentFieldFilter = this.contentFieldFilter;
+ contentFieldFilter.myPopup = webix.ui({
+ view: "popup",
+ height: 240,
+ width: 480,
+ hidden: true,
+ body: contentFieldFilter.ui,
+ });
return super.ui([
{
id: ids.datacollectionID,
@@ -88,6 +213,139 @@ export default function (AB) {
onChange: () => this.onChange(),
},
},
+ {
+ cols: [
+ {
+ view: "label",
+ label: L("Content Field"),
+ width: uiConfig.labelWidthLarge,
+ },
+ {
+ id: ids.contentField,
+ name: "contentField",
+ view: "richselect",
+ options: [],
+ on: {
+ onChange: (newValue) => {
+ const $contentDisplayedFieldsAdd = $$(
+ ids.contentDisplayedFieldsAdd
+ );
+ const $contentFieldFilterButton = $$(
+ ids.contentFieldFilterButton
+ );
+ const $contentGroupByField = $$(
+ ids.contentGroupByField
+ );
+ contentFieldFilter.init();
+ contentFieldFilter.setValue({
+ glue: "and",
+ rules: [],
+ });
+ if (newValue != null && newValue !== "") {
+ const contentObj =
+ this.CurrentView.datacollection.datasource.fieldByID(
+ newValue
+ ).datasourceLink;
+ contentFieldFilter.fieldsLoad(
+ contentObj.fields()
+ );
+ $contentGroupByField.setValue("");
+ $contentGroupByField.define("options", [
+ { id: "", value: "", $empty: true },
+ ...contentObj
+ .fields(
+ (f) =>
+ f.key === "list" &&
+ f.settings.isMultiple === 0
+ )
+ .map((f) => ({
+ id: f.id,
+ value: f.label,
+ field: f,
+ })),
+ ]);
+ $contentFieldFilterButton.enable();
+ $contentDisplayedFieldsAdd.show();
+ $contentGroupByField.show();
+ } else {
+ contentFieldFilter.fieldsLoad([]);
+ $contentGroupByField.setValue("");
+ $contentGroupByField.define("options", []);
+ $contentFieldFilterButton.disable();
+ $contentDisplayedFieldsAdd.hide();
+ $contentGroupByField.hide();
+ }
+ this.populateContentDisplayedFields({});
+ this.onChange();
+ },
+ },
+ },
+ {
+ id: ids.contentFieldFilterButton,
+ view: "button",
+ type: "icon",
+ icon: "fa fa-filter",
+ css: "webix_primary",
+ disabled: true,
+ width: uiConfig.buttonWidthExtraSmall,
+ click() {
+ contentFieldFilter.popUp(this.$view, null, {
+ pos: "top",
+ });
+ },
+ },
+ ],
+ },
+ {
+ id: ids.contentGroupByField,
+ hidden: true,
+ view: "richselect",
+ label: L("Content Group By Field"),
+ labelWidth: uiConfig.labelWidthLarge,
+ options: [],
+ on: {
+ onChange: (newValue) => {
+ this.onChange();
+ },
+ },
+ },
+ {
+ id: ids.contentDisplayedFieldsAdd,
+ hidden: true,
+ cols: [
+ {
+ view: "label",
+ label: L("Content Displayed Fields"),
+ },
+ {
+ view: "button",
+ type: "icon",
+ icon: "fa fa-plus",
+ css: "webix_primary",
+ width: uiConfig.buttonWidthExtraSmall,
+ click: () => {
+ const $contentDisplayedFields = $$(
+ ids.contentDisplayedFields
+ );
+ if (!$contentDisplayedFields.isVisible())
+ $contentDisplayedFields.show();
+ const values = $contentDisplayedFields.getValues();
+ for (const key in values) {
+ }
+ Object.keys($contentDisplayedFields.elements);
+ $contentDisplayedFields.addView(
+ this._uiContentDisplayedField()
+ );
+ },
+ },
+ ],
+ },
+ {
+ id: ids.contentDisplayedFields,
+ view: "form",
+ hidden: true,
+ elements: [],
+ },
{
id: ids.draggable,
name: "draggable",
@@ -222,15 +480,44 @@ export default function (AB) {
async init(AB) {
this.AB = AB;
-
await super.init(AB);
-
webix.extend($$(this.ids.component), webix.ProgressBar);
+ this.contentFieldFilter.queriesLoad(
+ this.CurrentApplication?.queriesIncluded()
+ );
+ }
+
+ deleteContentDisplayedField(id) {
+ const ids = this.ids;
+ const $contentDisplayedFields = $$(ids.contentDisplayedFields);
+ const $elements = $contentDisplayedFields.elements;
+ const $richselect = $$(id);
+ const deletedElementKey = $richselect.config.name;
+ if (
+ deletedElementKey.includes(
+ this.CurrentView.datacollection.datasource.fieldByID(
+ $$(ids.contentField).getValue()
+ ).datasourceLink.id
+ )
+ ) {
+ const deletedAtDisplay = deletedElementKey.split(".")[0];
+ for (const key in $elements) {
+ if (!key.includes(`${deletedAtDisplay}.`)) continue;
+ $contentDisplayedFields.removeView(
+ $elements[key].getParentView().config.id
+ );
+ }
+ } else
+ $contentDisplayedFields.removeView(
+ $richselect.getParentView().config.id
+ );
+ this.populateContentDisplayedFields(
+ $contentDisplayedFields.getValues()
+ );
}
populate(view) {
super.populate(view);
-
const ids = this.ids;
const $component = $$(ids.component);
const defaultValues = this.defaultValues();
@@ -238,18 +525,22 @@ export default function (AB) {
$component.getValues(),
Object.assign(defaultValues, view.settings)
);
-
// const $fieldList = $$(ids.fields);
// $fieldList.clearAll();
this.populateDatacollection(values.datacollectionId);
const teamObj = this.CurrentView?.datacollection?.datasource;
if (teamObj) {
this.populateTeamFieldOptions(teamObj);
- $$(this.ids.teamLink).setValue(values.teamLink);
- $$(this.ids.teamName).setValue(values.teamName);
- $$(this.ids.topTeam).setValue(values.topTeam);
+ $$(ids.teamLink).setValue(values.teamLink);
+ $$(ids.teamName).setValue(values.teamName);
+ $$(ids.topTeam).setValue(values.topTeam);
+ $$(ids.contentField).setValue(values.contentField);
+ $$(ids.contentGroupByField).setValue(values.contentGroupByField);
+ this.contentFieldFilter.setValue(
+ JSON.parse(values.contentFieldFilter)
+ );
+ this.populateContentDisplayedFields(values.contentDisplayedFields);
}
-
$component.setValues(values);
}
@@ -305,8 +596,8 @@ export default function (AB) {
field: f,
};
});
- $$(this.ids.teamLink).define("options", linkFields);
-
+ const ids = this.ids;
+ $$(ids.teamLink).define("options", linkFields);
const textFields = object
?.fields((f) => f.key === "string")
.map((f) => {
@@ -316,8 +607,7 @@ export default function (AB) {
field: f,
};
});
- $$(this.ids.teamName).define("options", textFields);
-
+ $$(ids.teamName).define("options", textFields);
const booleanFields = object
?.fields((f) => f.key === "boolean")
.map((f) => {
@@ -327,9 +617,78 @@ export default function (AB) {
field: f,
};
});
+
// Add an empty option as this is an optional setting.
booleanFields.unshift({ id: "", value: "", $empty: true });
- $$(this.ids.topTeam).define("options", booleanFields);
+ $$(ids.topTeam).define("options", booleanFields);
+ $$(ids.contentField).define("options", [
+ { id: "", value: "", $empty: true },
+ ...linkFields,
+ ]);
+ }
+
+ populateContentDisplayedFields(values) {
+ const ids = this.ids;
+ const $contentDisplayedFields = $$(ids.contentDisplayedFields);
+ const elements = $contentDisplayedFields.elements;
+ for (const key in elements)
+ $contentDisplayedFields.removeView(
+ elements[key].getParentView().config.id
+ );
+ const keys = Object.keys(values);
+ if (keys.length === 0) {
+ $contentDisplayedFields.hide();
+ return;
+ }
+ const obj = this.CurrentView.datacollection.datasource.fieldByID(
+ $$(ids.contentField).getValue()
+ ).datasourceLink;
+ const objID = obj.id;
+ const parentKeys = [];
+ const childKeys = [];
+ while (keys.length > 0) {
+ const key = keys.pop();
+ (key.includes(objID) && parentKeys.push(key)) ||
+ childKeys.push(key);
+ }
+ while (parentKeys.length > 0) {
+ const parentKey = parentKeys.pop();
+ const parentFieldID = values[parentKey] ?? "";
+ $contentDisplayedFields.addView(
+ this._uiContentDisplayedField(parentFieldID)
+ );
+ if (
+ parentFieldID === "" ||
+ obj.fieldByID(parentFieldID).key !== "connectObject"
+ )
+ continue;
+ const currentAtDisplay =
+ Object.keys($contentDisplayedFields.getValues()).filter(
+ (currentKey) => currentKey.includes(objID)
+ ).length - 1;
+ while (
+ childKeys.findIndex((childKey) =>
+ childKey.includes(`${parentKey.split(".")[0]}.`)
+ ) > -1
+ ) {
+ const childKey = childKeys.pop();
+ const childObj = this.AB.objectByID(childKey.split(".")[1]);
+ const childFieldID = values[childKey] ?? "";
+ $contentDisplayedFields.addView(
+ this._uiContentDisplayedField(
+ childFieldID,
+ childObj,
+ currentAtDisplay
+ )
+ );
+ if (
+ childFieldID === "" ||
+ childObj.fieldByID(childFieldID).key !== "connectObject"
+ )
+ break;
+ }
+ }
+ $contentDisplayedFields.show();
}
// populateDescriptionFieldOptions(fieldId) {
@@ -370,17 +729,23 @@ export default function (AB) {
values() {
const values = super.values();
const ids = this.ids;
- // values.settings = values.setttings ?? {};
- values.settings = Object.assign(
+ const settings = (values.settings = Object.assign(
$$(ids.component).getValues(),
values.settings
- );
+ ));
// Retrive the values of your properties from Webix and store them in the view
- values.settings.teamLink = $$(ids.teamLink).getValue();
- values.settings.teamName = $$(ids.teamName).getValue();
- values.settings.topTeam = $$(ids.topTeam).getValue();
- values.settings.dataCollectionId = $$(ids.datacollectionID).getValue();
-
+ settings.teamLink = $$(ids.teamLink).getValue();
+ settings.teamName = $$(ids.teamName).getValue();
+ settings.topTeam = $$(ids.topTeam).getValue();
+ settings.dataCollectionId = $$(ids.datacollectionID).getValue();
+ settings.contentField = $$(ids.contentField).getValue();
+ settings.contentGroupByField = $$(ids.contentGroupByField).getValue();
+ settings.contentFieldFilter = JSON.stringify(
+ this.contentFieldFilter.getValue()
+ );
+ settings.contentDisplayedFields = $$(
+ ids.contentDisplayedFields
+ ).getValues();
return values;
}
From 976c20833786d2693703c58e390c4d08f6528305 Mon Sep 17 00:00:00 2001
From: guyyoo
Date: Thu, 17 Oct 2024 11:56:09 +0700
Subject: [PATCH 07/16] Merge nh branch
---
.../properties/views/ABViewOrgChartTeams.js | 78 ++++++++-----------
1 file changed, 34 insertions(+), 44 deletions(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index 1e3398b9..15ec8488 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -16,6 +16,8 @@ export default function (AB) {
constructor() {
super(BASE_ID, {
datacollectionID: "",
+ teamInactive: "",
+ teamCanInactivate: "",
teamLink: "",
teamName: "",
topTeam: "",
@@ -189,9 +191,7 @@ export default function (AB) {
label: L("Team Link"),
labelWidth: uiConfig.labelWidthLarge,
options: [],
- on: {
- onChange: () => this.onChange(),
- },
+ on: { onChange: () => this.onChange() },
},
{
id: ids.teamName,
@@ -199,9 +199,7 @@ export default function (AB) {
label: L("Team Name"),
labelWidth: uiConfig.labelWidthLarge,
options: [],
- on: {
- onChange: () => this.onChange(),
- },
+ on: { onChange: () => this.onChange() },
},
{
id: ids.topTeam,
@@ -209,9 +207,23 @@ export default function (AB) {
label: L("Top Team"),
labelWidth: uiConfig.labelWidthLarge,
options: [],
- on: {
- onChange: () => this.onChange(),
- },
+ on: { onChange: () => this.onChange() },
+ },
+ {
+ id: ids.teamInactive,
+ view: "richselect",
+ label: L("Team Inactive"),
+ labelWidth: uiConfig.labelWidthLarge,
+ options: [],
+ on: { onChange: () => this.onChange() },
+ },
+ {
+ id: ids.teamCanInactivate,
+ view: "richselect",
+ label: L("Can Inactivate"),
+ labelWidth: uiConfig.labelWidthLarge,
+ options: [],
+ on: { onChange: () => this.onChange() },
},
{
cols: [
@@ -353,11 +365,7 @@ export default function (AB) {
label: L("Drag & Drop"),
labelWidth: uiConfig.labelWidthLarge,
value: 0,
- on: {
- onChange: () => {
- this.onChange();
- },
- },
+ on: { onChange: () => this.onChange() },
},
{
id: ids.direction,
@@ -371,11 +379,7 @@ export default function (AB) {
{ id: "l2r", value: L("Left to Right") },
{ id: "r2l", value: L("Right to Left") },
],
- on: {
- onChange: () => {
- this.onChange();
- },
- },
+ on: { onChange: () => this.onChange() },
},
{
id: ids.depth,
@@ -385,11 +389,7 @@ export default function (AB) {
label: L("Depth"),
labelWidth: uiConfig.labelWidthLarge,
value: 0,
- on: {
- onChange: () => {
- this.onChange();
- },
- },
+ on: { onChange: () => this.onChange() },
},
{
id: ids.color,
@@ -397,11 +397,7 @@ export default function (AB) {
view: "colorpicker",
label: L("Color"),
labelWidth: uiConfig.labelWidthLarge,
- on: {
- onChange: () => {
- this.onChange();
- },
- },
+ on: { onChange: () => this.onChange() },
},
{
hidden: true, // NOTE: does not support
@@ -411,11 +407,7 @@ export default function (AB) {
label: L("Pan"),
labelWidth: uiConfig.labelWidthLarge,
value: 0,
- on: {
- onChange: () => {
- this.onChange();
- },
- },
+ on: { onChange: () => this.onChange() },
},
{
hidden: true, // NOTE: does not support
@@ -425,11 +417,7 @@ export default function (AB) {
label: L("Zoom"),
labelWidth: uiConfig.labelWidthLarge,
value: 0,
- on: {
- onChange: () => {
- this.onChange();
- },
- },
+ on: { onChange: () => this.onChange() },
},
{
id: ids.height,
@@ -437,11 +425,7 @@ export default function (AB) {
name: "height",
label: L("Height"),
labelWidth: uiConfig.labelWidthLarge,
- on: {
- onChange: () => {
- this.onChange();
- },
- },
+ on: { onChange: () => this.onChange() },
},
{
hidden: true, // NOTE: does not support
@@ -533,6 +517,8 @@ export default function (AB) {
this.populateTeamFieldOptions(teamObj);
$$(ids.teamLink).setValue(values.teamLink);
$$(ids.teamName).setValue(values.teamName);
+ $$(ids.teamInactive).setValue(values.teamInactive);
+ $$(ids.teamCanInactivate).setValue(values.teamCanInactivate);
$$(ids.topTeam).setValue(values.topTeam);
$$(ids.contentField).setValue(values.contentField);
$$(ids.contentGroupByField).setValue(values.contentGroupByField);
@@ -621,6 +607,8 @@ export default function (AB) {
// Add an empty option as this is an optional setting.
booleanFields.unshift({ id: "", value: "", $empty: true });
$$(ids.topTeam).define("options", booleanFields);
+ $$(ids.teamInactive).define("options", booleanFields);
+ $$(ids.teamCanInactivate).define("options", booleanFields);
$$(ids.contentField).define("options", [
{ id: "", value: "", $empty: true },
...linkFields,
@@ -737,6 +725,8 @@ export default function (AB) {
settings.teamLink = $$(ids.teamLink).getValue();
settings.teamName = $$(ids.teamName).getValue();
settings.topTeam = $$(ids.topTeam).getValue();
+ settings.teamInactive = $$(ids.teamInactive).getValue();
+ settings.teamCanInactivate = $$(ids.teamCanInactivate).getValue();
settings.dataCollectionId = $$(ids.datacollectionID).getValue();
settings.contentField = $$(ids.contentField).getValue();
settings.contentGroupByField = $$(ids.contentGroupByField).getValue();
From 6b338d44a97b0f7eb28e43341946311895b0c39e Mon Sep 17 00:00:00 2001
From: Johnny
Date: Thu, 17 Oct 2024 22:10:15 -0500
Subject: [PATCH 08/16] [wip] initial connection declarations
---
.../ui_work_object_list_newObject_netsuite.js | 101 ++++++---
...ect_list_newObject_netsuite_connections.js | 195 ++++++++++++------
...work_object_workspace_popupNewDataField.js | 4 +-
3 files changed, 208 insertions(+), 92 deletions(-)
diff --git a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js
index 377a49b6..70822ea3 100644
--- a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js
+++ b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js
@@ -135,7 +135,7 @@ export default function (AB) {
this.UI_Tables.setCredentials(creds);
this.UI_Fields.setCredentials(creds);
this.UI_FieldTest.setCredentials(creds);
- // this.UI_Tables.loadTables();
+ this.UI_Connections.setCredentials(creds);
this.UI_Tables.show();
});
@@ -294,31 +294,6 @@ export default function (AB) {
let allFields = this.UI_Fields.getValues();
- // allConnectFields = allFields.concat(this.UI_Connections.getValues());
- /*
- linkCol = linkObject.fieldNew({
- // id: OP.Util.uuid(),
-
- key: field.key,
-
- columnName: linkColumnName,
- label: this.CurrentObject.label,
-
- settings: {
- showIcon: field.settings.showIcon,
-
- linkObject: field.object.id,
- linkType: field.settings.linkViaType,
- linkViaType: field.settings.linkType,
- isCustomFK: field.settings.isCustomFK,
- indexField: field.settings.indexField,
- indexField2: field.settings.indexField2,
- isSource: 0,
- width: width,
- },
- });
- */
-
// Pick out our special columns: pk, created_at, updated_at
let pkField = allFields.find((f) => f.pk);
if (!pkField) {
@@ -366,13 +341,79 @@ export default function (AB) {
// values.fieldIDs.push(field.id);
}
// values.id = object.id;
-
- this.emit("save", object.toObj());
-
- this.ready();
} 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 colName = "";
+ if (f.thisField != "_this_object_") {
+ colName = f.thisField;
+ } else if (f.thatObjectField != "_that_object_") {
+ colName = f.thatObjectField;
+ }
+
+ 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;
+
+ // 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();
}
/**
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
index eb811400..22eb68fd 100644
--- a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_connections.js
+++ b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_connections.js
@@ -18,7 +18,7 @@ export default function (AB) {
form: "",
- fieldSelector: "",
+ // fieldSelector: "",
connections: "",
displayConnections: "",
displayNoConnections: "",
@@ -193,9 +193,11 @@ export default function (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);
+
+ // 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();
@@ -243,69 +245,130 @@ export default function (AB) {
const fieldKeys = ["string", "LongText", "number", "date", "boolean"];
const linkTypes = ["one:one", "one:many", "many:one", "many:many"];
+
+ // 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,
+ };
+ });
+ // we also need to include "_this_object_" reference so that
+ // we can make many:xxx connections (we don't store the value, the
+ // other object does)
+ fieldOptions.unshift({
+ id: "_this_object_",
+ value: L("This Object"),
+ });
+
return {
- cols: [
+ view: "form",
+ elements: [
{
- rows: [
+ cols: [
{
- label: L("Field"),
- view: "label",
+ rows: [
+ {
+ label: L("Field"),
+ view: "label",
+ },
+ {
+ placeholder: "Type",
+ options: fieldOptions,
+ view: "select",
+ // value: type,
+ name: "thisField",
+ },
+ ],
},
{
- placeholder: "Type",
- options: this.connectionList.map((conn) => {
- return {
- id: conn.column,
- value: conn.column,
- };
- }),
- view: "select",
- // value: type,
- },
- ],
- },
- {
- rows: [
- {
- placeholder: "Existing Netsuite Object",
- options: this.listNetsuiteObjects.map((nObj) => {
- return {
- id: nObj.id,
- value: nObj.label,
- };
- }),
- view: "select",
- // value: type,
- },
- {
- placeholder: "Link Column",
- options: [],
- view: "select",
- // value: type,
+ rows: [
+ {
+ placeholder: L("Existing Netsuite Object"),
+ options: this.listNetsuiteObjects.map((nObj) => {
+ return {
+ id: nObj.id,
+ value: nObj.label,
+ };
+ }),
+ view: "select",
+ name: "thatObject",
+ // 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"),
+ });
+ let $linkColumn =
+ this.getParentView().getChildViews()[1];
+
+ $linkColumn.define("options", options);
+ $linkColumn.refresh();
+ }
+ },
+ },
+ },
+ {
+ placeholder: "Link Column",
+ options: [],
+ view: "select",
+ // value: type,
+ name: "thatObjectField",
+ },
+ {
+ placeholder: "Link Type",
+ options: linkTypes.map((l) => {
+ return {
+ id: l,
+ value: l,
+ };
+ }),
+ view: "select",
+ name: "linkType",
+ // value: type,
+ },
+ ],
},
+
{
- placeholder: "Link Type",
- options: linkTypes.map((l) => {
- return {
- id: l,
- value: l,
- };
- }),
- view: "select",
- // value: type,
+ icon: "wxi-trash",
+ view: "icon",
+ width: 38,
+ click: function () {
+ const $item = this.getParentView().getParentView();
+ $$(self.ids.connections).removeView($item);
+ },
},
],
},
-
- {
- icon: "wxi-trash",
- view: "icon",
- width: 38,
- click: function () {
- const $item = this.getParentView();
- $$(self.ids.fields).removeView($item);
- },
- },
],
};
}
@@ -382,20 +445,30 @@ export default function (AB) {
busy() {
const $verifyButton = $$(this.ids.buttonVerify);
- this.$fieldSelector.showProgress({ type: "icon" });
+ // this.$fieldSelector.showProgress({ type: "icon" });
$verifyButton.disable();
}
ready() {
const $verifyButton = $$(this.ids.buttonVerify);
- this.$fieldSelector.hideProgress();
+ // this.$fieldSelector.hideProgress();
$verifyButton.enable();
}
- // setCredentials(creds) {
- // this.credentials = creds;
- // }
+ setCredentials(creds) {
+ this.credentials = creds;
+ }
+
+ getValues() {
+ let values = [];
+ $$(this.ids.connections)
+ .getChildViews()
+ .forEach(($row) => {
+ values.push($row.getValues());
+ });
+ return values;
+ }
// verify() {
// this.emit("fields.ready", {
diff --git a/src/rootPages/Designer/ui_work_object_workspace_popupNewDataField.js b/src/rootPages/Designer/ui_work_object_workspace_popupNewDataField.js
index 46a42248..15a8797e 100644
--- a/src/rootPages/Designer/ui_work_object_workspace_popupNewDataField.js
+++ b/src/rootPages/Designer/ui_work_object_workspace_popupNewDataField.js
@@ -420,7 +420,9 @@ export default function (AB, ibase) {
field.columnName === ""
) {
this.AB.Webix.message({
- text: "The column name can't contain special characters.",
+ text: L(
+ "The column name can't contain special characters."
+ ),
type: "error",
});
From aa0e664bb433588ecfe3796232cbea1e00e7d56b Mon Sep 17 00:00:00 2001
From: nh758 <7259@pm.me>
Date: Fri, 11 Oct 2024 10:27:44 +0700
Subject: [PATCH 09/16] add properties to color team node by strategy
---
.../properties/views/ABViewOrgChartTeams.js | 160 +++++++++++++++---
1 file changed, 134 insertions(+), 26 deletions(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index ff111fb9..7cd10e2a 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -16,10 +16,12 @@ export default function (AB) {
constructor() {
super(BASE_ID, {
datacollectionID: "",
+ strategyCode: "",
teamInactive: "",
teamCanInactivate: "",
teamLink: "",
teamName: "",
+ teamStrategy: "",
topTeam: "",
fields: "",
direction: "",
@@ -31,6 +33,8 @@ export default function (AB) {
height: "",
export: "",
exportFilename: "",
+ strategyColorPopup: "",
+ strategyColorForm: "",
});
this.AB = AB;
@@ -100,6 +104,42 @@ export default function (AB) {
options: [],
on: { onChange: () => this.onChange() },
},
+ {
+ id: ids.teamStrategy,
+ view: "richselect",
+ label: L("Strategy"),
+ labelWidth: uiConfig.labelWidthLarge,
+ options: [],
+ on: {
+ onChange: (value) => {
+ this.populateStrategyOptions(value);
+ this.onChange();
+ },
+ },
+ },
+ {
+ cols: [
+ {
+ id: ids.strategyCode,
+ view: "richselect",
+ label: L("Strategy Code"),
+ labelWidth: uiConfig.labelWidthLarge,
+ options: [],
+ on: {
+ onChange: () => {
+ this.onChange();
+ $$(this.ids.strategyColorPopup)?.close();
+ },
+ },
+ },
+ {
+ view: "icon",
+ icon: "fa fa-paint-brush",
+ allign: "right",
+ click: () => this.strategyColorPopup(),
+ },
+ ],
+ },
{
id: ids.draggable,
name: "draggable",
@@ -229,9 +269,18 @@ export default function (AB) {
const teamObj = this.CurrentView?.datacollection?.datasource;
if (teamObj) {
this.populateTeamFieldOptions(teamObj);
- $$(this.ids.teamLink).setValue(values.teamLink);
- $$(this.ids.teamName).setValue(values.teamName);
- $$(this.ids.topTeam).setValue(values.topTeam);
+ [
+ "teamCanInactivate",
+ "teamInactive",
+ "teamLink",
+ "teamName",
+ "teamStrategy",
+ "topTeam",
+ ].forEach((f) => $$(this.ids[f]).setValue(values[f]));
+ if (values.teamStrategy) {
+ this.populateStrategyOptions(values.teamStrategy);
+ $$(this.ids.strategyCode).setValue(values.strategyCode);
+ }
}
$component.setValues(values);
@@ -282,35 +331,25 @@ export default function (AB) {
populateTeamFieldOptions(object) {
const view = this.CurrentView;
- const linkFields = view.getValueFields(object).map((f) => {
- return {
- id: f.id,
- value: f.label,
- field: f,
- };
- });
- $$(this.ids.teamLink).define("options", linkFields);
+ const m2oFields = view.getValueFields(object).map(fieldToOption);
+ $$(this.ids.teamLink).define("options", m2oFields);
+ const o2mFields =
+ object.connectFields(
+ (f) => f.linkType() == "one" && f.linkViaType() == "many"
+ ) ?? [];
+ $$(this.ids.teamStrategy).define(
+ "options",
+ o2mFields.map(fieldToOption)
+ );
const textFields = object
?.fields((f) => f.key === "string")
- .map((f) => {
- return {
- id: f.id,
- value: f.label,
- field: f,
- };
- });
+ .map(fieldToOption);
$$(this.ids.teamName).define("options", textFields);
const booleanFields = object
?.fields((f) => f.key === "boolean")
- .map((f) => {
- return {
- id: f.id,
- value: f.label,
- field: f,
- };
- });
+ .map(fieldToOption);
// Add an empty option as this is an optional setting.
booleanFields.unshift({ id: "", value: "", $empty: true });
$$(this.ids.topTeam).define("options", booleanFields);
@@ -318,6 +357,61 @@ export default function (AB) {
$$(this.ids.teamCanInactivate).define("options", booleanFields);
}
+ populateStrategyOptions(fieldID) {
+ const strategyObj = this.AB.objectByID(
+ this.AB.definitionByID(fieldID).settings.linkObject
+ );
+ const listFields = strategyObj
+ .fields((f) => f.key === "list")
+ .map(fieldToOption);
+ $$(this.ids.strategyCode).define("options", listFields);
+ }
+
+ strategyColorPopup() {
+ const codeFieldID = $$(this.ids.strategyCode).getValue();
+ if (!codeFieldID) return;
+
+ let $popup = $$(this.ids.strategyColorPopup);
+
+ if (!$popup) {
+ const values = this.CurrentView.settings.strategyColors ?? {};
+ const strategyTypes = this.AB.definitionByID(
+ codeFieldID
+ ).settings.options.map((strategy) => {
+ return {
+ view: "colorpicker",
+ label: strategy.text,
+ name: strategy.id,
+ value: values[strategy.id] ?? "#111111",
+ };
+ });
+
+ $popup = this.AB.Webix.ui({
+ view: "window",
+ id: this.ids.strategyColorPopup,
+ close: true,
+ title: L("Set Colors"),
+ position: "center",
+ body: {
+ view: "form",
+ id: this.ids.strategyColorForm,
+ elements: [
+ ...strategyTypes,
+ {
+ view: "button",
+ label: L("Apply"),
+ click: () => {
+ this.onChange();
+ $$(this.ids.strategyColorPopup).hide();
+ },
+ },
+ ],
+ },
+ });
+ }
+ $popup.show();
+ }
+
// populateDescriptionFieldOptions(fieldId) {
// const valueField = this.CurrentView.valueField();
// const $columnDescription = $$(this.ids.columnDescription);
@@ -366,8 +460,14 @@ export default function (AB) {
values.settings.teamName = $$(ids.teamName).getValue();
values.settings.topTeam = $$(ids.topTeam).getValue();
values.settings.teamInactive = $$(ids.teamInactive).getValue();
- values.settings.teamCanInactivate = $$(ids.teamCanInactivate).getValue();
+ values.settings.teamCanInactivate = $$(
+ ids.teamCanInactivate
+ ).getValue();
+ values.settings.teamStrategy = $$(ids.teamStrategy).getValue();
+ values.settings.strategyCode = $$(ids.strategyCode).getValue();
values.settings.dataCollectionId = $$(ids.datacollectionID).getValue();
+ const $colorForm = $$(ids.strategyColorForm);
+ values.settings.strategyColors = $colorForm?.getValues() ?? {};
return values;
}
@@ -384,3 +484,11 @@ export default function (AB) {
return ABViewOrgChartTeamsProperty;
}
+
+function fieldToOption(f) {
+ return {
+ id: f.id,
+ value: f.label,
+ field: f,
+ };
+}
From 39e2a88eada7a78f8df84e242a6b420ec8ae4c17 Mon Sep 17 00:00:00 2001
From: Johnny
Date: Tue, 22 Oct 2024 03:00:20 -0500
Subject: [PATCH 10/16] [wip] modify existing Object workspace add connect
field to work with Netsuite objects.
---
.../properties/dataFields/ABFieldConnect.js | 107 +++++++++++++++++-
...work_object_workspace_popupNewDataField.js | 11 +-
2 files changed, 115 insertions(+), 3 deletions(-)
diff --git a/src/rootPages/Designer/properties/dataFields/ABFieldConnect.js b/src/rootPages/Designer/properties/dataFields/ABFieldConnect.js
index c6ac0f7d..c981e262 100644
--- a/src/rootPages/Designer/properties/dataFields/ABFieldConnect.js
+++ b/src/rootPages/Designer/properties/dataFields/ABFieldConnect.js
@@ -31,6 +31,12 @@ export default function (AB) {
indexField: "",
indexField2: "",
+ netsuite_one: "",
+ netsuiteOneLabel: "",
+ netsuiteOneColumn: "",
+
+ netsuite_many: "",
+
connectDataPopup: "",
});
}
@@ -237,6 +243,37 @@ export default function (AB) {
},
},
},
+ {
+ view: "layout",
+ id: ids.netsuite_one,
+ hidden: true,
+ cols: [
+ {
+ id: ids.netsuiteOneLabel,
+ view: "label",
+ label: L(" [Select object]'s field"),
+ width: 300,
+ },
+ {
+ id: ids.netsuiteOneColumn,
+ name: "netsuiteOneColumn",
+ disallowEdit: true,
+ view: "richselect",
+ // value: FC.defaultValues().linkViaType,
+ // width: 200,
+ fillspace: true,
+ options: [],
+ on: {
+ // onChange: (newV, oldV) => {
+ // this.selectLinkViaType(newV, oldV);
+ // },
+ onAfterRender: function () {
+ ABField.CYPRESS_REF(this);
+ },
+ },
+ },
+ ],
+ },
]);
}
@@ -295,6 +332,7 @@ export default function (AB) {
$fieldLink2.refresh();
this.updateCustomIndex();
+ this.checkNetsuiteObjects();
}
show() {
@@ -387,13 +425,19 @@ export default function (AB) {
const options = [];
// if an ABApplication is set then load in the related objects
const application = this.CurrentApplication;
+
+ // if this is a Netsuite Object, just gather other Netsuite Objs
+ let objFilter = () => true;
+ if (this.CurrentObject.isNetsuite) {
+ objFilter = (o) => o.isNetsuite;
+ }
if (application) {
- application.objectsIncluded().forEach((o) => {
+ application.objectsIncluded(objFilter).forEach((o) => {
options.push({ id: o.id, value: o.label });
});
} else {
// else load in all the ABObjects
- this.AB.objects().forEach((o) => {
+ this.AB.objects(objFilter).forEach((o) => {
options.push({ id: o.id, value: o.label });
});
}
@@ -449,6 +493,7 @@ export default function (AB) {
$field.refresh();
this.updateCustomIndex();
+ this.checkNetsuiteObjects();
}
selectObjectTo(newValue, oldValue) {
@@ -474,6 +519,8 @@ export default function (AB) {
$$(ids.link2).show();
this.updateCustomIndex();
+
+ this.checkNetsuiteObjects();
}
updateCustomIndex() {
@@ -578,6 +625,62 @@ export default function (AB) {
this.checkCustomFK();
}
+
+ async checkNetsuiteObjects() {
+ let ids = this.ids;
+ if (!this.CurrentObject.isNetsuite) {
+ $$(ids.netsuite_one)?.hide();
+ $$(ids.netsuite_many)?.hide();
+ return;
+ }
+
+ let linkType = $$(ids.linkType).getValue();
+ let linkViaType = $$(ids.linkViaType).getValue();
+
+ if (linkType == "one") {
+ await this.updateNetsuiteOneUI(this.CurrentObject);
+ $$(ids.netsuite_one)?.show();
+ $$(ids.netsuite_many)?.hide();
+ } else if (linkViaType == "one") {
+ // fill label and Drop list with object in Droplist
+ let objID = $$(ids.linkObject).getValue();
+ let connObj = this.AB.objectByID(objID);
+ if (!connObj) return;
+ await this.updateNetsuiteOneUI(connObj);
+ $$(ids.netsuite_one)?.show();
+ $$(ids.netsuite_many)?.hide();
+ } else {
+ // this is many:many
+ $$(ids.netsuite_one)?.hide();
+ $$(ids.netsuite_many)?.show();
+ }
+ }
+
+ async updateNetsuiteOneUI(object) {
+ let ids = this.ids;
+
+ // fill label and Drop list with Current Object
+ $$(ids.netsuiteOneLabel).setValue(
+ L(" {0}'s field", [object.label])
+ );
+
+ let result = await this.AB.Network.get({
+ url: `/netsuite/table/${object.tableName}`,
+ params: {
+ credentials: JSON.stringify(object.credentials),
+ },
+ });
+ let fields = result.filter((r) => r.type == "object");
+ let options = fields.map((f) => {
+ return {
+ id: f.column,
+ value: f.column,
+ };
+ });
+
+ $$(ids.netsuiteOneColumn).define("options", options);
+ $$(ids.netsuiteOneColumn).refresh();
+ }
}
return ABFieldConnectProperty;
diff --git a/src/rootPages/Designer/ui_work_object_workspace_popupNewDataField.js b/src/rootPages/Designer/ui_work_object_workspace_popupNewDataField.js
index 15a8797e..ec83732e 100644
--- a/src/rootPages/Designer/ui_work_object_workspace_popupNewDataField.js
+++ b/src/rootPages/Designer/ui_work_object_workspace_popupNewDataField.js
@@ -410,6 +410,12 @@ export default function (AB, ibase) {
let linkCol;
+ if (this.CurrentObject.isNetsuite) {
+ if (vals.settings?.netsuiteOneColumn) {
+ vals.columnName = vals.settings.netsuiteOneColumn;
+ }
+ }
+
// if this is an ADD operation, (_editField will be undefined)
if (!this._editField) {
// get a new instance of a field:
@@ -579,7 +585,10 @@ export default function (AB, ibase) {
await field.save();
// when add new link fields, then run create migrate fields here
- if (!this._editField) {
+ if (
+ !this._editField &&
+ !this.CurrentObject.isNetsuite
+ ) {
await field.migrateCreate();
await linkCol.migrateCreate();
}
From 4dcfdb2ead6cefa56cc7eb55ee48573d1b0e2e32 Mon Sep 17 00:00:00 2001
From: guyyoo
Date: Mon, 28 Oct 2024 10:28:34 +0700
Subject: [PATCH 11/16] The option for content to update exist data/create new
data
---
.../properties/views/ABViewOrgChartTeams.js | 27 ++++++++++++++-----
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index 15ec8488..f801061d 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -25,6 +25,7 @@ export default function (AB) {
direction: "",
depth: "",
draggable: "",
+ dropContentToCreate: "",
color: "",
pan: "",
zoom: "",
@@ -161,13 +162,6 @@ export default function (AB) {
ui() {
const ids = this.ids;
const contentFieldFilter = this.contentFieldFilter;
- contentFieldFilter.myPopup = webix.ui({
- view: "popup",
- height: 240,
- width: 480,
- hidden: true,
- body: contentFieldFilter.ui,
- });
return super.ui([
{
id: ids.datacollectionID,
@@ -365,6 +359,25 @@ export default function (AB) {
label: L("Drag & Drop"),
labelWidth: uiConfig.labelWidthLarge,
value: 0,
+ on: {
+ onChange: (newValue) => {
+ const $dropContentToCreate = $$(ids.dropContentToCreate);
+ if (newValue === 0) {
+ $dropContentToCreate.setValue(0);
+ $dropContentToCreate.hide();
+ } else $dropContentToCreate.show();
+ this.onChange();
+ },
+ },
+ },
+ {
+ id: ids.dropContentToCreate,
+ name: "dropContentToCreateNew",
+ view: "checkbox",
+ label: L("Drop content to create"),
+ labelWidth: uiConfig.labelWidthLarge,
+ hidden: true,
+ value: 0,
on: { onChange: () => this.onChange() },
},
{
From 3f042ec3eb21dee467f0bb7183efd4e4e02ea386 Mon Sep 17 00:00:00 2001
From: Johnny
Date: Sat, 2 Nov 2024 23:53:42 -0500
Subject: [PATCH 12/16] [wip] capturing information about many:many connections
---
.../ui_work_object_list_newObject_netsuite.js | 44 +-
...ect_list_newObject_netsuite_connections.js | 483 +++++++++++++++++-
...k_object_list_newObject_netsuite_tables.js | 5 +-
3 files changed, 515 insertions(+), 17 deletions(-)
diff --git a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js
index 70822ea3..5536a8f3 100644
--- a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js
+++ b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js
@@ -143,6 +143,10 @@ export default function (AB) {
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);
@@ -365,16 +369,9 @@ export default function (AB) {
let link = parts[0];
let linkVia = parts[1];
- let colName = "";
- if (f.thisField != "_this_object_") {
- colName = f.thisField;
- } else if (f.thatObjectField != "_that_object_") {
- colName = f.thatObjectField;
- }
-
let thisField = {
key: "connectObject",
- columnName: f.thisField,
+ // columnName: f.thisField,
label: linkObject.label,
settings: {
showIcon: "1",
@@ -391,12 +388,41 @@ export default function (AB) {
};
let linkField = this.AB.cloneDeep(thisField);
- linkField.columnName = f.thatObjectField;
+ // 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;
+ break;
+ }
+
// create an initial LinkColumn
let fieldLink = linkObject.fieldNew(linkField);
await fieldLink.save(true); // should get an .id now
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
index 22eb68fd..d48c7944 100644
--- a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_connections.js
+++ b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_connections.js
@@ -29,6 +29,12 @@ export default function (AB) {
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
@@ -245,6 +251,10 @@ export default function (AB) {
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.
@@ -254,14 +264,458 @@ export default function (AB) {
value: conn.column,
};
});
- // we also need to include "_this_object_" reference so that
- // we can make many:xxx connections (we don't store the value, the
- // other object does)
- fieldOptions.unshift({
- id: "_this_object_",
- value: L("This Object"),
+
+ 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();
+ },
+ },
+ },
+
+ {
+ 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,
+ },
+ ],
+ },
+ },
+ ],
+ },
+ {
+ // 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
+ },
+ ],
+ },
+ ],
+ };
+ /*
return {
view: "form",
elements: [
@@ -371,6 +825,7 @@ export default function (AB) {
},
],
};
+ */
}
_addConnection(key, type) {
@@ -383,6 +838,17 @@ export default function (AB) {
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
@@ -460,6 +926,11 @@ export default function (AB) {
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)
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
index f5481169..e3a62781 100644
--- a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_tables.js
+++ b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_tables.js
@@ -44,7 +44,7 @@ export default function (AB) {
view: "form",
id: this.ids.form,
width: 800,
- height: 400,
+ height: 700,
rules: {
// TODO:
// name: inputValidator.rules.validateObjectName
@@ -222,7 +222,8 @@ export default function (AB) {
$table.clearAll();
$table.parse(data);
- console.error(data);
+ // console.error(data);
+ this.emit("tables", data);
}
_fieldItem(def) {
From cd8e54ec6d88d8700d676b50e01bcf5e807fe7ba Mon Sep 17 00:00:00 2001
From: Johnny
Date: Tue, 5 Nov 2024 21:08:23 -0600
Subject: [PATCH 13/16] [wip] additional info for many:many connections
---
.../ui_work_object_list_newObject_netsuite.js | 10 ++++
...ect_list_newObject_netsuite_connections.js | 56 +++++++++++++++++++
2 files changed, 66 insertions(+)
diff --git a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js
index 5536a8f3..33c2578d 100644
--- a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js
+++ b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js
@@ -420,6 +420,16 @@ export default function (AB) {
thisField.settings.joinTablePK = f.joinTablePK;
linkField.settings.joinTablePK = f.joinTablePK;
+
+ 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;
}
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
index d48c7944..9ad7f3e0 100644
--- a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_connections.js
+++ b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_connections.js
@@ -659,6 +659,21 @@ export default function (AB) {
}
$objectPK.refresh();
$objectPK.show();
+
+ let fOptions =
+ self.AB.cloneDeep(options);
+ fOptions.unshift({
+ id: "_none_",
+ value: "",
+ });
+ let $activeField =
+ this.getParentView().getChildViews()[5];
+ $activeField.define(
+ "options",
+ fOptions
+ );
+ $activeField.refresh();
+ $activeField.show();
},
},
},
@@ -687,6 +702,47 @@ export default function (AB) {
name: "joinTablePK",
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: "",
+ },
],
},
},
From 76067536c07671bbf2f83a3b2ff8b70cce0c08dd Mon Sep 17 00:00:00 2001
From: guyyoo
Date: Wed, 13 Nov 2024 16:21:34 +0700
Subject: [PATCH 14/16] Data panel settings and group title settings
---
.../properties/views/ABViewOrgChartTeams.js | 276 +++++++++++++++---
1 file changed, 228 insertions(+), 48 deletions(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index ecb2c34f..b06b6ac1 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -35,12 +35,16 @@ export default function (AB) {
export: "",
exportFilename: "",
groupByField: "",
+ showGroupTitle: "",
contentField: "",
contentFieldFilter: "",
contentFieldFilterButton: "",
contentGroupByField: "",
contentDisplayedFields: "",
contentDisplayedFieldsAdd: "",
+ showDataPanel: "",
+ dataPanelDCs: "",
+ dataPanelDCsAdd: "",
strategyColorPopup: "",
strategyColorForm: "",
});
@@ -50,7 +54,7 @@ export default function (AB) {
contentFieldFilter.on("save", () => {
if (
!contentFieldFilter.isConditionComplete(
- contentFieldFilter.getValue()
+ contentFieldFilter.getValue(),
)
)
contentFieldFilter.setValue({ glue: "and", rules: [] });
@@ -62,13 +66,94 @@ export default function (AB) {
return "orgchart_teams";
}
+ _uiDataPanelDC(labelValue = "", dcID = "") {
+ const self = this;
+ const ids = self.ids;
+ const $dataPanelDCs = $$(ids.dataPanelDCs);
+ const validOBJIDs = this.CurrentView.datacollection.datasource
+ .fieldByID($$(ids.contentField).getValue())
+ .datasourceLink.connectFields(
+ (connectField) => connectField.linkType() === "one",
+ )
+ .map((connectField) => connectField.datasourceLink.id);
+ const dcs = this.AB.datacollections(
+ (dc) => validOBJIDs.indexOf(dc.datasource.id) > -1,
+ );
+ const dcOptions = dcs.map((dc) => ({
+ id: dc.id,
+ value: dc.label,
+ dc,
+ }));
+ const getUILabel = (dcID, elementIndex) => ({
+ view: "text",
+ name: `${elementIndex}.${dcID}`,
+ // label: L("Name"),
+ // labelWidth: uiConfig.labelWidthMedium,
+ on: {
+ onChange: () => {
+ this.onChange();
+ },
+ onViewShow() {
+ this.setValue(labelValue);
+ },
+ },
+ });
+ return {
+ cols: [
+ {
+ view: "richselect",
+ label: `${L("Panel")} ${
+ $dataPanelDCs.getChildViews().length + 1
+ }`,
+ labelWidth: uiConfig.labelWidthMedium,
+ options: dcOptions,
+ on: {
+ onChange(newValue) {
+ const $parentView = this.getParentView();
+ const sameLevelViews = $parentView.getChildViews();
+ if ($parentView.getChildViews().length === 3)
+ $parentView.removeView(sameLevelViews[1].config.id);
+ $parentView.addView(
+ getUILabel(
+ newValue,
+ $dataPanelDCs
+ .getChildViews()
+ .findIndex(
+ ($dataPanelDCsChild) =>
+ $dataPanelDCsChild === $parentView,
+ ),
+ ),
+ 1,
+ );
+ },
+ onViewShow() {
+ if (dcID == null || dcID === "") return;
+ this.setValue(dcID);
+ },
+ },
+ },
+ {
+ view: "button",
+ css: "webix_danger",
+ type: "icon",
+ icon: "wxi-close",
+ width: uiConfig.buttonWidthExtraSmall,
+ click() {
+ self.deleteDataPanelDC(this.getParentView().config.id);
+ self.onChange();
+ },
+ },
+ ],
+ };
+ }
+
_uiContentDisplayedField(fieldID = "", obj, atDisplay) {
const self = this;
const ids = self.ids;
const datasource = this.CurrentView.datacollection.datasource;
const datasourceID = datasource.id;
const parentObj = datasource.fieldByID(
- $$(ids.contentField).getValue()
+ $$(ids.contentField).getValue(),
).datasourceLink;
const parentObjID = parentObj.id;
const objID = obj?.id || parentObjID;
@@ -90,18 +175,18 @@ export default function (AB) {
this._uiContentDisplayedField(
"",
field.datasourceLink,
- currentAtDisplay
- )
+ currentAtDisplay,
+ ),
);
}
this.populateContentDisplayedFields(
- $contentDisplayedFields.getValues()
+ $contentDisplayedFields.getValues(),
);
this.onChange();
};
if (objID === parentObjID) {
const rootAtDisplay = Object.keys(
- $contentDisplayedFields.elements
+ $contentDisplayedFields.elements,
).filter((key) => key.includes(objID)).length;
return {
cols: [
@@ -125,7 +210,7 @@ export default function (AB) {
width: uiConfig.buttonWidthExtraSmall,
click() {
self.deleteContentDisplayedField(
- this.getParentView().getChildViews()[0].config.id
+ this.getParentView().getChildViews()[0].config.id,
);
self.onChange();
},
@@ -154,7 +239,7 @@ export default function (AB) {
width: uiConfig.buttonWidthExtraSmall,
click() {
self.deleteContentDisplayedField(
- this.getParentView().getChildViews()[0].config.id
+ this.getParentView().getChildViews()[0].config.id,
);
self.onChange();
},
@@ -238,14 +323,15 @@ export default function (AB) {
on: {
onChange: (newValue) => {
const $contentDisplayedFieldsAdd = $$(
- ids.contentDisplayedFieldsAdd
+ ids.contentDisplayedFieldsAdd,
);
const $contentFieldFilterButton = $$(
- ids.contentFieldFilterButton
+ ids.contentFieldFilterButton,
);
const $contentGroupByField = $$(
- ids.contentGroupByField
+ ids.contentGroupByField,
);
+ const $showGroupTitle = $$(ids.showGroupTitle);
contentFieldFilter.init();
contentFieldFilter.setValue({
glue: "and",
@@ -254,10 +340,10 @@ export default function (AB) {
if (newValue != null && newValue !== "") {
const contentObj =
this.CurrentView.datacollection.datasource.fieldByID(
- newValue
+ newValue,
).datasourceLink;
contentFieldFilter.fieldsLoad(
- contentObj.fields()
+ contentObj.fields(),
);
$contentGroupByField.setValue("");
$contentGroupByField.define("options", [
@@ -266,7 +352,7 @@ export default function (AB) {
.fields(
(f) =>
f.key === "list" &&
- f.settings.isMultiple === 0
+ f.settings.isMultiple === 0,
)
.map((f) => ({
id: f.id,
@@ -277,14 +363,17 @@ export default function (AB) {
$contentFieldFilterButton.enable();
$contentDisplayedFieldsAdd.show();
$contentGroupByField.show();
+ $showGroupTitle.show();
} else {
contentFieldFilter.fieldsLoad([]);
- $contentGroupByField.setValue("");
$contentGroupByField.define("options", []);
$contentFieldFilterButton.disable();
$contentDisplayedFieldsAdd.hide();
$contentGroupByField.hide();
+ $showGroupTitle.hide();
}
+ $showGroupTitle.setValue(0);
+ $contentGroupByField.setValue("");
this.populateContentDisplayedFields({});
this.onChange();
},
@@ -319,6 +408,20 @@ export default function (AB) {
},
},
},
+ {
+ id: ids.showGroupTitle,
+ hidden: true,
+ name: "showGroupTitle",
+ view: "checkbox",
+ label: L("Show Group Title"),
+ labelWidth: uiConfig.labelWidthLarge,
+ value: 0,
+ on: {
+ onChange: (newValue) => {
+ this.onChange();
+ },
+ },
+ },
{
id: ids.contentDisplayedFieldsAdd,
hidden: true,
@@ -335,16 +438,12 @@ export default function (AB) {
width: uiConfig.buttonWidthExtraSmall,
click: () => {
const $contentDisplayedFields = $$(
- ids.contentDisplayedFields
+ ids.contentDisplayedFields,
);
if (!$contentDisplayedFields.isVisible())
$contentDisplayedFields.show();
- const values = $contentDisplayedFields.getValues();
- for (const key in values) {
- }
- Object.keys($contentDisplayedFields.elements);
$contentDisplayedFields.addView(
- this._uiContentDisplayedField()
+ this._uiContentDisplayedField(),
);
},
},
@@ -356,6 +455,51 @@ export default function (AB) {
hidden: true,
elements: [],
},
+ {
+ id: ids.showDataPanel,
+ name: "showDataPanel",
+ view: "checkbox",
+ label: L("Show Data Panel"),
+ labelWidth: uiConfig.labelWidthLarge,
+ value: 0,
+ on: {
+ onChange: (newValue) => {
+ const $dataPanelDCsAdd = $$(ids.dataPanelDCsAdd);
+ if (newValue === 1) $dataPanelDCsAdd.show();
+ else $dataPanelDCsAdd.hide();
+ this.populateDataPanelDCs({});
+ this.onChange();
+ },
+ },
+ },
+ {
+ id: ids.dataPanelDCsAdd,
+ hidden: true,
+ cols: [
+ {
+ view: "label",
+ label: L("Data Panel DCs"),
+ },
+ {
+ view: "button",
+ type: "icon",
+ icon: "fa fa-plus",
+ css: "webix_primary",
+ width: uiConfig.buttonWidthExtraSmall,
+ click: () => {
+ const $dataPanelDCs = $$(ids.dataPanelDCs);
+ if (!$dataPanelDCs.isVisible()) $dataPanelDCs.show();
+ $dataPanelDCs.addView(this._uiDataPanelDC());
+ },
+ },
+ ],
+ },
+ {
+ id: ids.dataPanelDCs,
+ view: "form",
+ hidden: true,
+ elements: [],
+ },
{
id: ids.teamStrategy,
view: "richselect",
@@ -520,7 +664,7 @@ export default function (AB) {
await super.init(AB);
webix.extend($$(this.ids.component), webix.ProgressBar);
this.contentFieldFilter.queriesLoad(
- this.CurrentApplication?.queriesIncluded()
+ this.CurrentApplication?.queriesIncluded(),
);
}
@@ -533,26 +677,32 @@ export default function (AB) {
if (
deletedElementKey.includes(
this.CurrentView.datacollection.datasource.fieldByID(
- $$(ids.contentField).getValue()
- ).datasourceLink.id
+ $$(ids.contentField).getValue(),
+ ).datasourceLink.id,
)
) {
const deletedAtDisplay = deletedElementKey.split(".")[0];
for (const key in $elements) {
if (!key.includes(`${deletedAtDisplay}.`)) continue;
$contentDisplayedFields.removeView(
- $elements[key].getParentView().config.id
+ $elements[key].getParentView().config.id,
);
}
} else
$contentDisplayedFields.removeView(
- $richselect.getParentView().config.id
+ $richselect.getParentView().config.id,
);
this.populateContentDisplayedFields(
- $contentDisplayedFields.getValues()
+ $contentDisplayedFields.getValues(),
);
}
+ deleteDataPanelDC(id) {
+ const $dataPanelDCs = $$(this.ids.dataPanelDCs);
+ $dataPanelDCs.removeView(id);
+ this.populateDataPanelDCs($dataPanelDCs.getValues());
+ }
+
populate(view) {
super.populate(view);
const ids = this.ids;
@@ -560,7 +710,7 @@ export default function (AB) {
const defaultValues = this.defaultValues();
const values = Object.assign(
$component.getValues(),
- Object.assign(defaultValues, view.settings)
+ Object.assign(defaultValues, view.settings),
);
// const $fieldList = $$(ids.fields);
// $fieldList.clearAll();
@@ -577,11 +727,14 @@ export default function (AB) {
"topTeam",
"contentField",
"contentGroupByField",
+ "showGroupTitle",
+ "showDataPanel",
].forEach((f) => $$(ids[f]).setValue(values[f]));
this.contentFieldFilter.setValue(
- JSON.parse(values.contentFieldFilter)
+ JSON.parse(values.contentFieldFilter),
);
this.populateContentDisplayedFields(values.contentDisplayedFields);
+ this.populateDataPanelDCs(values.dataPanelDCs);
if (values.teamStrategy) {
this.populateStrategyOptions(values.teamStrategy);
$$(ids.strategyCode).setValue(values.strategyCode);
@@ -640,12 +793,9 @@ export default function (AB) {
const m2oFields = view.getValueFields(object).map(fieldToOption);
const o2mFields =
object.connectFields(
- (f) => f.linkType() == "one" && f.linkViaType() == "many"
+ (f) => f.linkType() == "one" && f.linkViaType() == "many",
) ?? [];
- $$(ids.teamStrategy).define(
- "options",
- o2mFields.map(fieldToOption)
- );
+ $$(ids.teamStrategy).define("options", o2mFields.map(fieldToOption));
$$(ids.teamLink).define("options", m2oFields);
const textFields = object
?.fields((f) => f.key === "string")
@@ -672,16 +822,21 @@ export default function (AB) {
const elements = $contentDisplayedFields.elements;
for (const key in elements)
$contentDisplayedFields.removeView(
- elements[key].getParentView().config.id
+ elements[key].getParentView().config.id,
);
const keys = Object.keys(values);
+ const obj = this.CurrentView.datacollection.datasource.fieldByID(
+ $$(ids.contentField).getValue(),
+ )?.datasourceLink;
if (keys.length === 0) {
$contentDisplayedFields.hide();
return;
}
- const obj = this.CurrentView.datacollection.datasource.fieldByID(
- $$(ids.contentField).getValue()
- ).datasourceLink;
+ if (obj == null) {
+ $contentDisplayedFields.hide();
+ $$(ids.contentDisplayedFieldsAdd).hide();
+ return;
+ }
const objID = obj.id;
const parentKeys = [];
const childKeys = [];
@@ -694,7 +849,7 @@ export default function (AB) {
const parentKey = parentKeys.pop();
const parentFieldID = values[parentKey] ?? "";
$contentDisplayedFields.addView(
- this._uiContentDisplayedField(parentFieldID)
+ this._uiContentDisplayedField(parentFieldID),
);
if (
parentFieldID === "" ||
@@ -703,11 +858,11 @@ export default function (AB) {
continue;
const currentAtDisplay =
Object.keys($contentDisplayedFields.getValues()).filter(
- (currentKey) => currentKey.includes(objID)
+ (currentKey) => currentKey.includes(objID),
).length - 1;
while (
childKeys.findIndex((childKey) =>
- childKey.includes(`${parentKey.split(".")[0]}.`)
+ childKey.includes(`${parentKey.split(".")[0]}.`),
) > -1
) {
const childKey = childKeys.pop();
@@ -717,8 +872,8 @@ export default function (AB) {
this._uiContentDisplayedField(
childFieldID,
childObj,
- currentAtDisplay
- )
+ currentAtDisplay,
+ ),
);
if (
childFieldID === "" ||
@@ -730,9 +885,33 @@ export default function (AB) {
$contentDisplayedFields.show();
}
+ populateDataPanelDCs(values) {
+ const ids = this.ids;
+ const $dataPanelDCs = $$(ids.dataPanelDCs);
+ const dataPanelDCsChidren = $dataPanelDCs.getChildViews();
+ while (dataPanelDCsChidren.length > 0)
+ $dataPanelDCs.removeView(dataPanelDCsChidren[0].config.id);
+ $dataPanelDCs.hide();
+ const contentFieldValue = $$(ids.contentField).getValue();
+ const keys = Object.keys(values);
+ if (
+ contentFieldValue == null ||
+ contentFieldValue === "" ||
+ keys.length === 0
+ )
+ return;
+ while (keys.length > 0) {
+ const key = keys.shift();
+ $dataPanelDCs.addView(
+ this._uiDataPanelDC(values[key] ?? "", key.split(".")[1] ?? ""),
+ );
+ }
+ $dataPanelDCs.show();
+ }
+
populateStrategyOptions(fieldID) {
const strategyObj = this.AB.objectByID(
- this.AB.definitionByID(fieldID).settings.linkObject
+ this.AB.definitionByID(fieldID).settings.linkObject,
);
const listFields = strategyObj
.fields((f) => f.key === "list")
@@ -749,7 +928,7 @@ export default function (AB) {
if (!$popup) {
const values = this.CurrentView.settings.strategyColors ?? {};
const strategyTypes = this.AB.definitionByID(
- codeFieldID
+ codeFieldID,
).settings.options.map((strategy) => {
return {
view: "colorpicker",
@@ -825,7 +1004,7 @@ export default function (AB) {
const ids = this.ids;
const settings = (values.settings = Object.assign(
$$(ids.component).getValues(),
- values.settings
+ values.settings,
));
// Retrive the values of your properties from Webix and store them in the view
settings.teamLink = $$(ids.teamLink).getValue();
@@ -839,11 +1018,12 @@ export default function (AB) {
settings.contentField = $$(ids.contentField).getValue();
settings.contentGroupByField = $$(ids.contentGroupByField).getValue();
settings.contentFieldFilter = JSON.stringify(
- this.contentFieldFilter.getValue()
+ this.contentFieldFilter.getValue(),
);
settings.contentDisplayedFields = $$(
- ids.contentDisplayedFields
+ ids.contentDisplayedFields,
).getValues();
+ settings.dataPanelDCs = $$(ids.dataPanelDCs).getValues();
const $colorForm = $$(ids.strategyColorForm);
settings.strategyColors = $colorForm?.getValues() ?? {};
return values;
From e134f7aa039d1d94fa8e67b5214b37817a8e0943 Mon Sep 17 00:00:00 2001
From: Johnny
Date: Wed, 20 Nov 2024 14:04:15 +0700
Subject: [PATCH 15/16] [wip] enable labels on api objects, fill out missing
many:many information
---
.../ui_work_object_list_newObject_netsuite.js | 3 +
...ect_list_newObject_netsuite_connections.js | 176 ++++--------------
.../Designer/ui_work_object_workspace.js | 37 ++--
3 files changed, 60 insertions(+), 156 deletions(-)
diff --git a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js
index 33c2578d..32018fb8 100644
--- a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js
+++ b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite.js
@@ -421,6 +421,9 @@ export default function (AB) {
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;
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
index 9ad7f3e0..bdae1a56 100644
--- a/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_connections.js
+++ b/src/rootPages/Designer/ui_work_object_list_newObject_netsuite_connections.js
@@ -158,33 +158,6 @@ export default function (AB) {
},
],
},
-
- {
- 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();
- },
- },
- ],
- },
],
},
],
@@ -660,6 +633,32 @@ export default function (AB) {
$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({
@@ -667,7 +666,7 @@ export default function (AB) {
value: "",
});
let $activeField =
- this.getParentView().getChildViews()[5];
+ this.getParentView().getChildViews()[6];
$activeField.define(
"options",
fOptions
@@ -702,6 +701,16 @@ export default function (AB) {
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:"),
@@ -771,117 +780,6 @@ export default function (AB) {
},
],
};
- /*
- return {
- view: "form",
- elements: [
- {
- cols: [
- {
- rows: [
- {
- label: L("Field"),
- view: "label",
- },
- {
- placeholder: "Type",
- options: fieldOptions,
- view: "select",
- // value: type,
- name: "thisField",
- },
- ],
- },
- {
- rows: [
- {
- placeholder: L("Existing Netsuite Object"),
- options: this.listNetsuiteObjects.map((nObj) => {
- return {
- id: nObj.id,
- value: nObj.label,
- };
- }),
- view: "select",
- name: "thatObject",
- // 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"),
- });
- let $linkColumn =
- this.getParentView().getChildViews()[1];
-
- $linkColumn.define("options", options);
- $linkColumn.refresh();
- }
- },
- },
- },
- {
- placeholder: "Link Column",
- options: [],
- view: "select",
- // value: type,
- name: "thatObjectField",
- },
- {
- placeholder: "Link Type",
- options: linkTypes.map((l) => {
- return {
- id: l,
- value: l,
- };
- }),
- view: "select",
- name: "linkType",
- // value: type,
- },
- ],
- },
-
- {
- icon: "wxi-trash",
- view: "icon",
- width: 38,
- click: function () {
- const $item = this.getParentView().getParentView();
- $$(self.ids.connections).removeView($item);
- },
- },
- ],
- },
- ],
- };
- */
}
_addConnection(key, type) {
diff --git a/src/rootPages/Designer/ui_work_object_workspace.js b/src/rootPages/Designer/ui_work_object_workspace.js
index 94527dd0..9513c00c 100644
--- a/src/rootPages/Designer/ui_work_object_workspace.js
+++ b/src/rootPages/Designer/ui_work_object_workspace.js
@@ -179,15 +179,18 @@ export default function (AB, ibase, init_settings) {
this.callbackHeaderEditorMenu(action, field, node);
});
- if (!this.isReadOnly) {
- this.PopupDefineLabelComponent = new FPopupDefineLabel(
- AB,
- `${base}_defineLabel`
- );
- this.PopupDefineLabelComponent.on("changed", () => {
- this.callbackDefineLabel();
- });
- }
+ // NOTE: label information is only concerning how we display the info
+ // from this Object. It doesn't impact the data. So we can go ahead
+ // and allow users to modify the Label data.
+ // if (!this.isReadOnly) {
+ this.PopupDefineLabelComponent = new FPopupDefineLabel(
+ AB,
+ `${base}_defineLabel`
+ );
+ this.PopupDefineLabelComponent.on("changed", () => {
+ this.callbackDefineLabel();
+ });
+ // }
this.PopupFilterDataTableComponent = new FPopupFilterDataTable(
AB,
@@ -437,7 +440,7 @@ export default function (AB, ibase, init_settings) {
icon: "fa fa-crosshairs",
css: "webix_transparent",
type: "icon",
- hidden: this.isReadOnly,
+ // hidden: this.isReadOnly,
click: function () {
_logic.toolbarDefineLabel(this.$view);
},
@@ -707,9 +710,9 @@ export default function (AB, ibase, init_settings) {
allInits.push(this.PopupHeaderEditMenu.init(AB));
- if (!this.isReadOnly) {
- allInits.push(this.PopupDefineLabelComponent.init(AB));
- }
+ // if (!this.isReadOnly) {
+ allInits.push(this.PopupDefineLabelComponent.init(AB));
+ // }
allInits.push(this.PopupFilterDataTableComponent.init(AB));
this.PopupFilterDataTableComponent.on("save", (...params) => {
@@ -1391,8 +1394,8 @@ export default function (AB, ibase, init_settings) {
if (!this.isReadOnly) {
this.PopupNewDataFieldComponent.objectLoad(object);
- this.PopupDefineLabelComponent.objectLoad(object);
}
+ this.PopupDefineLabelComponent.objectLoad(object);
this.PopupFilterDataTableComponent.objectLoad(object);
this.PopupFrozenColumnsComponent.objectLoad(object);
@@ -1782,7 +1785,7 @@ export default function (AB, ibase, init_settings) {
const ids = this.ids;
const $buttonAddField = $$(ids.buttonAddField),
$spaceAddField = $$(ids.spaceAddField),
- $buttonLabel = $$(ids.buttonLabel),
+ // $buttonLabel = $$(ids.buttonLabel),
$spaceLabel = $$(ids.spaceLabel),
$buttonImport = $$(ids.buttonImport),
$spaceImport = $$(ids.spaceImport),
@@ -1792,7 +1795,7 @@ export default function (AB, ibase, init_settings) {
if (this._isReadOnly) {
$buttonAddField?.hide();
$spaceAddField?.hide();
- $buttonLabel?.hide();
+ // $buttonLabel?.hide();
$spaceLabel?.hide();
$buttonImport?.hide();
$spaceImport?.hide();
@@ -1801,7 +1804,7 @@ export default function (AB, ibase, init_settings) {
} else {
$buttonAddField?.show();
$spaceAddField?.show();
- $buttonLabel?.show();
+ // $buttonLabel?.show();
$spaceLabel?.show();
$buttonImport?.show();
$spaceImport?.show();
From a35f9c7904c7d13b1c201c27d309b6bd47dc528a Mon Sep 17 00:00:00 2001
From: nh758 <7259@pm.me>
Date: Wed, 19 Feb 2025 13:59:57 +0700
Subject: [PATCH 16/16] remove orgchart view (moved to plugin)
---
.../Designer/editors/EditorManager.js | 6 +-
.../Designer/editors/views/ABViewOrgChart.js | 53 -
.../editors/views/ABViewOrgChartTeams.js | 53 -
.../Designer/properties/PropertyManager.js | 12 +-
.../properties/views/ABViewOrgChart.js | 359 ------
.../properties/views/ABViewOrgChartTeams.js | 1051 -----------------
6 files changed, 7 insertions(+), 1527 deletions(-)
delete mode 100644 src/rootPages/Designer/editors/views/ABViewOrgChart.js
delete mode 100644 src/rootPages/Designer/editors/views/ABViewOrgChartTeams.js
delete mode 100644 src/rootPages/Designer/properties/views/ABViewOrgChart.js
delete mode 100644 src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
diff --git a/src/rootPages/Designer/editors/EditorManager.js b/src/rootPages/Designer/editors/EditorManager.js
index 123d8856..9b6c1f57 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.
@@ -34,8 +34,6 @@ export default function (AB) {
require("./views/ABViewLabel"),
require("./views/ABViewLayout"),
require("./views/ABViewMenu"),
- require("./views/ABViewOrgChart"),
- require("./views/ABViewOrgChartTeams"),
require("./views/ABViewPage"),
require("./views/ABViewPDFImporter"),
require("./views/ABViewPivot"),
@@ -60,7 +58,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/ABViewOrgChart.js b/src/rootPages/Designer/editors/views/ABViewOrgChart.js
deleted file mode 100644
index 8ffb0774..00000000
--- a/src/rootPages/Designer/editors/views/ABViewOrgChart.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * ABViewOrgChartEditor
- * 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 FABViewDefault from "./_ABViewDefault";
-
-export default function (AB) {
- if (!myClass) {
- const ABViewDefault = FABViewDefault(AB);
- // var L = UIClass.L();
- // var L = ABViewContainer.L();
-
- myClass = class ABViewOrgChartEditor extends ABViewDefault {
- static get key() {
- return "orgchart";
- }
-
- constructor(view, base = "interface_editor_viewOrgChart") {
- // base: {string} unique base id reference
-
- super(view, base);
-
- // this.component = this.view.component();
- }
-
- ui() {
- let _ui = super.ui();
- 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/ABViewOrgChartTeams.js b/src/rootPages/Designer/editors/views/ABViewOrgChartTeams.js
deleted file mode 100644
index 5a568fb4..00000000
--- a/src/rootPages/Designer/editors/views/ABViewOrgChartTeams.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * ABViewOrgChartEditor
- * 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 FABViewDefault from "./_ABViewDefault";
-
-export default function (AB) {
- if (!myClass) {
- const ABViewDefault = FABViewDefault(AB);
- // var L = UIClass.L();
- // var L = ABViewContainer.L();
-
- myClass = class ABViewOrgChartTeamsEditor extends ABViewDefault {
- static get key() {
- return "orgchart_teams";
- }
-
- constructor(view, base = "interface_editor_viewOrgChartTeans") {
- // base: {string} unique base id reference
-
- super(view, base);
-
- // this.component = this.view.component();
- }
-
- ui() {
- let _ui = super.ui();
- 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/properties/PropertyManager.js b/src/rootPages/Designer/properties/PropertyManager.js
index d46513a2..296684c9 100644
--- a/src/rootPages/Designer/properties/PropertyManager.js
+++ b/src/rootPages/Designer/properties/PropertyManager.js
@@ -8,7 +8,7 @@ import ABView from "./views/ABView";
var PropertyMgr = null;
-export default function (AB) {
+export default function(AB) {
if (!PropertyMgr) {
var Fields = [];
// {array}
@@ -110,8 +110,6 @@ export default function (AB) {
require("./views/ABViewLayout"),
require("./views/ABViewList"),
require("./views/ABViewMenu"),
- require("./views/ABViewOrgChart"),
- require("./views/ABViewOrgChartTeams"),
require("./views/ABViewPage"),
require("./views/ABViewPDFImporter"),
require("./views/ABViewPivot"),
@@ -162,19 +160,19 @@ export default function (AB) {
* A filter for limiting which fields you want.
* @return [{ClassUI(Field1)}, {ClassUI(Field2)}, ...]
*/
- fields: function (f = () => true) {
+ fields: function(f = () => true) {
return Fields.filter(f);
},
- processElements: function (f = () => true) {
+ processElements: function(f = () => true) {
return Processes.filter(f);
},
- views: function (v = () => true) {
+ views: function(v = () => true) {
return Views.filter(v);
},
- mobileViews: function (v = () => true) {
+ mobileViews: function(v = () => true) {
return MobileViews.filter(v);
},
};
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChart.js b/src/rootPages/Designer/properties/views/ABViewOrgChart.js
deleted file mode 100644
index 5146e430..00000000
--- a/src/rootPages/Designer/properties/views/ABViewOrgChart.js
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * ABViewChart
- * A Property manager for our ABViewChart definitions
- */
-
-import FABView from "./ABView";
-
-export default function (AB) {
- const BASE_ID = "properties_abview_org_chart";
-
- const ABView = FABView(AB);
- const uiConfig = AB.Config.uiSettings();
- const L = ABView.L();
-
- class ABViewOrgChartProperty extends ABView {
- constructor() {
- super(BASE_ID, {
- datacollectionID: "",
- fields: "",
- direction: "",
- depth: "",
- color: "",
- pan: "",
- zoom: "",
- height: "",
- export: "",
- exportFilename: "",
- });
-
- this.AB = AB;
- }
-
- static get key() {
- return "orgchart";
- }
-
- ui() {
- const ids = this.ids;
-
- return super.ui([
- {
- id: ids.datacollectionID,
- name: "datacollectionID",
- view: "richselect",
- label: L("Data Collection"),
- labelWidth: uiConfig.labelWidthLarge,
- options: [],
- on: {
- onChange: (value) => {
- this.CurrentView.settings.datacollectionID = value;
- this.populateSubValueFieldOptions(
- this.CurrentView?.datacollection?.datasource
- );
- this.onChange();
- },
- },
- },
- {
- cols: [
- {
- view: "label",
- label: "Fields",
- width: uiConfig.labelWidthLarge,
- },
- {
- id: ids.fields,
- name: "fields",
- view: "tree",
- template:
- "{common.icon()} {common.checkbox()} #value#",
- select: false,
- height: 200,
- data: [],
- on: {
- onItemCheck: () => {
- const fieldValues = $$(this.ids.fields).getChecked();
- this.refreshValueFieldOptions(fieldValues);
- this.onChange();
- },
- },
- },
- ],
- },
- {
- id: ids.direction,
- name: "direction",
- view: "richselect",
- label: L("Direction"),
- labelWidth: uiConfig.labelWidthLarge,
- options: [
- { id: "t2b", value: L("Top to Bottom") },
- { id: "b2t", value: L("Bottom to Top") },
- { id: "l2r", value: L("Left to Right") },
- { id: "r2l", value: L("Right to Left") },
- ],
- on: {
- onChange: () => {
- this.onChange();
- },
- },
- },
- {
- id: ids.depth,
- name: "depth",
- hidden: true, // NOTE: use choose Connect Fields option
- view: "counter",
- label: L("Depth"),
- labelWidth: uiConfig.labelWidthLarge,
- value: 0,
- on: {
- onChange: () => {
- this.onChange();
- },
- },
- },
- {
- id: ids.color,
- name: "color",
- view: "colorpicker",
- label: L("Color"),
- labelWidth: uiConfig.labelWidthLarge,
- on: {
- onChange: () => {
- this.onChange();
- },
- },
- },
- {
- hidden: true, // NOTE: does not support
- id: ids.pan,
- name: "pan",
- view: "checkbox",
- label: L("Pan"),
- labelWidth: uiConfig.labelWidthLarge,
- value: 0,
- on: {
- onChange: () => {
- this.onChange();
- },
- },
- },
- {
- hidden: true, // NOTE: does not support
- id: ids.zoom,
- name: "zoom",
- view: "checkbox",
- label: L("Zoom"),
- labelWidth: uiConfig.labelWidthLarge,
- value: 0,
- on: {
- onChange: () => {
- this.onChange();
- },
- },
- },
- {
- id: ids.height,
- view: "counter",
- name: "height",
- label: L("Height"),
- labelWidth: uiConfig.labelWidthLarge,
- on: {
- onChange: () => {
- this.onChange();
- },
- },
- },
- {
- hidden: true, // NOTE: does not support
- view: "fieldset",
- label: L("Export"),
- body: {
- view: "layout",
- borderless: true,
- rows: [
- {
- id: ids.export,
- name: "export",
- view: "checkbox",
- label: L("Is Exportable"),
- labelWidth: uiConfig.labelWidthLarge,
- value: 0,
- on: {
- onChange: () => {
- this.onChange();
- },
- },
- },
- {
- id: ids.exportFilename,
- view: "text",
- name: "exportFilename",
- label: L("File name"),
- placeholder: L("Enter file name"),
- labelWidth: uiConfig.labelWidthLarge,
- },
- ],
- },
- },
- ]);
- }
-
- async init(AB) {
- this.AB = AB;
-
- await super.init(AB);
-
- webix.extend($$(this.ids.component), webix.ProgressBar);
- }
-
- populate(view) {
- super.populate(view);
-
- const ids = this.ids;
- const $component = $$(ids.component);
- const defaultValues = this.defaultValues();
- const values = Object.assign(
- $component.getValues(),
- Object.assign(defaultValues, view.settings)
- );
-
- const $fieldList = $$(ids.fields);
- $fieldList.clearAll();
-
- this.populateDatacollection(values.datacollectionId);
- // this.populateDescriptionFieldOptions(values.columnDescription);
-
- const fieldValues = (view.settings?.fields ?? "").split(",");
- this.refreshValueFieldOptions(fieldValues);
-
- $component.setValues(values);
- }
-
- populateDatacollection(datacollectionId) {
- const $dataCollection = $$(this.ids.datacollectionID);
-
- // Pull data collections to options
- const dcOptions = this.CurrentView.application
- .datacollectionsIncluded()
- .map((d) => {
- return { id: d.id, value: d.label };
- });
- $dataCollection.define("options", dcOptions);
- $dataCollection.define("value", datacollectionId);
- $dataCollection.refresh();
- }
-
- refreshValueFieldOptions(fieldValues = []) {
- const ids = this.ids;
- const view = this.CurrentView;
- const $fieldList = $$(ids.fields);
-
- $fieldList.clearAll();
-
- // Populate 1:M fields option of the root object
- this.populateSubValueFieldOptions(view.datacollection?.datasource);
-
- // Populate sub 1:M fields option of each fields
- fieldValues.forEach((fId) => {
- if (!fId) return;
-
- const $fieldItem = $fieldList.getItem(fId);
- if ($fieldItem) {
- const abField = $fieldItem.field;
- this.populateSubValueFieldOptions(abField.datasourceLink, fId);
- }
- });
-
- // Set check items
- $fieldList.blockEvent();
- fieldValues.forEach((fId) => {
- if ($fieldList.exists(fId)) $fieldList.checkItem(fId);
- });
- $fieldList.unblockEvent();
- }
-
- populateSubValueFieldOptions(object, parentFieldId) {
- const view = this.CurrentView;
- const $fields = $$(this.ids.fields);
-
- view.getValueFields(object).forEach((f, index) => {
- if ($fields.exists(f.id)) return;
- $fields.add(
- {
- id: f.id,
- value: f.label,
- field: f,
- },
- index,
- parentFieldId
- );
- });
-
- $fields.openAll();
- }
-
- // populateDescriptionFieldOptions(fieldId) {
- // const valueField = this.CurrentView.valueField();
- // const $columnDescription = $$(this.ids.columnDescription);
-
- // const connectFieldOpts =
- // valueField?.datasourceLink
- // ?.fields?.((f) => f.key != "connectObject")
- // .map?.((f) => {
- // return {
- // id: f.id,
- // value: f.label,
- // };
- // }) ?? [];
- // $columnDescription.define("options", connectFieldOpts);
- // $columnDescription.define("value", fieldId);
- // $columnDescription.refresh();
- // }
-
- defaultValues() {
- const ViewClass = this.ViewClass();
-
- let values = null;
-
- if (ViewClass) {
- values = ViewClass.defaultValues();
- }
-
- return values;
- }
-
- /**
- * @method values
- * return the values for this form.
- * @return {obj}
- */
- values() {
- const values = super.values();
- const ids = this.ids;
- const $component = $$(ids.component);
-
- values.settings = Object.assign(
- $component.getValues(),
- values.settings
- );
-
- // Retrive the values of your properties from Webix and store them in the view
- values.settings.fields = $$(ids.fields).getChecked().join(",");
-
- return values;
- }
-
- /**
- * @method FieldClass()
- * A method to return the proper ABViewXXX Definition.
- * NOTE: Must be overwritten by the Child Class
- */
- ViewClass() {
- return super._ViewClass("orgchart");
- }
- }
-
- return ABViewOrgChartProperty;
-}
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
deleted file mode 100644
index b06b6ac1..00000000
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ /dev/null
@@ -1,1051 +0,0 @@
-/*
- * ABViewChartTeams
- * A Property manager for our ABViewChartTeams definitions
- */
-
-import FABView from "./ABView";
-
-export default function (AB) {
- const BASE_ID = "properties_abview_org_chart_teams";
-
- const ABView = FABView(AB);
- const uiConfig = AB.Config.uiSettings();
- const L = ABView.L();
-
- class ABViewOrgChartTeamsProperty extends ABView {
- constructor() {
- super(BASE_ID, {
- datacollectionID: "",
- strategyCode: "",
- teamInactive: "",
- teamCanInactivate: "",
- teamLink: "",
- teamName: "",
- teamStrategy: "",
- topTeam: "",
- fields: "",
- direction: "",
- depth: "",
- draggable: "",
- dropContentToCreate: "",
- color: "",
- pan: "",
- zoom: "",
- height: "",
- export: "",
- exportFilename: "",
- groupByField: "",
- showGroupTitle: "",
- contentField: "",
- contentFieldFilter: "",
- contentFieldFilterButton: "",
- contentGroupByField: "",
- contentDisplayedFields: "",
- contentDisplayedFieldsAdd: "",
- showDataPanel: "",
- dataPanelDCs: "",
- dataPanelDCsAdd: "",
- strategyColorPopup: "",
- strategyColorForm: "",
- });
- this.AB = AB;
- const contentFieldFilter = (this.contentFieldFilter =
- AB.filterComplexNew(this.ids.contentFieldFilter));
- contentFieldFilter.on("save", () => {
- if (
- !contentFieldFilter.isConditionComplete(
- contentFieldFilter.getValue(),
- )
- )
- contentFieldFilter.setValue({ glue: "and", rules: [] });
- this.onChange();
- });
- }
-
- static get key() {
- return "orgchart_teams";
- }
-
- _uiDataPanelDC(labelValue = "", dcID = "") {
- const self = this;
- const ids = self.ids;
- const $dataPanelDCs = $$(ids.dataPanelDCs);
- const validOBJIDs = this.CurrentView.datacollection.datasource
- .fieldByID($$(ids.contentField).getValue())
- .datasourceLink.connectFields(
- (connectField) => connectField.linkType() === "one",
- )
- .map((connectField) => connectField.datasourceLink.id);
- const dcs = this.AB.datacollections(
- (dc) => validOBJIDs.indexOf(dc.datasource.id) > -1,
- );
- const dcOptions = dcs.map((dc) => ({
- id: dc.id,
- value: dc.label,
- dc,
- }));
- const getUILabel = (dcID, elementIndex) => ({
- view: "text",
- name: `${elementIndex}.${dcID}`,
- // label: L("Name"),
- // labelWidth: uiConfig.labelWidthMedium,
- on: {
- onChange: () => {
- this.onChange();
- },
- onViewShow() {
- this.setValue(labelValue);
- },
- },
- });
- return {
- cols: [
- {
- view: "richselect",
- label: `${L("Panel")} ${
- $dataPanelDCs.getChildViews().length + 1
- }`,
- labelWidth: uiConfig.labelWidthMedium,
- options: dcOptions,
- on: {
- onChange(newValue) {
- const $parentView = this.getParentView();
- const sameLevelViews = $parentView.getChildViews();
- if ($parentView.getChildViews().length === 3)
- $parentView.removeView(sameLevelViews[1].config.id);
- $parentView.addView(
- getUILabel(
- newValue,
- $dataPanelDCs
- .getChildViews()
- .findIndex(
- ($dataPanelDCsChild) =>
- $dataPanelDCsChild === $parentView,
- ),
- ),
- 1,
- );
- },
- onViewShow() {
- if (dcID == null || dcID === "") return;
- this.setValue(dcID);
- },
- },
- },
- {
- view: "button",
- css: "webix_danger",
- type: "icon",
- icon: "wxi-close",
- width: uiConfig.buttonWidthExtraSmall,
- click() {
- self.deleteDataPanelDC(this.getParentView().config.id);
- self.onChange();
- },
- },
- ],
- };
- }
-
- _uiContentDisplayedField(fieldID = "", obj, atDisplay) {
- const self = this;
- const ids = self.ids;
- const datasource = this.CurrentView.datacollection.datasource;
- const datasourceID = datasource.id;
- const parentObj = datasource.fieldByID(
- $$(ids.contentField).getValue(),
- ).datasourceLink;
- const parentObjID = parentObj.id;
- const objID = obj?.id || parentObjID;
- const $contentDisplayedFields = $$(ids.contentDisplayedFields);
- const filterFields = (f) => {
- const linkedObjID = f.datasourceLink?.id;
- return linkedObjID !== datasourceID && linkedObjID !== parentObjID;
- };
- const mapFields = (f) => ({
- id: f.id,
- value: f.label,
- field: f,
- });
- const getOnSelectChangeFn =
- (currentObj, currentAtDisplay) => (newValue) => {
- const field = currentObj.fieldByID(newValue);
- if (field.key === "connectObject") {
- $contentDisplayedFields.addView(
- this._uiContentDisplayedField(
- "",
- field.datasourceLink,
- currentAtDisplay,
- ),
- );
- }
- this.populateContentDisplayedFields(
- $contentDisplayedFields.getValues(),
- );
- this.onChange();
- };
- if (objID === parentObjID) {
- const rootAtDisplay = Object.keys(
- $contentDisplayedFields.elements,
- ).filter((key) => key.includes(objID)).length;
- return {
- cols: [
- {
- view: "richselect",
- name: `${rootAtDisplay}.${parentObjID}`,
- label: `${L("Display")} ${rootAtDisplay + 1}`,
- labelWidth: uiConfig.labelWidthMedium,
- options:
- parentObj.fields(filterFields).map(mapFields) || [],
- value: fieldID,
- on: {
- onChange: getOnSelectChangeFn(parentObj, rootAtDisplay),
- },
- },
- {
- view: "button",
- css: "webix_danger",
- type: "icon",
- icon: "wxi-close",
- width: uiConfig.buttonWidthExtraSmall,
- click() {
- self.deleteContentDisplayedField(
- this.getParentView().getChildViews()[0].config.id,
- );
- self.onChange();
- },
- },
- ],
- };
- }
- return {
- cols: [
- {
- view: "richselect",
- name: `${atDisplay}.${objID}`,
- label: "->",
- labelWidth: uiConfig.labelWidthMedium,
- options: obj.fields(filterFields).map(mapFields) || [],
- value: fieldID,
- on: {
- onChange: getOnSelectChangeFn(obj, atDisplay),
- },
- },
- {
- view: "button",
- css: "webix_danger",
- type: "icon",
- icon: "wxi-close",
- width: uiConfig.buttonWidthExtraSmall,
- click() {
- self.deleteContentDisplayedField(
- this.getParentView().getChildViews()[0].config.id,
- );
- self.onChange();
- },
- },
- ],
- };
- }
-
- ui() {
- const ids = this.ids;
- const contentFieldFilter = this.contentFieldFilter;
- return super.ui([
- {
- id: ids.datacollectionID,
- name: "datacollectionID",
- view: "richselect",
- label: L("Team Data"),
- labelWidth: uiConfig.labelWidthLarge,
- options: [],
- on: {
- onChange: (value) => {
- this.CurrentView.settings.datacollectionID = value;
- const obj = this.CurrentView?.datacollection?.datasource;
- this.populateTeamFieldOptions(obj);
- this.onChange();
- },
- },
- },
- {
- id: ids.teamLink,
- view: "richselect",
- label: L("Team Link"),
- labelWidth: uiConfig.labelWidthLarge,
- options: [],
- on: { onChange: () => this.onChange() },
- },
- {
- id: ids.teamName,
- view: "richselect",
- label: L("Team Name"),
- labelWidth: uiConfig.labelWidthLarge,
- options: [],
- on: { onChange: () => this.onChange() },
- },
- {
- id: ids.topTeam,
- view: "richselect",
- label: L("Top Team"),
- labelWidth: uiConfig.labelWidthLarge,
- options: [],
- on: { onChange: () => this.onChange() },
- },
- {
- id: ids.teamInactive,
- view: "richselect",
- label: L("Team Inactive"),
- labelWidth: uiConfig.labelWidthLarge,
- options: [],
- on: { onChange: () => this.onChange() },
- },
- {
- id: ids.teamCanInactivate,
- view: "richselect",
- label: L("Can Inactivate"),
- labelWidth: uiConfig.labelWidthLarge,
- options: [],
- on: { onChange: () => this.onChange() },
- },
- {
- cols: [
- {
- view: "label",
- label: L("Content Field"),
- width: uiConfig.labelWidthLarge,
- },
- {
- id: ids.contentField,
- name: "contentField",
- view: "richselect",
- options: [],
- on: {
- onChange: (newValue) => {
- const $contentDisplayedFieldsAdd = $$(
- ids.contentDisplayedFieldsAdd,
- );
- const $contentFieldFilterButton = $$(
- ids.contentFieldFilterButton,
- );
- const $contentGroupByField = $$(
- ids.contentGroupByField,
- );
- const $showGroupTitle = $$(ids.showGroupTitle);
- contentFieldFilter.init();
- contentFieldFilter.setValue({
- glue: "and",
- rules: [],
- });
- if (newValue != null && newValue !== "") {
- const contentObj =
- this.CurrentView.datacollection.datasource.fieldByID(
- newValue,
- ).datasourceLink;
- contentFieldFilter.fieldsLoad(
- contentObj.fields(),
- );
- $contentGroupByField.setValue("");
- $contentGroupByField.define("options", [
- { id: "", value: "", $empty: true },
- ...contentObj
- .fields(
- (f) =>
- f.key === "list" &&
- f.settings.isMultiple === 0,
- )
- .map((f) => ({
- id: f.id,
- value: f.label,
- field: f,
- })),
- ]);
- $contentFieldFilterButton.enable();
- $contentDisplayedFieldsAdd.show();
- $contentGroupByField.show();
- $showGroupTitle.show();
- } else {
- contentFieldFilter.fieldsLoad([]);
- $contentGroupByField.define("options", []);
- $contentFieldFilterButton.disable();
- $contentDisplayedFieldsAdd.hide();
- $contentGroupByField.hide();
- $showGroupTitle.hide();
- }
- $showGroupTitle.setValue(0);
- $contentGroupByField.setValue("");
- this.populateContentDisplayedFields({});
- this.onChange();
- },
- },
- },
- {
- id: ids.contentFieldFilterButton,
- view: "button",
- type: "icon",
- icon: "fa fa-filter",
- css: "webix_primary",
- disabled: true,
- width: uiConfig.buttonWidthExtraSmall,
- click() {
- contentFieldFilter.popUp(this.$view, null, {
- pos: "top",
- });
- },
- },
- ],
- },
- {
- id: ids.contentGroupByField,
- hidden: true,
- view: "richselect",
- label: L("Content Group By Field"),
- labelWidth: uiConfig.labelWidthLarge,
- options: [],
- on: {
- onChange: (newValue) => {
- this.onChange();
- },
- },
- },
- {
- id: ids.showGroupTitle,
- hidden: true,
- name: "showGroupTitle",
- view: "checkbox",
- label: L("Show Group Title"),
- labelWidth: uiConfig.labelWidthLarge,
- value: 0,
- on: {
- onChange: (newValue) => {
- this.onChange();
- },
- },
- },
- {
- id: ids.contentDisplayedFieldsAdd,
- hidden: true,
- cols: [
- {
- view: "label",
- label: L("Content Displayed Fields"),
- },
- {
- view: "button",
- type: "icon",
- icon: "fa fa-plus",
- css: "webix_primary",
- width: uiConfig.buttonWidthExtraSmall,
- click: () => {
- const $contentDisplayedFields = $$(
- ids.contentDisplayedFields,
- );
- if (!$contentDisplayedFields.isVisible())
- $contentDisplayedFields.show();
- $contentDisplayedFields.addView(
- this._uiContentDisplayedField(),
- );
- },
- },
- ],
- },
- {
- id: ids.contentDisplayedFields,
- view: "form",
- hidden: true,
- elements: [],
- },
- {
- id: ids.showDataPanel,
- name: "showDataPanel",
- view: "checkbox",
- label: L("Show Data Panel"),
- labelWidth: uiConfig.labelWidthLarge,
- value: 0,
- on: {
- onChange: (newValue) => {
- const $dataPanelDCsAdd = $$(ids.dataPanelDCsAdd);
- if (newValue === 1) $dataPanelDCsAdd.show();
- else $dataPanelDCsAdd.hide();
- this.populateDataPanelDCs({});
- this.onChange();
- },
- },
- },
- {
- id: ids.dataPanelDCsAdd,
- hidden: true,
- cols: [
- {
- view: "label",
- label: L("Data Panel DCs"),
- },
- {
- view: "button",
- type: "icon",
- icon: "fa fa-plus",
- css: "webix_primary",
- width: uiConfig.buttonWidthExtraSmall,
- click: () => {
- const $dataPanelDCs = $$(ids.dataPanelDCs);
- if (!$dataPanelDCs.isVisible()) $dataPanelDCs.show();
- $dataPanelDCs.addView(this._uiDataPanelDC());
- },
- },
- ],
- },
- {
- id: ids.dataPanelDCs,
- view: "form",
- hidden: true,
- elements: [],
- },
- {
- id: ids.teamStrategy,
- view: "richselect",
- label: L("Strategy"),
- labelWidth: uiConfig.labelWidthLarge,
- options: [],
- on: {
- onChange: (value) => {
- this.populateStrategyOptions(value);
- this.onChange();
- },
- },
- },
- {
- cols: [
- {
- id: ids.strategyCode,
- view: "richselect",
- label: L("Strategy Code"),
- labelWidth: uiConfig.labelWidthLarge,
- options: [],
- on: {
- onChange: () => {
- this.onChange();
- $$(this.ids.strategyColorPopup)?.close();
- },
- },
- },
- {
- view: "icon",
- icon: "fa fa-paint-brush",
- allign: "right",
- click: () => this.strategyColorPopup(),
- },
- ],
- },
- {
- id: ids.draggable,
- name: "draggable",
- view: "checkbox",
- label: L("Drag & Drop"),
- labelWidth: uiConfig.labelWidthLarge,
- value: 0,
- on: {
- onChange: (newValue) => {
- const $dropContentToCreate = $$(ids.dropContentToCreate);
- if (newValue === 0) {
- $dropContentToCreate.setValue(0);
- $dropContentToCreate.hide();
- } else $dropContentToCreate.show();
- this.onChange();
- },
- },
- },
- {
- id: ids.dropContentToCreate,
- name: "dropContentToCreate",
- view: "checkbox",
- label: L("Drop content to create"),
- labelWidth: uiConfig.labelWidthLarge,
- hidden: true,
- value: 0,
- on: { onChange: () => this.onChange() },
- },
- {
- id: ids.direction,
- name: "direction",
- view: "richselect",
- label: L("Direction"),
- labelWidth: uiConfig.labelWidthLarge,
- options: [
- { id: "t2b", value: L("Top to Bottom") },
- { id: "b2t", value: L("Bottom to Top") },
- { id: "l2r", value: L("Left to Right") },
- { id: "r2l", value: L("Right to Left") },
- ],
- on: { onChange: () => this.onChange() },
- },
- {
- id: ids.depth,
- name: "depth",
- hidden: true, // NOTE: use choose Connect Fields option
- view: "counter",
- label: L("Depth"),
- labelWidth: uiConfig.labelWidthLarge,
- value: 0,
- on: { onChange: () => this.onChange() },
- },
- {
- id: ids.color,
- name: "color",
- view: "colorpicker",
- label: L("Color"),
- labelWidth: uiConfig.labelWidthLarge,
- on: { onChange: () => this.onChange() },
- },
- {
- hidden: true, // NOTE: does not support
- id: ids.pan,
- name: "pan",
- view: "checkbox",
- label: L("Pan"),
- labelWidth: uiConfig.labelWidthLarge,
- value: 0,
- on: { onChange: () => this.onChange() },
- },
- {
- hidden: true, // NOTE: does not support
- id: ids.zoom,
- name: "zoom",
- view: "checkbox",
- label: L("Zoom"),
- labelWidth: uiConfig.labelWidthLarge,
- value: 0,
- on: { onChange: () => this.onChange() },
- },
- {
- id: ids.height,
- view: "counter",
- name: "height",
- label: L("Height"),
- labelWidth: uiConfig.labelWidthLarge,
- on: { onChange: () => this.onChange() },
- },
- {
- hidden: true, // NOTE: does not support
- view: "fieldset",
- label: L("Export"),
- body: {
- view: "layout",
- borderless: true,
- rows: [
- {
- id: ids.export,
- name: "export",
- view: "checkbox",
- label: L("Is Exportable"),
- labelWidth: uiConfig.labelWidthLarge,
- value: 0,
- on: {
- onChange: () => {
- this.onChange();
- },
- },
- },
- {
- id: ids.exportFilename,
- view: "text",
- name: "exportFilename",
- label: L("File name"),
- placeholder: L("Enter file name"),
- labelWidth: uiConfig.labelWidthLarge,
- },
- ],
- },
- },
- ]);
- }
-
- async init(AB) {
- this.AB = AB;
- await super.init(AB);
- webix.extend($$(this.ids.component), webix.ProgressBar);
- this.contentFieldFilter.queriesLoad(
- this.CurrentApplication?.queriesIncluded(),
- );
- }
-
- deleteContentDisplayedField(id) {
- const ids = this.ids;
- const $contentDisplayedFields = $$(ids.contentDisplayedFields);
- const $elements = $contentDisplayedFields.elements;
- const $richselect = $$(id);
- const deletedElementKey = $richselect.config.name;
- if (
- deletedElementKey.includes(
- this.CurrentView.datacollection.datasource.fieldByID(
- $$(ids.contentField).getValue(),
- ).datasourceLink.id,
- )
- ) {
- const deletedAtDisplay = deletedElementKey.split(".")[0];
- for (const key in $elements) {
- if (!key.includes(`${deletedAtDisplay}.`)) continue;
- $contentDisplayedFields.removeView(
- $elements[key].getParentView().config.id,
- );
- }
- } else
- $contentDisplayedFields.removeView(
- $richselect.getParentView().config.id,
- );
- this.populateContentDisplayedFields(
- $contentDisplayedFields.getValues(),
- );
- }
-
- deleteDataPanelDC(id) {
- const $dataPanelDCs = $$(this.ids.dataPanelDCs);
- $dataPanelDCs.removeView(id);
- this.populateDataPanelDCs($dataPanelDCs.getValues());
- }
-
- populate(view) {
- super.populate(view);
- const ids = this.ids;
- const $component = $$(ids.component);
- const defaultValues = this.defaultValues();
- const values = Object.assign(
- $component.getValues(),
- Object.assign(defaultValues, view.settings),
- );
- // const $fieldList = $$(ids.fields);
- // $fieldList.clearAll();
- this.populateDatacollection(values.datacollectionId);
- const teamObj = this.CurrentView?.datacollection?.datasource;
- if (teamObj) {
- this.populateTeamFieldOptions(teamObj);
- [
- "teamCanInactivate",
- "teamInactive",
- "teamLink",
- "teamName",
- "teamStrategy",
- "topTeam",
- "contentField",
- "contentGroupByField",
- "showGroupTitle",
- "showDataPanel",
- ].forEach((f) => $$(ids[f]).setValue(values[f]));
- this.contentFieldFilter.setValue(
- JSON.parse(values.contentFieldFilter),
- );
- this.populateContentDisplayedFields(values.contentDisplayedFields);
- this.populateDataPanelDCs(values.dataPanelDCs);
- if (values.teamStrategy) {
- this.populateStrategyOptions(values.teamStrategy);
- $$(ids.strategyCode).setValue(values.strategyCode);
- }
- }
- $component.setValues(values);
- }
-
- populateDatacollection(datacollectionId) {
- const $dataCollection = $$(this.ids.datacollectionID);
-
- // Pull data collections to options
- const dcOptions = this.CurrentView.application
- .datacollectionsIncluded()
- .map((d) => {
- return { id: d.id, value: d.label };
- });
- $dataCollection.define("options", dcOptions);
- $dataCollection.define("value", datacollectionId);
- $dataCollection.refresh();
- }
-
- refreshValueFieldOptions(fieldValues = []) {
- const ids = this.ids;
- const view = this.CurrentView;
- const $fieldList = $$(ids.fields);
-
- $fieldList.clearAll();
-
- // Populate 1:M fields option of the root object
- this.populateSubValueFieldOptions(view.datacollection?.datasource);
-
- // Populate sub 1:M fields option of each fields
- fieldValues.forEach((fId) => {
- if (!fId) return;
-
- const $fieldItem = $fieldList.getItem(fId);
- if ($fieldItem) {
- const abField = $fieldItem.field;
- this.populateSubValueFieldOptions(abField.datasourceLink, fId);
- }
- });
-
- // Set check items
- $fieldList.blockEvent();
- fieldValues.forEach((fId) => {
- if ($fieldList.exists(fId)) $fieldList.checkItem(fId);
- });
- $fieldList.unblockEvent();
- }
-
- populateTeamFieldOptions(object) {
- const view = this.CurrentView;
- // const linkFields = view.getValueFields(object).map(fieldToOption);
- const ids = this.ids;
- const m2oFields = view.getValueFields(object).map(fieldToOption);
- const o2mFields =
- object.connectFields(
- (f) => f.linkType() == "one" && f.linkViaType() == "many",
- ) ?? [];
- $$(ids.teamStrategy).define("options", o2mFields.map(fieldToOption));
- $$(ids.teamLink).define("options", m2oFields);
- const textFields = object
- ?.fields((f) => f.key === "string")
- .map(fieldToOption);
- $$(ids.teamName).define("options", textFields);
- const booleanFields = object
- ?.fields((f) => f.key === "boolean")
- .map(fieldToOption);
-
- // Add an empty option as this is an optional setting.
- booleanFields.unshift({ id: "", value: "", $empty: true });
- $$(ids.topTeam).define("options", booleanFields);
- $$(ids.teamInactive).define("options", booleanFields);
- $$(ids.teamCanInactivate).define("options", booleanFields);
- $$(ids.contentField).define("options", [
- { id: "", value: "", $empty: true },
- ...m2oFields,
- ]);
- }
-
- populateContentDisplayedFields(values) {
- const ids = this.ids;
- const $contentDisplayedFields = $$(ids.contentDisplayedFields);
- const elements = $contentDisplayedFields.elements;
- for (const key in elements)
- $contentDisplayedFields.removeView(
- elements[key].getParentView().config.id,
- );
- const keys = Object.keys(values);
- const obj = this.CurrentView.datacollection.datasource.fieldByID(
- $$(ids.contentField).getValue(),
- )?.datasourceLink;
- if (keys.length === 0) {
- $contentDisplayedFields.hide();
- return;
- }
- if (obj == null) {
- $contentDisplayedFields.hide();
- $$(ids.contentDisplayedFieldsAdd).hide();
- return;
- }
- const objID = obj.id;
- const parentKeys = [];
- const childKeys = [];
- while (keys.length > 0) {
- const key = keys.pop();
- (key.includes(objID) && parentKeys.push(key)) ||
- childKeys.push(key);
- }
- while (parentKeys.length > 0) {
- const parentKey = parentKeys.pop();
- const parentFieldID = values[parentKey] ?? "";
- $contentDisplayedFields.addView(
- this._uiContentDisplayedField(parentFieldID),
- );
- if (
- parentFieldID === "" ||
- obj.fieldByID(parentFieldID).key !== "connectObject"
- )
- continue;
- const currentAtDisplay =
- Object.keys($contentDisplayedFields.getValues()).filter(
- (currentKey) => currentKey.includes(objID),
- ).length - 1;
- while (
- childKeys.findIndex((childKey) =>
- childKey.includes(`${parentKey.split(".")[0]}.`),
- ) > -1
- ) {
- const childKey = childKeys.pop();
- const childObj = this.AB.objectByID(childKey.split(".")[1]);
- const childFieldID = values[childKey] ?? "";
- $contentDisplayedFields.addView(
- this._uiContentDisplayedField(
- childFieldID,
- childObj,
- currentAtDisplay,
- ),
- );
- if (
- childFieldID === "" ||
- childObj.fieldByID(childFieldID).key !== "connectObject"
- )
- break;
- }
- }
- $contentDisplayedFields.show();
- }
-
- populateDataPanelDCs(values) {
- const ids = this.ids;
- const $dataPanelDCs = $$(ids.dataPanelDCs);
- const dataPanelDCsChidren = $dataPanelDCs.getChildViews();
- while (dataPanelDCsChidren.length > 0)
- $dataPanelDCs.removeView(dataPanelDCsChidren[0].config.id);
- $dataPanelDCs.hide();
- const contentFieldValue = $$(ids.contentField).getValue();
- const keys = Object.keys(values);
- if (
- contentFieldValue == null ||
- contentFieldValue === "" ||
- keys.length === 0
- )
- return;
- while (keys.length > 0) {
- const key = keys.shift();
- $dataPanelDCs.addView(
- this._uiDataPanelDC(values[key] ?? "", key.split(".")[1] ?? ""),
- );
- }
- $dataPanelDCs.show();
- }
-
- populateStrategyOptions(fieldID) {
- const strategyObj = this.AB.objectByID(
- this.AB.definitionByID(fieldID).settings.linkObject,
- );
- const listFields = strategyObj
- .fields((f) => f.key === "list")
- .map(fieldToOption);
- $$(this.ids.strategyCode).define("options", listFields);
- }
-
- strategyColorPopup() {
- const codeFieldID = $$(this.ids.strategyCode).getValue();
- if (!codeFieldID) return;
-
- let $popup = $$(this.ids.strategyColorPopup);
-
- if (!$popup) {
- const values = this.CurrentView.settings.strategyColors ?? {};
- const strategyTypes = this.AB.definitionByID(
- codeFieldID,
- ).settings.options.map((strategy) => {
- return {
- view: "colorpicker",
- label: strategy.text,
- name: strategy.id,
- value: values[strategy.id] ?? "#111111",
- };
- });
-
- $popup = this.AB.Webix.ui({
- view: "window",
- id: this.ids.strategyColorPopup,
- close: true,
- title: L("Set Colors"),
- position: "center",
- body: {
- view: "form",
- id: this.ids.strategyColorForm,
- elements: [
- ...strategyTypes,
- {
- view: "button",
- label: L("Apply"),
- click: () => {
- this.onChange();
- $$(this.ids.strategyColorPopup).hide();
- },
- },
- ],
- },
- });
- }
- $popup.show();
- }
-
- // populateDescriptionFieldOptions(fieldId) {
- // const valueField = this.CurrentView.valueField();
- // const $columnDescription = $$(this.ids.columnDescription);
-
- // const connectFieldOpts =
- // valueField?.datasourceLink
- // ?.fields?.((f) => f.key != "connectObject")
- // .map?.((f) => {
- // return {
- // id: f.id,
- // value: f.label,
- // };
- // }) ?? [];
- // $columnDescription.define("options", connectFieldOpts);
- // $columnDescription.define("value", fieldId);
- // $columnDescription.refresh();
- // }
-
- defaultValues() {
- const ViewClass = this.ViewClass();
-
- let values = null;
-
- if (ViewClass) {
- values = ViewClass.defaultValues();
- }
-
- return values;
- }
-
- /**
- * @method values
- * return the values for this form.
- * @return {obj}
- */
- values() {
- const values = super.values();
- const ids = this.ids;
- const settings = (values.settings = Object.assign(
- $$(ids.component).getValues(),
- values.settings,
- ));
- // Retrive the values of your properties from Webix and store them in the view
- settings.teamLink = $$(ids.teamLink).getValue();
- settings.teamName = $$(ids.teamName).getValue();
- settings.topTeam = $$(ids.topTeam).getValue();
- settings.teamInactive = $$(ids.teamInactive).getValue();
- settings.teamCanInactivate = $$(ids.teamCanInactivate).getValue();
- settings.teamStrategy = $$(ids.teamStrategy).getValue();
- settings.strategyCode = $$(ids.strategyCode).getValue();
- settings.dataCollectionId = $$(ids.datacollectionID).getValue();
- settings.contentField = $$(ids.contentField).getValue();
- settings.contentGroupByField = $$(ids.contentGroupByField).getValue();
- settings.contentFieldFilter = JSON.stringify(
- this.contentFieldFilter.getValue(),
- );
- settings.contentDisplayedFields = $$(
- ids.contentDisplayedFields,
- ).getValues();
- settings.dataPanelDCs = $$(ids.dataPanelDCs).getValues();
- const $colorForm = $$(ids.strategyColorForm);
- settings.strategyColors = $colorForm?.getValues() ?? {};
- return values;
- }
-
- /**
- * @method FieldClass()
- * A method to return the proper ABViewXXX Definition.
- * NOTE: Must be overwritten by the Child Class
- */
- ViewClass() {
- return super._ViewClass("orgchart_teams");
- }
- }
-
- return ABViewOrgChartTeamsProperty;
-}
-
-function fieldToOption(f) {
- return {
- id: f.id,
- value: f.label,
- field: f,
- };
-}