diff --git a/src/plugins/index.js b/src/plugins/index.js
index 758e1899..c5351263 100644
--- a/src/plugins/index.js
+++ b/src/plugins/index.js
@@ -8,6 +8,8 @@ import viewDataviewEditor from "./web_view_dataview/FNAbviewdataviewEditor.js";
import viewDataviewProperties from "./web_view_dataview/FNAbviewdataview.js";
import viewDetailEditor from "./web_view_detail/FNAbviewdetailEditor.js";
import viewDetailProperties from "./web_view_detail/FNAbviewdetail.js";
+import viewGanttEditor from "./web_view_gantt/FNAbviewganttEditor.js";
+import viewGanttProperties from "./web_view_gantt/FNAbviewgantt.js";
import viewGridEditor from "./web_view_grid/FNAbviewgridEditor.js";
import viewGridProperties from "./web_view_grid/FNAbviewgrid.js";
import viewImageEditor from "./web_view_image/FNAbviewimageEditor.js";
@@ -39,6 +41,8 @@ const AllPlugins = [
viewDataviewProperties,
viewDetailEditor,
viewDetailProperties,
+ viewGanttEditor,
+ viewGanttProperties,
viewGridEditor,
viewGridProperties,
viewImageEditor,
diff --git a/src/plugins/web_view_gantt/FNAbviewgantt.js b/src/plugins/web_view_gantt/FNAbviewgantt.js
new file mode 100644
index 00000000..68d2d115
--- /dev/null
+++ b/src/plugins/web_view_gantt/FNAbviewgantt.js
@@ -0,0 +1,220 @@
+// FNAbviewgantt Properties
+// A properties side import for an ABView.
+//
+import FABViewGanttWorkspaceView from "./FNAbviewganttWorkspace.js";
+
+export default function FNAbviewganttProperties({
+ AB,
+ ABViewPropertiesPlugin,
+ ABUIPlugin,
+}) {
+ const BASE_ID = "properties_abview_gantt";
+ const L = AB.Label();
+ const uiConfig = AB.Config.uiSettings();
+
+ const FPopupNewDataField =
+ require("../../rootPages/Designer/ui_work_object_workspace_popupNewDataField").default;
+
+ const ABUIPopupNewDataField = FPopupNewDataField(
+ AB,
+ `${BASE_ID}_popupNewDataField`
+ );
+ const ABViewGanttWorkspaceView = FABViewGanttWorkspaceView(
+ AB,
+ ABUIPlugin,
+ `${BASE_ID}_workspaceView_gantt`
+ );
+
+ return class ABAbviewganttProperties extends ABViewPropertiesPlugin {
+ static getPluginKey() {
+ return this.key;
+ }
+
+ static getPluginType() {
+ return "properties-view";
+ // properties-view : will display in the properties panel of the ABDesigner
+ }
+
+ constructor() {
+ super(BASE_ID, {
+ dataviewID: "",
+ fields: "",
+ });
+
+ this.AB = AB;
+ }
+
+ static get key() {
+ return "gantt";
+ }
+
+ ui() {
+ const ids = this.ids;
+
+ return super.ui([
+ {
+ view: "fieldset",
+ label: `${L("Gantt Data")}:`,
+ labelWidth: uiConfig.labelWidthLarge,
+ body: {
+ type: "clean",
+ padding: 10,
+ rows: [
+ {
+ id: ids.dataviewID,
+ view: "richselect",
+ name: "dataviewID",
+ label: `${L("Datacollection")}:`,
+ labelWidth: uiConfig.labelWidthLarge,
+ on: {
+ onChange: (newValue, oldValue) => {
+ if (newValue === oldValue) return;
+
+ ABViewGanttWorkspaceView.emit(
+ "dc.changed",
+ newValue,
+ this.CurrentView
+ );
+
+ this.onChange();
+ },
+ },
+ },
+ ],
+ },
+ },
+ {
+ view: "fieldset",
+ label: `${L("Gantt Fields")}:`,
+ labelWidth: uiConfig.labelWidthLarge,
+ body: {
+ id: ids.fields,
+ view: "form",
+ name: "fields",
+ borderless: true,
+ elements: [ABViewGanttWorkspaceView.ui()],
+ on: {
+ onChange: () => {
+ this.onChange();
+ },
+ },
+ },
+ },
+ ]);
+ }
+
+ async init(AB) {
+ this.AB = AB;
+ this.PopupNewDataFieldComponent = ABUIPopupNewDataField;
+
+ await this.PopupNewDataFieldComponent.init(AB);
+ this.PopupNewDataFieldComponent.on("save", (...params) => {
+ ABViewGanttWorkspaceView.emit("field.added", params[0]);
+ });
+
+ ABViewGanttWorkspaceView.on("dc.changed", (dcID, view) => {
+ const DC = this.AB.datacollectionByID(dcID);
+
+ ABViewGanttWorkspaceView.init(DC.datasource, view);
+ this.PopupNewDataFieldComponent.objectLoad(DC.datasource);
+ });
+
+ ABViewGanttWorkspaceView.on("new.field", (fieldKey) => {
+ this.PopupNewDataFieldComponent.show(null, fieldKey, false);
+ });
+
+ await super.init(AB);
+ }
+
+ populateDataview() {
+ // Pull data collections to options
+ // / NOTE: only include System Objects if the user has permission
+ const datacollectionFilter = this.AB.Account.isSystemDesigner()
+ ? (obj) => !obj.isSystemObject
+ : () => true;
+ const datacollections =
+ this.CurrentApplication.datacollectionsIncluded(
+ datacollectionFilter
+ );
+
+ // Set the objects you can choose from in the list
+ const $dataviewID = $$(this.ids.dataviewID);
+
+ $dataviewID.define(
+ "options",
+ datacollections.map((e) => {
+ return {
+ id: e.id,
+ value: e.label,
+ icon:
+ e.sourceType == "query"
+ ? "fa fa-filter"
+ : "fa fa-database",
+ };
+ })
+ );
+ $dataviewID.refresh();
+ }
+
+ populate(view) {
+ super.populate(view);
+
+ const ids = this.ids;
+ const $component = $$(ids.component);
+ const defaultValues = this.defaultValues();
+ const values = Object.assign(
+ $component.getValues(),
+ defaultValues,
+ view.settings
+ );
+
+ this.populateDataview();
+
+ $component.setValues(values);
+
+ let DC = this.AB.datacollectionByID(values.dataviewID);
+ if (DC) {
+ ABViewGanttWorkspaceView.init(DC.datasource, this.CurrentView);
+ this.PopupNewDataFieldComponent.objectLoad(DC.datasource);
+ }
+ }
+
+ 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;
+
+ values.settings = Object.assign(
+ $$(ids.component).getValues(),
+ $$(ids.fields).getValues()
+ );
+
+ return values;
+ }
+
+ /**
+ * @method FieldClass()
+ * A method to return the proper ABViewXXX Definition.
+ * NOTE: Must be overwritten by the Child Class
+ */
+ ViewClass() {
+ return super._ViewClass("gantt");
+ }
+ };
+}
diff --git a/src/plugins/web_view_gantt/FNAbviewganttEditor.js b/src/plugins/web_view_gantt/FNAbviewganttEditor.js
new file mode 100644
index 00000000..377cede7
--- /dev/null
+++ b/src/plugins/web_view_gantt/FNAbviewganttEditor.js
@@ -0,0 +1,56 @@
+// FNAbviewgantt Editor
+// An Editor wrapper for the ABView Component.
+// The Editor is displayed in the ABDesigner as a view is worked on.
+// The Editor allows a widget to be moved and placed on the canvas.
+//
+export default function FNAbviewganttEditor({ ABViewEditorPlugin }) {
+ const BASE_ID = "interface_editor_viewgantt";
+
+ return class ABAbviewganttEditor extends ABViewEditorPlugin {
+ static getPluginKey() {
+ return this.key;
+ }
+
+ /**
+ * @method getPluginType
+ * return the plugin type for this editor.
+ * plugin types are how our ClassManager knows how to store
+ * the plugin.
+ * @return {string} plugin type
+ */
+ static getPluginType() {
+ return "editor-view";
+ // editor-view : will display in the editor panel of the ABDesigner
+ }
+
+ static get key() {
+ return "gantt";
+ }
+
+ constructor(view, base = BASE_ID) {
+ // base: {string} unique base id reference
+ super(view, base, {
+ label: "",
+ });
+ }
+
+ ui() {
+ return this.component.ui();
+ }
+
+ async init(AB) {
+ this.AB = AB;
+ this.component.ignoreLocal = true;
+ // in our editor, we provide accessLv = 2
+ await this.component.init(AB, 2);
+ }
+
+ detatch() {
+ this.component.detatch?.();
+ }
+
+ onShow() {
+ this.component.onShow?.();
+ }
+ };
+}
diff --git a/src/plugins/web_view_gantt/FNAbviewganttWorkspace.js b/src/plugins/web_view_gantt/FNAbviewganttWorkspace.js
new file mode 100644
index 00000000..5b766912
--- /dev/null
+++ b/src/plugins/web_view_gantt/FNAbviewganttWorkspace.js
@@ -0,0 +1,608 @@
+// ABObjectWorkspaceViewGantt.js
+//
+// Manages the settings for a Gantt Chart View in the AppBuilder Object Workspace
+
+const defaultValues = {
+ name: "Default Gantt",
+ filterConditions: [], // array of filters to apply to the data table
+ sortFields: [],
+ settings: {
+ dataviewID: "",
+ // {string}
+ // {ABDatacollection.id} of the datacollection that contains the data for
+ // the Gantt chart.
+
+ titleFieldID: "",
+ // {string}
+ // {ABFieldXXX.id} of the field that contains the value of the title
+ // ABFieldString, ABFieldLongText
+
+ startDateFieldID: "",
+ // {string}
+ // {ABFieldDate.id} of the field that contains the start date
+
+ endDateFieldID: "",
+ // {string}
+ // {ABFieldDate.id} of the field that contains the end date
+
+ durationFieldID: "",
+ // {string}
+ // {ABFieldNumber.id} of the field that contains the duration
+
+ progressFieldID: "",
+ // {string}
+ // {ABFieldNumber.id} of the field that marks the duration
+
+ notesFieldID: "",
+ // {string}
+ // {ABFieldXXX.id} of the field that contains the value of the notes
+ // ABFieldString, ABFieldLongText
+ },
+};
+
+export default function (AB, ABUIPlugin, ibase) {
+ const L = AB.Label();
+
+ const ABFieldDate = AB.Class.ABFieldManager.fieldByKey("date");
+ const ABFieldNumber = AB.Class.ABFieldManager.fieldByKey("number");
+ const ABFieldString = AB.Class.ABFieldManager.fieldByKey("string");
+ const ABFieldLongText = AB.Class.ABFieldManager.fieldByKey("LongText");
+
+ class ABObjectWorkspaceViewGantt extends ABUIPlugin {
+ constructor(idBase) {
+ super(idBase, {
+ titleFieldID: "",
+ startDateFieldID: "",
+ endDateFieldID: "",
+ durationFieldID: "",
+ progressFieldID: "",
+ notesFieldID: "",
+ });
+
+ this.on("field.added", (field) => {
+ // refresh our droplists with the new field.
+ this.refreshOptions(this.CurrentObject, this._view);
+ if (this._autoSelectInput) {
+ $$(this._autoSelectInput)?.setValue(field.id);
+ }
+ });
+
+ this._autoSelectInput = null;
+ // {string}
+ // contains the webix.id of the input that should be auto selected
+ // if we receive a "field.add" event;
+
+ this._dateFields = [];
+ // {array}
+ // an array of webix options { id, value } that represent all the date
+ // fields of the CurrentObject.
+ }
+
+ /**
+ * unique key describing this View.
+ * @return {string}
+ */
+ type() {
+ return "gantt";
+ }
+
+ /**
+ * @return {string}
+ */
+ icon() {
+ return "fa fa-tasks";
+ }
+
+ refreshOptions(object, settings) {
+ const ids = this.ids;
+
+ const dateFields = object
+ .fields((f) => f instanceof ABFieldDate)
+ .map(({ id, label }) => ({ id, value: label }));
+
+ // sort by value
+ dateFields.sort((a, b) => (a.value > b.value ? 1 : -1));
+
+ // Add default option
+ dateFields.unshift({
+ id: null,
+ value: L("Select a date field"),
+ });
+ this._dateFields = dateFields;
+
+ // Start date
+ $$(ids.startDateFieldID).define("options", dateFields);
+
+ // // End date
+ $$(ids.endDateFieldID).define("options", dateFields);
+
+ // Duration
+ const numberFields = object
+ .fields((f) => f instanceof ABFieldNumber)
+ .map(({ id, label }) => ({ id, value: label }));
+
+ // sort by value
+ numberFields.sort((a, b) => (a.value > b.value ? 1 : -1));
+
+ // Add default option
+ numberFields.unshift({
+ id: null,
+ value: L("Select a number field"),
+ });
+ this._numberFields = numberFields;
+
+ $$(ids.durationFieldID).define("options", numberFields);
+
+ // Progress
+ $$(ids.progressFieldID).define("options", numberFields);
+
+ // Title & Notes
+ const stringFields = object
+ .fields(
+ (f) => f instanceof ABFieldString || f instanceof ABFieldLongText
+ )
+ .map(({ id, label }) => ({ id, value: label }));
+
+ // sort by value
+ stringFields.sort((a, b) => (a.value > b.value ? 1 : -1));
+
+ // Add default option
+ stringFields.unshift({
+ id: null,
+ value: L("Select a string field"),
+ });
+ this._stringFields = stringFields;
+
+ $$(ids.titleFieldID).define("options", stringFields);
+ $$(ids.notesFieldID).define("options", stringFields);
+
+ if (!settings) return;
+
+ // Select settings's values
+ if (settings.titleFieldID) {
+ $$(ids.titleFieldID).define("value", settings.titleFieldID);
+ $$(ids.titleFieldID).refresh();
+ this.syncCommonLists(
+ [ids.titleFieldID, ids.notesFieldID],
+ this._stringFields
+ );
+ }
+
+ if (settings.startDateFieldID) {
+ $$(ids.startDateFieldID).define("value", settings.startDateFieldID);
+ $$(ids.startDateFieldID).refresh();
+ this.syncCommonLists(
+ [ids.startDateFieldID, ids.endDateFieldID],
+ this._dateFields
+ );
+ }
+
+ if (settings.endDateFieldID) {
+ $$(ids.endDateFieldID).define(
+ "value",
+ settings.endDateFieldID ||
+ defaultValues.settings.endDateFieldIDFieldID
+ );
+ $$(ids.endDateFieldID).refresh();
+ this.syncCommonLists(
+ [ids.startDateFieldID, ids.endDateFieldID],
+ this._dateFields
+ );
+ }
+
+ if (settings.durationFieldID) {
+ $$(ids.durationFieldID).define(
+ "value",
+ settings.durationFieldID ||
+ defaultValues.settings.durationFieldID
+ );
+ $$(ids.durationFieldID).refresh();
+ this.syncCommonLists(
+ [ids.durationFieldID, ids.progressFieldID],
+ this._numberFields
+ );
+ }
+
+ if (settings.progressFieldID) {
+ $$(ids.progressFieldID).define("value", settings.progressFieldID);
+ $$(ids.progressFieldID).refresh();
+ this.syncCommonLists(
+ [ids.durationFieldID, ids.progressFieldID],
+ this._numberFields
+ );
+ }
+
+ if (settings.notesFieldID) {
+ $$(ids.notesFieldID).define("value", settings.notesFieldID);
+ $$(ids.notesFieldID).refresh();
+ this.syncCommonLists(
+ [ids.titleFieldID, ids.notesFieldID],
+ this._stringFields
+ );
+ }
+ }
+
+ /**
+ * @method syncCommonLists()
+ * Make sure the given lists do not contain options for the other lists
+ * in their selections.
+ * In this case, we have multiple lists of fields that can be options for
+ * the start and end dates. However once the start date field is chosen
+ * we want to make sure that entry doesn't show up in the end date.
+ * @param {array} commonIDs
+ * an array of [ webix.id, webix.id ] of the lists that share the
+ * same values, but shouldn't show the options of the others.
+ * @param {array} fullOptions
+ * The full list of options available for those lists.
+ */
+ syncCommonLists(commonIDs, fullOptions) {
+ // for each of the Other lists
+
+ commonIDs.forEach((idCurr) => {
+ const otherVals = [];
+ const otherIDs = commonIDs.filter((i) => i != idCurr);
+ otherIDs.forEach((idOther) => {
+ otherVals.push($$(idOther).getValue());
+ });
+
+ const $list = $$(idCurr);
+ const newOptions = fullOptions.filter(
+ (o) => otherVals.indexOf(o.id) == -1
+ );
+ $list.define("options", newOptions);
+ $list.refresh();
+ });
+ }
+
+ ui() {
+ const ids = this.ids;
+
+ // const labels = {
+ // common: App.labels,
+ // component: {
+ // titleFieldID: L("ab.add_view.gantt.title", "*Title"),
+ // startDateFieldID: L("ab.add_view.gantt.startDate", "*Start Date"),
+ // endDateFieldID: L("ab.add_view.gantt.endDate", "*End Date"),
+ // durationFieldID: L("ab.add_view.gantt.duration", "*Duration"),
+ // progressFieldID: L("ab.add_view.gantt.progress", "*Progress"),
+ // notesFieldID: L("ab.add_view.gantt.notes", "*Notes"),
+
+ // datePlaceholder: L(
+ // "ab.add_view.gantt.datePlaceholder",
+ // "*Select a date field"
+ // ),
+ // numberPlaceholder: L(
+ // "ab.add_view.gantt.numberPlaceholder",
+ // "*Select a number field"
+ // ),
+ // stringPlaceholder: L(
+ // "ab.add_view.gantt.stringPlaceholder",
+ // "*Select a string field"
+ // ),
+ // },
+ // };
+
+ // const PopupNewDataFieldComponent = new ABPopupNewDataField(
+ // App,
+ // idBase + "_gantt"
+ // );
+
+ return {
+ batch: "gantt",
+ rows: [
+ {
+ cols: [
+ {
+ id: ids.titleFieldID,
+ view: "richselect",
+ label: ` ${L(
+ "Title"
+ )}`,
+ placeholder: L("Select a string field"),
+ labelWidth: 130,
+ name: "titleFieldID",
+ options: [],
+ on: {
+ onChange: (newValue, oldValue) => {
+ this.syncCommonLists(
+ [ids.titleFieldID, ids.notesFieldID],
+ this._stringFields
+ );
+ },
+ },
+ },
+ {
+ view: "button",
+ css: "webix_primary",
+ type: "icon",
+ icon: "fa fa-plus",
+ label: "",
+ width: 30,
+ click: () => {
+ this._autoSelectInput = ids.titleFieldID;
+ this.emit("new.field", ABFieldString.defaults().key);
+ },
+ },
+ ],
+ },
+ {
+ cols: [
+ {
+ id: ids.startDateFieldID,
+ view: "richselect",
+ label: ` ${L(
+ "Start Date"
+ )}`,
+ placeholder: L("Select a date field"),
+ labelWidth: 130,
+ name: "startDateFieldID",
+ required: true,
+ options: [],
+ on: {
+ onChange: (newValue, oldValue) => {
+ this.syncCommonLists(
+ [ids.startDateFieldID, ids.endDateFieldID],
+ this._dateFields
+ );
+ },
+ },
+ },
+ {
+ view: "button",
+ css: "webix_primary",
+ type: "icon",
+ icon: "fa fa-plus",
+ label: "",
+ width: 30,
+ click: () => {
+ this._autoSelectInput = ids.startDateFieldID;
+ this.emit("new.field", ABFieldDate.defaults().key);
+ },
+ },
+ ],
+ },
+ {
+ cols: [
+ {
+ id: ids.endDateFieldID,
+ view: "richselect",
+ label: ` ${L(
+ "End Date"
+ )}`,
+ placeholder: L("Select a date field"),
+ labelWidth: 130,
+ name: "endDateFieldID",
+ options: [],
+ on: {
+ onChange: (newValue, oldValue) => {
+ this.syncCommonLists(
+ [ids.startDateFieldID, ids.endDateFieldID],
+ this._dateFields
+ );
+ },
+ },
+ },
+ {
+ view: "button",
+ css: "webix_primary",
+ type: "icon",
+ icon: "fa fa-plus",
+ label: "",
+ width: 30,
+ click: () => {
+ this._autoSelectInput = ids.endDateFieldID;
+ this.emit("new.field", ABFieldDate.defaults().key);
+ },
+ },
+ ],
+ },
+ {
+ cols: [
+ {
+ id: ids.durationFieldID,
+ view: "richselect",
+ label: ` ${L(
+ "Duration"
+ )}`,
+ placeholder: L("Select a number field"),
+ labelWidth: 130,
+ name: "durationFieldID",
+ options: [],
+ on: {
+ onChange: (newValue, oldValue) => {
+ this.syncCommonLists(
+ [ids.durationFieldID, ids.progressFieldID],
+ this._numberFields
+ );
+ },
+ },
+ },
+ {
+ view: "button",
+ css: "webix_primary",
+ type: "icon",
+ icon: "fa fa-plus",
+ label: "",
+ width: 30,
+ click: () => {
+ this._autoSelectInput = ids.durationFieldID;
+ this.emit("new.field", ABFieldNumber.defaults().key);
+ },
+ },
+ ],
+ },
+ {
+ cols: [
+ {
+ id: ids.progressFieldID,
+ view: "richselect",
+ label: ` ${L(
+ "Progress"
+ )}`,
+ placeholder: L("Select a number field"),
+ labelWidth: 130,
+ name: "progressFieldID",
+ required: false,
+ options: [],
+ on: {
+ onChange: (newValue, oldValue) => {
+ this.syncCommonLists(
+ [ids.durationFieldID, ids.progressFieldID],
+ this._numberFields
+ );
+ },
+ },
+ },
+ {
+ view: "button",
+ css: "webix_primary",
+ type: "icon",
+ icon: "fa fa-plus",
+ label: "",
+ width: 30,
+ click: () => {
+ this._autoSelectInput = ids.progressFieldID;
+ this.emit("new.field", ABFieldNumber.defaults().key);
+ },
+ },
+ ],
+ },
+ {
+ cols: [
+ {
+ id: ids.notesFieldID,
+ view: "richselect",
+ label: ` ${L(
+ "Notes"
+ )}`,
+ placeholder: L("Select a string field"),
+ labelWidth: 130,
+ name: "notesFieldID",
+ required: false,
+ options: [],
+ on: {
+ onChange: (newValue, oldValue) => {
+ this.syncCommonLists(
+ [ids.titleFieldID, ids.notesFieldID],
+ this._stringFields
+ );
+ },
+ },
+ },
+ {
+ view: "button",
+ css: "webix_primary",
+ type: "icon",
+ icon: "fa fa-plus",
+ label: "",
+ width: 30,
+ click: () => {
+ this._autoSelectInput = ids.notesFieldID;
+ this.emit(
+ "new.field",
+ ABFieldLongText.defaults().key
+ );
+ },
+ },
+ ],
+ },
+ ],
+ };
+ }
+
+ init(object, view) {
+ this.objectLoad(object);
+ this._view = view;
+ this.refreshOptions(object, view?.settings);
+ }
+
+ validate($form) {
+ const ids = this.ids;
+ const endDateFieldID =
+ $$(ids.endDateFieldID).getValue() ||
+ defaultValues.settings.endDateFieldID;
+ const durationFieldID =
+ $$(ids.durationFieldID).getValue() ||
+ defaultValues.settings.durationFieldID;
+
+ if (!endDateFieldID && !durationFieldID) {
+ $form.markInvalid("endDateFieldID", "Required");
+ $form.markInvalid("durationFieldID", "Required");
+
+ return false;
+ }
+
+ return true;
+ }
+
+ values() {
+ const ids = this.ids;
+
+ const result = {};
+
+ result.titleFieldID =
+ $$(ids.titleFieldID).getValue() ||
+ defaultValues.settings.titleFieldID;
+ result.startDateFieldID =
+ $$(ids.startDateFieldID).getValue() ||
+ defaultValues.settings.startDateFieldID;
+ result.endDateFieldID =
+ $$(ids.endDateFieldID).getValue() ||
+ defaultValues.settings.endDateFieldID;
+ result.durationFieldID =
+ $$(ids.durationFieldID).getValue() ||
+ defaultValues.settings.durationFieldID;
+ result.progressFieldID =
+ $$(ids.progressFieldID).getValue() ||
+ defaultValues.settings.progressFieldID;
+ result.notesFieldID =
+ $$(ids.notesFieldID).getValue() ||
+ defaultValues.settings.notesFieldID;
+
+ return result;
+ }
+
+ /**
+ * @method fromObj
+ * take our persisted data, and properly load it
+ * into this object instance.
+ * @param {json} data the persisted data
+ */
+ fromSettings(data) {
+ for (const key in defaultValues)
+ this[key] = data[key] || defaultValues[key];
+
+ this.settings = Object.assign(
+ {},
+ defaultValues.settings,
+ data.settings ?? {}
+ );
+
+ this.type = this.type();
+ }
+
+ /**
+ * @method toObj()
+ * compile our current state into a {json} object
+ * that can be persisted.
+ */
+ toSettings() {
+ const obj = {}; //super.toObj();
+
+ for (const key in defaultValues)
+ obj[key] = this[key] || defaultValues[key];
+
+ obj.settings = Object.assign(
+ {},
+ defaultValues.settings,
+ obj.settings ?? {}
+ );
+ obj.key = this.type();
+ obj.type = this.type();
+
+ return obj;
+ }
+ }
+
+ return new ABObjectWorkspaceViewGantt(ibase);
+}
diff --git a/src/plugins/web_view_kanban/Abkanbanworkspace.js b/src/plugins/web_view_kanban/Abkanbanworkspace.js
index fc4c2e4c..d963886f 100644
--- a/src/plugins/web_view_kanban/Abkanbanworkspace.js
+++ b/src/plugins/web_view_kanban/Abkanbanworkspace.js
@@ -2,21 +2,17 @@
//
// Manages the settings for a KanBan View in the Object Workspace
-import UI_Class from "../../rootPages/Designer/ui_class";
-
let classABViewKanban = null;
-export default function (AB, ibase) {
+export default function (AB, ABUIPlugin, ibase) {
const L = AB.Label();
- const UIClass = UI_Class(AB);
-
const ABFieldConnect = AB.Class.ABFieldManager.fieldByKey("connectObject");
const ABFieldList = AB.Class.ABFieldManager.fieldByKey("list");
const ABFieldUser = AB.Class.ABFieldManager.fieldByKey("user");
if (!classABViewKanban) {
- classABViewKanban = class ABViewKanban extends UIClass {
+ classABViewKanban = class ABViewKanban extends ABUIPlugin {
constructor(idBase) {
super(idBase, {
vGroupInput: "",
diff --git a/src/plugins/web_view_kanban/FNAbviewkanban.js b/src/plugins/web_view_kanban/FNAbviewkanban.js
index e473cbb6..66cf8f3c 100644
--- a/src/plugins/web_view_kanban/FNAbviewkanban.js
+++ b/src/plugins/web_view_kanban/FNAbviewkanban.js
@@ -6,6 +6,7 @@ import FABViewKanbanWorkspace from "./Abkanbanworkspace.js";
export default function FNAbviewkanbanProperties({
AB,
ABViewPropertiesPlugin,
+ ABUIPlugin,
}) {
const BASE_ID = "properties_abview_kanban";
@@ -17,7 +18,7 @@ export default function FNAbviewkanbanProperties({
const uiConfig = AB.UISettings.config();
const L = AB.Label();
- const ViewKanbanProperties = FABViewKanbanWorkspace(AB, BASE_ID);
+ const ViewKanbanProperties = FABViewKanbanWorkspace(AB, ABUIPlugin, BASE_ID);
let PopupNewDataFieldComponent = null;
return class ABAbviewkanbanProperties extends ABViewPropertiesPlugin {
diff --git a/src/rootPages/Designer/editors/EditorManager.js b/src/rootPages/Designer/editors/EditorManager.js
index 5a194c43..65143033 100644
--- a/src/rootPages/Designer/editors/EditorManager.js
+++ b/src/rootPages/Designer/editors/EditorManager.js
@@ -29,7 +29,7 @@ export default function (AB) {
require("./views/ABViewDocxBuilder"),
require("./views/ABViewForm"),
require("./views/ABViewFormUrl"),
- require("./views/ABViewGantt"),
+ // require("./views/ABViewGantt"),
// require("./views/ABViewKanban"),
// require("./views/ABViewGrid"),
// require("./views/ABViewLabel"),
diff --git a/src/rootPages/Designer/properties/PropertyManager.js b/src/rootPages/Designer/properties/PropertyManager.js
index f53cd950..edbaca5e 100644
--- a/src/rootPages/Designer/properties/PropertyManager.js
+++ b/src/rootPages/Designer/properties/PropertyManager.js
@@ -105,7 +105,7 @@ export default function (AB) {
require("./views/ABViewFormTextbox"),
require("./views/ABViewFormTree"),
require("./views/ABViewFormUrl"),
- require("./views/ABViewGantt"),
+ // require("./views/ABViewGantt"),
// require("./views/ABViewGrid"),
// require("./views/ABViewImage"),
// require("./views/ABViewKanban"),
diff --git a/src/rootPages/Designer/properties/workspaceViews/ABViewGantt.js b/src/rootPages/Designer/properties/workspaceViews/ABViewGantt.js
index 66fbfbfb..f906b526 100644
--- a/src/rootPages/Designer/properties/workspaceViews/ABViewGantt.js
+++ b/src/rootPages/Designer/properties/workspaceViews/ABViewGantt.js
@@ -184,7 +184,7 @@ export default function (AB, ibase) {
$$(ids.endDateFieldID).define(
"value",
settings.endDateFieldID ||
- defaultValues.settings.endDateFieldIDFieldID
+ defaultValues.settings.endDateFieldIDFieldID
);
$$(ids.endDateFieldID).refresh();
this.syncCommonLists(
@@ -197,7 +197,7 @@ export default function (AB, ibase) {
$$(ids.durationFieldID).define(
"value",
settings.durationFieldID ||
- defaultValues.settings.durationFieldID
+ defaultValues.settings.durationFieldID
);
$$(ids.durationFieldID).refresh();
this.syncCommonLists(
@@ -573,7 +573,7 @@ export default function (AB, ibase) {
*/
fromSettings(data) {
for (const key in defaultValues)
- this[v] = data[key] || defaultValues[key];
+ this[key] = data[key] || defaultValues[key];
this.settings = Object.assign(
{},
diff --git a/src/rootPages/Designer/ui_work_interface_workspace_editor_layout.js b/src/rootPages/Designer/ui_work_interface_workspace_editor_layout.js
index 94586edc..0f797d72 100644
--- a/src/rootPages/Designer/ui_work_interface_workspace_editor_layout.js
+++ b/src/rootPages/Designer/ui_work_interface_workspace_editor_layout.js
@@ -287,7 +287,8 @@ export default function (AB) {
}
if (idDashboard) {
const $dashboard = $$(idDashboard);
- if ($dashboard) $dashboard.clearAll();
+ if ($dashboard && typeof $dashboard.clearAll === "function")
+ $dashboard.clearAll();
}
// add the editorUI if it is not already added