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/32] 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/32] 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/32] 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/32] 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/32] [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/32] 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/32] 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/32] [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/32] 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/32] [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/32] 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/32] [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/32] [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/32] 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 ccda766c5a67f2c4ceed8ca04102e76ed0fd413b Mon Sep 17 00:00:00 2001
From: guyyoo
Date: Tue, 19 Nov 2024 17:39:21 +0700
Subject: [PATCH 15/32] Team Widget can edit assignments
---
.../properties/views/ABViewOrgChartTeams.js | 61 +++++++++++++------
1 file changed, 43 insertions(+), 18 deletions(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index b06b6ac1..29e57aff 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -36,6 +36,7 @@ export default function (AB) {
exportFilename: "",
groupByField: "",
showGroupTitle: "",
+ editContentFieldsToCreateNew: "",
contentField: "",
contentFieldFilter: "",
contentFieldFilterButton: "",
@@ -162,11 +163,6 @@ export default function (AB) {
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);
@@ -196,7 +192,7 @@ export default function (AB) {
label: `${L("Display")} ${rootAtDisplay + 1}`,
labelWidth: uiConfig.labelWidthMedium,
options:
- parentObj.fields(filterFields).map(mapFields) || [],
+ parentObj.fields(filterFields).map(fieldToOption) || [],
value: fieldID,
on: {
onChange: getOnSelectChangeFn(parentObj, rootAtDisplay),
@@ -225,7 +221,7 @@ export default function (AB) {
name: `${atDisplay}.${objID}`,
label: "->",
labelWidth: uiConfig.labelWidthMedium,
- options: obj.fields(filterFields).map(mapFields) || [],
+ options: obj.fields(filterFields).map(fieldToOption) || [],
value: fieldID,
on: {
onChange: getOnSelectChangeFn(obj, atDisplay),
@@ -322,6 +318,9 @@ export default function (AB) {
options: [],
on: {
onChange: (newValue) => {
+ const $editContentFieldsToCreateNew = $$(
+ ids.editContentFieldsToCreateNew,
+ );
const $contentDisplayedFieldsAdd = $$(
ids.contentDisplayedFieldsAdd,
);
@@ -342,36 +341,45 @@ export default function (AB) {
this.CurrentView.datacollection.datasource.fieldByID(
newValue,
).datasourceLink;
- contentFieldFilter.fieldsLoad(
- contentObj.fields(),
+ const contentObjFields = contentObj.fields();
+ $editContentFieldsToCreateNew.define(
+ "options",
+ // contentObjFields.map(fieldToOption),
+ contentObjFields.map((contentObjField) => ({
+ id: contentObjField.id,
+ value: contentObjField.label,
+ })),
);
- $contentGroupByField.setValue("");
+ contentFieldFilter.fieldsLoad(contentObjFields);
$contentGroupByField.define("options", [
{ id: "", value: "", $empty: true },
- ...contentObj
- .fields(
+ ...contentObjFields
+ .filter(
(f) =>
f.key === "list" &&
f.settings.isMultiple === 0,
)
- .map((f) => ({
- id: f.id,
- value: f.label,
- field: f,
- })),
+ .map(fieldToOption),
]);
+ $editContentFieldsToCreateNew.enable();
$contentFieldFilterButton.enable();
$contentDisplayedFieldsAdd.show();
$contentGroupByField.show();
$showGroupTitle.show();
} else {
+ $editContentFieldsToCreateNew.define(
+ "options",
+ [],
+ );
contentFieldFilter.fieldsLoad([]);
$contentGroupByField.define("options", []);
+ $editContentFieldsToCreateNew.enable();
$contentFieldFilterButton.disable();
$contentDisplayedFieldsAdd.hide();
$contentGroupByField.hide();
$showGroupTitle.hide();
}
+ $editContentFieldsToCreateNew.setValue([]);
$showGroupTitle.setValue(0);
$contentGroupByField.setValue("");
this.populateContentDisplayedFields({});
@@ -422,6 +430,20 @@ export default function (AB) {
},
},
},
+ {
+ id: ids.editContentFieldsToCreateNew,
+ view: "multicombo",
+ value: [],
+ options: [],
+ placeholder: L("Choose content fields to create new by editing"),
+ labelAlign: "left",
+ stringResult: false /* returns data as an array of [id] */,
+ on: {
+ onChange: (newValue) => {
+ this.onChange();
+ },
+ },
+ },
{
id: ids.contentDisplayedFieldsAdd,
hidden: true,
@@ -727,6 +749,7 @@ export default function (AB) {
"topTeam",
"contentField",
"contentGroupByField",
+ "editContentFieldsToCreateNew",
"showGroupTitle",
"showDataPanel",
].forEach((f) => $$(ids[f]).setValue(values[f]));
@@ -788,7 +811,6 @@ export default function (AB) {
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 =
@@ -1017,6 +1039,9 @@ export default function (AB) {
settings.dataCollectionId = $$(ids.datacollectionID).getValue();
settings.contentField = $$(ids.contentField).getValue();
settings.contentGroupByField = $$(ids.contentGroupByField).getValue();
+ settings.editContentFieldsToCreateNew = $$(
+ ids.editContentFieldsToCreateNew,
+ ).getValue();
settings.contentFieldFilter = JSON.stringify(
this.contentFieldFilter.getValue(),
);
From e134f7aa039d1d94fa8e67b5214b37817a8e0943 Mon Sep 17 00:00:00 2001
From: Johnny
Date: Wed, 20 Nov 2024 14:04:15 +0700
Subject: [PATCH 16/32] [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 5dfeab48c0883ab67f88e3c4f6b41527ec261adb Mon Sep 17 00:00:00 2001
From: guyyoo
Date: Wed, 20 Nov 2024 15:01:34 +0700
Subject: [PATCH 17/32] Fix layout
---
.../properties/views/ABViewOrgChartTeams.js | 32 ++++++++++++-------
1 file changed, 21 insertions(+), 11 deletions(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index 29e57aff..e7dfb9ba 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -431,18 +431,28 @@ export default function (AB) {
},
},
{
- id: ids.editContentFieldsToCreateNew,
- view: "multicombo",
- value: [],
- options: [],
- placeholder: L("Choose content fields to create new by editing"),
- labelAlign: "left",
- stringResult: false /* returns data as an array of [id] */,
- on: {
- onChange: (newValue) => {
- this.onChange();
+ rows: [
+ {
+ view: "label",
+ label: L("Create new by editing content fields"),
},
- },
+ {
+ id: ids.editContentFieldsToCreateNew,
+ view: "multicombo",
+ value: [],
+ options: [],
+ placeholder: L(
+ "Choose content fields to create new by editing",
+ ),
+ labelAlign: "left",
+ stringResult: false /* returns data as an array of [id] */,
+ on: {
+ onChange: (newValue) => {
+ this.onChange();
+ },
+ },
+ },
+ ],
},
{
id: ids.contentDisplayedFieldsAdd,
From a5c7c43b73f128794e0b4300f2b5622d2aa6670e Mon Sep 17 00:00:00 2001
From: nh758 <7259@pm.me>
Date: Fri, 22 Nov 2024 13:02:51 +0700
Subject: [PATCH 18/32] fix data types to match real data
---
.../properties/views/ABViewOrgChartTeams.js | 116 +++++++++---------
1 file changed, 56 insertions(+), 60 deletions(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index 29e57aff..45a2c4d5 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -55,7 +55,7 @@ export default function (AB) {
contentFieldFilter.on("save", () => {
if (
!contentFieldFilter.isConditionComplete(
- contentFieldFilter.getValue(),
+ contentFieldFilter.getValue()
)
)
contentFieldFilter.setValue({ glue: "and", rules: [] });
@@ -74,11 +74,11 @@ export default function (AB) {
const validOBJIDs = this.CurrentView.datacollection.datasource
.fieldByID($$(ids.contentField).getValue())
.datasourceLink.connectFields(
- (connectField) => connectField.linkType() === "one",
+ (connectField) => connectField.linkType() === "one"
)
.map((connectField) => connectField.datasourceLink.id);
const dcs = this.AB.datacollections(
- (dc) => validOBJIDs.indexOf(dc.datasource.id) > -1,
+ (dc) => validOBJIDs.indexOf(dc.datasource.id) > -1
);
const dcOptions = dcs.map((dc) => ({
id: dc.id,
@@ -121,10 +121,10 @@ export default function (AB) {
.getChildViews()
.findIndex(
($dataPanelDCsChild) =>
- $dataPanelDCsChild === $parentView,
- ),
+ $dataPanelDCsChild === $parentView
+ )
),
- 1,
+ 1
);
},
onViewShow() {
@@ -154,7 +154,7 @@ export default function (AB) {
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;
@@ -171,18 +171,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: [
@@ -206,7 +206,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();
},
@@ -235,7 +235,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();
},
@@ -319,16 +319,16 @@ export default function (AB) {
on: {
onChange: (newValue) => {
const $editContentFieldsToCreateNew = $$(
- ids.editContentFieldsToCreateNew,
+ ids.editContentFieldsToCreateNew
);
const $contentDisplayedFieldsAdd = $$(
- ids.contentDisplayedFieldsAdd,
+ ids.contentDisplayedFieldsAdd
);
const $contentFieldFilterButton = $$(
- ids.contentFieldFilterButton,
+ ids.contentFieldFilterButton
);
const $contentGroupByField = $$(
- ids.contentGroupByField,
+ ids.contentGroupByField
);
const $showGroupTitle = $$(ids.showGroupTitle);
contentFieldFilter.init();
@@ -339,25 +339,20 @@ export default function (AB) {
if (newValue != null && newValue !== "") {
const contentObj =
this.CurrentView.datacollection.datasource.fieldByID(
- newValue,
+ newValue
).datasourceLink;
const contentObjFields = contentObj.fields();
$editContentFieldsToCreateNew.define(
"options",
- // contentObjFields.map(fieldToOption),
- contentObjFields.map((contentObjField) => ({
- id: contentObjField.id,
- value: contentObjField.label,
- })),
+ contentObjFields.map(fieldToOption)
);
contentFieldFilter.fieldsLoad(contentObjFields);
$contentGroupByField.define("options", [
{ id: "", value: "", $empty: true },
...contentObjFields
.filter(
- (f) =>
- f.key === "list" &&
- f.settings.isMultiple === 0,
+ (f) => f.key === "connectObject" //&&
+ // f.settings.isMultiple === 0
)
.map(fieldToOption),
]);
@@ -369,7 +364,7 @@ export default function (AB) {
} else {
$editContentFieldsToCreateNew.define(
"options",
- [],
+ []
);
contentFieldFilter.fieldsLoad([]);
$contentGroupByField.define("options", []);
@@ -411,7 +406,7 @@ export default function (AB) {
labelWidth: uiConfig.labelWidthLarge,
options: [],
on: {
- onChange: (newValue) => {
+ onChange: (/*newValue*/) => {
this.onChange();
},
},
@@ -425,7 +420,7 @@ export default function (AB) {
labelWidth: uiConfig.labelWidthLarge,
value: 0,
on: {
- onChange: (newValue) => {
+ onChange: (/*newValue*/) => {
this.onChange();
},
},
@@ -439,7 +434,7 @@ export default function (AB) {
labelAlign: "left",
stringResult: false /* returns data as an array of [id] */,
on: {
- onChange: (newValue) => {
+ onChange: (/*newValue*/) => {
this.onChange();
},
},
@@ -460,12 +455,12 @@ export default function (AB) {
width: uiConfig.buttonWidthExtraSmall,
click: () => {
const $contentDisplayedFields = $$(
- ids.contentDisplayedFields,
+ ids.contentDisplayedFields
);
if (!$contentDisplayedFields.isVisible())
$contentDisplayedFields.show();
$contentDisplayedFields.addView(
- this._uiContentDisplayedField(),
+ this._uiContentDisplayedField()
);
},
},
@@ -686,7 +681,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()
);
}
@@ -699,23 +694,23 @@ 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()
);
}
@@ -732,7 +727,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();
@@ -754,7 +749,7 @@ export default function (AB) {
"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);
@@ -815,7 +810,7 @@ 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.teamLink).define("options", m2oFields);
@@ -844,11 +839,11 @@ 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(),
+ $$(ids.contentField).getValue()
)?.datasourceLink;
if (keys.length === 0) {
$contentDisplayedFields.hide();
@@ -871,7 +866,7 @@ export default function (AB) {
const parentKey = parentKeys.pop();
const parentFieldID = values[parentKey] ?? "";
$contentDisplayedFields.addView(
- this._uiContentDisplayedField(parentFieldID),
+ this._uiContentDisplayedField(parentFieldID)
);
if (
parentFieldID === "" ||
@@ -880,11 +875,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();
@@ -894,8 +889,8 @@ export default function (AB) {
this._uiContentDisplayedField(
childFieldID,
childObj,
- currentAtDisplay,
- ),
+ currentAtDisplay
+ )
);
if (
childFieldID === "" ||
@@ -925,7 +920,7 @@ export default function (AB) {
while (keys.length > 0) {
const key = keys.shift();
$dataPanelDCs.addView(
- this._uiDataPanelDC(values[key] ?? "", key.split(".")[1] ?? ""),
+ this._uiDataPanelDC(values[key] ?? "", key.split(".")[1] ?? "")
);
}
$dataPanelDCs.show();
@@ -933,15 +928,15 @@ export default function (AB) {
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")
+ .fields((f) => f.key === "connectObject")
.map(fieldToOption);
$$(this.ids.strategyCode).define("options", listFields);
}
- strategyColorPopup() {
+ async strategyColorPopup() {
const codeFieldID = $$(this.ids.strategyCode).getValue();
if (!codeFieldID) return;
@@ -949,12 +944,13 @@ export default function (AB) {
if (!$popup) {
const values = this.CurrentView.settings.strategyColors ?? {};
- const strategyTypes = this.AB.definitionByID(
- codeFieldID,
- ).settings.options.map((strategy) => {
+ const link =
+ this.AB.definitionByID(codeFieldID).settings.linkObject;
+ const strategies = await this.AB.objectByID(link).model().findAll();
+ const strategyTypes = strategies.data.map((strategy) => {
return {
view: "colorpicker",
- label: strategy.text,
+ label: strategy.name,
name: strategy.id,
value: values[strategy.id] ?? "#111111",
};
@@ -1026,7 +1022,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();
@@ -1040,13 +1036,13 @@ export default function (AB) {
settings.contentField = $$(ids.contentField).getValue();
settings.contentGroupByField = $$(ids.contentGroupByField).getValue();
settings.editContentFieldsToCreateNew = $$(
- ids.editContentFieldsToCreateNew,
+ ids.editContentFieldsToCreateNew
).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);
From 351e48138c4253f638c9b74d86b70e3a774243a5 Mon Sep 17 00:00:00 2001
From: guyyoo
Date: Fri, 22 Nov 2024 15:43:28 +0700
Subject: [PATCH 19/32] Content filter's feature settings
---
.../properties/views/ABViewOrgChartTeams.js | 143 +++++++++++++++---
1 file changed, 125 insertions(+), 18 deletions(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index e7dfb9ba..217038f8 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -43,6 +43,8 @@ export default function (AB) {
contentGroupByField: "",
contentDisplayedFields: "",
contentDisplayedFieldsAdd: "",
+ contentDisplayedFieldFilters: "",
+ contentDisplayedFieldFiltersSet: "",
showDataPanel: "",
dataPanelDCs: "",
dataPanelDCsAdd: "",
@@ -159,6 +161,9 @@ export default function (AB) {
const parentObjID = parentObj.id;
const objID = obj?.id || parentObjID;
const $contentDisplayedFields = $$(ids.contentDisplayedFields);
+ const $contentDisplayedFieldFilters = $$(
+ ids.contentDisplayedFieldFilters,
+ );
const filterFields = (f) => {
const linkedObjID = f.datasourceLink?.id;
return linkedObjID !== datasourceID && linkedObjID !== parentObjID;
@@ -177,6 +182,7 @@ export default function (AB) {
}
this.populateContentDisplayedFields(
$contentDisplayedFields.getValues(),
+ $contentDisplayedFieldFilters.getValues(),
);
this.onChange();
};
@@ -487,6 +493,21 @@ export default function (AB) {
hidden: true,
elements: [],
},
+ {
+ id: ids.contentDisplayedFieldFiltersSet,
+ hidden: false,
+ rows: [
+ {
+ view: "label",
+ label: L("Set content displayed filters by field"),
+ },
+ {
+ id: ids.contentDisplayedFieldFilters,
+ view: "form",
+ elements: [],
+ },
+ ],
+ },
{
id: ids.showDataPanel,
name: "showDataPanel",
@@ -766,7 +787,10 @@ export default function (AB) {
this.contentFieldFilter.setValue(
JSON.parse(values.contentFieldFilter),
);
- this.populateContentDisplayedFields(values.contentDisplayedFields);
+ this.populateContentDisplayedFields(
+ values.contentDisplayedFields,
+ values.contentDisplayedFieldFilters,
+ );
this.populateDataPanelDCs(values.dataPanelDCs);
if (values.teamStrategy) {
this.populateStrategyOptions(values.teamStrategy);
@@ -848,30 +872,99 @@ export default function (AB) {
]);
}
- populateContentDisplayedFields(values) {
+ populateContentDisplayedFields(values = {}, filters = {}) {
+ const self = this;
const ids = this.ids;
const $contentDisplayedFields = $$(ids.contentDisplayedFields);
- const elements = $contentDisplayedFields.elements;
- for (const key in elements)
+ const contentDisplayedFieldsElements =
+ $contentDisplayedFields.elements;
+ for (const key in contentDisplayedFieldsElements)
$contentDisplayedFields.removeView(
- elements[key].getParentView().config.id,
+ contentDisplayedFieldsElements[key].getParentView().config.id,
+ );
+ const $contentDisplayedFieldFilters = $$(
+ ids.contentDisplayedFieldFilters,
+ );
+ const contentDisplayedFieldFiltersElements =
+ $contentDisplayedFieldFilters.elements;
+ const $contentDisplayedFieldFiltersSet = $$(
+ ids.contentDisplayedFieldFiltersSet,
+ );
+ for (const key in contentDisplayedFieldFiltersElements)
+ $contentDisplayedFieldFilters.removeView(
+ contentDisplayedFieldFiltersElements[key].getParentView().config
+ .id,
);
+ $contentDisplayedFieldFiltersSet.hide();
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 filterKeys = Object.keys(filters);
const objID = obj.id;
const parentKeys = [];
const childKeys = [];
+ const createOptionsView = (key, field) => {
+ const filterPrefix = `${key}.${field.id}`;
+ const filterValue = parseInt(
+ filterKeys
+ .find((filterKey) => filterKey.indexOf(filterPrefix) > -1)
+ ?.split(".")[3],
+ );
+ $contentDisplayedFieldFilters.addView({
+ cols: [
+ {
+ view: "checkbox",
+ label: field.label,
+ labelWidth: uiConfig.labelWidthMedium,
+ value: isNaN(filterValue) ? 0 : filterValue,
+ on: {
+ onChange: (newValue, oldValue) => {
+ const oldFilters =
+ $contentDisplayedFieldFilters.getValues();
+ const oldFilterEntries = Object.entries(oldFilters);
+ const newFilters = {};
+ const oldFilterKey = `${filterPrefix}.${oldValue}`;
+ for (const [key, value] of oldFilterEntries)
+ if (key === oldFilterKey)
+ newFilters[`${filterPrefix}.${newValue}`] = "";
+ else newFilters[key] = value;
+ this.populateContentDisplayedFields(
+ $contentDisplayedFields.getValues(),
+ newFilters,
+ );
+ this.onChange();
+ },
+ onViewShow() {
+ const checkboxValue = this.getValue();
+ const filterKey = `${filterPrefix}.${checkboxValue}`;
+ this.getParentView().addView({
+ view: "text",
+ placeholder: L("Add the new field label."),
+ name: filterKey,
+ value: filters[filterKey],
+ disabled: checkboxValue === 1 ? false : true,
+ on: {
+ onChange: () => {
+ self.onChange();
+ },
+ },
+ });
+ },
+ },
+ },
+ ],
+ });
+ };
while (keys.length > 0) {
const key = keys.pop();
(key.includes(objID) && parentKeys.push(key)) ||
@@ -883,11 +976,16 @@ export default function (AB) {
$contentDisplayedFields.addView(
this._uiContentDisplayedField(parentFieldID),
);
- if (
- parentFieldID === "" ||
- obj.fieldByID(parentFieldID).key !== "connectObject"
- )
- continue;
+ const parentField = obj.fieldByID(parentFieldID);
+ if (parentField == null) continue;
+ switch (parentField.key) {
+ case "connectObject":
+ case "user":
+ break;
+ default:
+ createOptionsView(parentKey, parentField);
+ continue;
+ }
const currentAtDisplay =
Object.keys($contentDisplayedFields.getValues()).filter(
(currentKey) => currentKey.includes(objID),
@@ -907,14 +1005,20 @@ export default function (AB) {
currentAtDisplay,
),
);
- if (
- childFieldID === "" ||
- childObj.fieldByID(childFieldID).key !== "connectObject"
- )
- break;
+ const childField = childObj.fieldByID(childFieldID);
+ if (childField == null) continue;
+ switch (childField.key) {
+ case "connectObject":
+ case "user":
+ break;
+ default:
+ createOptionsView(parentKey, childField);
+ continue;
+ }
}
}
$contentDisplayedFields.show();
+ $contentDisplayedFieldFiltersSet.show();
}
populateDataPanelDCs(values) {
@@ -1058,6 +1162,9 @@ export default function (AB) {
settings.contentDisplayedFields = $$(
ids.contentDisplayedFields,
).getValues();
+ settings.contentDisplayedFieldFilters = $$(
+ ids.contentDisplayedFieldFilters,
+ ).getValues();
settings.dataPanelDCs = $$(ids.dataPanelDCs).getValues();
const $colorForm = $$(ids.strategyColorForm);
settings.strategyColors = $colorForm?.getValues() ?? {};
From 76675435595b20d467b6d3be0c0e5ff73ddbf94f Mon Sep 17 00:00:00 2001
From: guyyoo
Date: Mon, 25 Nov 2024 11:47:48 +0700
Subject: [PATCH 20/32] Content filter settings and [WIP] maping field data
types
---
.../properties/views/ABViewOrgChartTeams.js | 189 ++++++++++++++++--
1 file changed, 175 insertions(+), 14 deletions(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index 28e346e8..278c65ee 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -45,6 +45,8 @@ export default function (AB) {
contentDisplayedFieldsAdd: "",
contentDisplayedFieldFilters: "",
contentDisplayedFieldFiltersSet: "",
+ contentDisplayedFieldTypes: "",
+ contentDisplayedFieldTypesSet: "",
showDataPanel: "",
dataPanelDCs: "",
dataPanelDCsAdd: "",
@@ -161,6 +163,7 @@ export default function (AB) {
const parentObjID = parentObj.id;
const objID = obj?.id || parentObjID;
const $contentDisplayedFields = $$(ids.contentDisplayedFields);
+ const $contentDisplayedFieldTypes = $$(ids.contentDisplayedFieldTypes);
const $contentDisplayedFieldFilters = $$(
ids.contentDisplayedFieldFilters
);
@@ -182,6 +185,7 @@ export default function (AB) {
}
this.populateContentDisplayedFields(
$contentDisplayedFields.getValues(),
+ $contentDisplayedFieldTypes.getValues(),
$contentDisplayedFieldFilters.getValues()
);
this.onChange();
@@ -350,7 +354,11 @@ export default function (AB) {
const contentObjFields = contentObj.fields();
$editContentFieldsToCreateNew.define(
"options",
- contentObjFields.map(fieldToOption)
+ // contentObjFields.map(fieldToOption)
+ contentObjFields.map((contentObjField) => ({
+ id: contentObjField.id,
+ value: contentObjField.label,
+ }))
);
contentFieldFilter.fieldsLoad(contentObjFields);
$contentGroupByField.define("options", [
@@ -383,7 +391,7 @@ export default function (AB) {
$editContentFieldsToCreateNew.setValue([]);
$showGroupTitle.setValue(0);
$contentGroupByField.setValue("");
- this.populateContentDisplayedFields({});
+ this.populateContentDisplayedFields();
this.onChange();
},
},
@@ -488,9 +496,26 @@ export default function (AB) {
hidden: true,
elements: [],
},
+ {
+ id: ids.contentDisplayedFieldTypesSet,
+ hidden: true,
+ rows: [
+ {
+ view: "label",
+ label: L(
+ "Set content active displays and displayed types"
+ ),
+ },
+ {
+ id: ids.contentDisplayedFieldTypes,
+ view: "form",
+ elements: [],
+ },
+ ],
+ },
{
id: ids.contentDisplayedFieldFiltersSet,
- hidden: false,
+ hidden: true,
rows: [
{
view: "label",
@@ -784,6 +809,7 @@ export default function (AB) {
);
this.populateContentDisplayedFields(
values.contentDisplayedFields,
+ values.contentDisplayedFieldTypes,
values.contentDisplayedFieldFilters
);
this.populateDataPanelDCs(values.dataPanelDCs);
@@ -867,7 +893,7 @@ export default function (AB) {
]);
}
- populateContentDisplayedFields(values = {}, filters = {}) {
+ populateContentDisplayedFields(values = {}, types = {}, filters = {}) {
const self = this;
const ids = this.ids;
const $contentDisplayedFields = $$(ids.contentDisplayedFields);
@@ -877,6 +903,16 @@ export default function (AB) {
$contentDisplayedFields.removeView(
contentDisplayedFieldsElements[key].getParentView().config.id
);
+ const $contentDisplayedFieldTypes = $$(ids.contentDisplayedFieldTypes);
+ const contentDisplayedFieldTypesElements =
+ $contentDisplayedFieldTypes.elements;
+ const $contentDisplayedFieldTypesSet = $$(
+ ids.contentDisplayedFieldTypesSet
+ );
+ for (const key in contentDisplayedFieldTypesElements)
+ $contentDisplayedFieldTypes.removeView(
+ contentDisplayedFieldTypesElements[key].getParentView().config.id
+ );
const $contentDisplayedFieldFilters = $$(
ids.contentDisplayedFieldFilters
);
@@ -890,6 +926,7 @@ export default function (AB) {
contentDisplayedFieldFiltersElements[key].getParentView().config
.id
);
+ $contentDisplayedFieldTypesSet.hide();
$contentDisplayedFieldFiltersSet.hide();
const keys = Object.keys(values);
if (keys.length === 0) {
@@ -904,50 +941,170 @@ export default function (AB) {
$$(ids.contentDisplayedFieldsAdd).hide();
return;
}
+ const typeKeys = Object.keys(types);
const filterKeys = Object.keys(filters);
const objID = obj.id;
const parentKeys = [];
const childKeys = [];
const createOptionsView = (key, field) => {
- const filterPrefix = `${key}.${field.id}`;
- const filterValue = parseInt(
+ const optionPrefix = `${key}.${field.id}`;
+ const fieldLabel = field.label;
+ const typeKeyIndex = typeKeys.findIndex(
+ (typeKey) => typeKey.indexOf(optionPrefix) > -1
+ );
+ const typeKeyParts =
+ typeKeys
+ .find((typeKey) => typeKey.indexOf(optionPrefix) > -1)
+ ?.split(".") || [];
+ const typeSwitchValue = parseInt(typeKeyParts[3]);
+ const isTypeKeyIndexFound = typeKeyIndex > -1;
+ const typeSelectedValue =
+ (isTypeKeyIndexFound && typeKeyParts[4]) || "text";
+ const typeOptions = [
+ { id: "icon", value: "Icon" },
+ { id: "image", value: "Image" },
+ { id: "text", value: "Text" },
+ ];
+ $contentDisplayedFieldTypes.addView({
+ cols: [
+ {
+ view: "switch",
+ label: fieldLabel,
+ labelWidth: uiConfig.labelWidthMedium,
+ value: isNaN(typeSwitchValue) ? 1 : typeSwitchValue,
+ on: {
+ onChange: (newValue, oldValue) => {
+ const oldTypes =
+ $contentDisplayedFieldTypes.getValues();
+ const oldTypeEntries = Object.entries(oldTypes);
+ const newTypes = {};
+ const oldTypePrefix = `${optionPrefix}.${oldValue}`;
+ for (const [key, value] of oldTypeEntries)
+ if (key.indexOf(oldTypePrefix) > -1)
+ newTypes[`${optionPrefix}.${newValue}.${key.split(".")[4]}`] = "";
+ else newTypes[key] = value;
+ this.populateContentDisplayedFields(
+ $contentDisplayedFields.getValues(),
+ newTypes,
+ $contentDisplayedFieldFilters.getValues()
+ );
+ this.onChange();
+ },
+ onViewShow() {
+ const $parentView = this.getParentView();
+ $parentView.addView({
+ view: "richselect",
+ options: typeOptions,
+ value: typeSelectedValue,
+ on: {
+ onChange: (newValue, oldValue) => {
+ const currentTypeSwitchValue = this.getValue();
+ const typePrefix = `${optionPrefix}.${currentTypeSwitchValue}`;
+ const key = `${typePrefix}.${newValue}`;
+ switch (newValue) {
+ case "image":
+ $parentView.addView({
+ view: "textarea",
+ name: key,
+ placeholder: L("Image base 64 data."),
+ value: types[`${typePrefix}.${oldValue}`] ?? "",
+ on: {
+ onChange: () => {
+ self.onChange();
+ },
+ },
+ })
+ break;
+ default:
+ $parentView.addView({
+ view: "text",
+ name: key,
+ placeholder: L("No data need to fill up."),
+ disabled: true,
+ value: "",
+ });
+ break;
+ }
+ self.populateContentDisplayedFields(
+ $contentDisplayedFields.getValues(),
+ $contentDisplayedFieldTypes.getValues(),
+ $contentDisplayedFieldFilters.getValues()
+ );
+ self.onChange();
+ },
+ },
+ });
+ const key = `${optionPrefix}.${this.getValue()}.${typeSelectedValue}`;
+ switch (typeSelectedValue) {
+ case "image":
+ $parentView.addView({
+ view: "textarea",
+ name: key,
+ placeholder: L("Image base 64 data."),
+ value: types[key] ?? "",
+ on: {
+ onChange: () => {
+ self.onChange();
+ },
+ },
+ });
+ break;
+ default:
+ $parentView.addView({
+ view: "text",
+ name: key,
+ placeholder: L("No data need to fill up."),
+ disabled: true,
+ value: "",
+ });
+ break;
+ }
+ },
+ },
+ },
+ ],
+ });
+ const filterCheckboxValue = parseInt(
filterKeys
- .find((filterKey) => filterKey.indexOf(filterPrefix) > -1)
+ .find((filterKey) => filterKey.indexOf(optionPrefix) > -1)
?.split(".")[3]
);
$contentDisplayedFieldFilters.addView({
cols: [
{
view: "checkbox",
- label: field.label,
+ label: fieldLabel,
labelWidth: uiConfig.labelWidthMedium,
- value: isNaN(filterValue) ? 0 : filterValue,
+ value: isNaN(filterCheckboxValue)
+ ? 0
+ : filterCheckboxValue,
on: {
onChange: (newValue, oldValue) => {
const oldFilters =
$contentDisplayedFieldFilters.getValues();
const oldFilterEntries = Object.entries(oldFilters);
const newFilters = {};
- const oldFilterKey = `${filterPrefix}.${oldValue}`;
+ const oldFilterKey = `${optionPrefix}.${oldValue}`;
for (const [key, value] of oldFilterEntries)
if (key === oldFilterKey)
- newFilters[`${filterPrefix}.${newValue}`] = "";
+ newFilters[`${optionPrefix}.${newValue}`] = "";
else newFilters[key] = value;
this.populateContentDisplayedFields(
$contentDisplayedFields.getValues(),
+ $contentDisplayedFieldTypes.getValues(),
newFilters
);
this.onChange();
},
onViewShow() {
- const checkboxValue = this.getValue();
- const filterKey = `${filterPrefix}.${checkboxValue}`;
+ const filterKey = `${optionPrefix}.${this.getValue()}`;
this.getParentView().addView({
view: "text",
placeholder: L("Add the new field label."),
name: filterKey,
value: filters[filterKey],
- disabled: checkboxValue === 1 ? false : true,
+ disabled:
+ filterCheckboxValue === 1 ? false : true,
on: {
onChange: () => {
self.onChange();
@@ -1013,6 +1170,7 @@ export default function (AB) {
}
}
$contentDisplayedFields.show();
+ $contentDisplayedFieldTypesSet.show();
$contentDisplayedFieldFiltersSet.show();
}
@@ -1158,6 +1316,9 @@ export default function (AB) {
settings.contentDisplayedFields = $$(
ids.contentDisplayedFields
).getValues();
+ settings.contentDisplayedFieldTypes = $$(
+ ids.contentDisplayedFieldTypes
+ ).getValues();
settings.contentDisplayedFieldFilters = $$(
ids.contentDisplayedFieldFilters
).getValues();
From c3196de1d2f3e706c286fd87857054920fb19d5a Mon Sep 17 00:00:00 2001
From: guyyoo
Date: Mon, 25 Nov 2024 13:19:17 +0700
Subject: [PATCH 21/32] Fix filter default labels
---
.../properties/views/ABViewOrgChartTeams.js | 35 +++++++++++++------
1 file changed, 25 insertions(+), 10 deletions(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index 278c65ee..c39817de 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -980,8 +980,12 @@ export default function (AB) {
const newTypes = {};
const oldTypePrefix = `${optionPrefix}.${oldValue}`;
for (const [key, value] of oldTypeEntries)
- if (key.indexOf(oldTypePrefix) > -1)
- newTypes[`${optionPrefix}.${newValue}.${key.split(".")[4]}`] = "";
+ if (key.indexOf(oldTypePrefix) > -1)
+ newTypes[
+ `${optionPrefix}.${newValue}.${
+ key.split(".")[4]
+ }`
+ ] = "";
else newTypes[key] = value;
this.populateContentDisplayedFields(
$contentDisplayedFields.getValues(),
@@ -998,7 +1002,8 @@ export default function (AB) {
value: typeSelectedValue,
on: {
onChange: (newValue, oldValue) => {
- const currentTypeSwitchValue = this.getValue();
+ const currentTypeSwitchValue =
+ this.getValue();
const typePrefix = `${optionPrefix}.${currentTypeSwitchValue}`;
const key = `${typePrefix}.${newValue}`;
switch (newValue) {
@@ -1006,20 +1011,27 @@ export default function (AB) {
$parentView.addView({
view: "textarea",
name: key,
- placeholder: L("Image base 64 data."),
- value: types[`${typePrefix}.${oldValue}`] ?? "",
+ placeholder: L(
+ "Image base 64 data."
+ ),
+ value:
+ types[
+ `${typePrefix}.${oldValue}`
+ ] ?? "",
on: {
onChange: () => {
self.onChange();
},
},
- })
+ });
break;
default:
$parentView.addView({
view: "text",
name: key,
- placeholder: L("No data need to fill up."),
+ placeholder: L(
+ "No data need to fill up."
+ ),
disabled: true,
value: "",
});
@@ -1097,14 +1109,17 @@ export default function (AB) {
this.onChange();
},
onViewShow() {
- const filterKey = `${optionPrefix}.${this.getValue()}`;
+ const currentFilterCheckboxValue = this.getValue();
+ const filterKey = `${optionPrefix}.${currentFilterCheckboxValue}`;
this.getParentView().addView({
view: "text",
placeholder: L("Add the new field label."),
name: filterKey,
- value: filters[filterKey],
+ value: filters[filterKey] || fieldLabel,
disabled:
- filterCheckboxValue === 1 ? false : true,
+ currentFilterCheckboxValue === 1
+ ? false
+ : true,
on: {
onChange: () => {
self.onChange();
From d368a4a5ef128e234073cb0b059529fb8e987fd1 Mon Sep 17 00:00:00 2001
From: guyyoo
Date: Tue, 26 Nov 2024 18:08:16 +0700
Subject: [PATCH 22/32] Fix content mapping data and type
---
.../properties/views/ABViewOrgChartTeams.js | 244 ++++++++++++------
1 file changed, 169 insertions(+), 75 deletions(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index c39817de..12a5c807 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -47,6 +47,8 @@ export default function (AB) {
contentDisplayedFieldFiltersSet: "",
contentDisplayedFieldTypes: "",
contentDisplayedFieldTypesSet: "",
+ contentDisplayedFieldMappingData: "",
+ contentDisplayedFieldMappingDataSet: "",
showDataPanel: "",
dataPanelDCs: "",
dataPanelDCsAdd: "",
@@ -164,6 +166,9 @@ export default function (AB) {
const objID = obj?.id || parentObjID;
const $contentDisplayedFields = $$(ids.contentDisplayedFields);
const $contentDisplayedFieldTypes = $$(ids.contentDisplayedFieldTypes);
+ const $contentDisplayedFieldMappingData = $$(
+ ids.contentDisplayedFieldMappingData
+ );
const $contentDisplayedFieldFilters = $$(
ids.contentDisplayedFieldFilters
);
@@ -186,6 +191,7 @@ export default function (AB) {
this.populateContentDisplayedFields(
$contentDisplayedFields.getValues(),
$contentDisplayedFieldTypes.getValues(),
+ $contentDisplayedFieldMappingData.getValues(),
$contentDisplayedFieldFilters.getValues()
);
this.onChange();
@@ -513,6 +519,21 @@ export default function (AB) {
},
],
},
+ {
+ id: ids.contentDisplayedFieldMappingDataSet,
+ hidden: true,
+ rows: [
+ {
+ view: "label",
+ label: L("Set content mapping displayed data"),
+ },
+ {
+ id: ids.contentDisplayedFieldMappingData,
+ view: "form",
+ elements: [],
+ },
+ ],
+ },
{
id: ids.contentDisplayedFieldFiltersSet,
hidden: true,
@@ -810,6 +831,7 @@ export default function (AB) {
this.populateContentDisplayedFields(
values.contentDisplayedFields,
values.contentDisplayedFieldTypes,
+ values.contentDisplayedFieldMappingData,
values.contentDisplayedFieldFilters
);
this.populateDataPanelDCs(values.dataPanelDCs);
@@ -865,6 +887,7 @@ export default function (AB) {
}
populateTeamFieldOptions(object) {
+ const webix = this.AB.Webix;
const view = this.CurrentView;
const ids = this.ids;
const m2oFields = view.getValueFields(object).map(fieldToOption);
@@ -893,8 +916,14 @@ export default function (AB) {
]);
}
- populateContentDisplayedFields(values = {}, types = {}, filters = {}) {
+ populateContentDisplayedFields(
+ values = {},
+ types = {},
+ mappingDataValues = {},
+ filters = {}
+ ) {
const self = this;
+ const webix = this.AB.Webix;
const ids = this.ids;
const $contentDisplayedFields = $$(ids.contentDisplayedFields);
const contentDisplayedFieldsElements =
@@ -913,9 +942,22 @@ export default function (AB) {
$contentDisplayedFieldTypes.removeView(
contentDisplayedFieldTypesElements[key].getParentView().config.id
);
+ const $contentDisplayedFieldMappingData = $$(
+ ids.contentDisplayedFieldMappingData
+ );
+ const contentDisplayedFieldMappingDataElements =
+ $contentDisplayedFieldMappingData.elements;
+ const $contentDisplayedFieldMappingDataSet = $$(
+ ids.contentDisplayedFieldMappingDataSet
+ );
const $contentDisplayedFieldFilters = $$(
ids.contentDisplayedFieldFilters
);
+ for (const key in contentDisplayedFieldMappingDataElements)
+ $contentDisplayedFieldMappingData.removeView(
+ contentDisplayedFieldMappingDataElements[key].getParentView()
+ .config.id
+ );
const contentDisplayedFieldFiltersElements =
$contentDisplayedFieldFilters.elements;
const $contentDisplayedFieldFiltersSet = $$(
@@ -927,6 +969,7 @@ export default function (AB) {
.id
);
$contentDisplayedFieldTypesSet.hide();
+ $contentDisplayedFieldMappingDataSet.hide();
$contentDisplayedFieldFiltersSet.hide();
const keys = Object.keys(values);
if (keys.length === 0) {
@@ -960,11 +1003,6 @@ export default function (AB) {
const isTypeKeyIndexFound = typeKeyIndex > -1;
const typeSelectedValue =
(isTypeKeyIndexFound && typeKeyParts[4]) || "text";
- const typeOptions = [
- { id: "icon", value: "Icon" },
- { id: "image", value: "Image" },
- { id: "text", value: "Text" },
- ];
$contentDisplayedFieldTypes.addView({
cols: [
{
@@ -990,92 +1028,143 @@ export default function (AB) {
this.populateContentDisplayedFields(
$contentDisplayedFields.getValues(),
newTypes,
+ $contentDisplayedFieldMappingData.getValues(),
$contentDisplayedFieldFilters.getValues()
);
this.onChange();
},
onViewShow() {
- const $parentView = this.getParentView();
- $parentView.addView({
+ this.getParentView().addView({
view: "richselect",
- options: typeOptions,
+ options: [
+ { id: "icon", value: "Icon" },
+ { id: "image", value: "Image" },
+ { id: "text", value: "Text" },
+ ],
+ name: `${optionPrefix}.${this.getValue()}`,
value: typeSelectedValue,
on: {
- onChange: (newValue, oldValue) => {
- const currentTypeSwitchValue =
- this.getValue();
- const typePrefix = `${optionPrefix}.${currentTypeSwitchValue}`;
- const key = `${typePrefix}.${newValue}`;
- switch (newValue) {
- case "image":
- $parentView.addView({
- view: "textarea",
- name: key,
- placeholder: L(
- "Image base 64 data."
- ),
- value:
- types[
- `${typePrefix}.${oldValue}`
- ] ?? "",
- on: {
- onChange: () => {
- self.onChange();
- },
- },
- });
- break;
- default:
- $parentView.addView({
- view: "text",
- name: key,
- placeholder: L(
- "No data need to fill up."
- ),
- disabled: true,
- value: "",
- });
- break;
- }
- self.populateContentDisplayedFields(
- $contentDisplayedFields.getValues(),
- $contentDisplayedFieldTypes.getValues(),
- $contentDisplayedFieldFilters.getValues()
- );
+ onChange: () => {
self.onChange();
},
},
});
- const key = `${optionPrefix}.${this.getValue()}.${typeSelectedValue}`;
- switch (typeSelectedValue) {
- case "image":
- $parentView.addView({
- view: "textarea",
- name: key,
- placeholder: L("Image base 64 data."),
- value: types[key] ?? "",
- on: {
- onChange: () => {
- self.onChange();
- },
- },
- });
- break;
- default:
- $parentView.addView({
- view: "text",
- name: key,
- placeholder: L("No data need to fill up."),
- disabled: true,
- value: "",
- });
- break;
- }
},
},
},
],
});
+ const mappingDataValue = mappingDataValues[optionPrefix];
+ $contentDisplayedFieldMappingData.addView({
+ cols: [
+ {
+ view: "label",
+ label: fieldLabel,
+ width: uiConfig.labelWidthMedium,
+ },
+ {
+ view: "button",
+ label: "Set",
+ width: uiConfig.buttonWidthExtraSmall,
+ click: () => {
+ const getValueViewUI = (key = "", value = "") => ({
+ cols: [
+ { view: "text", value: key },
+ {
+ view: "label",
+ label: L("to"),
+ align: "center",
+ width: uiConfig.labelWidthSmall,
+ },
+ { view: "text", value },
+ {
+ view: "button",
+ css: "webix_danger",
+ type: "icon",
+ icon: "wxi-close",
+ width: uiConfig.buttonWidthExtraSmall,
+ click() {
+ const $childView = this.getParentView();
+ $childView
+ .getParentView()
+ .removeView($childView.config.id);
+ },
+ },
+ ],
+ });
+ const $popup = webix.ui({
+ view: "window",
+ close: true,
+ title: L("Map Data"),
+ position: "center",
+ body: {
+ view: "form",
+ elements: [
+ {
+ view: "button",
+ label: L("Add a value"),
+ click() {
+ this.getParentView()
+ .getChildViews()[1]
+ .addView(getValueViewUI());
+ },
+ },
+ {
+ rows: [],
+ },
+ {
+ view: "button",
+ label: L("Apply"),
+ click() {
+ const $valueView =
+ this.getParentView().getChildViews()[1];
+ const mapingValues = {};
+ const valueChildViews =
+ $valueView.getChildViews();
+ for (const $valueChildView of valueChildViews) {
+ const valueChildViewElements =
+ $valueChildView.getChildViews();
+ mapingValues[
+ valueChildViewElements[0].getValue()
+ ] =
+ valueChildViewElements[2].getValue();
+ }
+ $contentDisplayedFieldMappingData.elements[
+ optionPrefix
+ ]?.setValue(JSON.stringify(mapingValues));
+ $popup.hide();
+ self.onChange();
+ },
+ },
+ ],
+ },
+ on: {
+ onHide() {
+ this.destructor();
+ },
+ },
+ });
+ try {
+ const $valueView = $popup
+ .getChildViews()[1]
+ .getChildViews()[1];
+ const mappingDataObj = JSON.parse(
+ mappingDataValue
+ );
+ for (const key in mappingDataObj)
+ $valueView.addView(getValueViewUI(key, mappingDataObj[key]));
+ } catch {}
+ $popup.show();
+ },
+ },
+ {
+ view: "text",
+ name: optionPrefix,
+ disabled: true,
+ value: mappingDataValue || {},
+ },
+ ],
+ });
const filterCheckboxValue = parseInt(
filterKeys
.find((filterKey) => filterKey.indexOf(optionPrefix) > -1)
@@ -1104,6 +1193,7 @@ export default function (AB) {
this.populateContentDisplayedFields(
$contentDisplayedFields.getValues(),
$contentDisplayedFieldTypes.getValues(),
+ $contentDisplayedFieldMappingData.getValues(),
newFilters
);
this.onChange();
@@ -1186,6 +1276,7 @@ export default function (AB) {
}
$contentDisplayedFields.show();
$contentDisplayedFieldTypesSet.show();
+ $contentDisplayedFieldMappingDataSet.show();
$contentDisplayedFieldFiltersSet.show();
}
@@ -1334,6 +1425,9 @@ export default function (AB) {
settings.contentDisplayedFieldTypes = $$(
ids.contentDisplayedFieldTypes
).getValues();
+ settings.contentDisplayedFieldMappingData = $$(
+ ids.contentDisplayedFieldMappingData
+ ).getValues();
settings.contentDisplayedFieldFilters = $$(
ids.contentDisplayedFieldFilters
).getValues();
From 2944973c20e1ba57e80b3ca584ee543425a35880 Mon Sep 17 00:00:00 2001
From: guyyoo
Date: Tue, 26 Nov 2024 18:47:56 +0700
Subject: [PATCH 23/32] Fix the populating mapping field bug
---
src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index 12a5c807..236a1802 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -1161,7 +1161,7 @@ export default function (AB) {
view: "text",
name: optionPrefix,
disabled: true,
- value: mappingDataValue || {},
+ value: mappingDataValue || JSON.stringify({}),
},
],
});
From a33a40ff6b34df82bf948248443b39a6ab510aef Mon Sep 17 00:00:00 2001
From: guyyoo
Date: Tue, 26 Nov 2024 19:29:25 +0700
Subject: [PATCH 24/32] Fix getting the wrong key bug
---
src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index 236a1802..39c17432 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -1269,7 +1269,7 @@ export default function (AB) {
case "user":
break;
default:
- createOptionsView(parentKey, childField);
+ createOptionsView(childKey, childField);
continue;
}
}
From 0803c337524b8743cf780f9e0bd505cd1d2ab510 Mon Sep 17 00:00:00 2001
From: nh758 <7259@pm.me>
Date: Tue, 26 Nov 2024 16:38:08 +0700
Subject: [PATCH 25/32] add entity dc setting
---
.../properties/views/ABViewOrgChartTeams.js | 23 +++++++++++--------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index 45a2c4d5..25f71959 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -28,7 +28,6 @@ export default function (AB) {
depth: "",
draggable: "",
dropContentToCreate: "",
- color: "",
pan: "",
zoom: "",
height: "",
@@ -48,6 +47,7 @@ export default function (AB) {
dataPanelDCsAdd: "",
strategyColorPopup: "",
strategyColorForm: "",
+ entityDatacollection: "",
});
this.AB = AB;
const contentFieldFilter = (this.contentFieldFilter =
@@ -595,6 +595,17 @@ export default function (AB) {
],
on: { onChange: () => this.onChange() },
},
+ {
+ id: ids.entityDatacollection,
+ name: "entityDatacollection",
+ view: "richselect",
+ label: L("Entity"),
+ labelWidth: uiConfig.labelWidthLarge,
+ options: [],
+ on: {
+ onChange: () => this.onChange(),
+ },
+ },
{
id: ids.depth,
name: "depth",
@@ -605,14 +616,6 @@ export default function (AB) {
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,
@@ -773,6 +776,8 @@ export default function (AB) {
$dataCollection.define("options", dcOptions);
$dataCollection.define("value", datacollectionId);
$dataCollection.refresh();
+ $$(this.ids.entityDatacollection).define("options", dcOptions);
+ $$(this.ids.entityDatacollection).refresh();
}
refreshValueFieldOptions(fieldValues = []) {
From 4b20439a526900a48b5189a3ef784ca0c11a30a6 Mon Sep 17 00:00:00 2001
From: guyyoo
Date: Wed, 27 Nov 2024 16:03:26 +0700
Subject: [PATCH 26/32] Add the SVG field type and placeholder
---
.../properties/views/ABViewOrgChartTeams.js | 37 +++++++++++++++----
1 file changed, 30 insertions(+), 7 deletions(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index bfa2dda4..b53e34d4 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -1044,6 +1044,7 @@ export default function (AB) {
options: [
{ id: "icon", value: "Icon" },
{ id: "image", value: "Image" },
+ { id: "svg", value: "SVG" },
{ id: "text", value: "Text" },
],
name: `${optionPrefix}.${this.getValue()}`,
@@ -1074,14 +1075,34 @@ export default function (AB) {
click: () => {
const getValueViewUI = (key = "", value = "") => ({
cols: [
- { view: "text", value: key },
+ {
+ view: "text",
+ placeholder: L("The value need to map."),
+ value: key,
+ },
{
view: "label",
label: L("to"),
align: "center",
width: uiConfig.labelWidthSmall,
},
- { view: "text", value },
+ {
+ view: "text",
+ placeholder: (() => {
+ switch (value) {
+ case "icon":
+ return L("Icon class text.");
+ case "image":
+ case "svg":
+ return L(
+ "Base64 image url (ex. data:image/png;base64,AAABBBCCC)."
+ );
+ default:
+ return L("New text.");
+ }
+ })(),
+ value,
+ },
{
view: "button",
css: "webix_danger",
@@ -1136,7 +1157,9 @@ export default function (AB) {
}
$contentDisplayedFieldMappingData.elements[
optionPrefix
- ]?.setValue(JSON.stringify(mapingValues));
+ ]?.setValue(
+ JSON.stringify(mapingValues)
+ );
$popup.hide();
self.onChange();
},
@@ -1153,11 +1176,11 @@ export default function (AB) {
const $valueView = $popup
.getChildViews()[1]
.getChildViews()[1];
- const mappingDataObj = JSON.parse(
- mappingDataValue
- );
+ const mappingDataObj = JSON.parse(mappingDataValue);
for (const key in mappingDataObj)
- $valueView.addView(getValueViewUI(key, mappingDataObj[key]));
+ $valueView.addView(
+ getValueViewUI(key, mappingDataObj[key])
+ );
} catch {}
$popup.show();
},
From c0b3a431977f4cf9f7e05cdcae7524aec348a767 Mon Sep 17 00:00:00 2001
From: guyyoo
Date: Wed, 27 Nov 2024 16:24:03 +0700
Subject: [PATCH 27/32] Fix setting type bug
---
.../properties/views/ABViewOrgChartTeams.js | 20 +++++++++----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index b53e34d4..b54e42cf 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -1000,14 +1000,11 @@ export default function (AB) {
const typeKeyIndex = typeKeys.findIndex(
(typeKey) => typeKey.indexOf(optionPrefix) > -1
);
- const typeKeyParts =
+ const typeSwitchValue = parseInt(
typeKeys
.find((typeKey) => typeKey.indexOf(optionPrefix) > -1)
- ?.split(".") || [];
- const typeSwitchValue = parseInt(typeKeyParts[3]);
- const isTypeKeyIndexFound = typeKeyIndex > -1;
- const typeSelectedValue =
- (isTypeKeyIndexFound && typeKeyParts[4]) || "text";
+ ?.split(".")[3]
+ );
$contentDisplayedFieldTypes.addView({
cols: [
{
@@ -1025,10 +1022,8 @@ export default function (AB) {
for (const [key, value] of oldTypeEntries)
if (key.indexOf(oldTypePrefix) > -1)
newTypes[
- `${optionPrefix}.${newValue}.${
- key.split(".")[4]
- }`
- ] = "";
+ `${optionPrefix}.${newValue}`
+ ] = value;
else newTypes[key] = value;
this.populateContentDisplayedFields(
$contentDisplayedFields.getValues(),
@@ -1048,7 +1043,10 @@ export default function (AB) {
{ id: "text", value: "Text" },
],
name: `${optionPrefix}.${this.getValue()}`,
- value: typeSelectedValue,
+ value:
+ (typeKeyIndex > -1 &&
+ types[typeKeys[typeKeyIndex]]) ||
+ "text",
on: {
onChange: () => {
self.onChange();
From 6c8a50122b2533fcfcae4ce0ea32d4f1735fb22d Mon Sep 17 00:00:00 2001
From: guyyoo
Date: Thu, 28 Nov 2024 10:13:33 +0700
Subject: [PATCH 28/32] Fix placeholder text
---
.../Designer/properties/views/ABViewOrgChartTeams.js | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index b54e42cf..5583f564 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -1021,9 +1021,8 @@ export default function (AB) {
const oldTypePrefix = `${optionPrefix}.${oldValue}`;
for (const [key, value] of oldTypeEntries)
if (key.indexOf(oldTypePrefix) > -1)
- newTypes[
- `${optionPrefix}.${newValue}`
- ] = value;
+ newTypes[`${optionPrefix}.${newValue}`] =
+ value;
else newTypes[key] = value;
this.populateContentDisplayedFields(
$contentDisplayedFields.getValues(),
@@ -1093,7 +1092,7 @@ export default function (AB) {
case "image":
case "svg":
return L(
- "Base64 image url (ex. data:image/png;base64,AAABBBCCC)."
+ "Image url or Base64 (ex. data:image/png;base64,AAABBBCCC) url."
);
default:
return L("New text.");
From 2c17a59a1a771d177b43e49c6e21d34fe3f1d66a Mon Sep 17 00:00:00 2001
From: guyyoo
Date: Tue, 3 Dec 2024 09:57:10 +0700
Subject: [PATCH 29/32] Add start date and end date fields
---
.../properties/views/ABViewOrgChartTeams.js | 56 ++++++++++++++++++-
1 file changed, 55 insertions(+), 1 deletion(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index 5583f564..03974264 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -38,6 +38,8 @@ export default function (AB) {
editContentFieldsToCreateNew: "",
contentField: "",
contentFieldFilter: "",
+ contentFieldDateStart: "",
+ contentFieldDateEnd: "",
contentFieldFilterButton: "",
contentGroupByField: "",
contentDisplayedFields: "",
@@ -346,6 +348,12 @@ export default function (AB) {
const $contentGroupByField = $$(
ids.contentGroupByField
);
+ const $contentFieldDateStart = $$(
+ ids.contentFieldDateStart
+ );
+ const $contentFieldDateEnd = $$(
+ ids.contentFieldDateEnd
+ );
const $showGroupTitle = $$(ids.showGroupTitle);
contentFieldFilter.init();
contentFieldFilter.setValue({
@@ -358,6 +366,19 @@ export default function (AB) {
newValue
).datasourceLink;
const contentObjFields = contentObj.fields();
+ const contentDateFiels = contentObjFields.filter(
+ (field) =>
+ field.key === "date" ||
+ field.key === "datetime"
+ );
+ $contentFieldDateStart.define(
+ "options",
+ contentDateFiels.map(fieldToOption)
+ );
+ $contentFieldDateEnd.define(
+ "options",
+ contentDateFiels.map(fieldToOption)
+ );
$editContentFieldsToCreateNew.define(
"options",
// contentObjFields.map(fieldToOption)
@@ -379,6 +400,8 @@ export default function (AB) {
$editContentFieldsToCreateNew.enable();
$contentFieldFilterButton.enable();
$contentDisplayedFieldsAdd.show();
+ $contentFieldDateStart.show();
+ $contentFieldDateEnd.show();
$contentGroupByField.show();
$showGroupTitle.show();
} else {
@@ -391,6 +414,8 @@ export default function (AB) {
$editContentFieldsToCreateNew.enable();
$contentFieldFilterButton.disable();
$contentDisplayedFieldsAdd.hide();
+ $contentFieldDateStart.hide();
+ $contentFieldDateEnd.hide();
$contentGroupByField.hide();
$showGroupTitle.hide();
}
@@ -418,6 +443,32 @@ export default function (AB) {
},
],
},
+ {
+ id: ids.contentFieldDateStart,
+ name: "contentFieldDateStart",
+ label: L("Date Start"),
+ labelWidth: uiConfig.labelWidthLarge,
+ view: "richselect",
+ options: [],
+ on: {
+ onChange: () => {
+ this.onChange();
+ },
+ },
+ },
+ {
+ id: ids.contentFieldDateEnd,
+ name: "contentFieldDateEnd",
+ label: L("Date End"),
+ labelWidth: uiConfig.labelWidthLarge,
+ view: "richselect",
+ options: [],
+ on: {
+ onChange: () => {
+ this.onChange();
+ },
+ },
+ },
{
id: ids.contentGroupByField,
hidden: true,
@@ -892,7 +943,6 @@ export default function (AB) {
}
populateTeamFieldOptions(object) {
- const webix = this.AB.Webix;
const view = this.CurrentView;
const ids = this.ids;
const m2oFields = view.getValueFields(object).map(fieldToOption);
@@ -1456,6 +1506,10 @@ export default function (AB) {
settings.contentDisplayedFieldFilters = $$(
ids.contentDisplayedFieldFilters
).getValues();
+ settings.contentFieldDateStart = $$(
+ ids.contentFieldDateStart
+ ).getValue();
+ settings.contentFieldDateEnd = $$(ids.contentFieldDateEnd).getValue();
settings.dataPanelDCs = $$(ids.dataPanelDCs).getValues();
const $colorForm = $$(ids.strategyColorForm);
settings.strategyColors = $colorForm?.getValues() ?? {};
From d4986dfc9bc27d481fe401817a6037029029fde8 Mon Sep 17 00:00:00 2001
From: guyyoo
Date: Fri, 6 Dec 2024 15:09:53 +0700
Subject: [PATCH 30/32] Limit edit form's fields
---
.../properties/views/ABViewOrgChartTeams.js | 48 ++++++++++++++++---
1 file changed, 41 insertions(+), 7 deletions(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index 03974264..bb8c27b8 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -36,6 +36,7 @@ export default function (AB) {
groupByField: "",
showGroupTitle: "",
editContentFieldsToCreateNew: "",
+ setEditableContentFields: "",
contentField: "",
contentFieldFilter: "",
contentFieldDateStart: "",
@@ -339,6 +340,9 @@ export default function (AB) {
const $editContentFieldsToCreateNew = $$(
ids.editContentFieldsToCreateNew
);
+ const $setEditableContentFields = $$(
+ ids.setEditableContentFields
+ );
const $contentDisplayedFieldsAdd = $$(
ids.contentDisplayedFieldsAdd
);
@@ -379,13 +383,19 @@ export default function (AB) {
"options",
contentDateFiels.map(fieldToOption)
);
- $editContentFieldsToCreateNew.define(
- "options",
- // contentObjFields.map(fieldToOption)
+ const contentObjMappedFields =
+ // contentObjFields.map(fieldToOption) *** (Guy) this makes my chrome browser crash (Only multi-selection) it is because { field: f } ***
contentObjFields.map((contentObjField) => ({
id: contentObjField.id,
value: contentObjField.label,
- }))
+ }));
+ $editContentFieldsToCreateNew.define(
+ "options",
+ contentObjMappedFields
+ );
+ $setEditableContentFields.define(
+ "options",
+ contentObjMappedFields
);
contentFieldFilter.fieldsLoad(contentObjFields);
$contentGroupByField.define("options", [
@@ -500,7 +510,9 @@ export default function (AB) {
rows: [
{
view: "label",
- label: L("Create new by editing content fields"),
+ label: L(
+ "Force the creation of a new row of data by editing the content fields"
+ ),
},
{
id: ids.editContentFieldsToCreateNew,
@@ -508,12 +520,30 @@ export default function (AB) {
value: [],
options: [],
placeholder: L(
- "Choose content fields to create new by editing"
+ "Choose the content fields to create a new entry through editing"
),
labelAlign: "left",
stringResult: false /* returns data as an array of [id] */,
on: {
- onChange: (newValue) => {
+ onChange: () => {
+ this.onChange();
+ },
+ },
+ },
+ {
+ view: "label",
+ label: L("Set the editable content fields"),
+ },
+ {
+ id: ids.setEditableContentFields,
+ view: "multicombo",
+ value: [],
+ options: [],
+ placeholder: L("Choose the editable content fields"),
+ labelAlign: "left",
+ stringResult: false /* returns data as an array of [id] */,
+ on: {
+ onChange: () => {
this.onChange();
},
},
@@ -876,6 +906,7 @@ export default function (AB) {
"contentField",
"contentGroupByField",
"editContentFieldsToCreateNew",
+ "setEditableContentFields",
"showGroupTitle",
"showDataPanel",
].forEach((f) => $$(ids[f]).setValue(values[f]));
@@ -1491,6 +1522,9 @@ export default function (AB) {
settings.editContentFieldsToCreateNew = $$(
ids.editContentFieldsToCreateNew
).getValue();
+ settings.setEditableContentFields = $$(
+ ids.setEditableContentFields
+ ).getValue();
settings.contentFieldFilter = JSON.stringify(
this.contentFieldFilter.getValue()
);
From 932bc5a2c22049c7fb8f593554a457c04b537e4e Mon Sep 17 00:00:00 2001
From: nh758 <7259@pm.me>
Date: Mon, 9 Dec 2024 09:19:57 +0700
Subject: [PATCH 31/32] add substrategy field setting
---
.../Designer/properties/views/ABViewOrgChartTeams.js | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index bb8c27b8..de317bd0 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -17,6 +17,7 @@ export default function (AB) {
super(BASE_ID, {
datacollectionID: "",
strategyCode: "",
+ subStrategy: "",
teamInactive: "",
teamCanInactivate: "",
teamLink: "",
@@ -711,6 +712,14 @@ export default function (AB) {
},
],
},
+ {
+ id: ids.subStrategy,
+ view: "richselect",
+ label: L("Sub Strategy"),
+ labelWidth: uiConfig.labelWidthLarge,
+ options: [],
+ on: { onChange: () => this.onChange() },
+ },
{
id: ids.draggable,
name: "draggable",
@@ -923,6 +932,7 @@ export default function (AB) {
if (values.teamStrategy) {
this.populateStrategyOptions(values.teamStrategy);
$$(ids.strategyCode).setValue(values.strategyCode);
+ $$(ids.subStrategy).setValue(values.subStrategy);
}
}
$component.setValues(values);
@@ -1418,6 +1428,7 @@ export default function (AB) {
.fields((f) => f.key === "connectObject")
.map(fieldToOption);
$$(this.ids.strategyCode).define("options", listFields);
+ $$(this.ids.subStrategy).define("options", listFields);
}
async strategyColorPopup() {
@@ -1515,6 +1526,7 @@ export default function (AB) {
settings.teamInactive = $$(ids.teamInactive).getValue();
settings.teamCanInactivate = $$(ids.teamCanInactivate).getValue();
settings.teamStrategy = $$(ids.teamStrategy).getValue();
+ settings.subStrategy = $$(ids.subStrategy).getValue();
settings.strategyCode = $$(ids.strategyCode).getValue();
settings.dataCollectionId = $$(ids.datacollectionID).getValue();
settings.contentField = $$(ids.contentField).getValue();
From 53daa8def958ef331150fbd388c4b5e89d4ecaa8 Mon Sep 17 00:00:00 2001
From: nh758 <7259@pm.me>
Date: Fri, 3 Jan 2025 15:02:07 +0700
Subject: [PATCH 32/32] Fix save colors and allow custom colors
---
.../Designer/properties/views/ABViewOrgChartTeams.js | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
index de317bd0..e2f1acbe 100644
--- a/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
+++ b/src/rootPages/Designer/properties/views/ABViewOrgChartTeams.js
@@ -1448,6 +1448,12 @@ export default function (AB) {
label: strategy.name,
name: strategy.id,
value: values[strategy.id] ?? "#111111",
+ suggest: {
+ type: "colorselect",
+ body: {
+ button: true,
+ },
+ },
};
});
@@ -1558,7 +1564,8 @@ export default function (AB) {
settings.contentFieldDateEnd = $$(ids.contentFieldDateEnd).getValue();
settings.dataPanelDCs = $$(ids.dataPanelDCs).getValues();
const $colorForm = $$(ids.strategyColorForm);
- settings.strategyColors = $colorForm?.getValues() ?? {};
+ settings.strategyColors =
+ $colorForm?.getValues() ?? settings.strategyColors;
return values;
}