@syncfusion/ej2-gantt 19.4.56 → 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 (211) hide show
  1. package/CHANGELOG.md +1072 -1060
  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 +274 -176
  6. package/dist/es6/ej2-gantt.es2015.js.map +1 -1
  7. package/dist/es6/ej2-gantt.es5.js +642 -534
  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 +11 -2
  91. package/src/gantt/actions/rowdragdrop.js +37 -15
  92. package/src/gantt/actions/taskbar-edit.js +24 -24
  93. package/src/gantt/base/date-processor.js +0 -1
  94. package/src/gantt/base/gantt-chart.js +9 -4
  95. package/src/gantt/base/gantt-model.d.ts +779 -779
  96. package/src/gantt/base/gantt.d.ts +27 -27
  97. package/src/gantt/base/gantt.js +22 -22
  98. package/src/gantt/base/splitter.js +1 -0
  99. package/src/gantt/base/task-processor.js +13 -13
  100. package/src/gantt/base/tree-grid.js +3 -1
  101. package/src/gantt/export/pdf-base/treegrid-layouter.js +13 -13
  102. package/src/gantt/export/pdf-connector-line.js +11 -11
  103. package/src/gantt/export/pdf-gantt.js +24 -24
  104. package/src/gantt/export/pdf-taskbar.js +11 -11
  105. package/src/gantt/export/pdf-treegrid.js +13 -13
  106. package/src/gantt/models/add-dialog-field-settings-model.d.ts +21 -21
  107. package/src/gantt/models/add-dialog-field-settings.js +19 -19
  108. package/src/gantt/models/day-working-time-model.d.ts +11 -11
  109. package/src/gantt/models/day-working-time.js +19 -19
  110. package/src/gantt/models/edit-dialog-field-settings-model.d.ts +21 -21
  111. package/src/gantt/models/edit-dialog-field-settings.js +19 -19
  112. package/src/gantt/models/edit-settings-model.d.ts +50 -50
  113. package/src/gantt/models/edit-settings.js +19 -19
  114. package/src/gantt/models/event-marker-model.d.ts +16 -16
  115. package/src/gantt/models/event-marker.js +19 -19
  116. package/src/gantt/models/filter-settings-model.d.ts +34 -34
  117. package/src/gantt/models/filter-settings.js +19 -19
  118. package/src/gantt/models/holiday-model.d.ts +21 -21
  119. package/src/gantt/models/holiday.js +19 -19
  120. package/src/gantt/models/label-settings-model.d.ts +16 -16
  121. package/src/gantt/models/label-settings.js +19 -19
  122. package/src/gantt/models/resource-fields-model.d.ts +21 -21
  123. package/src/gantt/models/resource-fields.js +19 -19
  124. package/src/gantt/models/search-settings-model.d.ts +56 -56
  125. package/src/gantt/models/search-settings.js +19 -19
  126. package/src/gantt/models/selection-settings-model.d.ts +35 -35
  127. package/src/gantt/models/selection-settings.js +19 -19
  128. package/src/gantt/models/sort-settings-model.d.ts +24 -24
  129. package/src/gantt/models/sort-settings.js +19 -19
  130. package/src/gantt/models/splitter-settings-model.d.ts +30 -30
  131. package/src/gantt/models/splitter-settings.js +19 -19
  132. package/src/gantt/models/task-fields-model.d.ts +110 -110
  133. package/src/gantt/models/task-fields.js +19 -19
  134. package/src/gantt/models/timeline-settings-model.d.ts +71 -71
  135. package/src/gantt/models/timeline-settings.js +19 -19
  136. package/src/gantt/models/tooltip-settings-model.d.ts +26 -26
  137. package/src/gantt/models/tooltip-settings.js +19 -19
  138. package/src/gantt/renderer/chart-rows.js +49 -37
  139. package/src/gantt/renderer/connector-line.js +22 -18
  140. package/src/gantt/renderer/event-marker.js +1 -0
  141. package/src/gantt/renderer/nonworking-day.js +13 -6
  142. package/src/gantt/renderer/timeline.d.ts +1 -0
  143. package/src/gantt/renderer/timeline.js +48 -12
  144. package/src/gantt/renderer/tooltip.js +11 -3
  145. package/styles/bootstrap-dark.css +442 -427
  146. package/styles/bootstrap.css +442 -433
  147. package/styles/bootstrap4.css +454 -479
  148. package/styles/bootstrap5-dark.css +457 -433
  149. package/styles/bootstrap5.css +457 -433
  150. package/styles/fabric-dark.css +438 -421
  151. package/styles/fabric.css +445 -428
  152. package/styles/fluent-dark.css +1938 -0
  153. package/styles/fluent-dark.scss +1 -0
  154. package/styles/fluent.css +1938 -0
  155. package/styles/fluent.scss +1 -0
  156. package/styles/gantt/_all.scss +2 -2
  157. package/styles/gantt/_bootstrap-dark-definition.scss +210 -156
  158. package/styles/gantt/_bootstrap-definition.scss +211 -157
  159. package/styles/gantt/_bootstrap4-definition.scss +213 -158
  160. package/styles/gantt/_bootstrap5-definition.scss +215 -162
  161. package/styles/gantt/_fabric-dark-definition.scss +211 -157
  162. package/styles/gantt/_fabric-definition.scss +211 -157
  163. package/styles/gantt/_fluent-dark-definition.scss +1 -0
  164. package/styles/gantt/_fluent-definition.scss +215 -162
  165. package/styles/gantt/_fusionnew-definition.scss +214 -0
  166. package/styles/gantt/_highcontrast-definition.scss +211 -157
  167. package/styles/gantt/_highcontrast-light-definition.scss +211 -157
  168. package/styles/gantt/_layout.scss +1446 -1027
  169. package/styles/gantt/_material-dark-definition.scss +212 -157
  170. package/styles/gantt/_material-definition.scss +212 -157
  171. package/styles/gantt/_material3-definition.scss +215 -0
  172. package/styles/gantt/_tailwind-definition.scss +215 -161
  173. package/styles/gantt/_theme.scss +702 -668
  174. package/styles/gantt/bootstrap-dark.css +442 -427
  175. package/styles/gantt/bootstrap.css +442 -433
  176. package/styles/gantt/bootstrap4.css +454 -479
  177. package/styles/gantt/bootstrap5-dark.css +457 -433
  178. package/styles/gantt/bootstrap5.css +457 -433
  179. package/styles/gantt/fabric-dark.css +438 -421
  180. package/styles/gantt/fabric.css +445 -428
  181. package/styles/gantt/fluent-dark.css +1938 -0
  182. package/styles/gantt/fluent-dark.scss +22 -0
  183. package/styles/gantt/fluent.css +1938 -0
  184. package/styles/gantt/fluent.scss +22 -0
  185. package/styles/gantt/highcontrast-light.css +405 -405
  186. package/styles/gantt/highcontrast.css +444 -456
  187. package/styles/gantt/icons/_bootstrap-dark.scss +124 -113
  188. package/styles/gantt/icons/_bootstrap.scss +124 -113
  189. package/styles/gantt/icons/_bootstrap4.scss +124 -113
  190. package/styles/gantt/icons/_bootstrap5.scss +124 -112
  191. package/styles/gantt/icons/_fabric-dark.scss +124 -112
  192. package/styles/gantt/icons/_fabric.scss +124 -112
  193. package/styles/gantt/icons/_fluent-dark.scss +1 -0
  194. package/styles/gantt/icons/_fluent.scss +124 -112
  195. package/styles/gantt/icons/_fusionnew.scss +120 -0
  196. package/styles/gantt/icons/_highcontrast.scss +124 -112
  197. package/styles/gantt/icons/_material-dark.scss +124 -112
  198. package/styles/gantt/icons/_material.scss +124 -112
  199. package/styles/gantt/icons/_material3.scss +124 -0
  200. package/styles/gantt/icons/_tailwind-dark.scss +124 -113
  201. package/styles/gantt/icons/_tailwind.scss +124 -113
  202. package/styles/gantt/material-dark.css +446 -417
  203. package/styles/gantt/material.css +445 -419
  204. package/styles/gantt/tailwind-dark.css +452 -482
  205. package/styles/gantt/tailwind.css +449 -479
  206. package/styles/highcontrast-light.css +405 -405
  207. package/styles/highcontrast.css +444 -456
  208. package/styles/material-dark.css +446 -417
  209. package/styles/material.css +445 -419
  210. package/styles/tailwind-dark.css +452 -482
  211. package/styles/tailwind.css +449 -479
