@syncfusion/ej2-gantt 19.4.55 → 20.1.47-1460716

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/CHANGELOG.md +1072 -1047
  2. package/README.md +75 -75
  3. package/dist/ej2-gantt.umd.min.js +1 -10
  4. package/dist/ej2-gantt.umd.min.js.map +1 -1
  5. package/dist/es6/ej2-gantt.es2015.js +341 -240
  6. package/dist/es6/ej2-gantt.es2015.js.map +1 -1
  7. package/dist/es6/ej2-gantt.es5.js +713 -598
  8. package/dist/es6/ej2-gantt.es5.js.map +1 -1
  9. package/dist/global/ej2-gantt.min.js +1 -10
  10. package/dist/global/ej2-gantt.min.js.map +1 -1
  11. package/dist/global/index.d.ts +0 -9
  12. package/dist/ts/components.ts +4 -0
  13. package/dist/ts/gantt/actions/actions.ts +18 -0
  14. package/dist/ts/gantt/actions/cell-edit.ts +606 -0
  15. package/dist/ts/gantt/actions/chart-scroll.ts +167 -0
  16. package/dist/ts/gantt/actions/column-menu.ts +35 -0
  17. package/dist/ts/gantt/actions/column-reorder.ts +52 -0
  18. package/dist/ts/gantt/actions/column-resize.ts +52 -0
  19. package/dist/ts/gantt/actions/connector-line-edit.ts +829 -0
  20. package/dist/ts/gantt/actions/context-menu.ts +754 -0
  21. package/dist/ts/gantt/actions/day-markers.ts +80 -0
  22. package/dist/ts/gantt/actions/dependency.ts +692 -0
  23. package/dist/ts/gantt/actions/dialog-edit.ts +2208 -0
  24. package/dist/ts/gantt/actions/edit.ts +3499 -0
  25. package/dist/ts/gantt/actions/excel-export.ts +61 -0
  26. package/dist/ts/gantt/actions/filter.ts +302 -0
  27. package/dist/ts/gantt/actions/keyboard.ts +306 -0
  28. package/dist/ts/gantt/actions/pdf-export.ts +214 -0
  29. package/dist/ts/gantt/actions/rowdragdrop.ts +839 -0
  30. package/dist/ts/gantt/actions/selection.ts +536 -0
  31. package/dist/ts/gantt/actions/sort.ts +98 -0
  32. package/dist/ts/gantt/actions/taskbar-edit.ts +1940 -0
  33. package/dist/ts/gantt/actions/toolbar.ts +489 -0
  34. package/dist/ts/gantt/actions/virtual-scroll.ts +60 -0
  35. package/dist/ts/gantt/base/common.ts +9 -0
  36. package/dist/ts/gantt/base/constant.ts +13 -0
  37. package/dist/ts/gantt/base/css-constants.ts +148 -0
  38. package/dist/ts/gantt/base/date-processor.ts +1257 -0
  39. package/dist/ts/gantt/base/enum.ts +372 -0
  40. package/dist/ts/gantt/base/gantt-chart.ts +1248 -0
  41. package/dist/ts/gantt/base/gantt.ts +4069 -0
  42. package/dist/ts/gantt/base/interface.ts +955 -0
  43. package/dist/ts/gantt/base/splitter.ts +174 -0
  44. package/dist/ts/gantt/base/task-processor.ts +2217 -0
  45. package/dist/ts/gantt/base/tree-grid.ts +694 -0
  46. package/dist/ts/gantt/base/utils.ts +208 -0
  47. package/dist/ts/gantt/export/export-helper.ts +552 -0
  48. package/dist/ts/gantt/export/pdf-base/dictionary.ts +152 -0
  49. package/dist/ts/gantt/export/pdf-base/pdf-borders.ts +277 -0
  50. package/dist/ts/gantt/export/pdf-base/pdf-grid-table.ts +901 -0
  51. package/dist/ts/gantt/export/pdf-base/pdf-style/gantt-theme.ts +131 -0
  52. package/dist/ts/gantt/export/pdf-base/pdf-style/style.ts +91 -0
  53. package/dist/ts/gantt/export/pdf-base/treegrid-layouter.ts +414 -0
  54. package/dist/ts/gantt/export/pdf-connector-line.ts +422 -0
  55. package/dist/ts/gantt/export/pdf-gantt.ts +282 -0
  56. package/dist/ts/gantt/export/pdf-taskbar.ts +395 -0
  57. package/dist/ts/gantt/export/pdf-timeline.ts +202 -0
  58. package/dist/ts/gantt/export/pdf-treegrid.ts +406 -0
  59. package/dist/ts/gantt/models/add-dialog-field-settings.ts +33 -0
  60. package/dist/ts/gantt/models/column.ts +464 -0
  61. package/dist/ts/gantt/models/day-working-time.ts +22 -0
  62. package/dist/ts/gantt/models/edit-dialog-field-settings.ts +33 -0
  63. package/dist/ts/gantt/models/edit-settings.ts +79 -0
  64. package/dist/ts/gantt/models/event-marker.ts +27 -0
  65. package/dist/ts/gantt/models/filter-settings.ts +53 -0
  66. package/dist/ts/gantt/models/holiday.ts +34 -0
  67. package/dist/ts/gantt/models/label-settings.ts +30 -0
  68. package/dist/ts/gantt/models/models.ts +36 -0
  69. package/dist/ts/gantt/models/resource-fields.ts +38 -0
  70. package/dist/ts/gantt/models/search-settings.ts +77 -0
  71. package/dist/ts/gantt/models/selection-settings.ts +56 -0
  72. package/dist/ts/gantt/models/sort-settings.ts +50 -0
  73. package/dist/ts/gantt/models/splitter-settings.ts +47 -0
  74. package/dist/ts/gantt/models/task-fields.ts +171 -0
  75. package/dist/ts/gantt/models/timeline-settings.ts +112 -0
  76. package/dist/ts/gantt/models/tooltip-settings.ts +46 -0
  77. package/dist/ts/gantt/renderer/chart-rows.ts +1838 -0
  78. package/dist/ts/gantt/renderer/connector-line.ts +1025 -0
  79. package/dist/ts/gantt/renderer/edit-tooltip.ts +228 -0
  80. package/dist/ts/gantt/renderer/event-marker.ts +96 -0
  81. package/dist/ts/gantt/renderer/nonworking-day.ts +205 -0
  82. package/dist/ts/gantt/renderer/render.ts +5 -0
  83. package/dist/ts/gantt/renderer/timeline.ts +1397 -0
  84. package/dist/ts/gantt/renderer/tooltip.ts +450 -0
  85. package/dist/ts/gantt/renderer/virtual-content-render.ts +50 -0
  86. package/license +9 -9
  87. package/package.json +80 -80
  88. package/src/gantt/actions/cell-edit.js +2 -1
  89. package/src/gantt/actions/dialog-edit.js +2 -1
  90. package/src/gantt/actions/edit.js +36 -9
  91. package/src/gantt/actions/rowdragdrop.js +37 -15
  92. package/src/gantt/actions/selection.js +3 -2
  93. package/src/gantt/actions/taskbar-edit.js +24 -24
  94. package/src/gantt/base/date-processor.js +0 -1
  95. package/src/gantt/base/gantt-chart.js +36 -5
  96. package/src/gantt/base/gantt-model.d.ts +779 -779
  97. package/src/gantt/base/gantt.d.ts +27 -27
  98. package/src/gantt/base/gantt.js +35 -76
  99. package/src/gantt/base/splitter.js +1 -0
  100. package/src/gantt/base/task-processor.js +13 -13
  101. package/src/gantt/base/tree-grid.js +3 -1
  102. package/src/gantt/export/pdf-base/treegrid-layouter.js +13 -13
  103. package/src/gantt/export/pdf-connector-line.js +11 -11
  104. package/src/gantt/export/pdf-gantt.js +24 -24
  105. package/src/gantt/export/pdf-taskbar.js +11 -11
  106. package/src/gantt/export/pdf-treegrid.js +13 -13
  107. package/src/gantt/models/add-dialog-field-settings-model.d.ts +21 -21
  108. package/src/gantt/models/add-dialog-field-settings.js +19 -19
  109. package/src/gantt/models/day-working-time-model.d.ts +11 -11
  110. package/src/gantt/models/day-working-time.js +19 -19
  111. package/src/gantt/models/edit-dialog-field-settings-model.d.ts +21 -21
  112. package/src/gantt/models/edit-dialog-field-settings.js +19 -19
  113. package/src/gantt/models/edit-settings-model.d.ts +50 -50
  114. package/src/gantt/models/edit-settings.js +19 -19
  115. package/src/gantt/models/event-marker-model.d.ts +16 -16
  116. package/src/gantt/models/event-marker.js +19 -19
  117. package/src/gantt/models/filter-settings-model.d.ts +34 -34
  118. package/src/gantt/models/filter-settings.js +19 -19
  119. package/src/gantt/models/holiday-model.d.ts +21 -21
  120. package/src/gantt/models/holiday.js +19 -19
  121. package/src/gantt/models/label-settings-model.d.ts +16 -16
  122. package/src/gantt/models/label-settings.js +19 -19
  123. package/src/gantt/models/resource-fields-model.d.ts +21 -21
  124. package/src/gantt/models/resource-fields.js +19 -19
  125. package/src/gantt/models/search-settings-model.d.ts +56 -56
  126. package/src/gantt/models/search-settings.js +19 -19
  127. package/src/gantt/models/selection-settings-model.d.ts +35 -35
  128. package/src/gantt/models/selection-settings.js +19 -19
  129. package/src/gantt/models/sort-settings-model.d.ts +24 -24
  130. package/src/gantt/models/sort-settings.js +19 -19
  131. package/src/gantt/models/splitter-settings-model.d.ts +30 -30
  132. package/src/gantt/models/splitter-settings.js +19 -19
  133. package/src/gantt/models/task-fields-model.d.ts +110 -110
  134. package/src/gantt/models/task-fields.js +19 -19
  135. package/src/gantt/models/timeline-settings-model.d.ts +71 -71
  136. package/src/gantt/models/timeline-settings.js +19 -19
  137. package/src/gantt/models/tooltip-settings-model.d.ts +26 -26
  138. package/src/gantt/models/tooltip-settings.js +19 -19
  139. package/src/gantt/renderer/chart-rows.js +49 -37
  140. package/src/gantt/renderer/connector-line.js +22 -18
  141. package/src/gantt/renderer/event-marker.js +1 -0
  142. package/src/gantt/renderer/nonworking-day.js +13 -6
  143. package/src/gantt/renderer/timeline.d.ts +1 -0
  144. package/src/gantt/renderer/timeline.js +51 -12
  145. package/src/gantt/renderer/tooltip.js +11 -3
  146. package/styles/bootstrap-dark.css +442 -427
  147. package/styles/bootstrap.css +442 -433
  148. package/styles/bootstrap4.css +454 -479
  149. package/styles/bootstrap5-dark.css +457 -433
  150. package/styles/bootstrap5.css +457 -433
  151. package/styles/fabric-dark.css +438 -421
  152. package/styles/fabric.css +445 -428
  153. package/styles/fluent-dark.css +1938 -0
  154. package/styles/fluent-dark.scss +1 -0
  155. package/styles/fluent.css +1938 -0
  156. package/styles/fluent.scss +1 -0
  157. package/styles/gantt/_all.scss +2 -2
  158. package/styles/gantt/_bootstrap-dark-definition.scss +210 -156
  159. package/styles/gantt/_bootstrap-definition.scss +211 -157
  160. package/styles/gantt/_bootstrap4-definition.scss +213 -158
  161. package/styles/gantt/_bootstrap5-definition.scss +215 -162
  162. package/styles/gantt/_fabric-dark-definition.scss +211 -157
  163. package/styles/gantt/_fabric-definition.scss +211 -157
  164. package/styles/gantt/_fluent-dark-definition.scss +1 -0
  165. package/styles/gantt/_fluent-definition.scss +215 -162
  166. package/styles/gantt/_fusionnew-definition.scss +214 -0
  167. package/styles/gantt/_highcontrast-definition.scss +211 -157
  168. package/styles/gantt/_highcontrast-light-definition.scss +211 -157
  169. package/styles/gantt/_layout.scss +1446 -1027
  170. package/styles/gantt/_material-dark-definition.scss +212 -157
  171. package/styles/gantt/_material-definition.scss +212 -157
  172. package/styles/gantt/_material3-definition.scss +215 -0
  173. package/styles/gantt/_tailwind-definition.scss +215 -161
  174. package/styles/gantt/_theme.scss +702 -668
  175. package/styles/gantt/bootstrap-dark.css +442 -427
  176. package/styles/gantt/bootstrap.css +442 -433
  177. package/styles/gantt/bootstrap4.css +454 -479
  178. package/styles/gantt/bootstrap5-dark.css +457 -433
  179. package/styles/gantt/bootstrap5.css +457 -433
  180. package/styles/gantt/fabric-dark.css +438 -421
  181. package/styles/gantt/fabric.css +445 -428
  182. package/styles/gantt/fluent-dark.css +1938 -0
  183. package/styles/gantt/fluent-dark.scss +22 -0
  184. package/styles/gantt/fluent.css +1938 -0
  185. package/styles/gantt/fluent.scss +22 -0
  186. package/styles/gantt/highcontrast-light.css +405 -405
  187. package/styles/gantt/highcontrast.css +444 -456
  188. package/styles/gantt/icons/_bootstrap-dark.scss +124 -113
  189. package/styles/gantt/icons/_bootstrap.scss +124 -113
  190. package/styles/gantt/icons/_bootstrap4.scss +124 -113
  191. package/styles/gantt/icons/_bootstrap5.scss +124 -112
  192. package/styles/gantt/icons/_fabric-dark.scss +124 -112
  193. package/styles/gantt/icons/_fabric.scss +124 -112
  194. package/styles/gantt/icons/_fluent-dark.scss +1 -0
  195. package/styles/gantt/icons/_fluent.scss +124 -112
  196. package/styles/gantt/icons/_fusionnew.scss +120 -0
  197. package/styles/gantt/icons/_highcontrast.scss +124 -112
  198. package/styles/gantt/icons/_material-dark.scss +124 -112
  199. package/styles/gantt/icons/_material.scss +124 -112
  200. package/styles/gantt/icons/_material3.scss +124 -0
  201. package/styles/gantt/icons/_tailwind-dark.scss +124 -113
  202. package/styles/gantt/icons/_tailwind.scss +124 -113
  203. package/styles/gantt/material-dark.css +446 -417
  204. package/styles/gantt/material.css +445 -419
  205. package/styles/gantt/tailwind-dark.css +452 -482
  206. package/styles/gantt/tailwind.css +449 -479
  207. package/styles/highcontrast-light.css +405 -405
  208. package/styles/highcontrast.css +444 -456
  209. package/styles/material-dark.css +446 -417
  210. package/styles/material.css +445 -419
  211. package/styles/tailwind-dark.css +452 -482
  212. package/styles/tailwind.css +449 -479