@@ -0,0 +1,1940 @@
1
+ import { isNullOrUndefined, createElement, extend, addClass, remove, removeClass, closest, merge } from '@syncfusion/ej2-base';
2
+ import { Gantt } from '../base/gantt';
3
+ import { parentsUntil } from '../base/utils';
4
+ import {
5
+ IGanttData, ITaskData, ITaskbarEditedEventArgs, IActionBeginEventArgs, IDependencyEventArgs, MousePoint, IPredecessor, ITaskSegment
6
+ } from '../base/interface';
7
+ import { DateProcessor } from '../base/date-processor';
8
+ import * as cls from '../base/css-constants';
9
+ import { EditTooltip } from '../renderer/edit-tooltip';
10
+
11
+ /**
12
+ * File for handling taskbar editing operation in Gantt.
13
+ */
14
+ export class TaskbarEdit extends DateProcessor {
15
+ protected parent: Gantt;
16
+ public taskBarEditElement: HTMLElement;
17
+ public taskBarEditRecord: IGanttData;
18
+ public taskBarEditAction: string;
19
+ public roundOffDuration: boolean;
20
+
21
+ private mouseDownX: number;
22
+ private mouseDownY: number;
23
+ public mouseMoveX: number;
24
+ public mouseMoveY: number;
25
+ public previousItem: ITaskData;
26
+ public previousItemProperty: string[];
27
+ public taskbarEditedArgs: ITaskbarEditedEventArgs;
28
+ private progressBorderRadius: number;
29
+ private scrollTimer: number;
30
+ public timerCount: number;
31
+ public dragMouseLeave: boolean;
32
+ public tooltipPositionX: number;
33
+ public isMouseDragged: boolean = false;
34
+ private falseLine: HTMLElement;
35
+ public connectorSecondElement: Element;
36
+ public connectorSecondRecord: IGanttData;
37
+ public connectorSecondAction: string;
38
+ public fromPredecessorText: string;
39
+ public toPredecessorText: string;
40
+ public finalPredecessor: string;
41
+ public dependencyCancel: boolean = false;
42
+ public drawPredecessor: boolean;
43
+ private highlightedSecondElement: Element;
44
+ private editTooltip: EditTooltip;
45
+ private canDrag: boolean;
46
+ /** @private */
47
+ public tapPointOnFocus: boolean;
48
+ private editElement: Element = null;
49
+ public touchEdit: boolean;
50
+ private prevZIndex: string;
51
+ private previousMouseMove: number;
52
+ private elementOffsetLeft: number = 0;
53
+ private elementOffsetTop: number = 0;
54
+ private elementOffsetWidth: number = 0;
55
+ private elementOffsetHeight: number = 0;
56
+ public segmentIndex: number = -1;
57
+ private targetElement: Element;
58
+
59
+ constructor(ganttObj?: Gantt) {
60
+ super(ganttObj);
61
+ this.parent = ganttObj;
62
+ this.initPublicProp();
63
+ this.wireEvents();
64
+ this.editTooltip = new EditTooltip(this.parent, this);
65
+ }
66
+
67
+ private wireEvents(): void {
68
+ this.parent.on('chartMouseDown', this.mouseDownHandler, this);
69
+ this.parent.on('chartMouseUp', this.mouseUpHandler, this);
70
+ this.parent.on('chartMouseLeave', this.mouseLeaveHandler, this);
71
+ this.parent.on('chartMouseMove', this.mouseMoveAction, this);
72
+ this.parent.on('chartMouseClick', this.mouseClickHandler, this);
73
+ }
74
+
75
+ /**
76
+ * To initialize the public property.
77
+ *
78
+ * @returns {void} .
79
+ * @private
80
+ */
81
+ private initPublicProp(): void {
82
+ this.taskBarEditElement = null;
83
+ this.taskBarEditRecord = null;
84
+ this.taskBarEditAction = null;
85
+ this.connectorSecondElement = null;
86
+ this.connectorSecondRecord = null;
87
+ this.connectorSecondAction = null;
88
+ this.highlightedSecondElement = null;
89
+ this.fromPredecessorText = null;
90
+ this.toPredecessorText = null;
91
+ this.finalPredecessor = null;
92
+ this.drawPredecessor = false;
93
+ this.roundOffDuration = true;
94
+ this.dragMouseLeave = false;
95
+ this.isMouseDragged = false;
96
+ this.previousItemProperty = ['left', 'progress', 'duration', 'isMilestone', 'startDate', 'endDate', 'width', 'progressWidth',
97
+ 'autoLeft', 'autoDuration', 'autoStartDate', 'autoEndDate', 'autoWidth', 'segments'];
98
+ this.tapPointOnFocus = false;
99
+ this.touchEdit = false;
100
+ }
101
+
102
+ private mouseDownHandler(e: PointerEvent): void {
103
+ if (this.parent.editSettings.allowTaskbarEditing && !this.parent.readOnly) {
104
+ this.canDrag = false;
105
+ if (this.parent.isAdaptive && this.taskBarEditElement) {
106
+ const targetElement: Element = this.getElementByPosition(e);
107
+ const element: Element = parentsUntil(targetElement, cls.taskBarMainContainer);
108
+ if (element && element.innerHTML === this.taskBarEditElement.innerHTML &&
109
+ !(targetElement.classList.contains(cls.connectorPointLeft) ||
110
+ targetElement.classList.contains(cls.connectorPointRight)) &&
111
+ !this.tapPointOnFocus) {
112
+ this.updateTaskBarEditElement(e);
113
+ this.canDrag = true;
114
+ e.preventDefault();
115
+ }
116
+ } else if (!this.parent.isAdaptive) {
117
+ this.updateTaskBarEditElement(e);
118
+ }
119
+ }
120
+ }
121
+
122
+ private mouseClickHandler(e: PointerEvent): void {
123
+ const targetElement: Element = this.getElementByPosition(e);
124
+ const element: Element = parentsUntil(targetElement, cls.taskBarMainContainer);
125
+ if (this.parent.selectionModule && this.parent.selectionModule.enableSelectMultiTouch) {
126
+ if (this.tapPointOnFocus) {
127
+ this.updateTaskBarEditElement(e);
128
+ }
129
+ return;
130
+ }
131
+ if (this.tapPointOnFocus && element && element.innerHTML !== this.taskBarEditElement.innerHTML) {
132
+ this.connectorSecondRecord = this.parent.ganttChartModule.getRecordByTaskBar(element);
133
+ this.connectorSecondAction = 'ConnectorPointLeftDrag';
134
+ this.connectorSecondElement = element;
135
+ this.fromPredecessorText = 'Finish';
136
+ if (this.validateConnectorPoint()) {
137
+ this.taskBarEditingAction(e, true);
138
+ }
139
+ this.showHideActivePredecessors(false);
140
+ this.initPublicProp();
141
+ } else if (targetElement.classList.contains(cls.connectorPointLeftHover) ||
142
+ targetElement.classList.contains(cls.connectorPointRightHover)) {
143
+ this.canDrag = false;
144
+ this.multipleSelectionEnabled();
145
+ this.showHideTaskBarEditingElements(targetElement, this.taskBarEditElement);
146
+ this.tapPointOnFocus = true;
147
+ this.taskBarEditAction = 'ConnectorPointRightDrag';
148
+ this.connectorSecondRecord = this.taskBarEditRecord;
149
+ this.taskBarEditingAction(e, false);
150
+ } else {
151
+ if (this.tapPointOnFocus) {
152
+ this.showHideActivePredecessors(false);
153
+ this.showHideTaskBarEditingElements(element, this.taskBarEditElement);
154
+ }
155
+ this.updateTaskBarEditElement(e);
156
+ }
157
+ }
158
+
159
+ private showHideActivePredecessors(show: boolean): void {
160
+ const ganttProp: ITaskData = this.taskBarEditRecord.ganttProperties;
161
+ const predecessors: IPredecessor[] = ganttProp.predecessor;
162
+ const id: string = this.parent.viewType === 'ResourceView' ? ganttProp.taskId : ganttProp.rowUniqueID;
163
+ if (predecessors) {
164
+ for (let i: number = 0; i < predecessors.length; i++) {
165
+ const predecessor: IPredecessor = predecessors[i];
166
+ if (id.toString() === predecessor.from || id.toString() === predecessor.to) {
167
+ this.applyActiveColor(predecessor.from, predecessor.to, show);
168
+ }
169
+ }
170
+ }
171
+ const chartContent: Element = this.parent.ganttChartModule.chartBodyContainer;
172
+ if (show) {
173
+ addClass([this.taskBarEditElement], [cls.activeChildTask]);
174
+ addClass([chartContent], [cls.touchMode]);
175
+ } else {
176
+ removeClass([this.taskBarEditElement], [cls.activeChildTask]);
177
+ removeClass([chartContent], [cls.touchMode]);
178
+ }
179
+ this.touchEdit = show;
180
+ if (!isNullOrUndefined(this.parent.toolbarModule)) {
181
+ this.parent.toolbarModule.refreshToolbarItems();
182
+ }
183
+ }
184
+ private applyActiveColor(from: string, to: string, enable?: boolean): void {
185
+ const taskId: string = this.parent.viewType === 'ProjectView' ? this.taskBarEditRecord.ganttProperties.taskId.toString() :
186
+ this.taskBarEditRecord.ganttProperties.rowUniqueID.toString();
187
+ const ganttRecord: IGanttData = (taskId === from) ? this.parent.connectorLineModule.getRecordByID(to) :
188
+ this.parent.connectorLineModule.getRecordByID(from);
189
+ const $tr: Element = this.parent.ganttChartModule.getChartRows()[this.parent.currentViewData.indexOf(ganttRecord)];
190
+ if (!isNullOrUndefined($tr)) {
191
+ const $taskbar: Element = $tr.querySelector('.' + cls.taskBarMainContainer);
192
+ const $connectorElement: Element = this.parent.element.querySelector('#ConnectorLineparent' + from + 'child' + to);
193
+ if (enable) {
194
+ addClass([$taskbar], [cls.activeConnectedTask]);
195
+ if ($connectorElement) {
196
+ addClass([$connectorElement], [cls.activeConnectedTask]);
197
+ }
198
+ } else {
199
+ removeClass([$taskbar], [cls.activeConnectedTask]);
200
+ if ($connectorElement) {
201
+ removeClass([$connectorElement], [cls.activeConnectedTask]);
202
+ }
203
+ }
204
+ }
205
+ }
206
+
207
+ private validateConnectorPoint(): boolean {
208
+ const parentRecord: ITaskData = this.taskBarEditRecord.ganttProperties;
209
+ const childRecord: ITaskData = this.connectorSecondRecord.ganttProperties;
210
+ let isValid: boolean = true;
211
+ const parentId: string = this.parent.viewType === 'ResourceView' ? parentRecord.taskId : parentRecord.rowUniqueID;
212
+ const childId: string = this.parent.viewType === 'ResourceView' ? childRecord.taskId : childRecord.rowUniqueID;
213
+ if (this.connectorSecondRecord.hasChildRecords) {
214
+ isValid = false;
215
+ } else if (childRecord.predecessor) {
216
+ for (let i: number = 0; i < childRecord.predecessor.length; i++) {
217
+ const predecessor: IPredecessor = childRecord.predecessor[i];
218
+ if (predecessor.from === parentId.toString() &&
219
+ predecessor.to === childId.toString()) {
220
+ this.parent.connectorLineEditModule.childRecord = this.connectorSecondRecord;
221
+ this.parent.connectorLineEditModule.predecessorIndex = i;
222
+ this.parent.connectorLineEditModule.renderPredecessorDeleteConfirmDialog();
223
+ isValid = false;
224
+ break;
225
+ } else if (predecessor.from === childId.toString() &&
226
+ predecessor.to === parentId.toString()) {
227
+ this.parent.connectorLineEditModule.childRecord = this.taskBarEditRecord;
228
+ this.parent.connectorLineEditModule.predecessorIndex = i;
229
+ this.parent.connectorLineEditModule.renderPredecessorDeleteConfirmDialog();
230
+ isValid = false;
231
+ break;
232
+ }
233
+ }
234
+ }
235
+ return isValid;
236
+ }
237
+ // eslint-disable-next-line
238
+ private mouseLeaveHandler(e: PointerEvent): void {
239
+ this.dragMouseLeave = true;
240
+ }
241
+
242
+ /**
243
+ * To update taskbar edited elements on mouse down action.
244
+ *
245
+ * @param {PointerEvent} e .
246
+ * @returns {void} .
247
+ * @private
248
+ */
249
+ public updateTaskBarEditElement(e: PointerEvent): void {
250
+ const target: Element = this.getElementByPosition(e);
251
+ let element: Element;
252
+ if (target.classList.contains(cls.manualParentRightResizer) || target.classList.contains(cls.manualParentMainContainer)
253
+ || target.classList.contains(cls.manualParentTaskBar)) {
254
+ element = parentsUntil(target, cls.manualParentMainContainer);
255
+ } else if (target.classList.contains(cls.manualParentMilestoneTop) || target.classList.contains(cls.manualParentMilestoneBottom)
256
+ || target.classList.contains(cls.manualParentMilestone)) {
257
+ element = parentsUntil(target, cls.manualParentMilestone);
258
+ } else {
259
+ element = parentsUntil(target, cls.taskBarMainContainer);
260
+ if (!isNullOrUndefined(element) && !target.classList.contains('e-connectorpoint-left') &&
261
+ !target.classList.contains('e-connectorpoint-right')) {
262
+ const currentRecord: IGanttData = this.parent.ganttChartModule.getRecordByTaskBar(element);
263
+ if (!isNullOrUndefined(currentRecord.ganttProperties.segments) && currentRecord.ganttProperties.segments.length > 0) {
264
+ element = parentsUntil(target, cls.childTaskBarInnerDiv);
265
+ }
266
+ }
267
+ }
268
+ if (this.parent.editSettings.allowTaskbarEditing && element) {
269
+ this.showHideTaskBarEditingElements(element, this.taskBarEditElement);
270
+ this.editElement = element;
271
+ this.taskBarEditElement = element as HTMLElement;
272
+ const index: string = this.taskBarEditElement.getAttribute('data-segment-index');
273
+ if (!isNullOrUndefined(index)) {
274
+ this.segmentIndex = Number(index);
275
+ } else {
276
+ this.segmentIndex = -1;
277
+ }
278
+ this.taskBarEditRecord = this.parent.ganttChartModule.getRecordByTaskBar(this.taskBarEditElement);
279
+ if (e.type === 'mousedown' || e.type === 'touchstart' || e.type === 'click') {
280
+ this.roundOffDuration = true;
281
+ this.taskBarEditAction = this.getTaskBarAction(e);
282
+ if ((this.taskBarEditAction === 'ConnectorPointLeftDrag' || this.taskBarEditAction === 'ConnectorPointRightDrag') &&
283
+ isNullOrUndefined(this.parent.taskFields.dependency)) {
284
+ this.taskBarEditAction = null;
285
+ }
286
+ this.updateMouseDownProperties(e);
287
+ if (this.parent.viewType === 'ResourceView') {
288
+ if (this.taskBarEditRecord.level === 0) {
289
+ return;
290
+ } else if (this.parent.enableMultiTaskbar) {
291
+ const parentRecord: IGanttData = this.parent.getTaskByUniqueID(this.taskBarEditRecord.parentItem.uniqueID);
292
+ if (!isNullOrUndefined(parentRecord) && !parentRecord.expanded) {
293
+ this.prevZIndex = (this.taskBarEditElement).style.zIndex;
294
+ (this.taskBarEditElement).style.zIndex = '1000';
295
+ addClass([this.taskBarEditElement.querySelector('.e-gantt-child-taskbar')], 'e-collapsed-taskbar-drag');
296
+ }
297
+ }
298
+ }
299
+ }
300
+ } else {
301
+ if (this.parent.isAdaptive) {
302
+ if (this.taskBarEditElement) {
303
+ this.showHideTaskBarEditingElements(element, this.taskBarEditElement);
304
+ }
305
+ this.initPublicProp();
306
+ } else {
307
+ this.showHideTaskBarEditingElements(element, this.taskBarEditElement);
308
+ }
309
+ }
310
+ }
311
+
312
+ /**
313
+ * To show/hide taskbar editing elements.
314
+ *
315
+ * @param {Element} element .
316
+ * @param {Element} secondElement .
317
+ * @param {boolean} fadeConnectorLine .
318
+ * @returns {void} .
319
+ * @private
320
+ */
321
+ public showHideTaskBarEditingElements(element: Element, secondElement: Element, fadeConnectorLine?: boolean): void {
322
+ secondElement = secondElement ? secondElement : this.editElement;
323
+ let isShowProgressResizer: boolean = this.parent.taskFields.progress ? true : false;
324
+ let isShowConnectorPoints: boolean = true;
325
+ if (this.parent.readOnly) {
326
+ return;
327
+ }
328
+ if (this.parent.viewType === 'ResourceView' && this.parent.enableMultiTaskbar && element) {
329
+ const record: IGanttData = this.parent.ganttChartModule.getRecordByTaskBar(element);
330
+ const parentRecord: IGanttData = this.parent.getParentTask(record.parentItem);
331
+ if (!isNullOrUndefined(parentRecord)) {
332
+ if (!parentRecord.expanded) {
333
+ isShowProgressResizer = false;
334
+ isShowConnectorPoints = false;
335
+ }
336
+ }
337
+ }
338
+ if (element) {
339
+ if (element.querySelector('.' + cls.taskBarLeftResizer)) {
340
+ addClass([element.querySelector('.' + cls.taskBarLeftResizer)], [cls.leftResizeGripper]);
341
+ addClass([element.querySelector('.' + cls.taskBarRightResizer)], [cls.rightResizeGripper]);
342
+ if (isShowProgressResizer) {
343
+ const progresElement: boolean = !isNullOrUndefined(element.querySelector('.' + cls.childProgressResizer)) ? true : false;
344
+ if (progresElement) {
345
+ addClass([element.querySelector('.' + cls.childProgressResizer)], [cls.progressResizeGripper]);
346
+ }
347
+ }
348
+ } else if (this.parent.isAdaptive && isShowProgressResizer) {
349
+ const record: IGanttData = this.parent.ganttChartModule.getRecordByTaskBar(element);
350
+ if (record.hasChildRecords) {
351
+ addClass([element], [cls.activeParentTask]);
352
+ }
353
+ }
354
+ if (isShowProgressResizer) {
355
+ addClass(
356
+ this.parent.ganttChartModule.scrollElement.querySelectorAll('.' + cls.connectorLineContainer), [cls.connectorLineZIndex]);
357
+ }
358
+ if (!isNullOrUndefined(this.parent.taskFields.dependency)
359
+ && (element.querySelector('.' + cls.connectorPointLeft)
360
+ || element.parentElement.querySelector('.' + cls.connectorPointLeft))
361
+ && isShowConnectorPoints) {
362
+ const connectorElement: Element = !isNullOrUndefined(element.querySelector('.' + cls.connectorPointLeft)) ?
363
+ element : element.parentElement;
364
+
365
+ addClass(
366
+ [connectorElement.querySelector('.' + cls.connectorPointLeft)], [cls.connectorPointLeftHover]);
367
+ addClass(
368
+ [connectorElement.querySelector('.' + cls.connectorPointRight)], [cls.connectorPointRightHover]);
369
+ }
370
+ } else if (!fadeConnectorLine) {
371
+ removeClass(
372
+ this.parent.ganttChartModule.scrollElement.querySelectorAll('.' + cls.connectorLineContainer), [cls.connectorLineZIndex]);
373
+ }
374
+ if (secondElement && element !== secondElement) {
375
+ if (secondElement.querySelector('.' + cls.taskBarLeftResizer)) {
376
+ removeClass([secondElement.querySelector('.' + cls.taskBarLeftResizer)], [cls.leftResizeGripper]);
377
+ removeClass([secondElement.querySelector('.' + cls.taskBarRightResizer)], [cls.rightResizeGripper]);
378
+ if (secondElement.querySelector('.' + cls.childProgressResizer)) {
379
+ removeClass([secondElement.querySelector('.' + cls.childProgressResizer)], [cls.progressResizeGripper]);
380
+ }
381
+ }
382
+ if (!isNullOrUndefined(this.parent.taskFields.dependency)
383
+ && (secondElement.querySelector('.' + cls.connectorPointLeft)
384
+ || secondElement.parentElement.querySelector('.' + cls.connectorPointLeft))) {
385
+ const connectorElement: Element = !isNullOrUndefined(secondElement.querySelector('.' + cls.connectorPointLeft)) ?
386
+ secondElement : secondElement.parentElement;
387
+ removeClass(
388
+ [connectorElement.querySelector('.' + cls.connectorPointLeft)], [cls.connectorPointLeftHover]);
389
+ removeClass(
390
+ [connectorElement.querySelector('.' + cls.connectorPointRight)], [cls.connectorPointRightHover]);
391
+ } else if (this.parent.isAdaptive) {
392
+ const record: IGanttData = this.parent.ganttChartModule.getRecordByTaskBar(secondElement);
393
+ if (record && record.hasChildRecords) {
394
+ removeClass([secondElement], [cls.activeParentTask]);
395
+ }
396
+ }
397
+ this.editElement = null;
398
+ }
399
+ }
400
+
401
+ /**
402
+ * To get taskbar edit actions.
403
+ *
404
+ * @param {PointerEvent} e .
405
+ * @returns {string} .
406
+ * @private
407
+ */
408
+ private getTaskBarAction(e: PointerEvent): string {
409
+ const mouseDownElement: Element = this.getElementByPosition(e);
410
+ const data: IGanttData = this.taskBarEditRecord;
411
+ let action: string = '';
412
+ if (mouseDownElement.classList.contains(cls.taskBarLeftResizer)) {
413
+ action = 'LeftResizing';
414
+ } else if (mouseDownElement.classList.contains(cls.taskBarRightResizer)) {
415
+ action = 'RightResizing';
416
+ } else if ((mouseDownElement.classList.contains(cls.childProgressResizer) ||
417
+ closest(mouseDownElement, '.' + cls.childProgressResizer)) && (this.parent.taskFields.progress)) {
418
+ action = 'ProgressResizing';
419
+ } else if (mouseDownElement.classList.contains(cls.connectorPointLeft)) {
420
+ action = 'ConnectorPointLeftDrag';
421
+ } else if (mouseDownElement.classList.contains(cls.connectorPointRight)) {
422
+ action = 'ConnectorPointRightDrag';
423
+ } else if (mouseDownElement.classList.contains(cls.manualParentRightResizer)) {
424
+ action = 'ParentResizing';
425
+ } else if (mouseDownElement.classList.contains(cls.manualParentTaskBar) ||
426
+ mouseDownElement.classList.contains(cls.manualParentMainContainer) ||
427
+ mouseDownElement.classList.contains(cls.manualParentMilestone) ||
428
+ mouseDownElement.classList.contains(cls.manualParentMilestoneTop) ||
429
+ mouseDownElement.classList.contains(cls.manualParentMilestoneBottom) ||
430
+ mouseDownElement.classList.contains(cls.manualParentMilestone)
431
+ ) {
432
+ action = 'ManualParentDrag';
433
+ } else if (data) {
434
+ action = data.hasChildRecords ? this.parent.taskMode === 'Auto' ? 'ParentDrag' : ''
435
+ : data.ganttProperties.isMilestone ? 'MilestoneDrag' : 'ChildDrag';
436
+ }
437
+ return action;
438
+ }
439
+
440
+ /**
441
+ * To update property while perform mouse down.
442
+ *
443
+ * @param {PointerEvent} event .
444
+ * @returns {void} .
445
+ * @private
446
+ */
447
+ private updateMouseDownProperties(event: PointerEvent): void {
448
+ const e: MousePoint = this.getCoordinate(event);
449
+ if (e.pageX || e.pageY) {
450
+ const containerPosition: { top: number, left: number } =
451
+ this.parent.getOffsetRect(this.parent.ganttChartModule.chartBodyContainer);
452
+ this.mouseDownX = (e.pageX - containerPosition.left) +
453
+ this.parent.ganttChartModule.scrollObject.previousScroll.left;
454
+ this.tooltipPositionX = this.mouseDownX;
455
+ this.mouseDownY = e.pageY - containerPosition.top +
456
+ this.parent.ganttChartModule.scrollObject.previousScroll.top;
457
+ }
458
+ if (this.taskBarEditAction === 'ConnectorPointLeftDrag' || this.taskBarEditAction === 'ConnectorPointRightDrag') {
459
+ this.fromPredecessorText = this.taskBarEditAction === 'ConnectorPointLeftDrag' ? 'start' : 'finish';
460
+ this.parent.connectorLineModule.tooltipTable.innerHTML = this.parent.connectorLineModule.getConnectorLineTooltipInnerTd(
461
+ this.taskBarEditRecord.ganttProperties.taskName,
462
+ this.fromPredecessorText, '', ''
463
+ );
464
+ }
465
+ }
466
+ private isMouseDragCheck(): void {
467
+ if (!this.isMouseDragged && this.taskBarEditAction && ((this.mouseDownX !== this.mouseMoveX) &&
468
+ ((this.mouseDownX + 3) < this.mouseMoveX || (this.mouseDownX - 3) > this.mouseMoveX)
469
+ || (this.mouseDownY !== this.mouseMoveY) &&
470
+ ((this.mouseDownY + 3) < this.mouseMoveY || (this.mouseDownY - 3) > this.mouseMoveY))) {
471
+ this.isMouseDragged = true;
472
+ this.parent.initiateEditAction(true);
473
+ const item: ITaskData = this.taskBarEditRecord.ganttProperties;
474
+ this.previousItem = this.parent.timelineModule.extendFunction(item, this.previousItemProperty) as ITaskData;
475
+ if (this.taskBarEditAction !== 'ConnectorPointLeftDrag' &&
476
+ this.taskBarEditAction !== 'ConnectorPointRightDrag') {
477
+ this.editTooltip.showHideTaskbarEditTooltip(true, this.segmentIndex);
478
+ }
479
+ this.taskBarEditElement.setAttribute('aria-grabbed', 'true');
480
+ }
481
+ }
482
+ /**
483
+ * To handle mouse move action in chart
484
+ *
485
+ * @param {PointerEvent} event .
486
+ * @returns {void} .
487
+ * @private
488
+ */
489
+ public mouseMoveAction(event: PointerEvent): void {
490
+ if (this.parent.isAdaptive) {
491
+ if (!this.canDrag) {
492
+ return;
493
+ } else {
494
+ this.multipleSelectionEnabled();
495
+ }
496
+ }
497
+ const containerPosition: { top: number, left: number } =
498
+ this.parent.getOffsetRect(this.parent.ganttChartModule.chartBodyContainer);
499
+ const e: MousePoint = this.getCoordinate(event);
500
+ this.mouseMoveX = e.pageX - containerPosition.left +
501
+ this.parent.ganttChartModule.scrollObject.previousScroll.left;
502
+ this.mouseMoveY = e.pageY - containerPosition.top +
503
+ this.parent.ganttChartModule.scrollObject.previousScroll.top;
504
+ this.dragMouseLeave = false;
505
+ this.isMouseDragCheck();
506
+ if (this.isMouseDragged && this.taskBarEditAction) {
507
+ const args: IActionBeginEventArgs = {
508
+ cancel: false,
509
+ requestType: 'taskbarediting',
510
+ taskBarEditAction: this.taskBarEditAction,
511
+ data: this.taskBarEditRecord
512
+ };
513
+ if(this.segmentIndex !== -1) {
514
+ args.requestType = 'mergeSegment'
515
+ }
516
+ this.parent.trigger('actionBegin', args, (arg: IActionBeginEventArgs) => {
517
+ if (arg.cancel === false) {
518
+ this.taskBarEditingAction(event, false);
519
+ }
520
+ });
521
+ } else if (!this.parent.isAdaptive && !this.taskBarEditAction) {
522
+ this.updateTaskBarEditElement(event);
523
+ }
524
+ }
525
+ /**
526
+ * Method to update taskbar editing action on mous move.
527
+ *
528
+ * @param {PointerEvent} e .
529
+ * @param {boolean} isMouseClick .
530
+ * @returns {void} .
531
+ * @private
532
+ */
533
+ public taskBarEditingAction(e: PointerEvent, isMouseClick: boolean): void {
534
+ const args: ITaskbarEditedEventArgs = {} as ITaskbarEditedEventArgs;
535
+ const recordIndex: number = this.parent.ganttChartModule.getIndexByTaskBar(this.taskBarEditElement);
536
+ if (this.taskBarEditRecord !== null) {
537
+ args.editingFields = this.taskBarEditRecord.ganttProperties;
538
+ args.data = this.taskBarEditRecord;
539
+ if (this.parent.viewType === 'ResourceView' && args.data.level === 0) {
540
+ return;
541
+ }
542
+ args.recordIndex = recordIndex;
543
+ args.taskBarEditAction = this.taskBarEditAction;
544
+ args.roundOffDuration = this.roundOffDuration;
545
+ args.cancel = false;
546
+ args.previousData = this.previousItem;
547
+ args.segmentIndex = this.segmentIndex;
548
+ this.roundOffDuration = args.roundOffDuration;
549
+ this.targetElement = args.target = closest((e.target as Element), '.e-gantt-child-taskbar');
550
+ this.updateMouseMoveProperties(e);
551
+ if (this.taskBarEditAction === 'ProgressResizing') {
552
+ this.performProgressResize(e);
553
+ } else if (this.taskBarEditAction === 'LeftResizing') {
554
+ this.enableLeftResizing(e);
555
+ } else if (this.taskBarEditAction === 'RightResizing' || this.taskBarEditAction === 'ParentResizing') {
556
+ this.enableRightResizing(e);
557
+ } else if (this.taskBarEditAction === 'ParentDrag' || this.taskBarEditAction === 'ChildDrag' ||
558
+ this.taskBarEditAction === 'MilestoneDrag' || this.taskBarEditAction === 'ManualParentDrag') {
559
+ this.enableDragging(e);
560
+ } else if (this.taskBarEditAction === 'ConnectorPointLeftDrag' ||
561
+ this.taskBarEditAction === 'ConnectorPointRightDrag') {
562
+ this.updateConnectorLineSecondProperties(e);
563
+ this.triggerDependencyEvent(e);
564
+ if (!this.parent.isAdaptive) {
565
+ this.drawFalseLine();
566
+ }
567
+ }
568
+ this.setItemPosition();
569
+ this.updateEditedItem();
570
+ this.editTooltip.updateTooltip(this.segmentIndex);
571
+ if (isMouseClick) {
572
+ this.taskBarEditedAction(e);
573
+ }
574
+ this.parent.trigger('taskbarEditing', args, (arg: ITaskbarEditedEventArgs) => {
575
+ if (arg.cancel && this.taskBarEditRecord !== null) {
576
+ this.tapPointOnFocus = false;
577
+ merge(this.taskBarEditRecord.ganttProperties, arg.previousData);
578
+ }
579
+
580
+ });
581
+ }
582
+ }
583
+
584
+ /**
585
+ * To update property while perform mouse move.
586
+ *
587
+ * @param {PointerEvent} event .
588
+ * @returns {void} .
589
+ * @private
590
+ */
591
+ private updateMouseMoveProperties(event: PointerEvent): void {
592
+ const containerPosition: { top: number, left: number } =
593
+ this.parent.getOffsetRect(this.parent.ganttChartModule.chartBodyContainer);
594
+ const e: MousePoint = this.getCoordinate(event);
595
+ if (e.pageX || e.pageY) {
596
+ this.mouseMoveX = e.pageX - containerPosition.left +
597
+ this.parent.ganttChartModule.scrollObject.previousScroll.left;
598
+ this.tooltipPositionX = this.mouseMoveX;
599
+ this.mouseMoveY = e.pageY - containerPosition.top +
600
+ this.parent.ganttChartModule.scrollObject.previousScroll.top;
601
+ }
602
+ const isConnectorLineEdit: boolean = (this.taskBarEditAction === 'ConnectorPointLeftDrag' ||
603
+ this.taskBarEditAction === 'ConnectorPointRightDrag') ?
604
+ true : false;
605
+ if ((this.taskBarEditRecord.ganttProperties.width > 3 && !(this.taskBarEditAction === 'ProgressResizing' &&
606
+ (this.taskBarEditRecord.ganttProperties.progress === 0 || this.taskBarEditRecord.ganttProperties.progress === 100))) ||
607
+ isConnectorLineEdit) {
608
+ const mouseX: number = this.mouseMoveX - this.parent.ganttChartModule.scrollObject.previousScroll.left +
609
+ containerPosition.left;
610
+ const mouseY: number = this.mouseMoveY - this.parent.ganttChartModule.scrollObject.previousScroll.top +
611
+ containerPosition.top;
612
+ if ((mouseX + 20) >
613
+ containerPosition.left + this.parent.ganttChartModule.chartBodyContainer.offsetWidth) {
614
+ this.timerCount = this.parent.ganttChartModule.scrollObject.previousScroll.left;
615
+ this.startScrollTimer('right');
616
+ } else if ((mouseX - 20) < containerPosition.left) {
617
+ this.timerCount = this.parent.ganttChartModule.scrollObject.previousScroll.left;
618
+ this.startScrollTimer('left');
619
+ } else if (isConnectorLineEdit && ((mouseY + 20) >
620
+ containerPosition.top + this.parent.ganttChartModule.chartBodyContainer.offsetHeight)) {
621
+ this.timerCount = this.parent.ganttChartModule.scrollObject.previousScroll.top;
622
+ this.startScrollTimer('bottom');
623
+ } else if (isConnectorLineEdit && ((mouseY - 20) < containerPosition.top)) {
624
+ this.timerCount = this.parent.ganttChartModule.scrollObject.previousScroll.top;
625
+ this.startScrollTimer('top');
626
+ } else {
627
+ this.stopScrollTimer();
628
+ }
629
+ } else {
630
+ this.stopScrollTimer();
631
+ }
632
+ }
633
+
634
+ /**
635
+ * To start the scroll timer.
636
+ *
637
+ * @param {string} direction .
638
+ * @returns {void} .
639
+ * @private
640
+ */
641
+ public startScrollTimer(direction: string): void {
642
+ this.stopScrollTimer();
643
+ this.scrollTimer = window.setInterval(
644
+ () => {
645
+ if (direction === 'right' || direction === 'bottom') {
646
+ this.timerCount = (this.timerCount + 1) >= this.parent.timelineModule.totalTimelineWidth ?
647
+ this.parent.timelineModule.totalTimelineWidth : (this.timerCount + 1);
648
+ } else {
649
+ this.timerCount = (this.timerCount - 1) < 0 ? 0 : (this.timerCount - 1);
650
+ }
651
+ if (direction === 'bottom' || direction === 'top') {
652
+ this.parent.ganttChartModule.scrollObject.setScrollTop(this.timerCount);
653
+ } else {
654
+ this.parent.ganttChartModule.scrollObject.setScrollLeft(this.timerCount);
655
+ }
656
+ if (this.taskBarEditAction === 'ConnectorPointLeftDrag'
657
+ || this.taskBarEditAction === 'ConnectorPointRightDrag') {
658
+ this.drawFalseLine();
659
+ }
660
+ },
661
+ 0);
662
+ }
663
+
664
+ /**
665
+ * To stop the scroll timer.
666
+ *
667
+ * @returns {void} .
668
+ * @private
669
+ */
670
+ public stopScrollTimer(): void {
671
+ window.clearInterval(this.scrollTimer);
672
+ this.scrollTimer = null;
673
+ }
674
+
675
+ /**
676
+ * To update left and width while perform taskbar drag operation.
677
+ *
678
+ * @param {PointerEvent} e .
679
+ * @returns {void} .
680
+ * @private
681
+ */
682
+ // eslint-disable-next-line
683
+ private enableDragging(e: PointerEvent): void {
684
+ const item: ITaskData = this.taskBarEditRecord.ganttProperties;
685
+ let differenceWidth: number = 0;
686
+ if (this.taskBarEditElement.classList.contains('e-segmented-taskbar') &&
687
+ !this.taskBarEditElement.classList.contains('e-segment-first')) {
688
+ const segments: ITaskSegment[] = this.taskBarEditRecord.ganttProperties.segments.map((e: ITaskSegment) => ({ ...e }));
689
+ const segment: ITaskSegment = segments[this.segmentIndex];
690
+ if (this.mouseDownX > this.mouseMoveX) {
691
+ differenceWidth = isNullOrUndefined(this.previousMouseMove) ?
692
+ (this.mouseDownX - this.mouseMoveX) : (this.previousMouseMove - this.mouseMoveX);
693
+ this.previousMouseMove = this.mouseMoveX;
694
+ segment.left = segment.left - differenceWidth;
695
+ } else {
696
+ differenceWidth = isNullOrUndefined(this.previousMouseMove) ?
697
+ (this.mouseMoveX - this.mouseDownX) : (this.mouseMoveX - this.previousMouseMove);
698
+ this.previousMouseMove = this.mouseMoveX;
699
+ segment.left = segment.left + differenceWidth;
700
+ }
701
+ const previousSegment: ITaskSegment = segments[this.segmentIndex - 1];
702
+ const nextSegment: ITaskSegment = segments[this.segmentIndex + 1];
703
+ let left: number;
704
+ if (this.taskBarEditElement.classList.contains('e-segment-inprogress')) {
705
+ left = segment.left < (previousSegment.left + previousSegment.width) ? (previousSegment.left + previousSegment.width) :
706
+ ((segment.width + segment.left) > (nextSegment.left)) ? nextSegment.left - segment.width : segment.left;
707
+ } else {
708
+ left = segment.left < (previousSegment.left + previousSegment.width) ? (previousSegment.left + previousSegment.width) :
709
+ (item.left + segment.width + segment.left) >= this.parent.timelineModule.totalTimelineWidth ?
710
+ (this.parent.timelineModule.totalTimelineWidth - segment.width) : segment.left;
711
+ }
712
+ segment.left = left;
713
+ this.parent.setRecordValue('segments', segments, item, true);
714
+ this.parent.dataOperation.updateMappingData(this.taskBarEditRecord, 'segments');
715
+ } else {
716
+ if (this.mouseDownX > this.mouseMoveX) {
717
+ differenceWidth = this.mouseDownX - this.mouseMoveX;
718
+ if (differenceWidth > 0) {
719
+ this.parent.setRecordValue('left', this.previousItem.left - differenceWidth, item, true);
720
+ }
721
+ } else {
722
+ differenceWidth = this.mouseMoveX - this.mouseDownX;
723
+ this.parent.setRecordValue('left', this.previousItem.left + differenceWidth, item, true);
724
+ }
725
+ const left: number = item.left < 0 ? 0 : (item.left + item.width) >= this.parent.timelineModule.totalTimelineWidth ?
726
+ (this.parent.timelineModule.totalTimelineWidth - item.width) : item.left;
727
+ this.parent.setRecordValue('left', left, item, true);
728
+ }
729
+ }
730
+
731
+ /**
732
+ * To update left and width while perform progress resize operation.
733
+ *
734
+ * @param {PointerEvent} e .
735
+ * @returns {void} .
736
+ * @private
737
+ */
738
+ // eslint-disable-next-line
739
+ private performProgressResize(e: PointerEvent): void {
740
+ const item: ITaskData = this.taskBarEditRecord.ganttProperties;
741
+ let diffrenceWidth: number = 0;
742
+ if (this.mouseDownX > this.mouseMoveX) {
743
+ if (this.mouseMoveX > item.left &&
744
+ (this.mouseMoveX < (item.left + item.width)) && item.left > 0) {
745
+ diffrenceWidth = this.mouseMoveX - item.left;
746
+ this.parent.setRecordValue('progressWidth', diffrenceWidth, item, true);
747
+ } else {
748
+ if (this.mouseMoveX >= (item.left + item.width)) {
749
+ this.parent.setRecordValue('progressWidth', item.width, item, true);
750
+ } else {
751
+ this.parent.setRecordValue('progressWidth', 0, item, true);
752
+ }
753
+ }
754
+ } else {
755
+ if (this.mouseMoveX > item.left &&
756
+ (this.mouseMoveX < (item.left + item.width))) {
757
+ diffrenceWidth = this.mouseMoveX - item.left;
758
+ this.parent.setRecordValue('progressWidth', diffrenceWidth, item, true);
759
+ } else {
760
+ if (this.mouseMoveX <= item.left) {
761
+ this.parent.setRecordValue('progressWidth', 0, item, true);
762
+ } else {
763
+ this.parent.setRecordValue('progressWidth', item.width, item, true);
764
+ }
765
+ }
766
+ }
767
+ let widthValue: number = item.progressWidth > item.width ?
768
+ item.width : item.progressWidth;
769
+ widthValue = item.progressWidth < 0 ? 0 : item.progressWidth;
770
+ this.parent.setRecordValue('progressWidth', widthValue, item, true);
771
+ const diff: number = item.width - item.progressWidth;
772
+ if (diff <= 4) {
773
+ this.progressBorderRadius = 4 - diff;
774
+ } else {
775
+ this.progressBorderRadius = 0;
776
+ }
777
+ }
778
+
779
+ /**
780
+ * To update left and width while perform taskbar left resize operation.
781
+ *
782
+ * @param {PointerEvent} e .
783
+ * @returns {void} .
784
+ * @private
785
+ */
786
+ private enableLeftResizing(e: PointerEvent): void {
787
+ const item: ITaskData = this.taskBarEditRecord.ganttProperties;
788
+ let differenceWidth: number = 0;
789
+ if (this.taskBarEditElement.classList.contains('e-segmented-taskbar')) {
790
+ this.enableSplitTaskLeftResize(item);
791
+ } else {
792
+ if (this.mouseDownX > this.mouseMoveX) {
793
+ if (this.mouseMoveX < (item.left + item.width)) {
794
+ differenceWidth = this.mouseDownX - this.mouseMoveX;
795
+ if (item.left > 0) {
796
+ this.parent.setRecordValue('left', this.previousItem.left - differenceWidth, item, true);
797
+ this.parent.setRecordValue('width', this.previousItem.width + differenceWidth, item, true);
798
+ }
799
+ } else {
800
+ if (this.mouseMoveX > (item.left + item.width)) {
801
+ differenceWidth = this.mouseDownX - this.mouseMoveX;
802
+ this.parent.setRecordValue('left', this.previousItem.left - differenceWidth, item, true);
803
+ this.parent.setRecordValue('width', 3, item, true);
804
+ }
805
+ }
806
+ } else {
807
+ if (this.mouseMoveX < (item.left + item.width)) {
808
+ differenceWidth = this.mouseMoveX - this.mouseDownX;
809
+ if ((item.left) < (item.left + item.width) &&
810
+ ((this.previousItem.left + differenceWidth) <= (this.previousItem.left + this.previousItem.width))) {
811
+ this.parent.setRecordValue('left', this.previousItem.left + differenceWidth, item, true);
812
+ this.parent.setRecordValue('width', this.previousItem.width - differenceWidth, item, true);
813
+ }
814
+ } else {
815
+ differenceWidth = this.mouseMoveX - this.mouseDownX;
816
+ this.parent.setRecordValue('left', this.previousItem.left + differenceWidth, item, true);
817
+ this.parent.setRecordValue('width', 3, item, true);
818
+ }
819
+ }
820
+ this.updateEditPosition(e, item);
821
+ this.parent.setRecordValue(
822
+ 'left', (this.previousItem.left + this.previousItem.width - item.width), item, true);
823
+ }
824
+ }
825
+ private enableSplitTaskLeftResize(item: ITaskData): void {
826
+ const segments: ITaskSegment[] = this.taskBarEditRecord.ganttProperties.segments.map((e: ITaskSegment) => ({ ...e }));
827
+ const segment: ITaskSegment = segments[this.segmentIndex];
828
+ let differenceWidth: number = 0;
829
+ //when decrease the left and increase the width
830
+ if (this.mouseDownX > this.mouseMoveX) {
831
+ if (this.mouseMoveX < (item.left + segment.width + segment.left)) {
832
+ differenceWidth = isNullOrUndefined(this.previousMouseMove) ?
833
+ (this.mouseDownX - this.mouseMoveX) : (this.previousMouseMove - this.mouseMoveX);
834
+ this.previousMouseMove = this.mouseMoveX;
835
+ // when resize other than 0th segment
836
+ if (segment.left > 0) {
837
+ segment.left = segment.left - differenceWidth;
838
+ segment.width = segment.width + differenceWidth;
839
+ if (this.segmentIndex !== 0) {
840
+ const previousSegment: ITaskSegment = segments[this.segmentIndex - 1];
841
+ if ((item.left + segment.left) < (item.left + previousSegment.left + previousSegment.width)) {
842
+ const difference: number =
843
+ (item.left + previousSegment.left + previousSegment.width) - (item.left + segment.left);
844
+ segment.width -= difference;
845
+ segment.left = segment.left + difference;
846
+ }
847
+ }
848
+ } else if (segment.left <= 0 && this.segmentIndex === 0) {
849
+ this.parent.setRecordValue('left', item.left - differenceWidth, item, true);
850
+ this.parent.setRecordValue('width', item.width + differenceWidth, item, true);
851
+ segment.width = segment.width + differenceWidth;
852
+ for (let i: number = 1; i < item.segments.length; i++) {
853
+ const segment: ITaskSegment = segments[i];
854
+ segment.left = segment.left + differenceWidth;
855
+ }
856
+ }
857
+ } else {
858
+ if (this.mouseMoveX > (item.left + segment.width + segment.left)) {
859
+ differenceWidth = isNullOrUndefined(this.previousMouseMove) ?
860
+ (this.mouseDownX - this.mouseMoveX) : (this.previousMouseMove - this.mouseMoveX);
861
+ this.previousMouseMove = this.mouseMoveX;
862
+ segment.left = segment.left - differenceWidth;
863
+ segment.width = this.parent.perDayWidth;
864
+ }
865
+ }
866
+ } else {
867
+ // when increase left value and decrease width of segment
868
+ if (this.mouseMoveX < (item.left + segment.width + segment.left - this.parent.perDayWidth)) {
869
+ differenceWidth = isNullOrUndefined(this.previousMouseMove) ?
870
+ (this.mouseMoveX - this.mouseDownX) : (this.mouseMoveX - this.previousMouseMove);
871
+ this.previousMouseMove = this.mouseMoveX;
872
+ // when decrease the first segment width
873
+ if (this.segmentIndex === 0 && segment.left <= 0) {
874
+ this.parent.setRecordValue('left', item.left + differenceWidth, item, true);
875
+ this.parent.setRecordValue('width', item.width - differenceWidth, item, true);
876
+ segment.width = segment.width - differenceWidth;
877
+ for (let i: number = 1; i < item.segments.length; i++) {
878
+ const segment: ITaskSegment = segments[i];
879
+ segment.left = segment.left - differenceWidth;
880
+ }
881
+ // when decrease remaining segments
882
+ } else if ((segment.left) < (segment.left + segment.width) &&
883
+ ((segment.left + differenceWidth) <= (segment.left + segment.width))) {
884
+ segment.left = segment.left + differenceWidth;
885
+ segment.width = segment.width - differenceWidth;
886
+ }
887
+ // when mouse move goes beyond one day width of task bar.
888
+ } else {
889
+ if (this.mouseMoveX < (item.left + segment.left + segment.width)) {
890
+ if (segment.width > this.parent.perDayWidth) {
891
+ differenceWidth = isNullOrUndefined(this.previousMouseMove) ?
892
+ (this.mouseMoveX - this.mouseDownX) : (this.mouseMoveX - this.previousMouseMove);
893
+ this.previousMouseMove = this.mouseMoveX;
894
+ const singleDayDifference: number = (segment.width - differenceWidth) < this.parent.perDayWidth ?
895
+ this.parent.perDayWidth > segment.width ?
896
+ this.parent.perDayWidth - segment.width : segment.width - this.parent.perDayWidth : 0;
897
+ differenceWidth -= singleDayDifference;
898
+ if (this.segmentIndex === 0) {
899
+ this.parent.setRecordValue('width', item.width - differenceWidth, item, true);
900
+ this.parent.setRecordValue('left', item.left + differenceWidth, item, true);
901
+ for (let i: number = 1; i < item.segments.length; i++) {
902
+ const segment: ITaskSegment = segments[i];
903
+ segment.left = segment.left - differenceWidth;
904
+ }
905
+ } else {
906
+ segment.left = segment.left + differenceWidth;
907
+ segment.width = segment.width - differenceWidth;
908
+ }
909
+ }
910
+ }
911
+ }
912
+ }
913
+ this.parent.setRecordValue('segments', segments, item, true);
914
+ this.parent.dataOperation.updateMappingData(this.taskBarEditRecord, 'segments');
915
+ }
916
+ /**
917
+ * Update mouse position and edited item value
918
+ *
919
+ * @param {PointerEvent} e .
920
+ * @param {ITaskData} item .
921
+ * @returns {void} .
922
+ */
923
+ private updateEditPosition(e: PointerEvent, item: ITaskData): void {
924
+ this.updateIsMilestone(item);
925
+ this.parent.setRecordValue(
926
+ 'progressWidth', this.parent.dataOperation.getProgressWidth(item.width, item.progress), item, true);
927
+ }
928
+ /**
929
+ * To update milestone property.
930
+ *
931
+ * @param {ITaskData} item .
932
+ * @returns {void} .
933
+ * @private
934
+ */
935
+ private updateIsMilestone(item: ITaskData): void {
936
+ if (item.width <= 3) {
937
+ this.parent.setRecordValue('width', 3, item, true);
938
+ this.parent.setRecordValue('isMilestone', true, item, true);
939
+ } else {
940
+ this.parent.setRecordValue('width', item.width, item, true);
941
+ this.parent.setRecordValue('isMilestone', false, item, true);
942
+ }
943
+ }
944
+
945
+ /**
946
+ * To update left and width while perform taskbar right resize operation.
947
+ *
948
+ * @param {PointerEvent} e .
949
+ * @returns {void} .
950
+ * @private
951
+ */
952
+ private enableRightResizing(e: PointerEvent): void {
953
+ const item: ITaskData = this.taskBarEditRecord.ganttProperties;
954
+ let differenceWidth: number = 0;
955
+ if (this.taskBarEditElement.classList.contains('e-segmented-taskbar')) {
956
+ const segments: ITaskSegment[] = this.taskBarEditRecord.ganttProperties.segments.map((e: ITaskSegment) => ({ ...e }));
957
+ const segment: ITaskSegment = segments[this.segmentIndex];
958
+ if (this.mouseDownX > this.mouseMoveX) {
959
+ if (this.mouseMoveX > (item.left + segment.left) && (this.mouseDownX - this.mouseMoveX) > 3) {
960
+ differenceWidth = isNullOrUndefined(this.previousMouseMove) ?
961
+ (this.mouseDownX - this.mouseMoveX) : (this.previousMouseMove - this.mouseMoveX);
962
+ this.previousMouseMove = this.mouseMoveX;
963
+ segment.width = segment.width - differenceWidth;
964
+ } else {
965
+ if (this.mouseMoveX < (item.left + segment.left)) {
966
+ segment.width = this.parent.perDayWidth;
967
+ }
968
+ }
969
+ } else {
970
+ if (this.mouseMoveX > segment.left) {
971
+ differenceWidth = isNullOrUndefined(this.previousMouseMove) ?
972
+ (this.mouseMoveX - this.mouseDownX) : (this.mouseMoveX - this.previousMouseMove);
973
+ this.previousMouseMove = this.mouseMoveX;
974
+ segment.width = segment.width + differenceWidth;
975
+ }
976
+ }
977
+ let width: number;
978
+ const nextSegment: ITaskSegment = this.segmentIndex !== segments.length - 1 ? segments[this.segmentIndex + 1] : null;
979
+ if (!isNullOrUndefined(nextSegment)) {
980
+ if (!this.taskBarEditElement.classList.contains('e-segment-last')) {
981
+ width = (segment.left + segment.width) > nextSegment.left ? (nextSegment.left - segment.left) : segment.width;
982
+ }
983
+ segment.width = width;
984
+ }
985
+ if (this.segmentIndex === item.segments.length - 1) {
986
+ if (this.segmentIndex === 0) {
987
+ this.parent.setRecordValue('width', segment.width, item, true);
988
+ }
989
+ }
990
+ this.parent.setRecordValue('segments', segments, item, true);
991
+ this.parent.dataOperation.updateMappingData(this.taskBarEditRecord, 'segments');
992
+ } else {
993
+ if (this.mouseDownX > this.mouseMoveX) {
994
+ if (this.mouseMoveX > item.left && (this.mouseDownX - this.mouseMoveX) > 3) {
995
+ differenceWidth = this.mouseDownX - this.mouseMoveX;
996
+ this.parent.setRecordValue('width', this.previousItem.width - differenceWidth, item, true);
997
+ } else {
998
+ if (this.mouseMoveX < item.left) {
999
+ this.parent.setRecordValue('width', 3, item, true);
1000
+ }
1001
+ }
1002
+ } else {
1003
+ if (this.mouseMoveX > item.left) {
1004
+ differenceWidth = this.mouseMoveX - this.mouseDownX;
1005
+ this.parent.setRecordValue('width', this.previousItem.width + differenceWidth, item, true);
1006
+ }
1007
+ }
1008
+ this.updateEditPosition(e, item);
1009
+ }
1010
+ }
1011
+
1012
+ /**
1013
+ * To updated startDate and endDate while perform taskbar edit operation.
1014
+ *
1015
+ * @returns {void} .
1016
+ * @private
1017
+ */
1018
+ private updateEditedItem(): void {
1019
+ const item: ITaskData = this.taskBarEditRecord.ganttProperties;
1020
+ let left: number;
1021
+ let projectStartDate: Date;
1022
+ let endDate: Date;
1023
+ let startDate: Date;
1024
+ switch (this.taskBarEditAction) {
1025
+ case 'ProgressResizing':
1026
+ this.parent.setRecordValue(
1027
+ 'progress',
1028
+ this.getProgressPercent(item.width, item.progressWidth),
1029
+ item,
1030
+ true);
1031
+ break;
1032
+ case 'LeftResizing':
1033
+ if (this.segmentIndex === -1) {
1034
+ left = this.getRoundOffStartLeft(item, this.roundOffDuration);
1035
+ projectStartDate = this.getDateByLeft(left);
1036
+ if (isNullOrUndefined(item.endDate)) {
1037
+ endDate = this.parent.dateValidationModule.getValidEndDate(item);
1038
+ this.parent.setRecordValue('endDate', endDate, item, true);
1039
+ }
1040
+ startDate = this.parent.dateValidationModule.checkStartDate(projectStartDate, item, null);
1041
+ this.parent.setRecordValue('startDate', new Date(startDate.getTime()), item, true);
1042
+ if (this.parent.dateValidationModule.compareDates(item.startDate, item.endDate) === 0
1043
+ && isNullOrUndefined(item.isMilestone) && item.isMilestone === false && item.duration === 0) {
1044
+ this.parent.setRecordValue('duration', 1, item, true);
1045
+ }
1046
+ if (item.isMilestone) {
1047
+ this.parent.setRecordValue('endDate', new Date(startDate.getTime()), item, true);
1048
+ }
1049
+ this.parent.dateValidationModule.calculateDuration(this.taskBarEditRecord);
1050
+ this.parent.editModule.updateResourceRelatedFields(this.taskBarEditRecord, 'duration');
1051
+ } else {
1052
+ this.updateSplitLeftResize(item);
1053
+ }
1054
+
1055
+ break;
1056
+ case 'RightResizing':
1057
+ case 'ParentResizing':
1058
+ if (this.segmentIndex === -1) {
1059
+ left = this.getRoundOffEndLeft(item, this.roundOffDuration);
1060
+ const tempEndDate: Date = this.getDateByLeft(left);
1061
+ if (isNullOrUndefined(item.startDate)) {
1062
+ startDate = this.parent.dateValidationModule.getValidStartDate(item);
1063
+ this.parent.setRecordValue('startDate', startDate, item, true);
1064
+ }
1065
+ const tempdate: Date = isNullOrUndefined(item.startDate) ? startDate : item.startDate;
1066
+ endDate = item.isMilestone ? tempdate :
1067
+ this.parent.dateValidationModule.checkEndDate(tempEndDate, this.taskBarEditRecord.ganttProperties);
1068
+ this.parent.setRecordValue('endDate', new Date(endDate.getTime()), item, true);
1069
+ this.parent.dateValidationModule.calculateDuration(this.taskBarEditRecord);
1070
+ this.parent.editModule.updateResourceRelatedFields(this.taskBarEditRecord, 'duration');
1071
+ } else {
1072
+ this.updateSplitRightResizing(item);
1073
+ }
1074
+ break;
1075
+ case 'ParentDrag':
1076
+ case 'ChildDrag':
1077
+ case 'MilestoneDrag':
1078
+ case 'ManualParentDrag':
1079
+ if (this.segmentIndex === -1 || this.segmentIndex === 0) {
1080
+ this.updateChildDrag(item);
1081
+ } else {
1082
+ this.setSplitTaskDrag(item);
1083
+ }
1084
+ break;
1085
+ }
1086
+ }
1087
+ private updateChildDrag(item: ITaskData): void {
1088
+ const left: number = this.getRoundOffStartLeft(item, this.roundOffDuration);
1089
+ const projectStartDate: Date = this.getDateByLeft(left);
1090
+ let endDate: Date;
1091
+ if (this.segmentIndex === 0) {
1092
+ this.parent.setRecordValue(
1093
+ 'startDate',
1094
+ this.parent.dateValidationModule.checkStartDate(projectStartDate, item, null),
1095
+ item,
1096
+ true);
1097
+ item.segments[0].startDate = projectStartDate;
1098
+ item.segments[0].endDate = this.parent.dataOperation.getEndDate(
1099
+ item.segments[0].startDate, item.segments[0].duration, item.durationUnit, item, false);
1100
+ this.parent.setRecordValue('segments', item.segments, item, true);
1101
+ this.parent.dataOperation.updateMappingData(this.taskBarEditRecord, 'segments');
1102
+ this.parent.chartRowsModule.incrementSegments(item.segments, 0, this.taskBarEditRecord);
1103
+ this.parent.setRecordValue(
1104
+ 'endDate',
1105
+ item.segments[item.segments.length - 1].endDate,
1106
+ item,
1107
+ true);
1108
+ } else {
1109
+ if (!isNullOrUndefined(item.endDate) && isNullOrUndefined(item.startDate)) {
1110
+ endDate = this.parent.dateValidationModule.checkStartDate(projectStartDate, item, null);
1111
+ endDate = this.parent.dateValidationModule.checkEndDate(endDate, this.taskBarEditRecord.ganttProperties);
1112
+ this.parent.setRecordValue('endDate', endDate, item, true);
1113
+ } else {
1114
+ this.parent.setRecordValue(
1115
+ 'startDate',
1116
+ this.parent.dateValidationModule.checkStartDate(projectStartDate, item, null),
1117
+ item,
1118
+ true);
1119
+ if (!isNullOrUndefined(item.duration)) {
1120
+ this.parent.dateValidationModule.calculateEndDate(this.taskBarEditRecord);
1121
+ }
1122
+ }
1123
+ }
1124
+ }
1125
+ private updateSplitLeftResize(item: ITaskData): void {
1126
+ const segment: ITaskSegment = item.segments[this.segmentIndex];
1127
+ const left: number = this.segmentIndex === 0 ? this.getRoundOffStartLeft(item, this.roundOffDuration) :
1128
+ this.getRoundOffStartLeft(segment, this.roundOffDuration);
1129
+ const projectStartDate: Date = this.segmentIndex === 0 ? this.getDateByLeft(left) : this.getDateByLeft(item.left + left);
1130
+
1131
+ const startDate: Date = this.parent.dataOperation.checkStartDate(projectStartDate, item, false);
1132
+ const duration: number = this.parent.dataOperation.getDuration(
1133
+ startDate, segment.endDate, item.durationUnit,
1134
+ item.isAutoSchedule, item.isMilestone);
1135
+
1136
+ segment.startDate = new Date(startDate.getTime());
1137
+ segment.duration = duration;
1138
+ this.parent.setRecordValue('duration', this.sumOfDuration(item.segments), item, true);
1139
+ if (this.segmentIndex === 0) {
1140
+ this.parent.setRecordValue('startDate', segment.startDate, item, true);
1141
+ }
1142
+ this.parent.editModule.updateResourceRelatedFields(this.taskBarEditRecord, 'duration');
1143
+
1144
+ if (!isNullOrUndefined(item.segments[this.segmentIndex - 1])) {
1145
+ const segmentOffsetDuration: number = this.parent.dataOperation.getDuration(
1146
+ item.segments[this.segmentIndex - 1].endDate, item.segments[this.segmentIndex].startDate, item.durationUnit,
1147
+ item.isAutoSchedule, item.isMilestone);
1148
+ segment.offsetDuration = segmentOffsetDuration;
1149
+ }
1150
+ this.parent.setRecordValue('segments', item.segments, item, true);
1151
+ this.parent.dataOperation.updateMappingData(this.taskBarEditRecord, 'segments');
1152
+ }
1153
+ private updateSplitRightResizing(item: ITaskData): void {
1154
+ const segment: ITaskSegment = item.segments[this.segmentIndex];
1155
+ const left: number = this.getRoundOffEndLeft(item, this.roundOffDuration);
1156
+ const tempEndDate: Date = this.getDateByLeft(left);
1157
+ const endDate: Date = this.parent.dataOperation.checkEndDate(tempEndDate, item, false);
1158
+ const duration: number = this.parent.dataOperation.getDuration(
1159
+ segment.startDate, endDate, item.durationUnit,
1160
+ item.isAutoSchedule, item.isMilestone);
1161
+ segment.endDate = new Date(endDate.getTime());
1162
+ segment.duration = duration;
1163
+ // update next segment offset duration
1164
+ if (!isNullOrUndefined(item.segments[this.segmentIndex + 1])) {
1165
+ const nextSegment: ITaskSegment = item.segments[this.segmentIndex + 1];
1166
+ const segmentOffset: number = this.parent.dataOperation.getDuration(
1167
+ item.segments[this.segmentIndex].endDate, nextSegment.startDate, item.durationUnit,
1168
+ item.isAutoSchedule, item.isMilestone);
1169
+ segment.offsetDuration = segmentOffset;
1170
+ }
1171
+ this.parent.setRecordValue('segments', item.segments, item, true);
1172
+ this.parent.dataOperation.updateMappingData(this.taskBarEditRecord, 'segments');
1173
+ this.parent.setRecordValue('duration', this.sumOfDuration(item.segments), item, true);
1174
+ this.parent.setRecordValue(
1175
+ 'endDate',
1176
+ item.segments[item.segments.length - 1].endDate,
1177
+ item,
1178
+ true);
1179
+ this.parent.editModule.updateResourceRelatedFields(this.taskBarEditRecord, 'duration');
1180
+ }
1181
+ public sumOfDuration(segments: ITaskSegment[]): number {
1182
+ let duration: number = 0;
1183
+ for (let i: number = 0; i < segments.length; i++) {
1184
+ const segment: ITaskSegment = segments[i];
1185
+ duration += segment.duration;
1186
+ }
1187
+ return duration;
1188
+ }
1189
+
1190
+ private setSplitTaskDrag(item: ITaskData): void {
1191
+ const segment: ITaskSegment = item.segments[this.segmentIndex];
1192
+ const left: number = this.getRoundOffStartLeft(segment, this.roundOffDuration);
1193
+ let projectStartDate: Date = this.getDateByLeft(item.left + left);
1194
+ projectStartDate = this.parent.dateValidationModule.checkStartDate(projectStartDate, item, null);
1195
+ segment.startDate = projectStartDate;
1196
+ segment.endDate = this.parent.dataOperation.getEndDate(
1197
+ segment.startDate, segment.duration, item.durationUnit, item, false
1198
+ );
1199
+ segment.duration = this.parent.dataOperation.getDuration(
1200
+ segment.startDate, segment.endDate, item.durationUnit, item.isAutoSchedule, item.isMilestone
1201
+ );
1202
+ this.parent.setRecordValue('duration', this.sumOfDuration(item.segments), item, true);
1203
+ this.parent.setRecordValue(
1204
+ 'endDate',
1205
+ item.segments[item.segments.length - 1].endDate,
1206
+ item,
1207
+ true);
1208
+ if (!isNullOrUndefined(this.parent.taskFields.endDate)) {
1209
+ this.parent.dataOperation.updateMappingData(this.taskBarEditRecord, 'endDate');
1210
+ }
1211
+
1212
+ //set offset if previous record present
1213
+ if (!isNullOrUndefined(item.segments[this.segmentIndex - 1])) {
1214
+ let offsetDuration: number = this.parent.dataOperation.getDuration(
1215
+ item.segments[this.segmentIndex - 1].endDate, item.segments[this.segmentIndex].startDate, item.durationUnit,
1216
+ item.isAutoSchedule, item.isMilestone);
1217
+ if (segment.startDate.getDay() === 1 && offsetDuration === 0 && !this.parent.includeWeekend) {
1218
+ offsetDuration = 1;
1219
+ }
1220
+ segment.offsetDuration = offsetDuration;
1221
+ }
1222
+ //set next record offset if present
1223
+ if (!isNullOrUndefined(item.segments[this.segmentIndex + 1])) {
1224
+ const nextSegment: ITaskSegment = item.segments[this.segmentIndex + 1];
1225
+ let offsetDuration: number = this.parent.dataOperation.getDuration(
1226
+ item.segments[this.segmentIndex].endDate, nextSegment.startDate, item.durationUnit,
1227
+ item.isAutoSchedule, item.isMilestone);
1228
+ if (nextSegment.startDate.getDay() === 1 && offsetDuration === 0 && !this.parent.includeWeekend) {
1229
+ offsetDuration = 1;
1230
+ }
1231
+ nextSegment.offsetDuration = offsetDuration;
1232
+ }
1233
+ this.parent.setRecordValue('segments', item.segments, item, true);
1234
+ this.parent.dataOperation.updateMappingData(this.taskBarEditRecord, 'segments');
1235
+ }
1236
+ /**
1237
+ * To get roundoff enddate.
1238
+ *
1239
+ * @param {ITaskData} ganttRecord .
1240
+ * @param {boolean} isRoundOff .
1241
+ * @returns {number} .
1242
+ * @private
1243
+ */
1244
+ private getRoundOffEndLeft(ganttRecord: ITaskData, isRoundOff: boolean): number {
1245
+ const tierMode: string = this.parent.timelineModule.bottomTier !== 'None' ? this.parent.timelineModule.bottomTier :
1246
+ this.parent.timelineModule.topTier;
1247
+ let totalLeft: number = ganttRecord.width + ganttRecord.left;
1248
+ if (this.segmentIndex !== -1) {
1249
+ const segment: ITaskSegment = ganttRecord.segments[this.segmentIndex];
1250
+ totalLeft = totalLeft - ganttRecord.width + segment.width + segment.left;
1251
+ }
1252
+ let remainingContribution: number =
1253
+ (1 / (this.parent.timelineModule.getIncrement(this.getDateByLeft(totalLeft), 1, 'Day') / (1000 * 60 * 60 * 24)));
1254
+ let remainingLeft: number = this.parent.perDayWidth - (this.parent.perDayWidth / remainingContribution);
1255
+ const positionValue: number = remainingLeft / this.parent.perDayWidth;
1256
+ if (isRoundOff === undefined) {
1257
+ isRoundOff = false;
1258
+ }
1259
+ /*Rounding the decimal value for week-month-year schedule mode*/
1260
+ if (!isRoundOff) {
1261
+ if ((tierMode !== 'Hour' && tierMode !== 'Minutes')) {
1262
+ if (positionValue > 0.5) {
1263
+ totalLeft = totalLeft - remainingLeft + this.parent.perDayWidth;
1264
+ } else if (positionValue < 0.5) {
1265
+ totalLeft = (totalLeft - remainingLeft) + (this.parent.perDayWidth / 2);
1266
+ }
1267
+ }
1268
+ } else if (isRoundOff) {
1269
+ if (tierMode === 'Hour') {
1270
+ const inHour: number = (this.parent.perDayWidth / 24);
1271
+ remainingContribution =
1272
+ (1 / (this.parent.timelineModule.getIncrement(this.getDateByLeft(totalLeft), 1, 'Hour') / (1000 * 60 * 60)));
1273
+ remainingLeft = (this.parent.perDayWidth / 24) - ((this.parent.perDayWidth / 24) / remainingContribution);
1274
+ if (remainingLeft !== 0) {
1275
+ totalLeft = (totalLeft - remainingLeft) + inHour;
1276
+ }
1277
+ } else if (tierMode === 'Minutes') {
1278
+ const inMinutes: number = (this.parent.perDayWidth / (24 * 60));
1279
+ remainingContribution =
1280
+ (1 / (this.parent.timelineModule.getIncrement(this.getDateByLeft(totalLeft), 1, 'Minutes') / (1000 * 60)));
1281
+ remainingLeft = (this.parent.perDayWidth / (24 * 60)) - ((this.parent.perDayWidth / (24 * 60)) / remainingContribution);
1282
+ if (remainingLeft !== 0) {
1283
+ totalLeft = (totalLeft - remainingLeft) + inMinutes;
1284
+ }
1285
+ } else {
1286
+ if (remainingLeft !== 0) {
1287
+ totalLeft = (totalLeft - remainingLeft) + this.parent.perDayWidth;
1288
+ }
1289
+ }
1290
+ }
1291
+ return totalLeft;
1292
+ }
1293
+
1294
+ /**
1295
+ * To get roundoff startdate.
1296
+ *
1297
+ * @param {ITaskData | ITaskSegment} ganttRecord .
1298
+ * @param {boolean} isRoundOff .
1299
+ * @returns {number} .
1300
+ * @private
1301
+ */
1302
+ public getRoundOffStartLeft(ganttRecord: ITaskData | ITaskSegment, isRoundOff: boolean): number {
1303
+ let left: number = isNullOrUndefined(ganttRecord as ITaskData) ? (ganttRecord as ITaskSegment).left
1304
+ : (ganttRecord as ITaskData).left;
1305
+ const tierMode: string = this.parent.timelineModule.bottomTier !== 'None' ? this.parent.timelineModule.bottomTier :
1306
+ this.parent.timelineModule.topTier;
1307
+ let remainingContribution: number =
1308
+ (1 / (this.parent.timelineModule.getIncrement(this.getDateByLeft(left), 1, 'Day') / (1000 * 60 * 60 * 24)));
1309
+ let remainDays: number = this.parent.perDayWidth - (this.parent.perDayWidth / remainingContribution);
1310
+ const remainDaysInDecimal: number = remainDays / this.parent.perDayWidth;
1311
+ if (isRoundOff === undefined) {
1312
+ isRoundOff = false;
1313
+ }
1314
+ /*Rounding the decimal value for week-month-year schedule mode*/
1315
+ if (!isRoundOff) {
1316
+ if ((tierMode !== 'Hour' && tierMode !== 'Minutes')) {
1317
+ if (remainDaysInDecimal <= 0.5) {
1318
+ left = left - remainDays;
1319
+ } else if (remainDaysInDecimal > 0.5) {
1320
+ left = (left - remainDays) + this.parent.perDayWidth / 2;
1321
+ }
1322
+ }
1323
+ } else if (isRoundOff) {
1324
+ if (tierMode === 'Hour') {
1325
+ remainingContribution =
1326
+ (1 / (this.parent.timelineModule.getIncrement(this.getDateByLeft(left), 1, 'Hour') / (1000 * 60 * 60)));
1327
+ remainDays = (this.parent.perDayWidth / 24) - ((this.parent.perDayWidth / 24) / remainingContribution);
1328
+ left = left - remainDays;
1329
+ } else if (tierMode === 'Minutes') {
1330
+ remainingContribution =
1331
+ (1 / (this.parent.timelineModule.getIncrement(this.getDateByLeft(left), 1, 'Minutes') / (1000 * 60)));
1332
+ remainDays = (this.parent.perDayWidth / (24 * 60)) - ((this.parent.perDayWidth / (24 * 60)) / remainingContribution);
1333
+ left = left - remainDays;
1334
+ } else {
1335
+ left = left - remainDays;
1336
+ }
1337
+ }
1338
+ return left;
1339
+ }
1340
+
1341
+ /**
1342
+ * To get date by left value.
1343
+ *
1344
+ * @param {number} left .
1345
+ * @returns {Date} .
1346
+ * @private
1347
+ */
1348
+ public getDateByLeft(left: number): Date {
1349
+ const pStartDate: Date = new Date(this.parent.timelineModule.timelineStartDate.toString());
1350
+ const milliSecondsPerPixel: number = (24 * 60 * 60 * 1000) / this.parent.perDayWidth;
1351
+ pStartDate.setTime(pStartDate.getTime() + (left * milliSecondsPerPixel));
1352
+ const tierMode: string = this.parent.timelineModule.bottomTier !== 'None' ? this.parent.timelineModule.topTier :
1353
+ this.parent.timelineModule.bottomTier;
1354
+ if (tierMode !== 'Hour' && tierMode !== 'Minutes') {
1355
+ if (this.parent.isInDst(new Date(this.parent.timelineModule.timelineStartDate.toString())) && !this.parent.isInDst(pStartDate)) {
1356
+ pStartDate.setTime(pStartDate.getTime() + (60 * 60 * 1000));
1357
+ } else if (!this.parent.isInDst(new Date(this.parent.timelineModule.timelineStartDate.toString())) && this.parent.isInDst(pStartDate)) {
1358
+ pStartDate.setTime(pStartDate.getTime() - (60 * 60 * 1000));
1359
+ }
1360
+ }
1361
+ return pStartDate;
1362
+ }
1363
+
1364
+ /**
1365
+ * To set item position.
1366
+ *
1367
+ * @returns {void} .
1368
+ * @private
1369
+ */
1370
+ private setItemPosition(): void {
1371
+ const item: ITaskData = this.taskBarEditRecord.ganttProperties;
1372
+ const segment: ITaskSegment = !isNullOrUndefined(item.segments) ? item.segments[this.segmentIndex] : null;
1373
+ const width: number = this.taskBarEditAction === 'MilestoneDrag' || item.isMilestone ?
1374
+ this.parent.chartRowsModule.milestoneHeight : item.width;
1375
+ let rightResizer: number = this.parent.isAdaptive ? (width - 2) : (width - 10);
1376
+ if (!isNullOrUndefined(segment)) {
1377
+ rightResizer = this.parent.isAdaptive ? (segment.width - 2) : (segment.width - 10);
1378
+ }
1379
+ const taskBarMainContainer: HTMLElement = (!this.taskBarEditElement.classList.contains(cls.taskBarMainContainer)) ? closest(this.taskBarEditElement, 'tr.' + cls.chartRow)
1380
+ .querySelector('.' + cls.taskBarMainContainer) : this.taskBarEditElement;
1381
+ const segmentedTaskBarContainer: boolean = this.taskBarEditElement.classList.contains('e-segmented-taskbar');
1382
+ const leftLabelContainer: HTMLElement = closest(this.taskBarEditElement, 'tr.' + cls.chartRow)
1383
+ .querySelector('.' + cls.leftLabelContainer);
1384
+ const rightLabelContainer: HTMLElement = closest(this.taskBarEditElement, 'tr.' + cls.chartRow)
1385
+ .querySelector('.' + cls.rightLabelContainer);
1386
+ const traceChildProgressBar: HTMLElement =
1387
+ this.taskBarEditElement.querySelector('.' + cls.traceChildProgressBar);
1388
+ const traceChildTaskBar: HTMLElement =
1389
+ this.taskBarEditElement.querySelector('.' + cls.traceChildTaskBar);
1390
+ const childProgressResizer: HTMLElement =
1391
+ this.taskBarEditElement.querySelector('.' + cls.childProgressResizer);
1392
+ const taskBarRightResizer: HTMLElement =
1393
+ this.taskBarEditElement.querySelector('.' + cls.taskBarRightResizer);
1394
+ const traceParentTaskBar: HTMLElement =
1395
+ this.taskBarEditElement.querySelector('.' + cls.traceParentTaskBar);
1396
+ const traceParentProgressBar: HTMLElement =
1397
+ this.taskBarEditElement.querySelector('.' + cls.traceParentProgressBar);
1398
+ const traceConnectorPointRight: HTMLElement =
1399
+ this.taskBarEditElement.querySelector('.' + cls.rightConnectorPointOuterDiv);
1400
+ const manualParentTaskbar: HTMLElement = this.taskBarEditElement;
1401
+ const manualTaskbar: HTMLElement = this.taskBarEditElement.querySelector('.' + cls.manualParentTaskBar);
1402
+ const manualParentRight: HTMLElement =
1403
+ this.taskBarEditElement.querySelector('.' + cls.manualParentRightResizer);
1404
+ const manualParentLeft: HTMLElement =
1405
+ this.taskBarEditElement.querySelector('.' + cls.manualParentLeftResizer);
1406
+ if (this.taskBarEditAction !== 'ConnectorPointRightDrag' &&
1407
+ this.taskBarEditAction !== 'ConnectorPointLeftDrag') {
1408
+ if (this.taskBarEditAction !== 'ParentResizing' && this.taskBarEditAction !== 'ManualParentDrag') {
1409
+ if (segmentedTaskBarContainer && !isNullOrUndefined(item.segments)
1410
+ && (this.taskBarEditAction === 'RightResizing' || this.segmentIndex !== 0)) {
1411
+
1412
+ (this.taskBarEditElement as HTMLElement).style.width = (segment.width) + 'px';
1413
+ (this.taskBarEditElement as HTMLElement).style.left = (segment.left) + 'px';
1414
+ }
1415
+ taskBarMainContainer.style.width = (width) + 'px';
1416
+ taskBarMainContainer.style.left = (item.left) + 'px';
1417
+ leftLabelContainer.style.width = (item.left) + 'px';
1418
+ if (this.taskBarEditAction === 'LeftResizing' && this.segmentIndex === 0) {
1419
+ const parent: HTMLElement = this.taskBarEditElement.parentElement;
1420
+ const segmentedTasks: HTMLCollectionOf<HTMLElement> =
1421
+ parent.getElementsByClassName('e-segmented-taskbar') as HTMLCollectionOf<HTMLElement>;
1422
+ for (let i: number = 0; i < item.segments.length; i++) {
1423
+ const segment: ITaskSegment = item.segments[i];
1424
+ const segmentElement: HTMLElement = segmentedTasks[i] as HTMLElement;
1425
+ (segmentElement as HTMLElement).style.width = (segment.width) + 'px';
1426
+ (segmentElement as HTMLElement).style.left = (segment.left) + 'px';
1427
+ }
1428
+ }
1429
+
1430
+ if (!isNullOrUndefined(rightLabelContainer)) {
1431
+ rightLabelContainer.style.left = (item.left + width) + 'px';
1432
+ }
1433
+ }
1434
+ if (traceConnectorPointRight) {
1435
+ traceConnectorPointRight.style.left = (this.parent.isAdaptive ? (width + 10) : (width + 2)) + 'px';
1436
+ }
1437
+ if (this.taskBarEditAction === 'MilestoneDrag' || item.isMilestone) {
1438
+ taskBarMainContainer.style.left = (item.left - (width / 2)) + 'px';
1439
+ leftLabelContainer.style.width = (item.left - (width / 2)) + 'px';
1440
+ if (!isNullOrUndefined(rightLabelContainer)) {
1441
+ rightLabelContainer.style.left = (item.left + (width / 2)) + 'px';
1442
+ }
1443
+ } else if (this.taskBarEditAction === 'ProgressResizing') {
1444
+ if (this.segmentIndex === -1) {
1445
+ traceChildTaskBar.style.left = (item.left + item.progressWidth - 10) + 'px';
1446
+ if (!isNullOrUndefined(traceChildProgressBar)) {
1447
+ traceChildProgressBar.style.width = item.progressWidth + 'px';
1448
+ traceChildProgressBar.style.borderBottomRightRadius = this.progressBorderRadius + 'px';
1449
+ traceChildProgressBar.style.borderTopRightRadius = this.progressBorderRadius + 'px';
1450
+ childProgressResizer.style.left = item.progressWidth - 8 + 'px';
1451
+ }
1452
+ }
1453
+ else {
1454
+ this.updateSegmentProgress(this.taskBarEditRecord.ganttProperties);
1455
+ traceChildProgressBar.style.width = item.segments[this.segmentIndex].progressWidth + 'px';
1456
+ traceChildProgressBar.style.borderBottomRightRadius = this.progressBorderRadius + 'px';
1457
+ traceChildProgressBar.style.borderTopRightRadius = this.progressBorderRadius + 'px';
1458
+ childProgressResizer.style.left = item.segments[this.segmentIndex].progressWidth - 8 + 'px';
1459
+ }
1460
+ } else if (this.taskBarEditAction === 'RightResizing' && !isNullOrUndefined(traceChildTaskBar)) {
1461
+ traceChildTaskBar.style.width = (width) + 'px';
1462
+ if (!isNullOrUndefined(traceChildProgressBar)) {
1463
+ traceChildProgressBar.style.width = (item.progressWidth) + 'px';
1464
+ taskBarRightResizer.style.left = rightResizer + 'px';
1465
+ if (!isNullOrUndefined(childProgressResizer)) {
1466
+ childProgressResizer.style.left = (item.progressWidth - 10) + 'px';
1467
+ }
1468
+ }
1469
+ } else if (this.taskBarEditAction === 'ParentDrag') {
1470
+ if (!isNullOrUndefined(traceParentTaskBar)) {
1471
+ traceParentTaskBar.style.width = (width) + 'px';
1472
+ }
1473
+ if (!isNullOrUndefined(traceChildProgressBar)) {
1474
+ traceParentProgressBar.style.width = (item.progressWidth) + 'px';
1475
+ }
1476
+ } else if (this.taskBarEditAction === 'ParentResizing') {
1477
+ manualParentTaskbar.style.width = manualTaskbar.style.width = (item.width) + 'px';
1478
+ manualParentRight.style.left = (item.width - manualParentLeft.offsetLeft) + 'px';
1479
+ } else if (this.taskBarEditAction === 'ManualParentDrag') {
1480
+ manualParentTaskbar.style.left = (item.left - item.autoLeft) + 'px';
1481
+ } else {
1482
+ if (!isNullOrUndefined(traceChildTaskBar) && !segmentedTaskBarContainer) {
1483
+ traceChildTaskBar.style.width = (width) + 'px';
1484
+ }
1485
+ if (!isNullOrUndefined(traceChildProgressBar)) {
1486
+ taskBarRightResizer.style.left = rightResizer + 'px';
1487
+ traceChildProgressBar.style.width = (item.progressWidth) + 'px';
1488
+ if (!isNullOrUndefined(childProgressResizer)) {
1489
+ childProgressResizer.style.left = item.progressWidth - 10 + 'px';
1490
+ }
1491
+ }
1492
+ if (segmentedTaskBarContainer) {
1493
+ taskBarRightResizer.style.left = rightResizer + 'px';
1494
+ traceChildProgressBar.style.width = (segment.progressWidth) + 'px';
1495
+ if (!isNullOrUndefined(childProgressResizer)) {
1496
+ childProgressResizer.style.left = segment.progressWidth - 10 + 'px';
1497
+ }
1498
+ }
1499
+ }
1500
+ }
1501
+ }
1502
+
1503
+ /**
1504
+ * To handle mouse up event in chart
1505
+ *
1506
+ * @param {PointerEvent} e .
1507
+ * @returns {void} .
1508
+ * @private
1509
+ */
1510
+ public mouseUpHandler(e: PointerEvent): void {
1511
+ const mouseDragged: boolean = this.isMouseDragged;
1512
+ this.previousMouseMove = null;
1513
+ this.editTooltip.showHideTaskbarEditTooltip(false, this.segmentIndex);
1514
+ if (this.taskBarEditAction && this.isMouseDragged) {
1515
+ if (!this.dragMouseLeave && this.taskBarEditedAction) {
1516
+ this.taskBarEditedAction(e);
1517
+ this.isMouseDragged = false;
1518
+ } else {
1519
+ this.parent.isOnEdit = false;
1520
+ this.cancelTaskbarEditActionInMouseLeave();
1521
+ }
1522
+ }
1523
+ if (this.parent.viewType === 'ResourceView' && this.parent.enableMultiTaskbar && !isNullOrUndefined(this.taskBarEditElement)) {
1524
+ if (!isNullOrUndefined(this.taskBarEditElement.querySelector('.e-gantt-child-taskbar'))) {
1525
+ if (this.taskBarEditElement.querySelector('.e-gantt-child-taskbar').classList.contains('e-collapsed-taskbar-drag')) {
1526
+ removeClass([this.taskBarEditElement.querySelector('.e-gantt-child-taskbar')], 'e-collapsed-taskbar-drag');
1527
+ this.taskBarEditElement.style.zIndex = this.prevZIndex;
1528
+ this.prevZIndex = '';
1529
+ }
1530
+ }
1531
+ }
1532
+ if (!this.parent.isAdaptive || mouseDragged) {
1533
+ this.initPublicProp();
1534
+ }
1535
+ this.stopScrollTimer();
1536
+ }
1537
+ /**
1538
+ * To perform taskbar edit operation.
1539
+ *
1540
+ * @param {PointerEvent} event .
1541
+ * @returns {void} .
1542
+ * @private
1543
+ */
1544
+ public taskBarEditedAction(event: PointerEvent): void {
1545
+ const args: ITaskbarEditedEventArgs = {} as ITaskbarEditedEventArgs;
1546
+ const x1: number = this.mouseDownX;
1547
+ const y1: number = this.mouseDownY;
1548
+ const item: IGanttData = this.taskBarEditRecord;
1549
+ const recordIndex: number = this.parent.ganttChartModule.getIndexByTaskBar(this.taskBarEditElement);
1550
+ const x2: number = this.mouseMoveX;
1551
+ const e: MousePoint = this.getCoordinate(event);
1552
+ const resMouseY: number = e.pageY - this.parent.ganttChartModule.chartBodyContainer.offsetTop;
1553
+ if ((this.taskBarEditAction === 'ConnectorPointLeftDrag' ||
1554
+ this.taskBarEditAction === 'ConnectorPointRightDrag') && !this.drawPredecessor) {
1555
+ this.dependencyCancel = true;
1556
+ }
1557
+ if ((this.taskBarEditAction === 'ConnectorPointLeftDrag' ||
1558
+ this.taskBarEditAction === 'ConnectorPointRightDrag') && this.drawPredecessor) {
1559
+ this.parent.connectorLineEditModule.updatePredecessor(this.connectorSecondRecord, this.finalPredecessor);
1560
+ } else {
1561
+ if (x1 !== x2 || (Math.abs(y1 - resMouseY) >= (this.parent.rowHeight - this.parent.taskbarHeight) / 2)) {
1562
+ if (item !== null) {
1563
+ args.editingFields = item.ganttProperties;
1564
+ args.data = item;
1565
+ args.recordIndex = recordIndex;
1566
+ args.previousData = this.previousItem;
1567
+ args.taskBarEditAction = this.taskBarEditAction;
1568
+ args.action = 'TaskbarEditing';
1569
+ args.roundOffDuration = this.roundOffDuration;
1570
+ args.target = this.targetElement;
1571
+ this.taskbarEditedArgs = args;
1572
+ this.taskbarEdited(args);
1573
+ }
1574
+ }
1575
+ }
1576
+ }
1577
+
1578
+ /**
1579
+ * To cancel the taskbar edt action.
1580
+ *
1581
+ * @returns {void} .
1582
+ * @private
1583
+ */
1584
+ public cancelTaskbarEditActionInMouseLeave(): void {
1585
+ this.parent.editModule.reUpdatePreviousRecords(true);
1586
+ }
1587
+
1588
+ public updateSegmentProgress(taskData: ITaskData): void {
1589
+ const segments: ITaskSegment[] = taskData.segments;
1590
+ let fixedWidth: boolean = true;
1591
+ const totalTaskWidth: number = this.splitTasksDuration(segments) * this.parent.perDayWidth;
1592
+ let totalProgressWidth: number = this.parent.dataOperation.getProgressWidth(totalTaskWidth, taskData.progress);
1593
+ for (let i: number = 0; i < segments.length; i++) {
1594
+ const segment: ITaskSegment = segments[i];
1595
+ delete segment.progressWidth;
1596
+ if (totalProgressWidth > 0 && totalProgressWidth > segment.width) {
1597
+ totalProgressWidth = totalProgressWidth - segment.width;
1598
+ segment.progressWidth = segment.width;
1599
+ segment.showProgress = false;
1600
+ } else if (fixedWidth) {
1601
+ segment.progressWidth = totalProgressWidth;
1602
+ segment.showProgress = true;
1603
+ totalProgressWidth = totalProgressWidth - segment.width;
1604
+ fixedWidth = false;
1605
+ }
1606
+ }
1607
+ }
1608
+
1609
+ /**
1610
+ * To trigger taskbar edited event.
1611
+ *
1612
+ * @param {ITaskbarEditedEventArgs} arg .
1613
+ * @returns {void} .
1614
+ * @private
1615
+ */
1616
+ public taskbarEdited(arg: ITaskbarEditedEventArgs): void {
1617
+ const args: ITaskbarEditedEventArgs = extend({}, arg);
1618
+ const ganttRecord: IGanttData = args.data;
1619
+ const taskData: ITaskData = ganttRecord.ganttProperties;
1620
+ if (args.taskBarEditAction === 'ProgressResizing') {
1621
+ if (args.previousData.progress !== taskData.progress) {
1622
+ this.parent.setRecordValue(
1623
+ 'progress',
1624
+ this.getProgressPercent(taskData.width, taskData.progressWidth),
1625
+ taskData,
1626
+ true);
1627
+ if (ganttRecord.parentItem) {
1628
+ this.parent.editModule.updateParentProgress(ganttRecord.parentItem);
1629
+ }
1630
+ if (!isNullOrUndefined(taskData.segments)) {
1631
+ this.updateSegmentProgress(taskData);
1632
+ }
1633
+ }
1634
+ } else {
1635
+ const segments: ITaskSegment[] = args.data.ganttProperties.segments;
1636
+ if (!isNullOrUndefined(segments) && segments.length > 0
1637
+ && ((this.taskBarEditAction === 'LeftResizing' && this.segmentIndex !== 0)
1638
+ || (this.taskBarEditAction === 'ChildDrag' && this.segmentIndex !== 0)
1639
+ || (this.taskBarEditAction === 'RightResizing'))) {
1640
+ const segment: ITaskSegment = segments[this.segmentIndex];
1641
+ const ganttProp: ITaskData = this.taskBarEditRecord.ganttProperties;
1642
+ const previousSegment: ITaskSegment = this.segmentIndex === 0 ? null
1643
+ : segments[this.segmentIndex - 1];
1644
+ const nextSegment: ITaskSegment = this.segmentIndex === segments.length - 1 ? null
1645
+ : segments[this.segmentIndex + 1];
1646
+ const sDate: Date = !isNullOrUndefined(nextSegment) ?
1647
+ new Date(nextSegment.startDate.getTime()) : this.parent.cloneProjectEndDate;
1648
+ const eDate: Date = !isNullOrUndefined(previousSegment) ?
1649
+ new Date(previousSegment.endDate.getTime()) : this.parent.cloneProjectStartDate;
1650
+ sDate.setHours(0, 0, 0, 0); eDate.setHours(0, 0, 0, 0);
1651
+ const cStartDate: Date = new Date(segment.startDate.getTime());
1652
+ const cEndDate: Date = new Date(segment.endDate.getTime());
1653
+ cStartDate.setDate(cStartDate.getDate() - 1); cEndDate.setDate(cEndDate.getDate() + 1);
1654
+ cStartDate.setHours(0, 0, 0, 0); cEndDate.setHours(0, 0, 0, 0);
1655
+ if (cStartDate.getTime() <= eDate.getTime() && !isNullOrUndefined(previousSegment) && !isNullOrUndefined(segment)) {
1656
+ const segmentIndexes: { firstSegmentIndex: number, secondSegmentIndex: number }[] = [
1657
+ { 'firstSegmentIndex': previousSegment.segmentIndex, 'secondSegmentIndex': segment.segmentIndex }
1658
+ ];
1659
+ this.parent.chartRowsModule.mergeTask(ganttProp.taskId, segmentIndexes);
1660
+ } else if (cEndDate.getTime() >= sDate.getTime() && this.segmentIndex !== segments.length - 1) {
1661
+ const segmentIndexes: { firstSegmentIndex: number, secondSegmentIndex: number }[] = [
1662
+ { 'firstSegmentIndex': segment.segmentIndex, 'secondSegmentIndex': nextSegment.segmentIndex }
1663
+ ];
1664
+ this.parent.chartRowsModule.mergeTask(ganttProp.taskId, segmentIndexes);
1665
+ } else if (cEndDate.getTime() >= sDate.getTime()) {
1666
+ segment.endDate.setDate(this.parent.cloneProjectEndDate.getDate() - 1);
1667
+ segment.startDate = this.parent.dataOperation.getStartDate(
1668
+ segment.endDate, segment.duration, ganttProp.durationUnit, ganttProp);
1669
+ // eslint-disable-next-line
1670
+ for (let i: number = segments.length - 2; i >= 0; i++) {
1671
+ const segment: ITaskSegment = segments[i];
1672
+ const eDate: Date = segment.endDate;
1673
+ eDate.setDate(eDate.getDate() - segment.offsetDuration);
1674
+ segment.endDate = eDate;
1675
+ segment.startDate = this.parent.dataOperation.getStartDate(
1676
+ segment.endDate, segment.duration, ganttProp.durationUnit, ganttProp);
1677
+ }
1678
+ }
1679
+ }
1680
+ this.parent.dataOperation.updateWidthLeft(args.data);
1681
+ }
1682
+ this.parent.dataOperation.updateTaskData(ganttRecord);
1683
+ this.parent.editModule.initiateUpdateAction(args);
1684
+ }
1685
+
1686
+ /**
1687
+ * To get progress in percentage.
1688
+ *
1689
+ * @param {number} parentwidth .
1690
+ * @param {number} progresswidth .
1691
+ * @returns {number} .
1692
+ * @private
1693
+ */
1694
+ private getProgressPercent(parentwidth: number, progresswidth: number): number {
1695
+ return Math.ceil(((progresswidth / parentwidth) * 100));
1696
+ }
1697
+
1698
+ /**
1699
+ * false line implementation.
1700
+ *
1701
+ * @returns {void} .
1702
+ * @private
1703
+ */
1704
+ private drawFalseLine(): void {
1705
+
1706
+ const x1: number = this.mouseDownX;
1707
+ const y1: number = this.mouseDownY;
1708
+ const x2: number = this.mouseMoveX;
1709
+ const y2: number = this.mouseMoveY;
1710
+ const length: number = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
1711
+ const angle: number = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
1712
+ const transform: string = 'rotate(' + angle + 'deg)';
1713
+ let left: number;
1714
+ if (this.taskBarEditAction === 'ConnectorPointLeftDrag') {
1715
+ left = (this.elementOffsetLeft - (this.parent.chartRowsModule.connectorPointWidth / 2)) -
1716
+ this.parent.ganttChartModule.scrollObject.previousScroll.left;
1717
+ }
1718
+ if (this.taskBarEditAction === 'ConnectorPointRightDrag') {
1719
+ left = (this.elementOffsetLeft + this.elementOffsetWidth) +
1720
+ (this.parent.chartRowsModule.connectorPointWidth / 2) - this.parent.ganttChartModule.scrollObject.previousScroll.left;
1721
+ }
1722
+ const top: number = ((this.elementOffsetTop) + (this.elementOffsetHeight / 2) +
1723
+ this.parent.ganttChartModule.chartBodyContainer.offsetTop) - this.parent.ganttChartModule.scrollObject.previousScroll.top;
1724
+
1725
+ this.removeFalseLine(false);
1726
+
1727
+ this.falseLine = createElement('div', {
1728
+ className: cls.falseLine, id: 'ganttfalseline' + this.parent.element.id,
1729
+ styles: 'transform-origin: 0% 100%;right: auto;position: absolute;transform:' + transform + ';' +
1730
+ 'border-top-width: 1px;border-top-style: dashed;z-index: 5;width:' + (length - 3) + 'px;' +
1731
+ 'left:' + left + 'px;top:' + top + 'px;'
1732
+ });
1733
+
1734
+ this.parent.ganttChartModule.chartBodyContainer.appendChild(this.falseLine);
1735
+
1736
+
1737
+ }
1738
+ /**
1739
+ *
1740
+ * @param {boolean} isRemoveConnectorPointDisplay .
1741
+ * @returns {void} .
1742
+ * @private
1743
+ */
1744
+ public removeFalseLine(isRemoveConnectorPointDisplay: boolean): void {
1745
+ if (this.falseLine) {
1746
+ remove(this.falseLine);
1747
+ this.falseLine = null;
1748
+ if (isRemoveConnectorPointDisplay) {
1749
+ this.elementOffsetLeft = 0;
1750
+ this.elementOffsetTop = 0;
1751
+ this.elementOffsetWidth = 0;
1752
+ this.elementOffsetHeight = 0;
1753
+ removeClass(
1754
+ this.parent.ganttChartModule.scrollElement.querySelectorAll(
1755
+ '.' + cls.connectorLineContainer),
1756
+ [cls.connectorLineZIndex]);
1757
+ }
1758
+ }
1759
+ }
1760
+ /**
1761
+ *
1762
+ * @param {PointerEvent} e .
1763
+ * @returns {void} .
1764
+ * @private
1765
+ */
1766
+ public updateConnectorLineSecondProperties(e: PointerEvent): void {
1767
+ const target: Element = this.getElementByPosition(e);
1768
+ const element: Element = parentsUntil(target, cls.taskBarMainContainer);
1769
+ this.connectorSecondAction = null;
1770
+ let scrollTop: number = 0;
1771
+ if (parentsUntil(target, cls.connectorPointLeft)) {
1772
+ this.connectorSecondAction = 'ConnectorPointLeftDrag';
1773
+ this.toPredecessorText = 'Start';
1774
+ } else if (parentsUntil(target, cls.connectorPointRight)) {
1775
+ this.connectorSecondAction = 'ConnectorPointRightDrag';
1776
+ this.toPredecessorText = 'Finish';
1777
+ } else {
1778
+ this.connectorSecondAction = null;
1779
+ this.toPredecessorText = null;
1780
+ }
1781
+ if (this.taskBarEditElement !== element && this.taskBarEditElement !== this.highlightedSecondElement) {
1782
+ if (this.parent.virtualScrollModule && this.parent.enableVirtualization) {
1783
+ const top: number = this.parent.virtualScrollModule.getTopPosition();
1784
+ scrollTop = top;
1785
+ }
1786
+ if ((this.parent.virtualScrollModule && this.parent.enableVirtualization &&
1787
+ !this.elementOffsetLeft) || !this.parent.enableVirtualization) {
1788
+ this.elementOffsetLeft = this.taskBarEditElement.offsetLeft;
1789
+ this.elementOffsetTop = this.taskBarEditElement.offsetTop + scrollTop;
1790
+ this.elementOffsetWidth = this.taskBarEditElement.offsetWidth;
1791
+ this.elementOffsetHeight = this.taskBarEditElement.offsetHeight;
1792
+ }
1793
+ this.showHideTaskBarEditingElements(element, this.highlightedSecondElement, true);
1794
+ }
1795
+ if (isNullOrUndefined(this.connectorSecondAction) && !isNullOrUndefined(this.connectorSecondElement)) {
1796
+ this.editTooltip.showHideTaskbarEditTooltip(false, this.segmentIndex);
1797
+ removeClass([this.connectorSecondElement.querySelector('.' + cls.connectorPointLeft)], [cls.connectorPointAllowBlock]);
1798
+ removeClass([this.connectorSecondElement.querySelector('.' + cls.connectorPointRight)], [cls.connectorPointAllowBlock]);
1799
+ }
1800
+ this.connectorSecondElement = this.connectorSecondAction ? element : null;
1801
+ this.highlightedSecondElement = element;
1802
+ this.connectorSecondRecord = isNullOrUndefined(this.connectorSecondElement) ?
1803
+ null : this.parent.ganttChartModule.getRecordByTaskBar(this.connectorSecondElement);
1804
+ }
1805
+ // eslint-disable-next-line
1806
+ private triggerDependencyEvent(e: PointerEvent, mouseUp?: boolean): void {
1807
+ const fromItem: ITaskData = this.taskBarEditRecord.ganttProperties;
1808
+ const toItem: ITaskData = this.connectorSecondRecord ? this.connectorSecondRecord.ganttProperties : null;
1809
+ let predecessor: string;
1810
+ let currentTarget: string;
1811
+ const target: Element = this.getElementByPosition(e);
1812
+ const element: HTMLElement = target as HTMLElement;
1813
+ const uniqueId: string = this.parent.viewType === 'ResourceView' ? fromItem.taskId : fromItem.rowUniqueID;
1814
+
1815
+ if (this.taskBarEditAction === 'ConnectorPointLeftDrag') {
1816
+ predecessor = uniqueId + 'S';
1817
+ } else if (this.taskBarEditAction === 'ConnectorPointRightDrag') {
1818
+ predecessor = uniqueId + 'F';
1819
+ }
1820
+
1821
+ if (this.connectorSecondAction) {
1822
+ if (this.connectorSecondAction === 'ConnectorPointLeftDrag') {
1823
+ predecessor += 'S';
1824
+ currentTarget = 'start';
1825
+ } else if (this.connectorSecondAction === 'ConnectorPointRightDrag') {
1826
+ predecessor += 'F';
1827
+ currentTarget = 'finish';
1828
+ }
1829
+ }
1830
+
1831
+ if (isNullOrUndefined(toItem)) {
1832
+ this.drawPredecessor = false;
1833
+ return;
1834
+ }
1835
+ if (toItem.predecessorsName) {
1836
+ this.finalPredecessor = toItem.predecessorsName + ',' + predecessor;
1837
+ } else {
1838
+ this.finalPredecessor = predecessor;
1839
+ }
1840
+ const isValidLink: boolean =
1841
+ this.parent.connectorLineEditModule.validatePredecessorRelation(this.connectorSecondRecord, this.finalPredecessor);
1842
+ // eslint-disable-next-line
1843
+ const predecessorArray: IPredecessor[] = this.parent.predecessorModule.calculatePredecessor(predecessor, this.connectorSecondRecord);
1844
+ const args: IDependencyEventArgs = {} as IDependencyEventArgs;
1845
+ args.fromItem = fromItem;
1846
+ args.toItem = toItem;
1847
+ args.newPredecessorString = this.finalPredecessor;
1848
+ args.predecessor = predecessorArray && predecessorArray[0];
1849
+ args.isValidLink = isValidLink;
1850
+ args.requestType = 'ValidateDependency';
1851
+ this.parent.trigger('actionBegin', args);
1852
+ args.isValidLink = !isValidLink && args.isValidLink ? false : args.isValidLink;
1853
+ if (args.isValidLink) {
1854
+ if (!this.editTooltip.toolTipObj && !this.parent.isAdaptive) {
1855
+ this.editTooltip.showHideTaskbarEditTooltip(true, this.segmentIndex);
1856
+ }
1857
+ if (this.editTooltip.toolTipObj) {
1858
+ this.parent.connectorLineModule.tooltipTable.innerHTML = this.parent.connectorLineModule.getConnectorLineTooltipInnerTd(
1859
+ this.parent.editModule.taskbarEditModule.taskBarEditRecord.ganttProperties.taskName,
1860
+ this.parent.editModule.taskbarEditModule.fromPredecessorText, '', ''
1861
+ );
1862
+ const table: NodeList = this.parent.connectorLineModule.tooltipTable.querySelector('#toPredecessor').querySelectorAll('td');
1863
+ (table[1] as HTMLElement).innerText = toItem.taskName;
1864
+ (table[2] as HTMLElement).innerText = this.parent.localeObj.getConstant(currentTarget);
1865
+ const tooltipElement: HTMLElement = this.parent.connectorLineModule.tooltipTable.parentElement.parentElement;
1866
+ if (tooltipElement.offsetTop + tooltipElement.offsetHeight > e.pageY) {
1867
+ tooltipElement.style.top = (e.pageY - tooltipElement.offsetHeight - 20) + 'px';
1868
+ }
1869
+ }
1870
+ this.drawPredecessor = true;
1871
+ } else {
1872
+ if (this.parent.isAdaptive) {
1873
+ if (target.classList.contains(cls.connectorPointLeft) ||
1874
+ target.classList.contains(cls.connectorPointRight)) {
1875
+ this.showHideActivePredecessors(true);
1876
+ }
1877
+ } else {
1878
+ addClass([element], [cls.connectorPointAllowBlock]);
1879
+ }
1880
+ this.drawPredecessor = false;
1881
+ }
1882
+ }
1883
+
1884
+ // Get XY coordinates for touch and non-touch device
1885
+ private getCoordinate(event: TouchEvent | PointerEvent): MousePoint {
1886
+ const coordinates: MousePoint = {};
1887
+ if (this.parent.isAdaptive && event && event.type !== 'click') {
1888
+ const e: TouchEvent = event as TouchEvent;
1889
+ if (e.type === 'touchmove' || e.type === 'touchstart' || e.type === 'touchend') {
1890
+ coordinates.pageX = e.changedTouches[0].pageX;
1891
+ coordinates.pageY = e.changedTouches[0].pageY;
1892
+ }
1893
+ } else if (event) {
1894
+ const e: PointerEvent = event as PointerEvent;
1895
+ coordinates.pageX = e.pageX;
1896
+ coordinates.pageY = e.pageY;
1897
+ }
1898
+ return coordinates;
1899
+ }
1900
+
1901
+ // Get current target element by mouse position
1902
+ // window.pageXOffset && window.pageYOffset is used to find the accurate element position in IPad/IPhone
1903
+ private getElementByPosition(event: TouchEvent | PointerEvent): Element {
1904
+ if (!this.parent.isAdaptive) {
1905
+ return event.target as Element;
1906
+ } else {
1907
+ const e: MousePoint = this.getCoordinate(event);
1908
+ return document.elementFromPoint((e.pageX - window.pageXOffset), (e.pageY - window.pageYOffset));
1909
+ }
1910
+
1911
+ }
1912
+
1913
+ private multipleSelectionEnabled(): void {
1914
+ if (this.parent.selectionModule &&
1915
+ this.parent.selectionSettings.mode !== 'Cell'
1916
+ && this.parent.selectionSettings.type === 'Multiple') {
1917
+ this.parent.selectionModule.hidePopUp();
1918
+ }
1919
+ }
1920
+
1921
+ private unWireEvents(): void {
1922
+ if (this.parent.isDestroyed) {
1923
+ return;
1924
+ }
1925
+ this.parent.off('chartMouseDown', this.mouseDownHandler);
1926
+ this.parent.off('chartMouseUp', this.mouseUpHandler);
1927
+ this.parent.off('chartMouseLeave', this.mouseLeaveHandler);
1928
+ this.parent.off('chartMouseMove', this.mouseMoveAction);
1929
+ this.parent.off('chartMouseClick', this.mouseClickHandler);
1930
+ }
1931
+ /**
1932
+ * @returns {void} .
1933
+ * @private
1934
+ */
1935
+ public destroy(): void {
1936
+ this.unWireEvents();
1937
+ this.stopScrollTimer();
1938
+ this.parent.editModule.taskbarEditModule = undefined;
1939
+ }
1940
+ }