@@ -0,0 +1,2208 @@
1
+ import { remove, extend, isNullOrUndefined, createElement, L10n, getValue, setValue, closest } from '@syncfusion/ej2-base';
2
+ import { DataManager, DataUtil } from '@syncfusion/ej2-data';
3
+ import { Dialog, PositionDataModel, DialogModel } from '@syncfusion/ej2-popups';
4
+ import { Tab, TabModel, TabItemModel, SelectEventArgs } from '@syncfusion/ej2-navigations';
5
+ import {
6
+ Grid, Edit, Toolbar as GridToolbar, Page, GridModel, GridActionEventArgs, getObject, ActionEventArgs
7
+ } from '@syncfusion/ej2-grids';
8
+ import {
9
+ ColumnModel as GridColumnModel, ForeignKey,
10
+ getActualProperties, RowSelectEventArgs
11
+ } from '@syncfusion/ej2-grids';
12
+ import { Gantt } from '../base/gantt';
13
+ import {
14
+ RichTextEditor, Toolbar as RTEToolbar, Link, HtmlEditor, QuickToolbar,
15
+ RichTextEditorModel,
16
+ Count
17
+ } from '@syncfusion/ej2-richtexteditor';
18
+ import { AddDialogFieldSettingsModel, EditDialogFieldSettingsModel, TaskFieldsModel, ResourceFieldsModel, AddDialogFieldSettings } from '../models/models';
19
+ import { CObject } from '../base/enum';
20
+ import { ColumnModel as GanttColumnModel } from '../models/column';
21
+ import { TextBox, NumericTextBox, NumericTextBoxModel, MaskedTextBox, TextBoxModel } from '@syncfusion/ej2-inputs';
22
+ import {
23
+ IGanttData, ITaskData, ITaskSegment, IDependencyEditData, IPredecessor, ITaskbarEditedEventArgs, ActionBeginArgs
24
+ } from '../base/interface';
25
+ import { CheckBox, CheckBoxModel } from '@syncfusion/ej2-buttons';
26
+ import { DatePicker, DateTimePicker, DatePickerModel } from '@syncfusion/ej2-calendars';
27
+ import { DropDownList, ComboBox, ComboBoxModel, ChangeEventArgs, DropDownListModel } from '@syncfusion/ej2-dropdowns';
28
+ import { isScheduledTask } from '../base/utils';
29
+ import {
30
+ TreeGridModel, ColumnModel as TreeGridColumnModel,
31
+ TreeGrid, Selection, Filter, Edit as TreeGridEdit, VirtualScroll
32
+ } from '@syncfusion/ej2-treegrid';
33
+ import { getUid } from '../base/utils';
34
+ interface EJ2Instance extends HTMLElement {
35
+ // eslint-disable-next-line
36
+ ej2_instances: Object[];
37
+ }
38
+
39
+ /**
40
+ *
41
+ * @hidden
42
+ */
43
+ export class DialogEdit {
44
+ //Internal variables
45
+ //Module declarations
46
+ private isEdit: boolean;
47
+ /**
48
+ * @private
49
+ */
50
+ public dialog: HTMLElement;
51
+ public isAddNewResource: boolean;
52
+ /**
53
+ * @private
54
+ */
55
+ public dialogObj: Dialog;
56
+ private preTableCollection: IDependencyEditData[];
57
+ private preTaskIds: string[];
58
+ private localeObj: L10n;
59
+ private parent: Gantt;
60
+ private rowIndex: number;
61
+ private types: IDependencyEditData[];
62
+ private editedRecord: IGanttData;
63
+ private rowData: IGanttData;
64
+ private beforeOpenArgs: CObject;
65
+ private inputs: Object;
66
+ private idCollection: IDependencyEditData[];
67
+ /**
68
+ * @private
69
+ */
70
+ public updatedEditFields: EditDialogFieldSettingsModel[] = null;
71
+ private updatedAddFields: AddDialogFieldSettingsModel[] = null;
72
+ private addedRecord: Record<string, unknown> = null;
73
+ private dialogEditValidationFlag: boolean = false;
74
+ private tabObj: Tab;
75
+ private selectedSegment: ITaskSegment;
76
+ public ganttResources: Object[] = [];
77
+ /**
78
+ * @private
79
+ */
80
+ public previousResource: Object[] = [];
81
+ /**
82
+ * @private
83
+ */
84
+ public isResourceUpdate: boolean = false;
85
+ /**
86
+ * Constructor for render module
87
+ *
88
+ * @param {Gantt} parent .
89
+ * @returns {void} .
90
+ */
91
+ constructor(parent: Gantt) {
92
+ this.parent = parent;
93
+ this.localeObj = this.parent.localeObj;
94
+ this.beforeOpenArgs = { cancel: false };
95
+ this.types = this.getPredecessorType();
96
+ this.rowData = {};
97
+ this.editedRecord = {};
98
+ this.inputs = {
99
+ booleanedit: CheckBox,
100
+ dropdownedit: DropDownList,
101
+ datepickeredit: DatePicker,
102
+ datetimepickeredit: DateTimePicker,
103
+ maskededit: MaskedTextBox,
104
+ numericedit: NumericTextBox,
105
+ stringedit: TextBox,
106
+ defaultedit: TextBox
107
+ };
108
+ this.processDialogFields();
109
+ this.wireEvents();
110
+ }
111
+
112
+ private wireEvents(): void {
113
+ this.parent.on('chartDblClick', this.dblClickHandler, this);
114
+ }
115
+
116
+ private dblClickHandler(e: PointerEvent): void {
117
+ const ganttData: IGanttData = this.parent.ganttChartModule.getRecordByTarget(e);
118
+ if (!isNullOrUndefined(ganttData) && this.parent.editModule && this.parent.editSettings.allowEditing) {
119
+ this.openEditDialog(ganttData);
120
+ }
121
+ }
122
+
123
+ /**
124
+ * Method to validate add and edit dialog fields property.
125
+ *
126
+ * @returns {void} .
127
+ * @private
128
+ */
129
+ public processDialogFields(): void {
130
+ if (isNullOrUndefined(this.parent.editDialogFields) ||
131
+ this.parent.editDialogFields && this.parent.editDialogFields.length === 0) {
132
+ this.updatedEditFields = this.getDefaultDialogFields();
133
+ this.updatedEditFields = this.validateDialogFields(this.updatedEditFields);
134
+ } else {
135
+ this.updatedEditFields = this.validateDialogFields(this.parent.editDialogFields);
136
+ }
137
+ if (isNullOrUndefined(this.parent.addDialogFields) ||
138
+ this.parent.addDialogFields && this.parent.addDialogFields.length === 0) {
139
+ this.updatedAddFields = this.getDefaultDialogFields();
140
+ this.updatedAddFields = this.validateDialogFields(this.updatedAddFields);
141
+ } else {
142
+ this.updatedAddFields = this.validateDialogFields(this.parent.addDialogFields);
143
+ }
144
+ }
145
+
146
+ private validateDialogFields(dialogFields: AddDialogFieldSettingsModel[]): AddDialogFieldSettingsModel[] {
147
+ const newDialogFields: AddDialogFieldSettingsModel[] = [];
148
+ let emptyCustomColumn: number = 0;
149
+ for (let i: number = 0; i < dialogFields.length; i++) {
150
+ const fieldItem: AddDialogFieldSettingsModel = getActualProperties(dialogFields[i]);
151
+ if (fieldItem.type === 'General' && (isNullOrUndefined(fieldItem.fields) || fieldItem.fields.length === 0)) {
152
+ fieldItem.fields = this.getGeneralColumnFields();
153
+ }
154
+ if (fieldItem.type === 'Dependency' && isNullOrUndefined(this.parent.taskFields.dependency)
155
+ || fieldItem.type === 'Resources' && isNullOrUndefined(this.parent.taskFields.resourceInfo)
156
+ || fieldItem.type === 'Notes' && isNullOrUndefined(this.parent.taskFields.notes)) {
157
+ continue;
158
+ }
159
+ if (fieldItem.type === 'Custom' && (isNullOrUndefined(fieldItem.fields) || fieldItem.fields.length === 0)) {
160
+ emptyCustomColumn += 1;
161
+ fieldItem.fields = this.getCustomColumnFields();
162
+ }
163
+ if (emptyCustomColumn > 1) {
164
+ continue;
165
+ }
166
+ newDialogFields.push(fieldItem);
167
+ }
168
+ return newDialogFields;
169
+ }
170
+ /**
171
+ * Method to get general column fields
172
+ *
173
+ * @returns {string[]} .
174
+ */
175
+ private getGeneralColumnFields(): string[] {
176
+ const fields: string[] = [];
177
+ for (const key of Object.keys(this.parent.columnMapping)) {
178
+ if (key === 'dependency' || key === 'resourceInfo' || key === 'notes') {
179
+ continue;
180
+ }
181
+ fields.push(this.parent.columnMapping[key]);
182
+ }
183
+ return fields;
184
+ }
185
+
186
+ /**
187
+ * Method to get custom column fields
188
+ *
189
+ * @returns {void} .
190
+ */
191
+ private getCustomColumnFields(): string[] {
192
+ const fields: string[] = [];
193
+ for (let i: number = 0; i < this.parent.customColumns.length; i++) {
194
+ fields.push(this.parent.customColumns[i]);
195
+ }
196
+ return fields;
197
+ }
198
+
199
+ /**
200
+ * Get default dialog fields when fields are not defined for add and edit dialogs
201
+ *
202
+ * @returns {AddDialogFieldSettings} .
203
+ */
204
+ private getDefaultDialogFields(): AddDialogFieldSettingsModel[] {
205
+ const dialogFields: AddDialogFieldSettingsModel[] = [];
206
+ let fieldItem: AddDialogFieldSettingsModel = {};
207
+ const taskFields: TaskFieldsModel = this.parent.taskFields;
208
+ const columnMapping: { [key: string]: string; } = this.parent.columnMapping;
209
+ if (Object.keys(columnMapping).length !== 0) {
210
+ fieldItem.type = 'General';
211
+ dialogFields.push(fieldItem);
212
+ }
213
+ if (!isNullOrUndefined(getValue('dependency', columnMapping))) {
214
+ fieldItem = {};
215
+ if (this.parent.columnByField[columnMapping.dependency.valueOf()].visible !== false) {
216
+ fieldItem.type = 'Dependency';
217
+ }
218
+ dialogFields.push(fieldItem);
219
+ }
220
+ if (!isNullOrUndefined(getValue('resourceInfo', columnMapping))) {
221
+ fieldItem = {};
222
+ if (this.parent.columnByField[columnMapping.resourceInfo.valueOf()].visible !== false) {
223
+ fieldItem.type = 'Resources';
224
+ }
225
+ dialogFields.push(fieldItem);
226
+ }
227
+ if (!isNullOrUndefined(getValue('notes', columnMapping))) {
228
+ fieldItem = {};
229
+ if (this.parent.columnByField[columnMapping.notes.valueOf()].visible !== false) {
230
+ fieldItem.type = 'Notes';
231
+ }
232
+ dialogFields.push(fieldItem);
233
+ }
234
+ if (!isNullOrUndefined(getValue('segments', taskFields))) {
235
+ fieldItem = {};
236
+ fieldItem.type = 'Segments';
237
+ dialogFields.push(fieldItem);
238
+ }
239
+ if (this.parent.customColumns.length > 0) {
240
+ fieldItem = {};
241
+ fieldItem.type = 'Custom';
242
+ dialogFields.push(fieldItem);
243
+ }
244
+ return dialogFields;
245
+ }
246
+ /**
247
+ * @returns {void} .
248
+ * @private
249
+ */
250
+ public openAddDialog(): void {
251
+ this.isEdit = false;
252
+ this.editedRecord = this.composeAddRecord();
253
+ this.createDialog();
254
+ }
255
+ /**
256
+ *
257
+ * @returns {Date} .
258
+ * @private
259
+ */
260
+ public getMinimumStartDate(): Date {
261
+ let minDate: Date = DataUtil.aggregates.min(this.parent.flatData, 'ganttProperties.startDate');
262
+ if (!isNullOrUndefined(minDate)) {
263
+ minDate = new Date(minDate.getTime());
264
+ } else {
265
+ minDate = new Date(this.parent.timelineModule.timelineStartDate.getTime());
266
+ }
267
+ minDate = this.parent.dateValidationModule.checkStartDate(minDate);
268
+ return new Date(minDate.getTime());
269
+ }
270
+
271
+ /**
272
+ * @returns {IGanttData} .
273
+ * @private
274
+ */
275
+ public composeAddRecord(): IGanttData {
276
+ const tempData: IGanttData = {};
277
+ tempData.ganttProperties = {};
278
+ const columns: GanttColumnModel[] = this.parent.ganttColumns;
279
+ const taskSettings: TaskFieldsModel = this.parent.taskFields;
280
+ const id: number | string = this.parent.editModule.getNewTaskId();
281
+ for (let i: number = 0; i < columns.length; i++) {
282
+ const field: string = columns[i].field;
283
+ if (field === taskSettings.id) {
284
+ tempData[field] = id;
285
+ tempData.ganttProperties.rowUniqueID = tempData[field];
286
+ } else if (columns[i].field === taskSettings.startDate) {
287
+ if (isNullOrUndefined(tempData[taskSettings.endDate])) {
288
+ tempData[field] = this.getMinimumStartDate();
289
+ } else {
290
+ tempData[field] = new Date(tempData[taskSettings.endDate]);
291
+ }
292
+ if (this.parent.timezone) {
293
+ tempData[field] = this.parent.dateValidationModule.remove(tempData[field], this.parent.timezone);
294
+ }
295
+ tempData.ganttProperties.startDate = new Date(tempData[field]);
296
+ } else if (columns[i].field === taskSettings.endDate) {
297
+ if (isNullOrUndefined(tempData[taskSettings.startDate])) {
298
+ tempData[field] = this.getMinimumStartDate();
299
+ } else {
300
+ tempData[field] = new Date(tempData[taskSettings.startDate]);
301
+ }
302
+ if (this.parent.timezone) {
303
+ tempData[field] = this.parent.dateValidationModule.remove(tempData[field], this.parent.timezone);
304
+ }
305
+ tempData.ganttProperties.endDate = new Date(tempData[field]);
306
+ } else if (columns[i].field === taskSettings.duration) {
307
+ tempData[field] = 1;
308
+ tempData.ganttProperties.duration = tempData[field];
309
+ tempData.ganttProperties.durationUnit = this.parent.durationUnit.toLocaleLowerCase();
310
+ } else if (columns[i].field === taskSettings.name) {
311
+ tempData[field] = this.localeObj.getConstant('addDialogTitle')+' '+ id;
312
+ tempData.ganttProperties.taskName = tempData[field];
313
+ } else if (columns[i].field === taskSettings.progress) {
314
+ tempData[field] = 0;
315
+ tempData.ganttProperties.progress = tempData[field];
316
+ } else if (columns[i].field === taskSettings.work) {
317
+ tempData[field] = 0;
318
+ tempData.ganttProperties.work = tempData[field];
319
+ } else if (columns[i].field === 'taskType') {
320
+ tempData[field] = this.parent.taskType;
321
+ tempData.ganttProperties.taskType = tempData[field];
322
+ } else {
323
+ tempData[this.parent.ganttColumns[i].field] = '';
324
+ }
325
+ }
326
+ tempData.ganttProperties.isAutoSchedule = (this.parent.taskMode === 'Auto') ? true :
327
+ (this.parent.taskMode === 'Manual') ? false :
328
+ tempData[taskSettings.manual] === true ? false : true;
329
+ return tempData;
330
+ }
331
+ /**
332
+ * @returns {void} .
333
+ * @private
334
+ */
335
+ public openToolbarEditDialog(): void {
336
+ const gObj: Gantt = this.parent;
337
+ if (gObj.editModule && gObj.editSettings.allowEditing) {
338
+ if (this.parent.ganttChartModule.focusedRowIndex > -1 && gObj.selectionModule) {
339
+ gObj.selectionModule.selectRow(this.parent.ganttChartModule.focusedRowIndex, false, false);
340
+ }
341
+ const selectedRowId: number | string = gObj.selectionModule ?
342
+ (gObj.selectionSettings.mode === 'Row' || gObj.selectionSettings.mode === 'Both') &&
343
+ gObj.selectionModule.selectedRowIndexes.length === 1 ?
344
+ gObj.updatedRecords[gObj.selectionModule.selectedRowIndexes[0]].ganttProperties.rowUniqueID :
345
+ gObj.selectionSettings.mode === 'Cell' &&
346
+ gObj.selectionModule.getSelectedRowCellIndexes().length === 1 ?
347
+ gObj.updatedRecords[gObj.selectionModule.getSelectedRowCellIndexes()[0].rowIndex].ganttProperties.rowUniqueID :
348
+ null : null;
349
+ if (!isNullOrUndefined(selectedRowId)) {
350
+ this.openEditDialog(selectedRowId);
351
+ }
352
+ }
353
+ }
354
+ /**
355
+ * @param { number | string | object} taskId .
356
+ * @returns {void} .
357
+ * @private
358
+ */
359
+ public openEditDialog(taskId: number | string | object): void {
360
+ const ganttObj: Gantt = this.parent;
361
+ if (typeof taskId === 'object' && !isNullOrUndefined(taskId)) {
362
+ this.rowIndex = this.parent.currentViewData.indexOf(taskId);
363
+ if (this.rowIndex > -1) {
364
+ this.rowData = taskId;
365
+ }
366
+ } else if (!isNullOrUndefined(taskId)) {
367
+ this.rowIndex = ganttObj.ids.indexOf(taskId.toString());
368
+ if (this.rowIndex > -1) {
369
+ this.rowData = ganttObj.flatData[this.rowIndex];
370
+ }
371
+ } else if (ganttObj.selectedRowIndex > -1) {
372
+ this.rowData = ganttObj.currentViewData[ganttObj.selectedRowIndex];
373
+ this.rowIndex = ganttObj.selectedRowIndex;
374
+ }
375
+ this.isEdit = true;
376
+ if (this.parent.viewType === 'ResourceView' && this.rowData.level === 0) {
377
+ return;
378
+ }
379
+ if (Object.keys(this.rowData).length !== 0) {
380
+ this.editedRecord = extend({}, {}, this.rowData, true);
381
+ this.createDialog();
382
+ }
383
+ }
384
+
385
+ private createDialog(): void {
386
+ const ganttObj: Gantt = this.parent;
387
+ const dialogModel: DialogModel = {};
388
+ this.beforeOpenArgs.dialogModel = dialogModel;
389
+ this.beforeOpenArgs.rowData = this.editedRecord;
390
+ this.beforeOpenArgs.rowIndex = this.rowIndex;
391
+ const dialogMaxWidth: string = this.parent.isAdaptive ? '' : '600px';
392
+ const dialog: HTMLElement = this.parent.createElement(
393
+ 'div', { id: ganttObj.element.id + '_dialog', styles: 'max-width:' + dialogMaxWidth });
394
+ ganttObj.element.appendChild(dialog);
395
+ dialogModel.animationSettings = { effect: 'None' };
396
+ dialogModel.header = this.localeObj.getConstant(this.isEdit ? 'editDialogTitle' : 'addDialogTitle');
397
+ dialogModel.isModal = true;
398
+ dialogModel.cssClass = 'e-gantt-dialog';
399
+ dialogModel.allowDragging = this.parent.isAdaptive ? false : true;
400
+ dialogModel.showCloseIcon = true;
401
+ const position: PositionDataModel = this.parent.isAdaptive ? { X: 'top', Y: 'left' } : { X: 'center', Y: 'center' };
402
+ dialogModel.position = position;
403
+ //dialogModel.width = '750px';
404
+ dialogModel.height = this.parent.isAdaptive ? '100%' : 'auto';
405
+ dialogModel.target = document.body;
406
+ dialogModel.close = this.dialogClose.bind(this);
407
+ dialogModel.closeOnEscape = true;
408
+ dialogModel.open = (args: Record<string, unknown>) => {
409
+ const dialogElement: HTMLElement = getValue('element', args);
410
+ const generalTabElement: HTMLElement = dialogElement.querySelector('#' + this.parent.element.id + 'GeneralTabContainer');
411
+ if (generalTabElement && generalTabElement.scrollHeight > generalTabElement.offsetHeight) {
412
+ generalTabElement.classList.add('e-scroll');
413
+ }
414
+ if (this.tabObj.selectedItem === 0) {
415
+ this.tabObj.select(0);
416
+ }
417
+ if (this.parent.isAdaptive) {
418
+ dialogElement.style.maxHeight = 'none';
419
+ }
420
+ if (this.parent.focusModule) {
421
+ this.parent.focusModule.setActiveElement(dialogElement);
422
+ }
423
+ };
424
+ dialogModel.locale = this.parent.locale;
425
+ dialogModel.buttons = [{
426
+ buttonModel: {
427
+ content: this.localeObj.getConstant('saveButton'), cssClass: 'e-primary'
428
+ },
429
+ click: this.buttonClick.bind(this)
430
+ }, {
431
+ buttonModel: { cssClass: 'e-flat', content: this.localeObj.getConstant('cancel') },
432
+ click: this.buttonClick.bind(this)
433
+ }];
434
+ this.createTab(dialogModel, dialog);
435
+ }
436
+
437
+ private buttonClick(e: MouseEvent): void {
438
+ const target: HTMLElement = e.target as HTMLElement;
439
+ target.style.pointerEvents = 'none';
440
+ if ((this.localeObj.getConstant('cancel')).toLowerCase() === (e.target as HTMLInputElement).innerText.trim().toLowerCase()) {
441
+ if (this.dialog && !this.dialogObj.isDestroyed) {
442
+ this.dialogObj.hide();
443
+ this.dialogClose();
444
+ }
445
+ } else {
446
+ this.initiateDialogSave();
447
+ target.style.pointerEvents = 'auto';
448
+ }
449
+ }
450
+ /**
451
+ * @returns {void} .
452
+ * @private
453
+ */
454
+ public dialogClose(): void {
455
+ if (this.dialog) {
456
+ this.resetValues();
457
+ }
458
+ if (!isNullOrUndefined(this.parent.focusModule) &&
459
+ !isNullOrUndefined(this.parent.focusModule.getActiveElement(true))) {
460
+ this.parent.focusModule.getActiveElement(true).focus();
461
+ }
462
+ }
463
+
464
+ private resetValues(): void {
465
+ this.isEdit = false;
466
+ this.isAddNewResource = false;
467
+ this.editedRecord = {};
468
+ this.rowData = {};
469
+ this.rowIndex = -1;
470
+ this.addedRecord = null;
471
+ this.ganttResources = [];
472
+ this.dialogEditValidationFlag = false;
473
+ if (this.dialog && !this.dialogObj.isDestroyed) {
474
+ this.destroyDialogInnerElements();
475
+ this.dialogObj.destroy();
476
+ remove(this.dialog);
477
+ }
478
+ }
479
+
480
+ private destroyDialogInnerElements(): void {
481
+ const ganttObj: Gantt = this.parent;
482
+ const tabModel: TabModel = this.beforeOpenArgs.tabModel;
483
+ const items: TabItemModel[] = tabModel.items;
484
+ for (let i: number = 0; i < items.length; i++) {
485
+ const element: HTMLElement = items[i].content as HTMLElement;
486
+ let id: string = element.id;
487
+ if (!isNullOrUndefined(id) || id !== '') {
488
+ id = id.replace(ganttObj.element.id, '');
489
+ id = id.replace('TabContainer', '');
490
+ if (id === 'General') {
491
+ this.destroyCustomField(element);
492
+ } else if (id === 'Dependency') {
493
+ const gridObj: Grid = <Grid>(<EJ2Instance>element).ej2_instances[0];
494
+ gridObj.destroy();
495
+ } else if (id === 'Notes') {
496
+ const rte: RichTextEditor = <RichTextEditor>(<EJ2Instance>element).ej2_instances[0];
497
+ rte.destroy();
498
+ } else if (id === 'Resources') {
499
+ const treeGridObj: TreeGrid = <TreeGrid>(<EJ2Instance>element).ej2_instances[0];
500
+ treeGridObj.destroy();
501
+ } else if (id.indexOf('Custom') !== -1) {
502
+ this.destroyCustomField(element);
503
+ }
504
+ }
505
+ }
506
+ }
507
+
508
+ private destroyCustomField(element: HTMLElement): void {
509
+ const childNodes: NodeList = element.childNodes;
510
+ const ganttObj: Gantt = this.parent;
511
+ for (let i: number = 0; i < childNodes.length; i++) {
512
+ const div: HTMLElement = childNodes[i] as HTMLElement;
513
+ const inputElement: HTMLInputElement = div.querySelector('input[id^="' + ganttObj.element.id + '"]');
514
+ if (inputElement) {
515
+ const fieldName: string = inputElement.id.replace(ganttObj.element.id, '');
516
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
517
+ const controlObj: any = <any>(<EJ2Instance>div.querySelector('#' + ganttObj.element.id + fieldName)).ej2_instances[0];
518
+ if (!isNullOrUndefined(controlObj)) {
519
+ const column: GanttColumnModel = ganttObj.columnByField[fieldName];
520
+ if (!isNullOrUndefined(column.edit) && isNullOrUndefined(column.edit.params)) {
521
+ let destroy: Function = column.edit.destroy as Function;
522
+ if (typeof destroy === 'string') {
523
+ destroy = getObject(destroy, window);
524
+ destroy();
525
+ } else {
526
+ (column.edit.destroy as () => void)();
527
+ }
528
+ } else {
529
+ controlObj.destroy();
530
+ }
531
+ }
532
+ }
533
+ }
534
+ }
535
+ /**
536
+ * @returns {void} .
537
+ * @private
538
+ */
539
+ public destroy(): void {
540
+ this.resetValues();
541
+ if (this.parent.isDestroyed) {
542
+ return;
543
+ }
544
+ this.parent.off('chartDblClick', this.dblClickHandler);
545
+ this.parent.editModule.dialogModule = undefined;
546
+ }
547
+ /**
548
+ * Method to get current edit dialog fields value
549
+ *
550
+ * @returns {AddDialogFieldSettings} .
551
+ */
552
+ private getEditFields(): AddDialogFieldSettingsModel[] {
553
+ if (this.isEdit) {
554
+ return this.updatedEditFields;
555
+ } else {
556
+ return this.updatedAddFields;
557
+
558
+ }
559
+ }
560
+ private createTab(dialogModel: DialogModel, dialog: HTMLElement): void {
561
+ const ganttObj: Gantt = this.parent;
562
+ const tabModel: TabModel = {}; const tabItems: TabItemModel[] = [];
563
+ const dialogSettings: AddDialogFieldSettingsModel[] = this.getEditFields();
564
+ let tabElement: HTMLElement;
565
+ const tasks: TaskFieldsModel = ganttObj.taskFields;
566
+ const length: number = dialogSettings.length;
567
+ tabModel.items = tabItems;
568
+ tabModel.locale = this.parent.locale;
569
+ this.beforeOpenArgs.tabModel = tabModel;
570
+ let count: number = 0; let index: number = 0;
571
+ if (length > 0) {
572
+ for (let i: number = 0; i < length; i++) {
573
+ const dialogField: AddDialogFieldSettingsModel = dialogSettings[i];
574
+ const tabItem: TabItemModel = {};
575
+ if (dialogField.type === 'General') {
576
+ if (Object.keys(ganttObj.columnMapping).length === 0) {
577
+ continue;
578
+ }
579
+ if (isNullOrUndefined(dialogField.headerText)) {
580
+ dialogField.headerText = this.localeObj.getConstant('generalTab');
581
+ }
582
+ tabItem.content = 'General';
583
+ this.beforeOpenArgs[tabItem.content] = this.getFieldsModel(dialogField.fields);
584
+ } else if (dialogField.type === 'Segments') {
585
+ if (isNullOrUndefined(tasks.segments)) {
586
+ continue;
587
+ }
588
+ if (isNullOrUndefined(dialogField.headerText)) {
589
+ dialogField.headerText = this.localeObj.getConstant('segments');
590
+ }
591
+ tabItem.content = 'Segments';
592
+ this.beforeOpenArgs[tabItem.content] = this.getSegmentsModel(dialogField.fields);
593
+ } else if (dialogField.type === 'Dependency') {
594
+ if (isNullOrUndefined(tasks.dependency)) {
595
+ continue;
596
+ }
597
+ if (isNullOrUndefined(dialogField.headerText)) {
598
+ dialogField.headerText = this.localeObj.getConstant('dependency');
599
+ }
600
+ tabItem.content = 'Dependency';
601
+ this.beforeOpenArgs[tabItem.content] = this.getPredecessorModel(dialogField.fields);
602
+ } else if (dialogField.type === 'Resources') {
603
+ if (isNullOrUndefined(tasks.resourceInfo)) {
604
+ continue;
605
+ }
606
+ if (isNullOrUndefined(dialogField.headerText)) {
607
+ dialogField.headerText = this.localeObj.getConstant('resourceName');
608
+ }
609
+ tabItem.content = 'Resources';
610
+ this.beforeOpenArgs[tabItem.content] = this.getResourcesModel(dialogField.fields);
611
+ } else if (dialogField.type === 'Notes') {
612
+ if (isNullOrUndefined(tasks.notes)) {
613
+ continue;
614
+ }
615
+ if (isNullOrUndefined(dialogField.headerText)) {
616
+ dialogField.headerText = this.localeObj.getConstant('notes');
617
+ }
618
+ tabItem.content = 'Notes';
619
+ this.beforeOpenArgs[tabItem.content] = this.getNotesModel(dialogField.fields);
620
+ } else {
621
+ if (isNullOrUndefined(dialogField.fields) || dialogField.fields.length === 0) {
622
+ continue;
623
+ }
624
+ if (isNullOrUndefined(dialogField.headerText)) {
625
+ dialogField.headerText = this.localeObj.getConstant('customTab'); // eslint-disable-next-line
626
+ count++;
627
+ }
628
+ tabItem.content = 'Custom' + '' + index++;
629
+ this.beforeOpenArgs[tabItem.content] = this.getFieldsModel(dialogField.fields);
630
+ }
631
+ tabItem.header = { text: dialogField.headerText };
632
+ tabItems.push(tabItem);
633
+ }
634
+ }
635
+ this.beforeOpenArgs.requestType = this.isEdit ? 'beforeOpenEditDialog' : 'beforeOpenAddDialog';
636
+ const args: ActionBeginArgs = {
637
+ rowData: this.beforeOpenArgs.rowData as IGanttData,
638
+ name: this.beforeOpenArgs.name as string,
639
+ requestType: this.beforeOpenArgs.requestType as string,
640
+ cancel: this.beforeOpenArgs.cancel as boolean
641
+ };
642
+ this.parent.trigger('actionBegin', this.beforeOpenArgs, (arg: ActionBeginArgs | CObject) => {
643
+ this.renderTabItems();
644
+ if (!arg.cancel) {
645
+ tabModel.selected = this.tabSelectedEvent.bind(this);
646
+ tabModel.height = this.parent.isAdaptive ? '100%' : 'auto';
647
+ tabModel.overflowMode = 'Scrollable';
648
+ this.tabObj = new Tab(tabModel);
649
+ this.tabObj.isStringTemplate = true;
650
+ tabElement = this.parent.createElement('div', { id: ganttObj.element.id + '_Tab' });
651
+ this.tabObj.appendTo(tabElement);
652
+ dialogModel.content = tabElement;
653
+ this.dialog = dialog;
654
+ this.dialogObj = new Dialog(dialogModel);
655
+ this.dialogObj.isStringTemplate = true;
656
+ this.dialogObj.appendTo(this.dialog);
657
+ const actionCompleteArgs: CObject = {
658
+ action: 'OpenDialog',
659
+ requestType: this.isEdit ? 'openEditDialog' : 'openAddDialog',
660
+ data: this.beforeOpenArgs.rowData,
661
+ element: this.dialog,
662
+ cancel: false
663
+ };
664
+ this.parent.trigger('actionComplete', actionCompleteArgs, (actionCompleteArg: CObject) => {
665
+ if (actionCompleteArg.cancel) {
666
+ this.resetValues();
667
+ }
668
+ });
669
+ }
670
+ });
671
+ }
672
+
673
+ private tabSelectedEvent(args: SelectEventArgs): void {
674
+ const ganttObj: Gantt = this.parent;
675
+ const id: string = (args.selectedContent.childNodes[0] as HTMLElement).id;
676
+ if (this.parent.isAdaptive) {
677
+ this.responsiveTabContent(id, ganttObj);
678
+ }
679
+ if (id === ganttObj.element.id + 'ResourcesTabContainer') {
680
+ this.resourceSelection(id);
681
+ } else if (id === ganttObj.element.id + 'NotesTabContainer') {
682
+ ((<EJ2Instance>document.getElementById(id)).ej2_instances[0] as RichTextEditor).refresh();
683
+ } else if (id === ganttObj.element.id + 'SegmentsTabContainer') {
684
+ if (isNullOrUndefined((this.beforeOpenArgs.rowData as IGanttData).ganttProperties.startDate)) {
685
+ ((<EJ2Instance>document.getElementById(id)).ej2_instances[0] as Grid)
686
+ .enableToolbarItems([this.parent.element.id + 'SegmentsTabContainer' + '_add'], false);
687
+ } else {
688
+ ((<EJ2Instance>document.getElementById(id)).ej2_instances[0] as Grid)
689
+ .enableToolbarItems([this.parent.element.id + 'SegmentsTabContainer' + '_add'], true);
690
+ }
691
+
692
+ }
693
+ }
694
+
695
+ private responsiveTabContent(id: string, ganttObj: Gantt): void {
696
+ const dialogContent: HTMLElement = document.getElementById(ganttObj.element.id + '_dialog_dialog-content');
697
+ let dialogContentHeight: number = dialogContent.clientHeight;
698
+ dialogContentHeight -= (dialogContent.querySelector('.e-tab-header') as HTMLElement).offsetHeight;
699
+ const grid: HTMLElement = document.querySelector('#' + id);
700
+ if (grid.classList.contains('e-grid')) {
701
+ dialogContentHeight -= (((grid as EJ2Instance).ej2_instances[0] as Grid).getHeaderContent() as HTMLElement).offsetHeight;
702
+ const toolbar: HTMLElement = grid.querySelector('.e-toolbar');
703
+ if (toolbar) {
704
+ dialogContentHeight -= toolbar.offsetHeight;
705
+ }
706
+ }
707
+ grid.parentElement.style.height = dialogContentHeight + 'px';
708
+ }
709
+
710
+ private getFieldsModel(fields: string[]): Record<string, unknown> {
711
+ const fieldsModel: Record<string, unknown> = {};
712
+ const columnByField: Object = this.parent.columnByField;
713
+ for (let i: number = 0; i < fields.length; i++) {
714
+ if (fields[i] === this.parent.taskFields.dependency ||
715
+ fields[i] === this.parent.taskFields.resourceInfo ||
716
+ fields[i] === this.parent.taskFields.notes) {
717
+ continue;
718
+ }
719
+ if (!isNullOrUndefined(columnByField[fields[i]])) {
720
+ const fieldName: string = fields[i];
721
+ this.createInputModel(columnByField[fieldName], fieldsModel);
722
+ }
723
+ }
724
+ return fieldsModel;
725
+ }
726
+ private createInputModel(column: GanttColumnModel, fieldsModel: object): object {
727
+ const ganttObj: Gantt = this.parent;
728
+ const locale: string = this.parent.locale;
729
+ const taskSettings: TaskFieldsModel = this.parent.taskFields;
730
+ const common: Object = {
731
+ placeholder: column.headerText,
732
+ floatLabelType: 'Auto'
733
+ };
734
+ switch (column.editType) {
735
+ case 'booleanedit':
736
+ {
737
+ const checkboxModel: CheckBoxModel = {
738
+ label: column.headerText,
739
+ locale: locale
740
+ };
741
+ fieldsModel[column.field] = checkboxModel;
742
+ break;
743
+ }
744
+ case 'defaultedit':
745
+ case 'stringedit':
746
+ {
747
+ const textBox: TextBox = common as TextBox;
748
+ if (column.field === ganttObj.columnMapping.duration || column.field === ganttObj.columnMapping.startDate ||
749
+ column.field === ganttObj.columnMapping.endDate) {
750
+ textBox.change = (args: CObject): void => {
751
+ this.validateScheduleFields(args, column, ganttObj);
752
+ };
753
+ }
754
+ fieldsModel[column.field] = common;
755
+ break;
756
+ }
757
+ case 'numericedit':
758
+ {
759
+ const numeric: NumericTextBoxModel = <NumericTextBoxModel>common;
760
+ if (taskSettings.progress === column.field) {
761
+ numeric.min = 0;
762
+ numeric.max = 100;
763
+ }
764
+ if (taskSettings.work === column.field) {
765
+ numeric.change = (args: CObject): void => {
766
+ this.validateScheduleFields(args, column, ganttObj);
767
+ };
768
+ }
769
+ fieldsModel[column.field] = numeric;
770
+ break;
771
+ }
772
+ case 'datepickeredit':
773
+ {
774
+ const datePickerObj: DatePickerModel = common as DatePickerModel;
775
+ datePickerObj.format = this.parent.getDateFormat();
776
+ datePickerObj.strictMode = true;
777
+ datePickerObj.firstDayOfWeek = ganttObj.timelineModule.customTimelineSettings.weekStartDay;
778
+ if (column.field === ganttObj.columnMapping.startDate ||
779
+ column.field === ganttObj.columnMapping.endDate) {
780
+ datePickerObj.renderDayCell = this.parent.renderWorkingDayCell.bind(this.parent);
781
+ datePickerObj.change = (args: CObject): void => {
782
+ this.validateScheduleFields(args, column, ganttObj);
783
+ };
784
+ }
785
+ fieldsModel[column.field] = datePickerObj;
786
+ break;
787
+ }
788
+ case 'datetimepickeredit':
789
+ {
790
+ const dateTimePickerObj: DatePickerModel = common as DatePickerModel;
791
+ dateTimePickerObj.format = this.parent.getDateFormat();
792
+ dateTimePickerObj.strictMode = true;
793
+ dateTimePickerObj.firstDayOfWeek = ganttObj.timelineModule.customTimelineSettings.weekStartDay;
794
+ if (column.field === ganttObj.columnMapping.startDate ||
795
+ column.field === ganttObj.columnMapping.endDate) {
796
+ dateTimePickerObj.renderDayCell = this.parent.renderWorkingDayCell.bind(this.parent);
797
+ dateTimePickerObj.change = (args: CObject): void => {
798
+ this.validateScheduleFields(args, column, ganttObj);
799
+ };
800
+ }
801
+ fieldsModel[column.field] = dateTimePickerObj;
802
+ break;
803
+ }
804
+ case 'dropdownedit':
805
+ if (column.field === 'taskType' || column.field === ganttObj.columnMapping.manual) {
806
+ const dataKey: string = 'dataSource';
807
+ const fieldsKey: string = 'fields';
808
+ const types: Record<string, unknown>[] = [
809
+ { 'ID': 1, 'Value': 'FixedUnit' }, { 'ID': 2, 'Value': 'FixedWork' }, { 'ID': 3, 'Value': 'FixedDuration' }];
810
+ common[dataKey] = types;
811
+ common[fieldsKey] = { value: 'Value' };
812
+ const dropDownListObj: DropDownListModel = common as DropDownListModel;
813
+ dropDownListObj.change = (args: CObject | ChangeEventArgs): void => {
814
+ if (column.field === taskSettings.manual) {
815
+ this.editedRecord.ganttProperties.isAutoSchedule = !args.value;
816
+ }
817
+ this.validateScheduleFields(args as CObject, column, ganttObj);
818
+ };
819
+ }
820
+ fieldsModel[column.field] = common;
821
+ break;
822
+ case 'maskededit':
823
+ fieldsModel[column.field] = common;
824
+ break;
825
+ }
826
+ if (!isNullOrUndefined(column.edit) && !isNullOrUndefined(column.edit.params)) {
827
+ extend(fieldsModel[column.field], column.edit.params);
828
+ }
829
+ return fieldsModel;
830
+ }
831
+
832
+ private validateScheduleFields(args: CObject, column: GanttColumnModel, ganttObj: Gantt): boolean {
833
+ const dialog: HTMLElement = ganttObj.editModule.dialogModule.dialog;
834
+ let targetId: string = null; let inputElement: HTMLInputElement;
835
+ const currentData: IGanttData = ganttObj.editModule.dialogModule.editedRecord;
836
+ let cellValue: string = null;
837
+ let colName: string = null;
838
+ if (!isNullOrUndefined(args.element)) {
839
+ inputElement = args.element as HTMLInputElement;
840
+ targetId = inputElement.getAttribute('id');
841
+ } else if (!isNullOrUndefined(args.container)) {
842
+ inputElement = args.container as HTMLInputElement;
843
+ targetId = inputElement.querySelector('input').getAttribute('id');
844
+ inputElement = inputElement.querySelector('#' + targetId);
845
+ } else if (!isNullOrUndefined(args.event) && !isNullOrUndefined((args.event as CObject).path[1])) {
846
+ inputElement = (args.event as CObject).path[1] as HTMLInputElement;
847
+ targetId = inputElement.querySelector('input').getAttribute('id');
848
+ inputElement = inputElement.querySelector('#' + targetId);
849
+ }
850
+ if (isNullOrUndefined(inputElement)) {
851
+ cellValue = args.value as string;
852
+ colName = column.field;
853
+ } else {
854
+ cellValue = inputElement.value;
855
+ colName = targetId.replace(ganttObj.element.id, '');
856
+ }
857
+ if (colName.search('Segments') === 0) {
858
+ colName = colName.replace('SegmentsTabContainer', '');
859
+ this.validateSegmentFields(ganttObj, colName, cellValue, args);
860
+ return true;
861
+ } else {
862
+ this.validateScheduleValuesByCurrentField(colName, cellValue, this.editedRecord);
863
+ const ganttProp: ITaskData = currentData.ganttProperties;
864
+ const tasks: TaskFieldsModel = ganttObj.taskFields;
865
+ if (!isNullOrUndefined(tasks.startDate) && tasks.startDate !== colName) {
866
+ this.updateScheduleFields(dialog, ganttProp, 'startDate');
867
+ }
868
+ if (!isNullOrUndefined(tasks.endDate) && tasks.endDate !== colName) {
869
+ this.updateScheduleFields(dialog, ganttProp, 'endDate');
870
+ }
871
+ if (!isNullOrUndefined(tasks.duration) && tasks.duration !== colName) {
872
+ this.updateScheduleFields(dialog, ganttProp, 'duration');
873
+ }
874
+ if (!isNullOrUndefined(tasks.work) && tasks.work !== colName) {
875
+ this.updateScheduleFields(dialog, ganttProp, 'work');
876
+ }
877
+ this.dialogEditValidationFlag = false;
878
+ return true;
879
+ }
880
+ }
881
+
882
+ private updateScheduleFields(dialog: HTMLElement, ganttProp: ITaskData, ganttField: string): void {
883
+ const ganttObj: Gantt = this.parent;
884
+ const ganttId: string = ganttObj.element.id;
885
+ const columnName: string = getValue(ganttField, ganttObj.columnMapping);
886
+ const col: GanttColumnModel = ganttObj.columnByField[columnName];
887
+ let tempValue: string | Date | number;
888
+ const taskField: TaskFieldsModel = this.parent.taskFields;
889
+ if (col.editType === 'stringedit') {
890
+ const textBox: TextBox = <TextBox>(<EJ2Instance>dialog.querySelector('#' + ganttId + columnName)).ej2_instances[0];
891
+ tempValue = !isNullOrUndefined(col.edit) && !isNullOrUndefined(col.edit.read) ? (col.edit.read as () => void)() :
892
+ !isNullOrUndefined(col.valueAccessor) ? (col.valueAccessor as Function) (columnName, ganttObj.editModule.dialogModule.editedRecord, col) : // eslint-disable-line
893
+ this.parent.dataOperation.getDurationString(ganttProp.duration, ganttProp.durationUnit);
894
+ if (textBox.value !== tempValue.toString() && taskField.duration === columnName) {
895
+ textBox.value = tempValue as string;
896
+ textBox.dataBind();
897
+ } else if (taskField.startDate === columnName || taskField.endDate === columnName) {
898
+ textBox.value = taskField.startDate === columnName ? ganttProp.startDate.toString() : ganttProp.endDate.toString();
899
+ textBox.dataBind();
900
+ }
901
+ } else if (col.editType === 'datepickeredit' || col.editType === 'datetimepickeredit') {
902
+ const picker: DatePicker = col.editType === 'datepickeredit' ?
903
+ <DatePicker>(<EJ2Instance>dialog.querySelector('#' + ganttId + columnName)).ej2_instances[0] :
904
+ <DateTimePicker>(<EJ2Instance>dialog.querySelector('#' + ganttId + columnName)).ej2_instances[0];
905
+ tempValue = ganttProp[ganttField];
906
+ if (((isNullOrUndefined(picker.value)) && !isNullOrUndefined(tempValue)) ||
907
+ (isNullOrUndefined(tempValue) && !isNullOrUndefined(picker.value)) ||
908
+ (picker.value !== tempValue && !isNullOrUndefined(picker.value) && !isNullOrUndefined(tempValue)
909
+ && picker.value.toString() !== tempValue.toString())) {
910
+ picker.value = tempValue as Date;
911
+ picker.dataBind();
912
+ }
913
+ } else if (col.editType === 'numericedit') {
914
+ const numericTextBox: NumericTextBox = <NumericTextBox>(
915
+ <EJ2Instance>dialog.querySelector('#' + ganttId + columnName)).ej2_instances[0];
916
+ tempValue = ganttProp[ganttField];
917
+ if (!isNullOrUndefined(tempValue) && numericTextBox.value !== tempValue) {
918
+ numericTextBox.value = tempValue as number;
919
+ numericTextBox.dataBind();
920
+ }
921
+ }
922
+ }
923
+
924
+ /**
925
+ * @param {IGanttData} ganttData .
926
+ * @returns {void} .
927
+ * @private
928
+ */
929
+ public validateDuration(ganttData: IGanttData): void {
930
+ const ganttProp: ITaskData = ganttData.ganttProperties;
931
+ if (!this.dialogEditValidationFlag) {
932
+ if (isNullOrUndefined(ganttProp.duration)) {
933
+ this.parent.setRecordValue('endDate', null, ganttProp, true);
934
+ this.parent.setRecordValue('isMilestone', false, ganttProp, true);
935
+ } else if (isScheduledTask(ganttProp) || !isNullOrUndefined(ganttProp.startDate)) {
936
+ if (ganttData.ganttProperties.isMilestone && ganttData.ganttProperties.duration !== 0) {
937
+ this.parent.dateValidationModule.calculateStartDate(ganttData);
938
+ }
939
+ this.parent.dateValidationModule.calculateEndDate(ganttData);
940
+ } else if (!isScheduledTask(ganttProp) && !isNullOrUndefined(ganttProp.endDate)) {
941
+ this.parent.dateValidationModule.calculateStartDate(ganttData);
942
+ }
943
+ const milestone: boolean = ganttProp.duration === 0 ? true : false;
944
+ this.parent.setRecordValue('isMilestone', milestone, ganttProp, true);
945
+ this.dialogEditValidationFlag = true;
946
+ }
947
+ }
948
+ private validateStartDate(ganttData: IGanttData): void {
949
+ const ganttProp: ITaskData = ganttData.ganttProperties;
950
+ const tasks: TaskFieldsModel = this.parent.taskFields;
951
+ if (!this.dialogEditValidationFlag) {
952
+ if (isNullOrUndefined(ganttProp.startDate)) {
953
+ this.parent.setRecordValue('duration', null, ganttProp, true);
954
+ this.parent.setRecordValue('isMilestone', false, ganttProp, true);
955
+ if (this.parent.allowUnscheduledTasks && isNullOrUndefined(tasks.endDate)) {
956
+ this.parent.setRecordValue('endDate', null, ganttProp, true);
957
+ }
958
+ } else if (isScheduledTask(ganttProp)) {
959
+ if (isNullOrUndefined(tasks.duration)) {
960
+ this.parent.dateValidationModule.calculateDuration(ganttData);
961
+ } else if (isNullOrUndefined(tasks.endDate)) {
962
+ this.parent.dateValidationModule.calculateEndDate(ganttData);
963
+ } else {
964
+ this.parent.dateValidationModule.calculateEndDate(ganttData);
965
+ }
966
+ } else {
967
+ if (!isNullOrUndefined(ganttProp.endDate)) {
968
+ this.parent.dateValidationModule.calculateDuration(ganttData);
969
+ } else if (!isNullOrUndefined(ganttProp.duration)) {
970
+ this.parent.dateValidationModule.calculateEndDate(ganttData);
971
+ }
972
+ }
973
+ this.dialogEditValidationFlag = true;
974
+ }
975
+ }
976
+ private validateEndDate(ganttData: IGanttData): void {
977
+ const ganttProp: ITaskData = ganttData.ganttProperties;
978
+ const tasks: TaskFieldsModel = this.parent.taskFields;
979
+ if (!this.dialogEditValidationFlag) {
980
+ if (isNullOrUndefined(ganttProp.endDate)) {
981
+ this.parent.setRecordValue('duration', null, ganttProp, true);
982
+ this.parent.setRecordValue('isMilestone', false, ganttProp, true);
983
+ } else if (isScheduledTask(ganttProp)) {
984
+ if (isNullOrUndefined(tasks.duration)) {
985
+ this.parent.dateValidationModule.calculateDuration(ganttData);
986
+ } else if (isNullOrUndefined(ganttProp.startDate)) {
987
+ this.parent.dateValidationModule.calculateStartDate(ganttData);
988
+ } else {
989
+ if (!isNullOrUndefined(ganttProp.segments) && ganttProp.segments.length > 0) {
990
+ ganttProp.segments = this.parent.editModule.cellEditModule.validateEndDateWithSegments(ganttProp);
991
+ }
992
+ this.parent.dateValidationModule.calculateDuration(ganttData);
993
+ }
994
+ } else {
995
+ if (!isNullOrUndefined(ganttProp.duration)) {
996
+ this.parent.dateValidationModule.calculateStartDate(ganttData);
997
+ } else if (!isNullOrUndefined(ganttProp.startDate)) {
998
+ this.parent.dateValidationModule.calculateDuration(ganttData);
999
+ }
1000
+ }
1001
+ this.dialogEditValidationFlag = true;
1002
+ }
1003
+ }
1004
+ /**
1005
+ *
1006
+ * @param {string} columnName .
1007
+ * @param {string} value .
1008
+ * @param {IGanttData} currentData .
1009
+ * @returns {boolean} .
1010
+ * @private
1011
+ */
1012
+ public validateScheduleValuesByCurrentField(columnName: string, value: string, currentData: IGanttData): boolean {
1013
+ const ganttObj: Gantt = this.parent;
1014
+ const ganttProp: ITaskData = currentData.ganttProperties;
1015
+ const taskSettings: TaskFieldsModel = ganttObj.taskFields;
1016
+ if (taskSettings.duration === columnName) {
1017
+ if (!isNullOrUndefined(value) && value !== '') {
1018
+ ganttObj.dataOperation.updateDurationValue(value, ganttProp);
1019
+ } else {
1020
+ if (ganttObj.allowUnscheduledTasks) {
1021
+ this.parent.setRecordValue('duration', null, ganttProp, true);
1022
+ }
1023
+ }
1024
+ this.validateDuration(currentData);
1025
+ this.parent.editModule.updateResourceRelatedFields(currentData, 'duration');
1026
+ }
1027
+ if (taskSettings.startDate === columnName) {
1028
+ if (value !== '') {
1029
+ let startDate: Date = this.parent.dateValidationModule.getDateFromFormat(value);
1030
+ startDate = this.parent.dateValidationModule.checkStartDate(startDate, ganttProp);
1031
+ this.parent.setRecordValue('startDate', startDate, ganttProp, true);
1032
+ } else {
1033
+ if (ganttObj.allowUnscheduledTasks && !(currentData.hasChildRecords)) {
1034
+ this.parent.setRecordValue('startDate', null, ganttProp, true);
1035
+ }
1036
+ }
1037
+ this.validateStartDate(currentData);
1038
+ }
1039
+ if (taskSettings.endDate === columnName) {
1040
+ if (value !== '') {
1041
+ let endDate: Date = this.parent.dateValidationModule.getDateFromFormat(value);
1042
+ if (endDate.getHours() === 0 && ganttObj.defaultEndTime !== 86400) {
1043
+ this.parent.dateValidationModule.setTime(ganttObj.defaultEndTime, endDate);
1044
+ }
1045
+ endDate = this.parent.dateValidationModule.checkEndDate(endDate, ganttProp);
1046
+ if (isNullOrUndefined(ganttProp.startDate) || endDate.getTime() > (ganttProp.startDate).getTime()) {
1047
+ this.parent.setRecordValue('endDate', endDate, ganttProp, true);
1048
+ }
1049
+ } else {
1050
+ if (ganttObj.allowUnscheduledTasks) {
1051
+ this.parent.setRecordValue('endDate', null, ganttProp, true);
1052
+ }
1053
+ }
1054
+ this.validateEndDate(currentData);
1055
+ }
1056
+ if (taskSettings.work === columnName) {
1057
+ if (!isNullOrUndefined(value) && value !== '') {
1058
+ this.parent.setRecordValue('work', value, ganttProp, true);
1059
+ this.parent.editModule.updateResourceRelatedFields(currentData, 'work');
1060
+ this.validateDuration(currentData);
1061
+ }
1062
+ }
1063
+ if (columnName === 'taskType') {
1064
+ this.parent.setRecordValue('taskType', value, ganttProp, true);
1065
+ }
1066
+ if (taskSettings.manual === columnName) {
1067
+ this.parent.editModule.updateTaskScheduleModes(currentData);
1068
+ }
1069
+ return true;
1070
+ }
1071
+ private getSegmentsModel(fields: string[]): Object {
1072
+ const taskSettings: TaskFieldsModel = this.parent.taskFields;
1073
+ if (isNullOrUndefined(fields) || fields.length === 0) {
1074
+ fields = [];
1075
+ if (!isNullOrUndefined(taskSettings.startDate)) {
1076
+ fields.push('startDate');
1077
+ }
1078
+ if (!isNullOrUndefined(taskSettings.endDate)) {
1079
+ fields.push('endDate');
1080
+ }
1081
+ if (!isNullOrUndefined(taskSettings.duration)) {
1082
+ fields.push('duration');
1083
+ }
1084
+ }
1085
+ const segmentInputModel: GridModel = {};
1086
+ segmentInputModel.editSettings = {
1087
+ allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Normal', newRowPosition: 'Bottom'
1088
+ };
1089
+ segmentInputModel.locale = this.parent.locale;
1090
+ segmentInputModel.dataSource = [];
1091
+ segmentInputModel.rowHeight = this.parent.isAdaptive ? 48 : null;
1092
+ segmentInputModel.toolbar = [
1093
+ {
1094
+ id: this.parent.element.id + 'SegmentsTabContainer' + '_add', prefixIcon: 'e-add',
1095
+ tooltipText: this.localeObj.getConstant('add'), align: 'Right',
1096
+ text: this.parent.isAdaptive ? '' : this.localeObj.getConstant('add')
1097
+ },
1098
+ {
1099
+ id: this.parent.element.id + 'SegmentsTabContainer' + '_delete', prefixIcon: 'e-delete',
1100
+ tooltipText: this.localeObj.getConstant('delete'), align: 'Right',
1101
+ text: this.parent.isAdaptive ? '' : this.localeObj.getConstant('delete')
1102
+ }
1103
+ ];
1104
+ const gridColumns: GridColumnModel[] = [];
1105
+ for (let i: number = 0; i < fields.length; i++) {
1106
+ let gridColumn: GridColumnModel = {};
1107
+ const generalTabString: string = 'General';
1108
+ switch (fields[i]) {
1109
+ case 'startDate':
1110
+ case 'endDate':
1111
+ gridColumn = {
1112
+ field: fields[i], headerText: this.localeObj.getConstant(fields[i]), editType: 'stringedit', width: '200px',
1113
+ edit: {
1114
+ write: (args: CObject): void => {
1115
+ let datePickerModel: object;
1116
+ if (!isNullOrUndefined(this.beforeOpenArgs[generalTabString])) {
1117
+ datePickerModel = this.beforeOpenArgs[generalTabString][this.parent.taskFields[fields[i]]];
1118
+ } else {
1119
+ let columnFields: string[] = this.getGeneralColumnFields();
1120
+ let columnModel: object = this.getFieldsModel(columnFields);
1121
+ datePickerModel = columnModel[this.parent.taskFields[fields[i]]];
1122
+ }
1123
+ const value: string = args.rowData[(args.column as GridColumnModel).field];
1124
+ setValue('value', value, datePickerModel);
1125
+ const datePicker: DatePicker = new this.inputs[this.parent.columnByField[this.parent.taskFields[fields[i]]].editType](datePickerModel);
1126
+ datePicker.appendTo(args.element as HTMLElement);
1127
+ },
1128
+ read: (args: HTMLElement): Date => {
1129
+ const ej2Instance: DatePickerModel =
1130
+ <CObject>(<EJ2Instance>args).ej2_instances[0];
1131
+ return ej2Instance.value as Date;
1132
+ }
1133
+
1134
+ },
1135
+ format: this.parent.getDateFormat()
1136
+ };
1137
+ if (fields[i] === 'startDate') {
1138
+ gridColumn.validationRules = { required: true };
1139
+ }
1140
+ gridColumns.push(gridColumn);
1141
+ break;
1142
+ case 'duration':
1143
+ gridColumn = {
1144
+ field: fields[i], headerText: this.localeObj.getConstant(fields[i]), editType: 'stringedit', width: '100px',
1145
+ edit: {
1146
+ write: (args: CObject): void => {
1147
+ let inputTextModel: object;
1148
+ if (!isNullOrUndefined(this.beforeOpenArgs[generalTabString])) {
1149
+ inputTextModel = this.beforeOpenArgs[generalTabString][this.parent.taskFields[fields[i]]];
1150
+ } else {
1151
+ let columnFields: string[] = this.getGeneralColumnFields();
1152
+ let columnModel: object = this.getFieldsModel(columnFields);
1153
+ inputTextModel = columnModel[this.parent.taskFields[fields[i]]];
1154
+ }
1155
+ (inputTextModel as TextBox).floatLabelType = 'Never';
1156
+ const value: string = args.rowData[(args.column as GridColumnModel).field];
1157
+ if (!isNullOrUndefined(value)) {
1158
+ setValue('value', value, inputTextModel);
1159
+ } else {
1160
+ setValue('value', null, inputTextModel);
1161
+ }
1162
+ setValue('value', value, inputTextModel);
1163
+ const inputModel: TextBox = new TextBox(inputTextModel);
1164
+ inputModel.appendTo(args.element as HTMLElement);
1165
+ },
1166
+ read: (args: HTMLElement): string => {
1167
+ const ej2Instance: TextBoxModel =
1168
+ <CObject>(<EJ2Instance>args).ej2_instances[0];
1169
+ return ej2Instance.value.toString();
1170
+ }
1171
+ }
1172
+ };
1173
+ gridColumns.push(gridColumn);
1174
+ break;
1175
+ }
1176
+ }
1177
+ segmentInputModel.columns = gridColumns;
1178
+ segmentInputModel.height = this.parent.isAdaptive ? '100%' : '153px';
1179
+ return segmentInputModel;
1180
+ }
1181
+ private getGridColumnByField(fieldName: string, columns: GridColumnModel[]): GridColumnModel {
1182
+ let column: GridColumnModel;
1183
+ for (let i: number = 0; i < columns.length; i++) {
1184
+ if (columns[i].field === fieldName) {
1185
+ column = columns[i];
1186
+ }
1187
+ }
1188
+ return column;
1189
+ }
1190
+ private updateSegmentField(columnName: string, args: CObject, segment: ITaskSegment): void {
1191
+ const dialog: HTMLElement = this.parent.editModule.dialogModule.dialog;
1192
+ const gridModel: GridModel = getValue('Segments', this.beforeOpenArgs) as GridModel;
1193
+ const col: GridColumnModel = this.getGridColumnByField(columnName, gridModel.columns as GridColumnModel[]);
1194
+ const ganttId: string = this.parent.element.id;
1195
+ const tempValue: string | Date | number = segment[columnName];
1196
+ let inputValue: TextBox | DatePicker;
1197
+
1198
+ if (col.editType === 'stringedit') {
1199
+ inputValue = <TextBox>(<EJ2Instance>dialog.querySelector('#' + ganttId + 'SegmentsTabContainer' + columnName))
1200
+ .ej2_instances[0] as TextBox;
1201
+ } else if (col.editType === 'datepickeredit') {
1202
+ inputValue = <DatePicker>(<EJ2Instance>dialog.querySelector('#' + ganttId + 'SegmentsTabContainer' + columnName))
1203
+ .ej2_instances[0] as DatePicker;
1204
+ }
1205
+ if (inputValue.value.toString() !== tempValue.toString()) {
1206
+ inputValue.value = tempValue as string;
1207
+ inputValue.dataBind();
1208
+ }
1209
+ }
1210
+ private validateSegmentFields(ganttObj: Gantt, columnName: string, cellValue: string, args: CObject): void {
1211
+ const taskSettings: TaskFieldsModel = this.parent.taskFields;
1212
+ if (!isNullOrUndefined(taskSettings.duration) && taskSettings.duration.toLowerCase() === columnName.toLowerCase()) {
1213
+ if (!isNullOrUndefined(cellValue) && cellValue !== '') {
1214
+ this.selectedSegment.duration = Number(cellValue);
1215
+ let endDate: Date = ganttObj.dataOperation.getEndDate(
1216
+ this.selectedSegment.startDate, Number(cellValue), this.editedRecord.ganttProperties.durationUnit,
1217
+ this.editedRecord.ganttProperties, false
1218
+ );
1219
+ endDate = ganttObj.dataOperation.checkEndDate(endDate, this.editedRecord.ganttProperties, false);
1220
+ this.selectedSegment.endDate = endDate;
1221
+ }
1222
+ }
1223
+ if (!isNullOrUndefined(taskSettings.startDate) && taskSettings.startDate.toLowerCase() === columnName.toLowerCase()) {
1224
+ if (cellValue !== '') {
1225
+ let startDate: Date = this.parent.dateValidationModule.getDateFromFormat(cellValue);
1226
+ startDate = this.parent.dateValidationModule.checkStartDate(startDate);
1227
+ this.selectedSegment.startDate = startDate;
1228
+
1229
+ if (!isNullOrUndefined(taskSettings.endDate)) {
1230
+ this.selectedSegment.endDate = this.parent.dataOperation.getEndDate(
1231
+ startDate, this.selectedSegment.duration, this.editedRecord.ganttProperties.durationUnit,
1232
+ this.editedRecord.ganttProperties, false
1233
+ );
1234
+ }
1235
+ }
1236
+ }
1237
+ if (!isNullOrUndefined(taskSettings.endDate) && taskSettings.endDate.toLowerCase() === columnName.toLowerCase()) {
1238
+ if (cellValue !== '') {
1239
+ let endDate: Date = this.parent.dateValidationModule.getDateFromFormat(cellValue);
1240
+ if (endDate.getHours() === 0 && ganttObj.defaultEndTime !== 86400) {
1241
+ this.parent.dateValidationModule.setTime(ganttObj.defaultEndTime, endDate);
1242
+ }
1243
+ endDate = this.parent.dateValidationModule.checkEndDate(endDate, this.editedRecord.ganttProperties);
1244
+ this.selectedSegment.endDate = endDate;
1245
+ this.selectedSegment.duration = this.parent.dataOperation.getDuration(
1246
+ this.selectedSegment.startDate, this.selectedSegment.endDate, this.editedRecord.ganttProperties.durationUnit,
1247
+ true, false, true
1248
+ );
1249
+ }
1250
+ }
1251
+ if (!isNullOrUndefined(taskSettings.startDate)) {
1252
+ this.updateSegmentField('startDate', args, this.selectedSegment);
1253
+ }
1254
+ if (!isNullOrUndefined(taskSettings.endDate)) {
1255
+ this.updateSegmentField('endDate', args, this.selectedSegment);
1256
+ }
1257
+ if (!isNullOrUndefined(taskSettings.duration)) {
1258
+ this.updateSegmentField('duration', args, this.selectedSegment);
1259
+ }
1260
+ }
1261
+ private getPredecessorModel(fields: string[]): Object {
1262
+ if (isNullOrUndefined(fields) || fields.length === 0) {
1263
+ fields = ['ID', 'Name', 'Type', 'Offset', 'UniqueId'];
1264
+ }
1265
+ const inputModel: GridModel = {};
1266
+ inputModel.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Normal' };
1267
+ inputModel.locale = this.parent.locale;
1268
+ inputModel.dataSource = [];
1269
+ inputModel.rowHeight = this.parent.isAdaptive ? 48 : null;
1270
+ inputModel.toolbar = [
1271
+ {
1272
+ id: this.parent.element.id + 'DependencyTabContainer' + '_add', prefixIcon: 'e-add',
1273
+ tooltipText: this.localeObj.getConstant('add'), align: 'Right',
1274
+ text: this.parent.isAdaptive ? '' : this.localeObj.getConstant('add')
1275
+ },
1276
+ {
1277
+ id: this.parent.element.id + 'DependencyTabContainer' + '_delete', prefixIcon: 'e-delete',
1278
+ tooltipText: this.localeObj.getConstant('delete'), align: 'Right',
1279
+ text: this.parent.isAdaptive ? '' : this.localeObj.getConstant('delete')
1280
+ }
1281
+ ];
1282
+ const columns: GridColumnModel[] = [];
1283
+ for (let i: number = 0; i < fields.length; i++) {
1284
+ let column: GridColumnModel = {};
1285
+ if (fields[i].toLowerCase() === 'id') {
1286
+ column = {
1287
+ field: 'id', headerText: this.localeObj.getConstant('id'), allowEditing: false, width: '70px'
1288
+ };
1289
+ columns.push(column);
1290
+ } else if (fields[i].toLowerCase() === 'name') {
1291
+ column = {
1292
+ field: 'name', headerText: this.localeObj.getConstant('name'), editType: 'stringedit', width: '250px',
1293
+ validationRules: { required: true }
1294
+ };
1295
+ columns.push(column);
1296
+ } else if (fields[i].toLowerCase() === 'type') {
1297
+ column = {
1298
+ field: 'type', headerText: this.localeObj.getConstant('type'), editType: 'dropdownedit',
1299
+ dataSource: this.types, foreignKeyField: 'id', foreignKeyValue: 'text',
1300
+ defaultValue: 'FS', validationRules: { required: true }, width: '150px'
1301
+ };
1302
+ columns.push(column);
1303
+ } else if (fields[i].toLowerCase() === 'offset') {
1304
+ column = {
1305
+ field: 'offset', headerText: this.localeObj.getConstant('offset'), editType: 'stringedit',
1306
+ defaultValue: this.parent.dataOperation.getDurationString(
1307
+ 0, (this.beforeOpenArgs.rowData as IGanttData).ganttProperties.durationUnit),
1308
+ validationRules: { required: true }, width: '100px'
1309
+ };
1310
+ columns.push(column);
1311
+ } else if (fields[i].toLowerCase() === 'uniqueid') {
1312
+ column = {
1313
+ field: 'uniqueId', isPrimaryKey: true, visible: false, defaultValue: getUid().toString()
1314
+ };
1315
+ columns.push(column);
1316
+ }
1317
+ }
1318
+ inputModel.columns = columns;
1319
+ inputModel.height = this.parent.isAdaptive ? '100%' : '153px';
1320
+ return inputModel;
1321
+ }
1322
+ private getResourcesModel(fields: string[]): Object {
1323
+ const ganttObj: Gantt = this.parent;
1324
+ const resourceSettings: ResourceFieldsModel = ganttObj.resourceFields;
1325
+ if (isNullOrUndefined(fields) || fields.length === 0) {
1326
+ fields = [resourceSettings.id, resourceSettings.name, resourceSettings.unit, resourceSettings.group];
1327
+ }
1328
+
1329
+ const inputModel: TreeGridModel = {
1330
+ allowFiltering: true,
1331
+ treeColumnIndex: -1,
1332
+ childMapping: '',
1333
+ editSettings: { allowEditing: true, mode: 'Cell' },
1334
+ locale: this.parent.locale,
1335
+ allowSelection: true,
1336
+ rowHeight: this.parent.isAdaptive ? 48 : null,
1337
+ filterSettings: { type: 'Menu' },
1338
+ selectionSettings: { checkboxOnly: true, checkboxMode: 'Default', persistSelection: true, type: 'Multiple' }
1339
+ };
1340
+ const columns: TreeGridColumnModel[] = [
1341
+ { type: 'checkbox', allowEditing: false, allowSorting: false, allowFiltering: false, width: 60 }
1342
+ ];
1343
+ for (let i: number = 0; i < fields.length; i++) {
1344
+ let column: TreeGridColumnModel = {};
1345
+ if (fields[i] === resourceSettings.id) {
1346
+ column = {
1347
+ field: resourceSettings.id,
1348
+ headerText: this.localeObj.getConstant('id'), isPrimaryKey: true, width: '100px',
1349
+ allowEditing: false
1350
+ };
1351
+ columns.push(column);
1352
+ } else if (fields[i] === resourceSettings.name) {
1353
+ column = {
1354
+ field: resourceSettings.name, headerText: this.localeObj.getConstant('name'),
1355
+ allowEditing: false
1356
+ };
1357
+ columns.push(column);
1358
+ } else if (fields[i] === resourceSettings.unit) {
1359
+ column = {
1360
+ field: resourceSettings.unit,
1361
+ headerText: this.localeObj.getConstant('unit'),
1362
+ editType: 'numericedit',
1363
+ edit: { params: { min: 0 } }
1364
+ };
1365
+ columns.push(column);
1366
+ } else if (fields[i] === resourceSettings.group && !isNullOrUndefined(resourceSettings.group)) {
1367
+ column = {
1368
+ field: resourceSettings.group,
1369
+ headerText: this.localeObj.getConstant('group'),
1370
+ allowEditing: false
1371
+ };
1372
+ columns.push(column);
1373
+ }
1374
+ }
1375
+ inputModel.columns = columns;
1376
+ inputModel.height = this.parent.isAdaptive ? '100%' : '196px';
1377
+ return inputModel;
1378
+ }
1379
+
1380
+ private getNotesModel(fields: string[]): Object {
1381
+ if (isNullOrUndefined(fields) || fields.length === 0) {
1382
+ fields = ['Bold', 'Italic', 'Underline', 'StrikeThrough',
1383
+ 'FontName', 'FontSize', 'FontColor', 'BackgroundColor',
1384
+ 'LowerCase', 'UpperCase', '|',
1385
+ 'Alignments', 'OrderedList', 'UnorderedList',
1386
+ 'Outdent', 'Indent', '|', 'CreateTable',
1387
+ 'CreateLink', '|', 'ClearFormat', 'Print',
1388
+ '|', 'Undo', 'Redo'];
1389
+ }
1390
+ const inputModel: RichTextEditorModel = {
1391
+ placeholder: this.localeObj.getConstant('writeNotes'),
1392
+ toolbarSettings: {
1393
+ items: fields
1394
+ },
1395
+ height: this.parent.isAdaptive ? '100%' : 'auto',
1396
+ locale: this.parent.locale
1397
+ };
1398
+ return inputModel;
1399
+ }
1400
+
1401
+ private createDivElement(className?: string, id?: string): HTMLElement {
1402
+ return createElement('div', { className: className, id: id });
1403
+ }
1404
+
1405
+ private createInputElement(className: string, id: string, fieldName: string, type?: string): HTMLElement {
1406
+ return createElement(type || 'input', {
1407
+ className: className, attrs: {
1408
+ type: 'text', id: id, name: fieldName,
1409
+ title: fieldName
1410
+ }
1411
+ });
1412
+ }
1413
+ private renderTabItems(): void {
1414
+ const tabModel: TabModel = this.beforeOpenArgs.tabModel;
1415
+ const items: TabItemModel[] = tabModel.items;
1416
+ let index: number = 0;
1417
+ for (let i: number = 0; i < items.length; i++) {
1418
+ const item: TabItemModel = items[i];
1419
+ if (item.content instanceof HTMLElement) {
1420
+ continue;
1421
+ } else if (item.content === 'General') {
1422
+ item.content = this.renderGeneralTab(item.content);
1423
+ } else if (item.content === 'Dependency') {
1424
+ if (this.editedRecord.hasChildRecords) {
1425
+ item.disabled = true;
1426
+ }
1427
+ item.content = this.renderPredecessorTab(item.content);
1428
+ } else if (item.content === 'Resources') {
1429
+ item.content = this.renderResourceTab(item.content);
1430
+ } else if (item.content === ('Custom' + '' + index)) {
1431
+ item.content = this.renderCustomTab(item.content);
1432
+ index++;
1433
+ } else if (item.content === 'Notes') {
1434
+ item.content = this.renderNotesTab(item.content);
1435
+ } else if (item.content === 'Segments') {
1436
+ if (this.editedRecord.hasChildRecords) {
1437
+ item.disabled = true;
1438
+ }
1439
+ item.content = this.renderSegmentsTab(item.content);
1440
+ }
1441
+ }
1442
+ }
1443
+ private segmentGridActionBegin(args: ActionEventArgs): void {
1444
+ const taskFields: TaskFieldsModel = this.parent.taskFields;
1445
+ const itemName: string = 'Segments';
1446
+ const gridModel: GridModel = this.beforeOpenArgs[itemName] as GridModel;
1447
+ if (args.requestType === 'add' || args.requestType === 'beginEdit' || args.requestType === 'save') {
1448
+ const gridData: Record<string, unknown>[] = gridModel.dataSource as Record<string, unknown>[];
1449
+ const selectedItem: Record<string, unknown> = getValue('rowData', args);
1450
+ const startDate: Date = (this.beforeOpenArgs.rowData as IGanttData).ganttProperties.startDate;
1451
+ if (!isNullOrUndefined(startDate)) {
1452
+ if (args.requestType === 'add') {
1453
+ let arg: Record<string, unknown> = {};
1454
+ let sDate: Date = getValue('startDate', selectedItem);
1455
+ let eDate: Date = getValue('endDate', selectedItem);
1456
+ let duration: number = getValue('duration', selectedItem);
1457
+ const startDate: Date = !isNullOrUndefined(gridData) && gridData.length > 0 ?
1458
+ !isNullOrUndefined(taskFields.endDate) ? new Date((getValue('endDate', gridData[0]) as Date).getTime()) :
1459
+ new Date((getValue('startDate', gridData[0]) as Date).getTime()) :
1460
+ !isNullOrUndefined((this.beforeOpenArgs.rowData as IGanttData).ganttProperties.startDate) &&
1461
+ new Date((this.beforeOpenArgs.rowData as IGanttData).ganttProperties.startDate.getTime());
1462
+ startDate.setHours(0, 0, 0, 0);
1463
+ if (!isNullOrUndefined(gridData) && gridData.length > 0) {
1464
+ startDate.setDate(startDate.getDate() + 2);
1465
+ }
1466
+ sDate = this.parent.dataOperation.checkStartDate(startDate);
1467
+ eDate = this.parent.dateValidationModule.getDateFromFormat(sDate);
1468
+ if (eDate.getHours() === 0 && this.parent.defaultEndTime !== 86400) {
1469
+ this.parent.dateValidationModule.setTime(this.parent.defaultEndTime, eDate);
1470
+ }
1471
+ eDate = !isNullOrUndefined(taskFields.endDate) && !isNullOrUndefined(gridData) && gridData.length <= 0 ?
1472
+ (this.beforeOpenArgs.rowData as IGanttData).ganttProperties.endDate : eDate;
1473
+
1474
+ duration = !isNullOrUndefined(taskFields.duration) && !isNullOrUndefined(gridData) && gridData.length <= 0 ?
1475
+ (this.beforeOpenArgs.rowData as IGanttData).ganttProperties.duration : 1;
1476
+ arg = {
1477
+ startDate: sDate,
1478
+ endDate: eDate,
1479
+ duration: duration
1480
+ };
1481
+ args.rowData = arg;
1482
+ }
1483
+ }
1484
+ this.selectedSegment = args.rowData;
1485
+ // if (args.requestType === 'save') {
1486
+ // // let duration: string = 'duration';
1487
+ // // let tempDuration: Object = this.parent.dataOperation.getDurationValue(args.data[duration]);
1488
+ // // args.data[duration] = getValue('duration', tempDuration);
1489
+ // this.selectedSegment = !isNullOrUndefined(this.editedRecord.ganttProperties.segments[args.rowIndex]) ?
1490
+ // this.editedRecord.ganttProperties.segments[args.rowIndex] : !isNullOrUndefined(gridData[args.rowIndex]) ?
1491
+ // gridData[args.rowIndex] : gridData;
1492
+ // }
1493
+ }
1494
+ }
1495
+ private renderSegmentsTab(itemName: string): HTMLElement {
1496
+ const ganttObj: Gantt = this.parent;
1497
+ const gridModel: GridModel = this.beforeOpenArgs[itemName];
1498
+ const ganttData: IGanttData = this.beforeOpenArgs.rowData;
1499
+ let preData: ITaskSegment[] = [];
1500
+ if (this.isEdit) {
1501
+ preData = isNullOrUndefined(ganttData.ganttProperties.segments) ? [] : ganttData.ganttProperties.segments;
1502
+ }
1503
+ gridModel.dataSource = preData;
1504
+ gridModel.actionBegin = this.segmentGridActionBegin.bind(this);
1505
+ Grid.Inject(Edit, Page, GridToolbar, ForeignKey);
1506
+ const gridObj: Grid = new Grid(gridModel);
1507
+ const divElement: HTMLElement = this.createDivElement('', ganttObj.element.id + '' + itemName + 'TabContainer');
1508
+ gridObj.appendTo(divElement);
1509
+ return divElement;
1510
+ }
1511
+ private renderGeneralTab(itemName: string): HTMLElement {
1512
+ const ganttObj: Gantt = this.parent;
1513
+ const itemModel: Object = this.beforeOpenArgs[itemName];
1514
+ const divElement: HTMLElement = this.createDivElement('e-edit-form-row', ganttObj.element.id
1515
+ + '' + itemName + 'TabContainer');
1516
+ for (const key of Object.keys(itemModel)) {
1517
+ if (this.parent.columnByField[key].visible === false) {
1518
+ continue;
1519
+ }
1520
+ const column: GanttColumnModel = this.parent.columnByField[key];
1521
+ const inputModel: { [key: string]: Record<string, unknown> } = itemModel[key];
1522
+ divElement.appendChild(this.renderInputElements(inputModel, column));
1523
+ }
1524
+ return divElement;
1525
+ }
1526
+
1527
+ private isCheckIsDisabled(column: GanttColumnModel): boolean {
1528
+ let disabled: boolean = false;
1529
+ if (column.allowEditing === false || column.isPrimaryKey || this.parent.readOnly) {
1530
+ if (this.parent.customColumns.indexOf(column.field) !== -1) {
1531
+ disabled = true;
1532
+ } else {
1533
+ if (column.field === this.parent.taskFields.id || column.field === this.parent.taskFields.name ||
1534
+ column.field === this.parent.taskFields.duration || column.field === this.parent.taskFields.progress ||
1535
+ column.field === this.parent.taskFields.startDate || column.field === this.parent.taskFields.endDate ||
1536
+ column.field === this.parent.taskFields.baselineStartDate || column.field === this.parent.taskFields.baselineEndDate ||
1537
+ column.field === this.parent.taskFields.work || column.field === 'taskType') {
1538
+ disabled = true;
1539
+ }
1540
+ }
1541
+ }
1542
+ if (this.isEdit) {
1543
+ if (column.field === this.parent.taskFields.id) {
1544
+ disabled = true;
1545
+ }
1546
+ if (this.editedRecord.hasChildRecords) {
1547
+ if ((column.field === this.parent.taskFields.endDate && ((!isNullOrUndefined(this.editedRecord['isManual']) &&
1548
+ this.editedRecord['isManual'] == false) || this.parent.taskMode == 'Auto')) || column.field === this.parent.taskFields.duration ||
1549
+ column.field === this.parent.taskFields.progress || column.field === this.parent.taskFields.work ||
1550
+ column.field === 'taskType') {
1551
+ disabled = true;
1552
+ }
1553
+ }
1554
+ }
1555
+ return disabled;
1556
+ }
1557
+
1558
+ private renderPredecessorTab(itemName: string): HTMLElement {
1559
+ const ganttObj: Gantt = this.parent;
1560
+ const gridModel: GridModel = this.beforeOpenArgs[itemName];
1561
+ const dependencyColumn: GanttColumnModel = this.parent.columnByField[this.parent.taskFields.dependency];
1562
+ if (dependencyColumn.allowEditing === false || dependencyColumn.isPrimaryKey || this.parent.readOnly) {
1563
+ gridModel.editSettings.allowEditing = false;
1564
+ gridModel.editSettings.allowAdding = false;
1565
+ gridModel.editSettings.allowDeleting = false;
1566
+ }
1567
+ const ganttData: IGanttData = this.beforeOpenArgs.rowData;
1568
+ let preData: IPreData[] = [];
1569
+ this.taskNameCollection();
1570
+ if (this.isEdit) {
1571
+ preData = this.predecessorEditCollection(ganttData);
1572
+ this.updatePredecessorDropDownData(ganttData);
1573
+ }
1574
+ gridModel.dataSource = preData;
1575
+ gridModel.actionBegin = this.gridActionBegin.bind(this);
1576
+ const columns: GridColumnModel[] = <GridColumnModel[]>gridModel.columns;
1577
+ columns[1].edit = {
1578
+ write: (args: CObject): void => {
1579
+ if (getValue('requestType', args) === 'add') {
1580
+ setValue('rowData.uniqueId', getUid(), args);
1581
+ }
1582
+ const field: string = 'name';
1583
+ const autoObj: ComboBox = new ComboBox({
1584
+ dataSource: new DataManager(this.idCollection),
1585
+ popupHeight: '180px',
1586
+ allowCustom: false,
1587
+ fields: { value: 'text' },
1588
+ value: args.rowData[field],
1589
+ change: (arg: ChangeEventArgs) => {
1590
+ const tr: HTMLElement = closest(arg.element, 'tr') as HTMLElement;
1591
+ const idInput: HTMLInputElement = tr.querySelector('#' + this.parent.element.id + 'DependencyTabContainerid');
1592
+ if (idInput) {
1593
+ if (!isNullOrUndefined(arg.itemData) && !isNullOrUndefined(arg.item)) {
1594
+ idInput.value = (arg.itemData as IPreData).id;
1595
+ } else {
1596
+ idInput.value = '';
1597
+ }
1598
+ }
1599
+ },
1600
+ autofill: true
1601
+ });
1602
+ autoObj.appendTo(args.element as HTMLElement);
1603
+ },
1604
+ read: (args: HTMLElement): string => {
1605
+ const ej2Instance: ComboBoxModel =
1606
+ <CObject>(<EJ2Instance>args).ej2_instances[0];
1607
+ return ej2Instance.value as string;
1608
+ }
1609
+ };
1610
+ Grid.Inject(Edit, Page, GridToolbar, ForeignKey);
1611
+ const gridObj: Grid = new Grid(gridModel);
1612
+ const divElement: HTMLElement = this.createDivElement('e-dependent-div', ganttObj.element.id + '' + itemName + 'TabContainer');
1613
+ gridObj.appendTo(divElement);
1614
+ return divElement;
1615
+ }
1616
+
1617
+ private gridActionBegin(args: GridActionEventArgs): void {
1618
+ const itemName: string = 'Dependency';
1619
+ const gridModel: GridModel = this.beforeOpenArgs[itemName] as GridModel;
1620
+ if (args.requestType === 'add' || args.requestType === 'beginEdit') {
1621
+ const isEdit: boolean = args.requestType === 'add' ? false : true;
1622
+ this.idCollection = extend([], [], this.preTableCollection, true) as IDependencyEditData[];
1623
+ const gridData: Record<string, unknown>[] = gridModel.dataSource as Record<string, unknown>[];
1624
+ for (let i: number = 0; i <= gridData.length; i++) {
1625
+ // eslint-disable-next-line
1626
+ this.idCollection.forEach((data: IDependencyEditData, index: number): void => {
1627
+ if (data.id === getValue('id', gridData[i])) {
1628
+ const selectedItem: object = getValue('rowData', args);
1629
+ if (isEdit && getValue('id', selectedItem) === data.id) {
1630
+ return;
1631
+ }
1632
+ this.idCollection.splice(this.idCollection.indexOf(data), 1);
1633
+ }
1634
+ });
1635
+ }
1636
+ }
1637
+ }
1638
+
1639
+ private updateResourceCollection(args: RowSelectEventArgs, resourceTreeGridId: string): void {
1640
+ if (!isNullOrUndefined(args.data) && Object.keys(args.data).length) {
1641
+ const ganttObj: Gantt = this.parent;
1642
+ const treeGridId: HTMLElement = document.querySelector('#' + resourceTreeGridId);
1643
+ const resourceTreeGrid: TreeGrid = <TreeGrid>(<EJ2Instance>treeGridId).ej2_instances[0];
1644
+ if (!isNullOrUndefined(resourceTreeGrid) && resourceTreeGrid.getSelectedRecords().length > 0) {
1645
+ const tempRecords: CObject[] = <CObject[]>resourceTreeGrid.getSelectedRecords();
1646
+ let index: number;
1647
+ const selectedItems: CObject[] = [];
1648
+ for (index = 0; index < tempRecords.length; index++) {
1649
+ selectedItems.push(<CObject>tempRecords[index].taskData);
1650
+ }
1651
+ this.ganttResources = <Record<string, unknown>[]>extend([], selectedItems);
1652
+ } else {
1653
+ this.ganttResources = [];
1654
+ }
1655
+ } else {
1656
+ this.ganttResources = [];
1657
+ }
1658
+ }
1659
+
1660
+ private renderResourceTab(itemName: string): HTMLElement {
1661
+ const ganttObj: Gantt = this.parent;
1662
+ const resourceSettings: ResourceFieldsModel = ganttObj.resourceFields;
1663
+ const ganttData: IGanttData = this.beforeOpenArgs.rowData;
1664
+ const rowResource: Object[] = ganttData.ganttProperties.resourceInfo;
1665
+ const inputModel: TreeGridModel = this.beforeOpenArgs[itemName];
1666
+ const resourceTreeGridId: string = ganttObj.element.id + '' + itemName + 'TabContainer';
1667
+ const resourceData: Record<string, unknown>[] = <Record<string, unknown>[]>extend([], [], ganttObj.resources, true);
1668
+ this.parent.dataOperation.updateResourceUnit(resourceData);
1669
+ if (!isNullOrUndefined(rowResource)) {
1670
+ let count: number;
1671
+ const rowResourceLength: number = rowResource.length;
1672
+ let index: number;
1673
+ const resourceDataLength: number = resourceData.length;
1674
+ for (count = 0; count < rowResourceLength; count++) {
1675
+ for (index = 0; index < resourceDataLength; index++) {
1676
+ if (rowResource[count][resourceSettings.id] === resourceData[index][resourceSettings.id]) {
1677
+ resourceData[index][resourceSettings.unit] = rowResource[count][resourceSettings.unit];
1678
+ }
1679
+ }
1680
+ }
1681
+ }
1682
+ inputModel.dataSource = resourceData;
1683
+ const resourceInfo: Object[] = ganttData.ganttProperties.resourceInfo;
1684
+ if (this.isEdit && !isNullOrUndefined(resourceInfo)) {
1685
+ for (let i: number = 0; i < resourceInfo.length; i++) {
1686
+ this.ganttResources.push(resourceInfo[i]);
1687
+ }
1688
+ }
1689
+ inputModel.rowSelected = (args: RowSelectEventArgs): void => {
1690
+ this.updateResourceCollection(args, resourceTreeGridId);
1691
+ };
1692
+ inputModel.rowDeselected = (args: RowSelectEventArgs): void => {
1693
+ this.updateResourceCollection(args, resourceTreeGridId);
1694
+ };
1695
+
1696
+ const divElement: HTMLElement = this.createDivElement('e-resource-div', resourceTreeGridId);
1697
+ TreeGrid.Inject(Selection, Filter, TreeGridEdit, VirtualScroll);
1698
+ const treeGridObj: TreeGrid = new TreeGrid(inputModel);
1699
+ const resourceColumn: GanttColumnModel = this.parent.columnByField[this.parent.taskFields.resourceInfo];
1700
+ if (resourceColumn.allowEditing === false || resourceColumn.isPrimaryKey || this.parent.readOnly) {
1701
+ treeGridObj.allowSelection = false;
1702
+ treeGridObj.allowFiltering = false;
1703
+ treeGridObj.editSettings.allowEditing = false;
1704
+ }
1705
+ treeGridObj.dataBound = () => {
1706
+ if (this.parent.editDialogFields.length >= 1 && this.parent.editDialogFields[0].type === 'Resources') {
1707
+ const id: string = this.parent.element.id + 'ResourcesTabContainer';
1708
+ this.resourceSelection(id);
1709
+ }
1710
+ }
1711
+ treeGridObj.appendTo(divElement);
1712
+ return divElement;
1713
+ }
1714
+ private resourceSelection(id: string) {
1715
+ const resourceTreeGrid: TreeGrid = <TreeGrid>(<EJ2Instance>document.querySelector('#' + id)).ej2_instances[0];
1716
+ let currentViewData: Object[] = resourceTreeGrid.getCurrentViewRecords();
1717
+ let resources: Object[] = this.ganttResources;
1718
+ if (resources && resources.length > 0) {
1719
+ currentViewData.forEach((data: CObject, index: number): void => {
1720
+ for (let i: number = 0; i < resources.length; i++) {
1721
+ if (data.taskData[this.parent.resourceFields.id] === resources[i][this.parent.resourceFields.id] &&
1722
+ !isNullOrUndefined(resourceTreeGrid.selectionModule) &&
1723
+ resourceTreeGrid.getSelectedRowIndexes().indexOf(index) === -1) {
1724
+ resourceTreeGrid.selectRow(index);
1725
+ }
1726
+ }
1727
+ });
1728
+ }
1729
+ }
1730
+ private renderCustomTab(itemName: string): HTMLElement {
1731
+ return this.renderGeneralTab(itemName);
1732
+ }
1733
+
1734
+ private renderNotesTab(itemName: string): HTMLElement {
1735
+ const ganttObj: Gantt = this.parent;
1736
+ const inputModel: RichTextEditorModel = this.beforeOpenArgs[itemName];
1737
+ const ganttProp: ITaskData = this.editedRecord.ganttProperties;
1738
+ const divElement: HTMLElement = this.createDivElement('', ganttObj.element.id + '' + itemName + 'TabContainer');
1739
+ RichTextEditor.Inject(RTEToolbar, Link, HtmlEditor, QuickToolbar, Count);
1740
+ inputModel.value = ganttProp.notes;
1741
+ const notesColumn: GanttColumnModel = this.parent.columnByField[this.parent.taskFields.notes];
1742
+ if (notesColumn.allowEditing === false || notesColumn.isPrimaryKey || this.parent.readOnly) {
1743
+ inputModel.enabled = false;
1744
+ }
1745
+ const rteObj: RichTextEditor = new RichTextEditor(inputModel);
1746
+ rteObj.appendTo(divElement);
1747
+ return divElement;
1748
+ }
1749
+
1750
+ private renderInputElements(inputModel: CObject, column: GanttColumnModel): HTMLElement {
1751
+ const ganttId: string = this.parent.element.id;
1752
+ const ganttData: IGanttData = this.editedRecord;
1753
+ const divElement: HTMLElement = this.createDivElement('e-edit-form-column');
1754
+ let inputElement: HTMLElement;
1755
+ const editArgs: Record<string, unknown> = { column: column, data: ganttData };
1756
+ if (!isNullOrUndefined(column.edit) && isNullOrUndefined(column.edit.params)) {
1757
+ let create: Function = column.edit.create as Function;
1758
+ if (typeof create === 'string') {
1759
+ create = getObject(create, window);
1760
+ inputElement = create(editArgs);
1761
+ } else {
1762
+ inputElement = (column.edit.create as Function)(editArgs);
1763
+ }
1764
+ inputElement.className = '';
1765
+ inputElement.setAttribute('type', 'text');
1766
+ inputElement.setAttribute('id', ganttId + '' + column.field);
1767
+ inputElement.setAttribute('name', column.field);
1768
+ inputElement.setAttribute('title', column.field);
1769
+ divElement.appendChild(inputElement);
1770
+ } else {
1771
+ inputElement = this.createInputElement('', ganttId + '' + column.field, column.field);
1772
+ divElement.appendChild(inputElement);
1773
+ }
1774
+ inputModel.enabled = !this.isCheckIsDisabled(column);
1775
+ if (column.field === this.parent.taskFields.duration) {
1776
+ if (!isNullOrUndefined(column.valueAccessor)) {
1777
+ if (typeof column.valueAccessor === 'string') {
1778
+ const valueAccessor: Function = getObject(column.valueAccessor, window);
1779
+ inputModel.value = valueAccessor(column.field, ganttData, column);
1780
+ } else {
1781
+ inputModel.value = (column.valueAccessor as Function)(column.field, ganttData, column);
1782
+ }
1783
+ } else if (isNullOrUndefined(column.edit)) {
1784
+ const ganttProp: ITaskData = ganttData.ganttProperties;
1785
+ inputModel.value = this.parent.dataOperation.getDurationString(ganttProp.duration, ganttProp.durationUnit);
1786
+ }
1787
+ } else {
1788
+ if (column.editType === 'booleanedit') {
1789
+ if (ganttData[column.field] === true) {
1790
+ inputModel.checked = true;
1791
+ } else {
1792
+ inputModel.checked = false;
1793
+ }
1794
+ } else {
1795
+ inputModel.value = ganttData[column.field];
1796
+ }
1797
+ }
1798
+ if (!isNullOrUndefined(column.edit) && isNullOrUndefined(column.edit.params)) {
1799
+ let write: Function = column.edit.write as Function;
1800
+ let inputObj: Inputs;
1801
+ if (typeof write === 'string') {
1802
+ write = getObject(write, window);
1803
+ inputObj = write({
1804
+ column: column, rowData: ganttData, element: inputElement
1805
+ });
1806
+ } else {
1807
+ inputObj = (column.edit.write as Function)({
1808
+ column: column, rowData: ganttData, element: inputElement
1809
+ });
1810
+ }
1811
+ if (column.field === this.parent.taskFields.duration) {
1812
+ inputObj.change = (args: CObject): void => {
1813
+ this.validateScheduleFields(args, column, this.parent);
1814
+ };
1815
+ }
1816
+ } else {
1817
+ const inputObj: Inputs = new this.inputs[column.editType](inputModel);
1818
+ inputObj.appendTo(inputElement);
1819
+ }
1820
+ return divElement;
1821
+ }
1822
+
1823
+ private taskNameCollection(): void {
1824
+ const flatData: IGanttData[] = this.parent.flatData;
1825
+ this.preTaskIds = [];
1826
+ this.preTableCollection = [];
1827
+ for (let i: number = 0; i < flatData.length; i++) {
1828
+ const data: IGanttData = flatData[i];
1829
+ if (data.hasChildRecords) {
1830
+ continue;
1831
+ }
1832
+ const taskId: string = this.parent.viewType === 'ResourceView' ? data.ganttProperties.taskId.toString()
1833
+ : data.ganttProperties.rowUniqueID.toString();
1834
+ const tempObject: IDependencyEditData = {
1835
+ id: taskId,
1836
+ text: (taskId + '-' + data.ganttProperties.taskName),
1837
+ value: taskId
1838
+ };
1839
+ this.preTaskIds.push(tempObject.id);
1840
+ this.preTableCollection.push(tempObject);
1841
+ }
1842
+ }
1843
+
1844
+ private predecessorEditCollection(ganttData: IGanttData): IPreData[] {
1845
+ const preDataCollection: IPreData[] = [];
1846
+ const ganttProp: ITaskData = ganttData.ganttProperties;
1847
+ if (this.isEdit && !isNullOrUndefined(this.parent.taskFields.dependency) && !isNullOrUndefined(ganttData) &&
1848
+ !isNullOrUndefined(ganttProp.predecessor)) {
1849
+ const predecessor: IPredecessor[] = ganttProp.predecessor;
1850
+ const idCollection: IDependencyEditData[] = this.preTableCollection;
1851
+ for (let i: number = 0; i < predecessor.length; i++) {
1852
+ const from: string = predecessor[i].from.toString();
1853
+ const preData: IPreData = {};
1854
+ const taskID: string = this.parent.viewType === 'ResourceView' ? ganttProp.taskId : ganttProp.rowUniqueID;
1855
+ if (taskID.toString() !== from) {
1856
+ preData.id = from;
1857
+ for (let index: number = 0; index < idCollection.length; index++) {
1858
+ if (idCollection[index].value === from) {
1859
+ preData.name = idCollection[index].text;
1860
+ break;
1861
+ }
1862
+ }
1863
+ preData.type = predecessor[i].type;
1864
+ const offset: number = predecessor[i].offset;
1865
+ const offsetUnit: string = predecessor[i].offsetUnit;
1866
+ preData.offset = this.parent.dataOperation.getDurationString(offset, offsetUnit);
1867
+ preData.uniqueId = getUid();
1868
+ preDataCollection.push(preData);
1869
+ }
1870
+ }
1871
+ }
1872
+ return preDataCollection;
1873
+ }
1874
+
1875
+ private updatePredecessorDropDownData(ganttData: IGanttData): void {
1876
+ let index: number = -1;
1877
+ const id: string = this.parent.viewType === 'ResourceView' ? ganttData.ganttProperties.taskId.toString()
1878
+ : ganttData.ganttProperties.rowUniqueID.toString();
1879
+ index = this.preTaskIds.indexOf(id);
1880
+ this.preTableCollection.splice(index, 1);
1881
+ this.preTaskIds.splice(index, 1);
1882
+ this.validSuccessorTasks(ganttData, this.preTaskIds, this.preTableCollection);
1883
+ }
1884
+
1885
+ private validSuccessorTasks(data: IGanttData, ids: string[], idCollection: IDependencyEditData[]): void {
1886
+ const ganttProp: ITaskData = data.ganttProperties;
1887
+ if (ganttProp.predecessor && ganttProp.predecessor.length > 0) {
1888
+ const predecessor: IPredecessor[] = ganttProp.predecessor;
1889
+ const fromId: string = this.parent.viewType === 'ResourceView' ? ganttProp.taskId.toString() : ganttProp.rowUniqueID.toString();
1890
+ predecessor.forEach((item: IPredecessor) => {
1891
+ if (item.from.toString() === fromId) {
1892
+ const toId: string = item.to; let idIndex: number = -1;
1893
+ idIndex = ids.indexOf(toId);
1894
+ if (idIndex > -1) {
1895
+ ids.splice(idIndex, 1);
1896
+ idCollection.splice(idIndex, 1);
1897
+ }
1898
+ const ganttData: IGanttData = this.parent.connectorLineModule.getRecordByID(toId);
1899
+ this.validSuccessorTasks(ganttData, ids, idCollection);
1900
+ }
1901
+ });
1902
+ }
1903
+ }
1904
+
1905
+ private getPredecessorType(): IDependencyEditData[] {
1906
+ const typeText: string[] = [this.parent.getPredecessorTextValue('SS'), this.parent.getPredecessorTextValue('SF'),
1907
+ this.parent.getPredecessorTextValue('FS'), this.parent.getPredecessorTextValue('FF')];
1908
+ const types: IDependencyEditData[] = [
1909
+ { id: 'FS', text: typeText[2], value: typeText[2] },
1910
+ { id: 'FF', text: typeText[3], value: typeText[3] },
1911
+ { id: 'SS', text: typeText[0], value: typeText[0] },
1912
+ { id: 'SF', text: typeText[1], value: typeText[1] }
1913
+ ];
1914
+ return types;
1915
+ }
1916
+ private initiateDialogSave(): boolean {
1917
+ if (this.isEdit) {
1918
+ this.parent.initiateEditAction(true);
1919
+ } else {
1920
+ this.addedRecord = {};
1921
+ }
1922
+ const ganttObj: Gantt = this.parent;
1923
+ const tabModel: TabModel = this.beforeOpenArgs.tabModel;
1924
+ const items: TabItemModel[] = tabModel.items;
1925
+ for (let i: number = 0; i < items.length; i++) {
1926
+ const element: HTMLElement = items[i].content as HTMLElement;
1927
+ let id: string = element.id;
1928
+ if (!isNullOrUndefined(id) || id !== '') {
1929
+ id = id.replace(ganttObj.element.id, '');
1930
+ id = id.replace('TabContainer', '');
1931
+ if (id === 'General') {
1932
+ this.updateGeneralTab(element, false);
1933
+ } else if (id === 'Dependency') {
1934
+ this.updatePredecessorTab(element);
1935
+ } else if (id === 'Notes') {
1936
+ this.updateNotesTab(element);
1937
+ } else if (id === 'Resources') {
1938
+ this.updateResourceTab(element);
1939
+ } else if (id.indexOf('Custom') !== -1) {
1940
+ this.updateCustomTab(element);
1941
+ } else if (id === 'Segments') {
1942
+ this.updateSegmentsData(element, this.beforeOpenArgs.rowData);
1943
+ }
1944
+ }
1945
+ }
1946
+ if (this.isEdit) {
1947
+ /**
1948
+ * If any update on edited task do it here
1949
+ */
1950
+ this.parent.dataOperation.updateWidthLeft(this.rowData);
1951
+ const editArgs: ITaskbarEditedEventArgs = {
1952
+ data: this.rowData,
1953
+ action: 'DialogEditing'
1954
+ };
1955
+ this.parent.editModule.initiateUpdateAction(editArgs);
1956
+ } else {
1957
+ if (this.parent.viewType === 'ResourceView') {
1958
+ const newRecords: Object = extend({}, this.addedRecord, true);
1959
+ if (newRecords[this.parent.taskFields.resourceInfo].length) {
1960
+ for (let i: number = 0; i < newRecords[this.parent.taskFields.resourceInfo].length; i++) {
1961
+ const id: string = newRecords[this.parent.taskFields.resourceInfo][i].toString();
1962
+ const parentRecordIndex: number = this.parent.getTaskIds().indexOf('R' + id.toString());
1963
+ if (parentRecordIndex !== -1) {
1964
+ this.parent.editModule.addRecord(this.addedRecord, 'Child', parentRecordIndex);
1965
+ break;
1966
+ }
1967
+ }
1968
+ } else {
1969
+ this.parent.editModule.addRecord(this.addedRecord, 'Bottom');
1970
+ }
1971
+ } else {
1972
+ this.parent.editModule.addRecord(this.addedRecord, this.parent.editSettings.newRowPosition);
1973
+ }
1974
+ }
1975
+ return true;
1976
+ }
1977
+
1978
+ private updateSegmentTaskData(dataSource: ITaskSegment[]): void {
1979
+ const userData: ITaskSegment[] = [];
1980
+ const taskSettings: TaskFieldsModel = this.parent.taskFields;
1981
+ for (let i: number = 0; i < dataSource.length; i++) {
1982
+ const taskData: Object = {};
1983
+
1984
+ if (!isNullOrUndefined(taskSettings.startDate)) {
1985
+ taskData[this.parent.taskFields.startDate] = dataSource[i].startDate;
1986
+ }
1987
+ if (!isNullOrUndefined(taskSettings.endDate)) {
1988
+ taskData[this.parent.taskFields.endDate] = dataSource[i].endDate;
1989
+ }
1990
+ if (!isNullOrUndefined(taskSettings.duration)) {
1991
+ taskData[this.parent.taskFields.duration] = Number(dataSource[i].duration);
1992
+ dataSource[i].duration = taskData[this.parent.taskFields.duration];
1993
+ }
1994
+ userData.push(taskData);
1995
+ }
1996
+ if (!this.isEdit) {
1997
+ this.addedRecord[taskSettings.segments] = userData;
1998
+ } else {
1999
+ this.rowData.ganttProperties.segments = dataSource;
2000
+ this.parent.setRecordValue(
2001
+ 'segments', this.parent.dataOperation.setSegmentsInfo(this.rowData, false), this.rowData.ganttProperties, true
2002
+ );
2003
+ this.parent.setRecordValue(
2004
+ 'taskData.' + this.parent.taskFields.segments,
2005
+ userData,
2006
+ this.rowData);
2007
+ if (dataSource.length <= 0){
2008
+ this.validateDuration(this.rowData);
2009
+ }
2010
+ }
2011
+ }
2012
+ // eslint-disable-next-line
2013
+ private updateSegmentsData(segmentForm: HTMLElement, data: IGanttData): void {
2014
+ const gridObj: Grid = <Grid>(<EJ2Instance>segmentForm).ej2_instances[0];
2015
+ if (gridObj.isEdit) {
2016
+ gridObj.endEdit();
2017
+ }
2018
+ const dataSource: ITaskSegment[] = <ITaskSegment[]>gridObj.currentViewData;
2019
+ this.updateSegmentTaskData(dataSource);
2020
+ }
2021
+
2022
+ private updateGeneralTab(generalForm: HTMLElement, isCustom: boolean): void {
2023
+ const ganttObj: Gantt = this.parent;
2024
+ const childNodes: NodeList = generalForm.childNodes;
2025
+ let tasksData: Record<string, unknown> = {};
2026
+ if (!this.isEdit) {
2027
+ tasksData = this.addedRecord;
2028
+ }
2029
+ for (let i: number = 0; i < childNodes.length; i++) {
2030
+ const div: HTMLElement = childNodes[i] as HTMLElement;
2031
+ const inputElement: HTMLInputElement = div.querySelector('input[id^="' + ganttObj.element.id + '"]');
2032
+ if (inputElement) {
2033
+ const fieldName: string = inputElement.id.replace(ganttObj.element.id, '');
2034
+ const controlObj: CObject = <CObject>(<EJ2Instance>div.querySelector('#' + ganttObj.element.id + fieldName)).ej2_instances[0];
2035
+ const column: GanttColumnModel = ganttObj.columnByField[fieldName];
2036
+ if (!isNullOrUndefined(column.edit) && isNullOrUndefined(column.edit.params)) {
2037
+ let read: Function = column.edit.read as Function;
2038
+ if (typeof read === 'string') {
2039
+ read = getObject(read, window);
2040
+ tasksData[fieldName] = read(inputElement, controlObj.value);
2041
+ } else {
2042
+ tasksData[fieldName] = (column.edit.read as Function)(inputElement, controlObj.value);
2043
+ }
2044
+ } else if (isCustom && column.editType === 'booleanedit') {
2045
+ if (inputElement.checked === true) {
2046
+ tasksData[fieldName] = true;
2047
+ } else {
2048
+ tasksData[fieldName] = false;
2049
+ }
2050
+ } else {
2051
+ tasksData[fieldName] = controlObj.value;
2052
+ }
2053
+ }
2054
+ }
2055
+ if (this.isEdit) {
2056
+ this.updateScheduleProperties(this.editedRecord, this.rowData);
2057
+ ganttObj.editModule.validateUpdateValues(tasksData, this.rowData, true);
2058
+ }
2059
+ }
2060
+ private updateScheduleProperties(fromRecord: IGanttData, toRecord: IGanttData): void {
2061
+ this.parent.setRecordValue('startDate', fromRecord.ganttProperties.startDate, toRecord.ganttProperties, true);
2062
+ this.parent.setRecordValue('endDate', fromRecord.ganttProperties.endDate, toRecord.ganttProperties, true);
2063
+ this.parent.setRecordValue('duration', fromRecord.ganttProperties.duration, toRecord.ganttProperties, true);
2064
+ this.parent.setRecordValue('durationUnit', fromRecord.ganttProperties.durationUnit, toRecord.ganttProperties, true);
2065
+ this.parent.setRecordValue('work', fromRecord.ganttProperties.work, toRecord.ganttProperties, true);
2066
+ if (!isNullOrUndefined(this.parent.taskFields.startDate)) {
2067
+ this.parent.dataOperation.updateMappingData(this.rowData, this.parent.taskFields.startDate);
2068
+ }
2069
+ if (!isNullOrUndefined(this.parent.taskFields.endDate)) {
2070
+ this.parent.dataOperation.updateMappingData(this.rowData, this.parent.taskFields.endDate);
2071
+ }
2072
+ if (!isNullOrUndefined(this.parent.taskFields.duration)) {
2073
+ this.parent.dataOperation.updateMappingData(this.rowData, this.parent.taskFields.duration);
2074
+ this.parent.setRecordValue('durationUnit', fromRecord.ganttProperties.durationUnit, this.rowData, true);
2075
+ if (this.rowData.ganttProperties.duration === 0) {
2076
+ this.parent.setRecordValue('isMilestone', true, this.rowData.ganttProperties, true);
2077
+ } else {
2078
+ this.parent.setRecordValue('isMilestone', false, this.rowData.ganttProperties, true);
2079
+ }
2080
+ }
2081
+ if (!isNullOrUndefined(this.parent.taskFields.work)) {
2082
+ this.parent.dataOperation.updateMappingData(this.rowData, this.parent.taskFields.work);
2083
+ }
2084
+ if (!isNullOrUndefined(this.parent.taskFields.manual)) {
2085
+ this.parent.dataOperation.updateMappingData(this.rowData, this.parent.taskFields.manual);
2086
+ }
2087
+ }
2088
+ private updatePredecessorTab(preElement: HTMLElement): void {
2089
+ const gridObj: Grid = <Grid>(<EJ2Instance>preElement).ej2_instances[0];
2090
+ if (gridObj.isEdit) {
2091
+ gridObj.endEdit();
2092
+ }
2093
+ const dataSource: IPreData[] = <IPreData[]>gridObj.dataSource;
2094
+ const predecessorName: string[] = [];
2095
+ let newValues: IPredecessor[] = [];
2096
+ let predecessorString: string = '';
2097
+ const ids: string[] = [];
2098
+ for (let i: number = 0; i < dataSource.length; i++) {
2099
+ const preData: IPreData = dataSource[i];
2100
+ const newId: string = preData.name.split('-')[0];
2101
+ if (preData.id !== newId) {
2102
+ preData.id = newId;
2103
+ }
2104
+ if (ids.indexOf(preData.id) === -1) {
2105
+ let name: string = preData.id + preData.type;
2106
+ if (preData.offset && preData.offset.indexOf('-') !== -1) {
2107
+ name += preData.offset;
2108
+ } else {
2109
+ name += ('+' + preData.offset);
2110
+ }
2111
+ predecessorName.push(name);
2112
+ ids.push(preData.id);
2113
+ }
2114
+ }
2115
+ if (this.isEdit) {
2116
+ if (predecessorName.length > 0) {
2117
+ newValues = this.parent.predecessorModule.calculatePredecessor(predecessorName.join(','), this.rowData);
2118
+ this.parent.setRecordValue('predecessor', newValues, this.rowData.ganttProperties, true);
2119
+ predecessorString = this.parent.predecessorModule.getPredecessorStringValue(this.rowData);
2120
+ } else {
2121
+ newValues = [];
2122
+ this.parent.setRecordValue('predecessor', newValues, this.rowData.ganttProperties, true);
2123
+ predecessorString = '';
2124
+ }
2125
+ this.parent.setRecordValue('predecessorsName', predecessorString, this.rowData.ganttProperties, true);
2126
+ this.parent.setRecordValue(
2127
+ 'taskData.' + this.parent.taskFields.dependency,
2128
+ predecessorString,
2129
+ this.rowData);
2130
+ this.parent.setRecordValue(
2131
+ this.parent.taskFields.dependency,
2132
+ predecessorString,
2133
+ this.rowData);
2134
+ this.parent.predecessorModule.updateUnscheduledDependency(this.rowData);
2135
+ } else {
2136
+ this.addedRecord[this.parent.taskFields.dependency] = predecessorName.length > 0 ? predecessorName.join(',') : '';
2137
+ }
2138
+ }
2139
+ private updateResourceTab(resourceElement: HTMLElement): void {
2140
+ const treeGridObj: TreeGrid = <TreeGrid>(<EJ2Instance>resourceElement).ej2_instances[0];
2141
+ if (treeGridObj) {
2142
+ treeGridObj.grid.endEdit();
2143
+ }
2144
+ const selectedItems: CObject[] = <CObject[]>this.ganttResources;
2145
+ if (this.parent.viewType === 'ResourceView' && !isNullOrUndefined(this.rowData.ganttProperties)) {
2146
+ if (JSON.stringify(this.ganttResources) !== JSON.stringify(this.rowData.ganttProperties.resourceInfo)) {
2147
+ this.isResourceUpdate = true;
2148
+ this.previousResource = !isNullOrUndefined(this.rowData.ganttProperties.resourceInfo) ?
2149
+ [...this.rowData.ganttProperties.resourceInfo] : [];
2150
+ } else {
2151
+ this.isResourceUpdate = false;
2152
+ }
2153
+ }
2154
+ const idArray: object[] = [];
2155
+ if (this.isEdit) {
2156
+ this.parent.setRecordValue('resourceInfo', selectedItems, this.rowData.ganttProperties, true);
2157
+ this.parent.dataOperation.updateMappingData(this.rowData, 'resourceInfo');
2158
+ this.parent.editModule.updateResourceRelatedFields(this.rowData, 'resource');
2159
+ this.validateDuration(this.rowData);
2160
+ } else {
2161
+ for (let i: number = 0; i < selectedItems.length; i++) {
2162
+ idArray.push(selectedItems[i][this.parent.resourceFields.id]);
2163
+ this.isAddNewResource = true;
2164
+ }
2165
+ this.addedRecord[this.parent.taskFields.resourceInfo] = idArray;
2166
+ }
2167
+ }
2168
+ private updateNotesTab(notesElement: HTMLElement): void {
2169
+ const ganttObj: Gantt = this.parent;
2170
+ const rte: RichTextEditor = <RichTextEditor>(<EJ2Instance>notesElement).ej2_instances[0];
2171
+ if (this.isEdit) {
2172
+ if (ganttObj.columnByField[ganttObj.taskFields.notes].disableHtmlEncode) {
2173
+ this.parent.setRecordValue('notes', rte.getHtml(), this.rowData.ganttProperties, true);
2174
+ } else {
2175
+ this.parent.setRecordValue('notes', rte.getText(), this.rowData.ganttProperties, true);
2176
+ }
2177
+ ganttObj.dataOperation.updateMappingData(this.rowData, 'notes');
2178
+ } else {
2179
+ this.addedRecord[this.parent.taskFields.notes] = rte.getHtml();
2180
+ }
2181
+ }
2182
+ private updateCustomTab(customElement: HTMLElement): void {
2183
+ this.updateGeneralTab(customElement, true);
2184
+ }
2185
+ }
2186
+
2187
+ /**
2188
+ * @hidden
2189
+ */
2190
+ export type Inputs =
2191
+ CheckBox |
2192
+ DropDownList |
2193
+ TextBox |
2194
+ NumericTextBox |
2195
+ DatePicker |
2196
+ DateTimePicker |
2197
+ MaskedTextBox;
2198
+
2199
+ /**
2200
+ * @hidden
2201
+ */
2202
+ export interface IPreData {
2203
+ id?: string;
2204
+ name?: string;
2205
+ type?: string;
2206
+ offset?: string;
2207
+ uniqueId?: number;
2208
+ }