@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,1248 @@
1
+ import { Gantt } from '../base/gantt';
2
+ import {
3
+ createElement, formatUnit, EventHandler, Browser, KeyboardEvents, getElement,
4
+ KeyboardEventArgs
5
+ } from '@syncfusion/ej2-base';
6
+ import { isNullOrUndefined, closest, addClass, removeClass, getValue, setValue } from '@syncfusion/ej2-base';
7
+ import * as cls from '../base/css-constants';
8
+ import { ChartScroll } from '../actions/chart-scroll';
9
+ import { IGanttData, IWorkTimelineRanges } from '../base/interface';
10
+ import { click } from '@syncfusion/ej2-grids';
11
+ import { ITaskbarClickEventArgs, RecordDoubleClickEventArgs, IMouseMoveEventArgs, IIndicator } from '../base/interface';
12
+ import { TooltipEventArgs } from '@syncfusion/ej2-popups';
13
+ import { FocusStrategy } from '@syncfusion/ej2-grids/src/grid/services/focus-strategy';
14
+ import { VirtualContentRenderer } from '../renderer/virtual-content-render';
15
+
16
+ /**
17
+ * module to render gantt chart - project view
18
+ */
19
+
20
+ export class GanttChart {
21
+ private parent: Gantt;
22
+ public chartElement: HTMLElement;
23
+ public chartTimelineContainer: HTMLElement;
24
+ public chartBodyContainer: HTMLElement;
25
+ public chartBodyContent: HTMLElement;
26
+ public rangeViewContainer: HTMLElement;
27
+ public scrollElement: HTMLElement;
28
+ public scrollObject: ChartScroll;
29
+ public isExpandCollapseFromChart: boolean = false;
30
+ public isExpandAll: boolean = false;
31
+ private focusedElement: HTMLElement;
32
+ public focusedRowIndex: number;
33
+ private isGanttElement: boolean = false;
34
+ public keyboardModule: KeyboardEvents;
35
+ public targetElement: Element;
36
+ public virtualRender: VirtualContentRenderer;
37
+ constructor(parent: Gantt) {
38
+ this.parent = parent;
39
+ this.chartTimelineContainer = null;
40
+ this.rangeViewContainer =
41
+ createElement('div', { className: cls.rangeContainer });
42
+ this.rangeViewContainer.setAttribute("role", "RangeContainer");
43
+ this.virtualRender = new VirtualContentRenderer(this.parent);
44
+ this.addEventListener();
45
+ }
46
+
47
+ private addEventListener(): void {
48
+ this.parent.on('renderPanels', this.renderChartContainer, this);
49
+ this.parent.on('recordsUpdated', this.renderChartElements, this);
50
+ this.parent.on('dataReady', this.renderInitialContents, this);
51
+ this.parent.on('tree-grid-created', this.renderChartContents, this);
52
+ this.parent.on('destroy', this.destroy, this);
53
+ }
54
+
55
+ private renderChartContents(): void {
56
+ this.parent.notify('refreshDayMarkers', {});
57
+ this.wireEvents();
58
+ }
59
+ /**
60
+ * Method to render top level containers in Gantt chart
61
+ *
62
+ * @returns {void} .
63
+ * @private
64
+ */
65
+ public renderChartContainer(): void {
66
+ this.chartElement = createElement('div', { id: this.parent.element.id + 'GanttChart', className: cls.ganttChart });
67
+ this.parent.chartPane.appendChild(this.chartElement);
68
+ this.renderTimelineContainer();
69
+ this.renderBodyContainers();
70
+ // render top level div header and content
71
+ // Get timeline header from timeline class file and append to header div
72
+ // render content div
73
+ // Render scroll able div
74
+ // Render container for all element like, table, weekend and holidays
75
+ // Get rows element from rows renderer class
76
+ // Get label related info label renderer class
77
+ // Get baseline from baseline renderer class
78
+ // Get weekend elements from weekend-holidays renderer class
79
+ }
80
+ /**
81
+ * method to render timeline, holidays, weekends at load time
82
+ *
83
+ * @returns {void} .
84
+ */
85
+ private renderInitialContents(): void {
86
+ this.parent.timelineModule.createTimelineSeries();
87
+ }
88
+ /**
89
+ * @returns {void} .
90
+ * @private
91
+ */
92
+ public renderOverAllocationContainer(): void {
93
+ for (let i: number = 0; i < this.parent.flatData.length; i++) {
94
+ const data: IGanttData = this.parent.flatData[i];
95
+ if (data.childRecords.length > 0) {
96
+ this.parent.dataOperation.updateOverlappingValues(data);
97
+ }
98
+ }
99
+ const rangeContainer: HTMLElement = this.parent.element.querySelector('.' + cls.rangeContainer);
100
+ if (rangeContainer) {
101
+ rangeContainer.innerHTML = '';
102
+ }
103
+ if (this.parent.treeGrid.grid.filterSettings.columns.length === 0) {
104
+ this.renderRangeContainer(this.parent.currentViewData);
105
+ }
106
+ }
107
+ private renderChartElements(): void {
108
+ if (this.parent.isFromOnPropertyChange) {
109
+ this.rangeViewContainer.innerHTML = '';
110
+ this.parent.updateProjectDates(
111
+ this.parent.cloneProjectStartDate, this.parent.cloneProjectEndDate, this.parent.isTimelineRoundOff);
112
+ this.parent.isFromOnPropertyChange = false;
113
+ } else {
114
+ this.parent.chartRowsModule.renderChartRows();
115
+ if (this.parent.predecessorModule && this.parent.taskFields.dependency) {
116
+ this.parent.connectorLineIds = [];
117
+ this.parent.updatedConnectorLineCollection = [];
118
+ this.parent.predecessorModule.createConnectorLinesCollection();
119
+ }
120
+ this.parent.connectorLineModule.renderConnectorLines(this.parent.updatedConnectorLineCollection);
121
+ if (this.parent.viewType === 'ResourceView' && this.parent.showOverAllocation) {
122
+ this.renderOverAllocationContainer();
123
+ }
124
+ }
125
+ this.updateWidthAndHeight();
126
+ this.parent.notify('selectRowByIndex', {});
127
+ }
128
+
129
+ /**
130
+ * @param {IGanttData[]} records .
131
+ * @returns {void} .
132
+ * @private
133
+ */
134
+ public renderRangeContainer(records: IGanttData[]): void {
135
+ const recordLength: number = records.length;
136
+ let count: number; let ganttRecord: IGanttData;
137
+ let rangeCollection: IWorkTimelineRanges[];
138
+ if (this.parent.treeGrid.grid.filterSettings.columns.length === 0) {
139
+ for (count = 0; count < recordLength; count++) {
140
+ ganttRecord = records[count];
141
+ rangeCollection = ganttRecord.ganttProperties.workTimelineRanges;
142
+ if (rangeCollection) {
143
+ this.renderRange(rangeCollection, ganttRecord);
144
+ }
145
+ }
146
+ }
147
+ }
148
+ private getTopValue(currentRecord: IGanttData): number {
149
+ const updatedRecords: IGanttData[] = this.parent.getExpandedRecords(this.parent.currentViewData);
150
+ const recordIndex: number = updatedRecords.indexOf(currentRecord);
151
+ if (!currentRecord.expanded) {
152
+ return (recordIndex * this.parent.rowHeight);
153
+ }
154
+ return ((recordIndex + 1) * this.parent.rowHeight);
155
+ }
156
+ /*get height for range bar*/
157
+ private getRangeHeight(data: IGanttData): number {
158
+ if (!data.expanded && data.hasChildRecords) {
159
+ return (this.parent.rowHeight - Math.floor((this.parent.rowHeight - this.parent.chartRowsModule.taskBarHeight)));
160
+ }
161
+ return (data.childRecords.length * this.parent.rowHeight) -
162
+ Math.floor((this.parent.rowHeight - this.parent.chartRowsModule.taskBarHeight));
163
+ }
164
+ private renderRange(rangeCollection: IWorkTimelineRanges[], currentRecord: IGanttData): void {
165
+ const topValue: number = this.getTopValue(currentRecord);
166
+ const sameIDElement: Element = this.rangeViewContainer.querySelector('.' + 'rangeContainer' + currentRecord.ganttProperties.rowUniqueID);
167
+ if (sameIDElement) {
168
+ sameIDElement.remove();
169
+ }
170
+ const parentDiv: HTMLElement = createElement('div', {
171
+ className: 'rangeContainer' + currentRecord.ganttProperties.rowUniqueID, styles: `top:${topValue}px; position: absolute;`
172
+ });
173
+ if (currentRecord.level === 0 && !currentRecord.expanded && isNullOrUndefined(currentRecord.parentItem)
174
+ && !this.parent.enableMultiTaskbar) {
175
+ return;
176
+ }
177
+ for (let i: number = 0; i < rangeCollection.length; i++) {
178
+ const height: number = this.getRangeHeight(currentRecord);
179
+ const leftDiv: HTMLElement = createElement('div', {
180
+ className: cls.rangeChildContainer + ' ' + 'e-leftarc', styles: `left:${rangeCollection[i].left}px;
181
+ top: ${Math.floor((this.parent.rowHeight - this.parent.chartRowsModule.taskBarHeight) / 2)}px;
182
+ height: ${height + 1}px; border-right: 0px`
183
+ });
184
+ const rightDiv: HTMLElement = createElement('div', {
185
+ className: cls.rangeChildContainer + ' ' + 'e-rightarc',
186
+ styles: `left:${rangeCollection[i].left + rangeCollection[i].width - 5}px;
187
+ top: ${Math.floor((this.parent.rowHeight - this.parent.chartRowsModule.taskBarHeight) / 2)}px; height: ${height + 1}px;
188
+ border-left: 0px`
189
+ });
190
+ parentDiv.appendChild(leftDiv);
191
+ parentDiv.appendChild(rightDiv);
192
+ this.rangeViewContainer.appendChild(parentDiv);
193
+ }
194
+ this.parent.ganttChartModule.chartBodyContent.appendChild(this.rangeViewContainer);
195
+ }
196
+ /**
197
+ * @returns {void} .
198
+ * @private
199
+ */
200
+ public renderTimelineContainer(): void {
201
+ this.chartTimelineContainer =
202
+ createElement('div', { className: cls.timelineHeaderContainer });
203
+ this.chartTimelineContainer.setAttribute("role", "TimelineHeader");
204
+ this.chartElement.appendChild(this.chartTimelineContainer);
205
+ }
206
+
207
+ /**
208
+ * initiate chart container
209
+ *
210
+ * @returns {void} .
211
+ */
212
+ private renderBodyContainers(): void {
213
+ this.chartBodyContainer = createElement('div', { className: cls.chartBodyContainer });
214
+ this.chartElement.appendChild(this.chartBodyContainer);
215
+ this.scrollElement = createElement('div', {
216
+ className: cls.chartScrollElement + ' ' + cls.scrollContent, styles: 'position:relative;'
217
+ });
218
+ this.chartBodyContainer.appendChild(this.scrollElement);
219
+ this.chartBodyContent = createElement('div', { className: cls.chartBodyContent, styles: 'position:relative; overflow:hidden ' });
220
+ if (this.parent.virtualScrollModule && this.parent.enableVirtualization) {
221
+ this.parent.ganttChartModule.virtualRender.renderWrapper();
222
+ } else {
223
+ this.scrollElement.appendChild(this.chartBodyContent);
224
+ }
225
+
226
+ // this.parent.chartRowsModule.createChartTable();
227
+ this.scrollObject = new ChartScroll(this.parent);
228
+ //this.scrollObject.setWidth(this.chartProperties.width);
229
+ let toolbarHeight: number = 0;
230
+ if (!isNullOrUndefined(this.parent.toolbarModule) && !isNullOrUndefined(this.parent.toolbarModule.element)) {
231
+ toolbarHeight = this.parent.toolbarModule.element.offsetHeight;
232
+ }
233
+ this.scrollObject.
234
+ setHeight(this.parent.ganttHeight - this.chartTimelineContainer.offsetHeight - toolbarHeight);
235
+ }
236
+ /**
237
+ * @returns {void} .
238
+ * @private
239
+ */
240
+ public updateWidthAndHeight(): void {
241
+ //empty row height
242
+ const emptydivHeight: number = 36;
243
+ const emptyHeight: number = this.parent.contentHeight === 0 ? this.parent.flatData.length > 1 ? emptydivHeight : 0 : this.parent.contentHeight;
244
+ let contentElement: HTMLElement = this.parent.element.getElementsByClassName('e-chart-scroll-container e-content')[0] as HTMLElement;
245
+ if (emptyHeight >= contentElement['offsetHeight']) {
246
+ this.chartBodyContent.style.height = formatUnit(emptyHeight);
247
+ } else {
248
+ let scrollHeight: number = this.parent.element.getElementsByClassName('e-chart-rows-container')[0]['offsetHeight'];
249
+ if (contentElement['offsetHeight'] >= scrollHeight) {
250
+ this.chartBodyContent.style.height = contentElement['offsetHeight'] - 17 + 'px';
251
+ }
252
+ else {
253
+ this.chartBodyContent.style.height = contentElement['offsetHeight'] + 'px';
254
+ }
255
+ } //let element: HTMLElement = this.chartTimelineContainer.querySelector('.' + cls.timelineHeaderTableContainer);
256
+ this.chartBodyContent.style.width = formatUnit(this.parent.timelineModule.totalTimelineWidth);
257
+ this.setVirtualHeight();
258
+ this.parent.notify('updateHeight', {});
259
+ this.parent.updateGridLineContainerHeight();
260
+ this.updateLastRowBottomWidth();
261
+ }
262
+
263
+ private setVirtualHeight(): void {
264
+ if (this.parent.virtualScrollModule && this.parent.enableVirtualization) {
265
+ const wrapper: HTMLElement = getValue('virtualTrack', this.parent.ganttChartModule.virtualRender);
266
+ wrapper.style.height = this.parent.updatedRecords.length * this.parent.rowHeight + 'px';
267
+ }
268
+ }
269
+ /**
270
+ * Method to update bottom border for chart rows
271
+ *
272
+ * @returns {void} .
273
+ */
274
+ public updateLastRowBottomWidth(): void {
275
+ if (this.parent.currentViewData.length > 0 && this.parent.height !== 'auto') {
276
+ const expandedRecords: IGanttData[] = this.parent.virtualScrollModule && this.parent.enableVirtualization ?
277
+ this.parent.currentViewData : this.parent.getExpandedRecords(this.parent.currentViewData);
278
+ const lastExpandedRow: IGanttData = expandedRecords[expandedRecords.length - 1];
279
+ const lastExpandedRowIndex: number = this.parent.currentViewData.indexOf(lastExpandedRow);
280
+ const lastRow: HTMLElement = this.parent.getRowByIndex(lastExpandedRowIndex);
281
+ const table: Element = this.parent.chartRowsModule.ganttChartTableBody;
282
+ if (table.querySelectorAll('.e-chart-row-cell.e-chart-row-border.e-lastrow')) {
283
+ removeClass(table.querySelectorAll('.e-chart-row-cell.e-chart-row-border.e-lastrow'), 'e-lastrow');
284
+ }
285
+ if (this.chartBodyContent.clientHeight < this.chartBodyContainer.clientHeight) {
286
+ if (lastRow) {
287
+ addClass(lastRow.querySelectorAll('td'), 'e-lastrow');
288
+ const emptydivHeight: number = 36;
289
+ const emptyHeight: number = this.parent.contentHeight === 0 ? this.parent.flatData.length > 1 ? emptydivHeight : 0 : this.parent.contentHeight;
290
+ let contentElement: HTMLElement = this.parent.element.getElementsByClassName('e-chart-scroll-container e-content')[0] as HTMLElement;
291
+ if (emptyHeight >= contentElement['offsetHeight']) {
292
+ this.chartBodyContent.style.height = formatUnit(emptyHeight);
293
+ } else {
294
+ let scrollHeight: number = this.parent.element.getElementsByClassName('e-chart-rows-container')[0]['offsetHeight'];
295
+ if (contentElement['offsetHeight'] >= scrollHeight) {
296
+ this.chartBodyContent.style.height = contentElement['offsetHeight'] - 17 + 'px';
297
+ }
298
+ else {
299
+ this.chartBodyContent.style.height = contentElement['offsetHeight'] + 'px';
300
+ }
301
+ }
302
+ }
303
+ }
304
+ }
305
+ }
306
+
307
+ private removeEventListener(): void {
308
+ if (this.parent.isDestroyed) {
309
+ return;
310
+ }
311
+ this.parent.off('renderPanels', this.renderChartContainer);
312
+ this.parent.off('recordsUpdated', this.renderChartElements);
313
+ this.parent.off('dataReady', this.renderInitialContents);
314
+ this.parent.off('tree-grid-created', this.renderChartContents);
315
+ this.parent.off('destroy', this.destroy);
316
+ }
317
+ /**
318
+ * Click event handler in chart side
319
+ *
320
+ * @param {PointerEvent} e .
321
+ * @returns {void} .
322
+ */
323
+ private ganttChartMouseDown(e: PointerEvent): void {
324
+ if (e.which !== 3 && this.parent.editSettings.allowTaskbarEditing) {
325
+ this.parent.notify('chartMouseDown', e);
326
+ this.parent.element.tabIndex = 0;
327
+ }
328
+ }
329
+
330
+ private ganttChartMouseClick(e: PointerEvent): void {
331
+ if (this.parent.editSettings.allowTaskbarEditing) {
332
+ if (this.parent.autoFocusTasks) {
333
+ this.scrollToTarget(e); /** Scroll to task */
334
+ }
335
+ this.parent.notify('chartMouseClick', e);
336
+ }
337
+ }
338
+
339
+ private ganttChartMouseUp(e: PointerEvent): void {
340
+ if (this.parent.editSettings.allowTaskbarEditing) {
341
+ this.parent.notify('chartMouseUp', e);
342
+ }
343
+ }
344
+
345
+ /**
346
+ *
347
+ * @param {PointerEvent} e .
348
+ * @returns {void} .
349
+ */
350
+ private scrollToTarget(e: PointerEvent): void {
351
+ const row: Element = closest(e.target as Element, 'tr');
352
+ if (row && this.parent.element.contains(row) &&
353
+ (this.parent.element.querySelectorAll('.e-chart-rows-container')[0].contains(e.target as Element) ||
354
+ this.parent.element.querySelectorAll('.e-gridcontent')[0].contains(e.target as Element)) &&
355
+ this.parent.currentViewData.length > 0) {
356
+ const rowIndex: number = getValue('rowIndex', closest(e.target as Element, 'tr'));
357
+ const dateObject: Date = this.parent.currentViewData[rowIndex].ganttProperties.startDate;
358
+ if (!isNullOrUndefined(dateObject)) {
359
+ const left: number = this.parent.dataOperation.getTaskLeft(dateObject, false);
360
+ if (this.parent.autoFocusTasks) {
361
+ this.updateScrollLeft(left);
362
+ }
363
+ }
364
+ }
365
+ }
366
+ /**
367
+ * To focus selected task in chart side
368
+ *
369
+ * @param {number} scrollLeft .
370
+ * @returns {void} .
371
+ * @private
372
+ */
373
+ public updateScrollLeft(scrollLeft: number): void {
374
+ scrollLeft = scrollLeft > 0 ? scrollLeft : 0;
375
+ scrollLeft = this.scrollElement.scrollWidth <= scrollLeft ? this.scrollElement.scrollWidth : scrollLeft;
376
+ if ((this.scrollElement.offsetWidth + this.parent.ganttChartModule.scrollElement.scrollLeft) < scrollLeft
377
+ || (this.scrollElement.scrollLeft > scrollLeft)) {
378
+ this.scrollObject.setScrollLeft(scrollLeft - 50);
379
+ }
380
+ // this.parent.ganttChartModule.scrollObject.updateLeftPosition();
381
+ }
382
+
383
+ /**
384
+ * Method trigger while perform mouse up action.
385
+ *
386
+ * @param {PointerEvent} e .
387
+ * @returns {void}
388
+ * @private
389
+ */
390
+ private mouseUp(e: PointerEvent): void {
391
+ if (this.parent.allowRowDragAndDrop) {
392
+ const ganttDragElemet: HTMLElement = this.parent.element.querySelector('.e-ganttdrag');
393
+ if (ganttDragElemet) {
394
+ ganttDragElemet.remove();
395
+ }
396
+ }
397
+ if (!this.isGanttElement) {
398
+ this.parent.notify('chartMouseUp', e);
399
+ }
400
+ this.isGanttElement = false;
401
+ }
402
+ /**
403
+ * Method trigger while perform mouse up action.
404
+ *
405
+ * @param {PointerEvent} e .
406
+ * @returns {void} .
407
+ * @private
408
+ */
409
+ private documentMouseUp(e: PointerEvent): void {
410
+ this.isGanttElement = true;
411
+ if (this.parent.allowRowDragAndDrop) {
412
+ const ganttDragElemet: HTMLElement = this.parent.element.querySelector('.e-ganttdrag');
413
+ if (ganttDragElemet) {
414
+ ganttDragElemet.remove();
415
+ }
416
+ }
417
+ if (this.parent.isDestroyed || e.which === 3) {
418
+ return;
419
+ }
420
+ let isTaskbarEdited: boolean = false;
421
+ if (this.parent.editSettings.allowTaskbarEditing &&
422
+ getValue('editModule.taskbarEditModule.isMouseDragged', this.parent) &&
423
+ getValue('editModule.taskbarEditModule.taskBarEditAction', this.parent)) {
424
+ isTaskbarEdited = true;
425
+ }
426
+ this.parent.notify('chartMouseUp', e);
427
+ if (this.parent.showActiveElement) {
428
+ if (this.focusedElement && !(e.target as HTMLElement).classList.contains('e-split-bar')) {
429
+ this.focusedElement.tabIndex = this.focusedElement.tabIndex === 0 ? -1 : this.focusedElement.tabIndex;
430
+ removeClass([this.focusedElement], 'e-active-container');
431
+ }
432
+ }
433
+ if (!isTaskbarEdited) {
434
+ /** Expand/collapse action */
435
+ const target: EventTarget = e.target;
436
+ const isOnTaskbarElement: boolean | Element = (e.target as HTMLElement).classList.contains(cls.taskBarMainContainer)
437
+ || closest(e.target as Element, '.' + cls.taskBarMainContainer);
438
+ if (closest((<HTMLElement>target), '.e-gantt-parent-taskbar') && !this.parent.editSettings.allowEditing) {
439
+ this.chartExpandCollapseRequest(e);
440
+ } else if (!isOnTaskbarElement && this.parent.autoFocusTasks) {
441
+ this.scrollToTarget(e); /** Scroll to task */
442
+ }
443
+ }
444
+ if (this.parent.editModule && this.parent.editModule.taskbarEditModule) {
445
+ this.parent.editModule.taskbarEditModule.removeFalseLine(true);
446
+ }
447
+ if (!isNullOrUndefined(this.parent.onTaskbarClick) && !isTaskbarEdited) {
448
+ const target: EventTarget = e.target;
449
+ const taskbarElement: Element =
450
+ closest((<HTMLElement>target), '.e-gantt-parent-taskbar,.e-gantt-child-taskbar,.e-gantt-milestone');
451
+ if (taskbarElement) {
452
+ this.onTaskbarClick(e, target, taskbarElement);
453
+ }
454
+ }
455
+ }
456
+
457
+ /**
458
+ * This event triggered when click on taskbar element
459
+ *
460
+ * @param {PointerEvent | KeyboardEventArgs} e .
461
+ * @param {EventTarget} target .
462
+ * @param {Element} taskbarElement .
463
+ * @returns {void}
464
+ */
465
+ public onTaskbarClick(e: PointerEvent | KeyboardEventArgs, target: EventTarget, taskbarElement: Element): void {
466
+ const chartRow: Node = closest(target as Element, 'tr');
467
+ const rowIndex: number = getValue('rowIndex', chartRow);
468
+ const data: IGanttData = this.getRecordByTarget(e);
469
+ const args: ITaskbarClickEventArgs = {
470
+ data: data,
471
+ taskbarElement: taskbarElement,
472
+ rowIndex: rowIndex,
473
+ target: target as Element
474
+ };
475
+ this.parent.trigger('onTaskbarClick', args);
476
+ }
477
+
478
+ /**
479
+ * Method trigger while perform mouse leave action.
480
+ *
481
+ * @param {PointerEvent} e .
482
+ * @returns {void} .
483
+ * @private
484
+ */
485
+ private ganttChartLeave(e: PointerEvent): void {
486
+ if (this.parent.editSettings.allowTaskbarEditing) {
487
+ this.parent.notify('chartMouseLeave', e);
488
+ }
489
+ }
490
+
491
+ /**
492
+ * Method trigger while perform mouse move action.
493
+ *
494
+ * @param {PointerEvent} e .
495
+ * @returns {void} .
496
+ * @private
497
+ */
498
+ private ganttChartMove(e: PointerEvent): void {
499
+ if (this.parent.editSettings.allowTaskbarEditing) {
500
+ this.parent.notify('chartMouseMove', e);
501
+ if (!isNullOrUndefined(this.parent.taskFields.dependency) && this.parent.connectorLineEditModule) {
502
+ this.parent.connectorLineEditModule.updateConnectorLineEditElement(e);
503
+ }
504
+ }
505
+ }
506
+
507
+ /**
508
+ * Method trigger while perform right click action.
509
+ *
510
+ * @param {PointerEvent} e .
511
+ * @returns {void} .
512
+ * @private
513
+ */
514
+ private contextClick(e: PointerEvent): void {
515
+ if (this.parent.allowFiltering && this.parent.filterModule) {
516
+ this.parent.filterModule.closeFilterOnContextClick(e.srcElement as Element);
517
+ }
518
+ }
519
+
520
+ /**
521
+ * Method to trigger while perform mouse move on Gantt.
522
+ *
523
+ * @param {PointerEvent} e .
524
+ * @returns {void} .
525
+ * @private
526
+ */
527
+ public mouseMoveHandler(e: PointerEvent): void {
528
+ if (!isNullOrUndefined(this.parent.onMouseMove) &&
529
+ (this.parent.flatData.length ||
530
+ (<HTMLElement>e.target).classList.contains('e-header-cell-label') ||
531
+ (<HTMLElement>e.target).classList.contains('e-headercell'))) {
532
+ const target: EventTarget = e.target;
533
+ const args: IMouseMoveEventArgs = { originalEvent: e };
534
+ const element: Element = closest((<HTMLElement>target), '.e-chart-row-cell,.e-connector-line-container,' +
535
+ '.e-event-markers,.e-header-cell-label,.e-rowcell,.e-headercell,.e-indicator-span');
536
+ if (element) {
537
+ let rowData: IGanttData;
538
+ const rowElement: Element = closest((<HTMLElement>target), '.e-rowcell,.e-chart-row-cell');
539
+ const columnElement: Element = closest((<HTMLElement>target), '.e-rowcell,.e-headercell');
540
+ if (rowElement) {
541
+ rowData = this.parent.ganttChartModule.getRecordByTarget(e);
542
+ args.data = rowData;
543
+ }
544
+ if (columnElement) {
545
+ const cellIndex: number = getValue('cellIndex', columnElement);
546
+ args.column = this.parent.treeGrid.columns[cellIndex];
547
+ }
548
+ if (closest((<HTMLElement>target), '.e-indicator-span')) {
549
+ let index: number = 0;
550
+ const indicators: IIndicator[] = rowData.ganttProperties.indicators;
551
+ if (indicators.length > 1) {
552
+ for (index = 0; index < indicators.length; index++) {
553
+ if (indicators[index].name === ((<HTMLElement>element).innerText).trim()) {
554
+ break;
555
+ }
556
+ }
557
+ }
558
+ args.indicator = indicators[index];
559
+ }
560
+ if (closest((<HTMLElement>target), '.e-connector-line-container')) {
561
+ const obj: TooltipEventArgs = {} as TooltipEventArgs;
562
+ obj.target = element as HTMLElement;
563
+ args.predecessor = this.parent.tooltipModule.getPredecessorTooltipData(obj);
564
+ }
565
+ if (closest((<HTMLElement>target), '.e-event-markers')) {
566
+ const obj: TooltipEventArgs = {} as TooltipEventArgs;
567
+ obj.target = element as HTMLElement;
568
+ args.eventMarkers = this.parent.tooltipModule.getMarkerTooltipData(obj);
569
+ }
570
+ if ((<HTMLElement>target).classList.contains('e-header-cell-label')) {
571
+ args.date = new Date((<HTMLElement>target).dataset.content);
572
+ }
573
+ }
574
+ this.parent.trigger('onMouseMove', args);
575
+ }
576
+ }
577
+
578
+ /**
579
+ * Double click handler for chart
580
+ *
581
+ * @param {PointerEvent} e .
582
+ * @returns {void} .
583
+ */
584
+ private doubleClickHandler(e: PointerEvent): void {
585
+ this.parent.notify('chartDblClick', e);
586
+ const target: EventTarget = e.target;
587
+ const row: Element = closest(target as Element, 'tr');
588
+ const rowIndex: number = getValue('rowIndex', row);
589
+ const rowData: IGanttData = this.parent.ganttChartModule.getRecordByTarget(e);
590
+ const args: RecordDoubleClickEventArgs = {
591
+ row: row,
592
+ rowData: rowData,
593
+ rowIndex: rowIndex,
594
+ target: target as Element
595
+ };
596
+ this.recordDoubleClick(args);
597
+ }
598
+
599
+ /**
600
+ * To trigger record double click event.
601
+ *
602
+ * @param {RecordDoubleClickEventArgs} args .
603
+ * @returns {void} .
604
+ * @private
605
+ */
606
+ public recordDoubleClick(args: RecordDoubleClickEventArgs): void {
607
+ this.parent.trigger('recordDoubleClick', args);
608
+ }
609
+
610
+ /**
611
+ * @param {PointerEvent | KeyboardEventArgs} e .
612
+ * @returns {IGanttData} .
613
+ * @private
614
+ */
615
+ public getRecordByTarget(e: PointerEvent | KeyboardEventArgs): IGanttData {
616
+ let ganttData: IGanttData;
617
+ let row: Element = closest(e.target as Element, 'div.' + cls.taskBarMainContainer);
618
+ if (!isNullOrUndefined(row)) {
619
+ const id: string = row.getAttribute('rowUniqueId');
620
+ ganttData = this.parent.getRecordByID(id);
621
+ } else {
622
+ row = closest(e.target as Element, 'tr');
623
+ if (row) {
624
+ const rowIndex: number = getValue('rowIndex', closest(e.target as Element, 'tr'));
625
+ ganttData = this.parent.currentViewData[rowIndex];
626
+ }
627
+ }
628
+ return ganttData;
629
+ }
630
+
631
+ /**
632
+ * To get gantt chart row elements
633
+ *
634
+ * @returns {NodeListOf<Element>} .
635
+ * @private
636
+ */
637
+ public getChartRows(): NodeListOf<Element> {
638
+ return document.getElementById(this.parent.element.id + 'GanttTaskTableBody').querySelectorAll('.e-chart-row');
639
+ }
640
+
641
+ /**
642
+ * Expand Collapse operations from gantt chart side
643
+ *
644
+ * @param {PointerEvent} e .
645
+ * @returns {void} .
646
+ * @private
647
+ */
648
+ private chartExpandCollapseRequest(e: PointerEvent): void {
649
+ if (this.parent.enableMultiTaskbar) {
650
+ return;
651
+ }
652
+ const target: EventTarget = e.target;
653
+ const parentElement: Element = closest((<HTMLElement>target), '.e-gantt-parent-taskbar');
654
+ const record: IGanttData = this.getRecordByTarget(e);
655
+ const chartRow: Node = closest(target as Element, 'tr');
656
+ const rowIndex: number = getValue('rowIndex', chartRow);
657
+ const gridRow: Node = this.parent.treeGrid.getRows()[rowIndex];
658
+ const args: object = { data: record, gridRow: gridRow, chartRow: chartRow, cancel: false };
659
+ this.isExpandCollapseFromChart = true;
660
+ if (parentElement.classList.contains('e-row-expand')) {
661
+ this.collapseGanttRow(args);
662
+ } else if (parentElement.classList.contains('e-row-collapse')) {
663
+ this.expandGanttRow(args);
664
+ }
665
+ }
666
+ /**
667
+ * @returns {void} .
668
+ * @private
669
+ */
670
+ public reRenderConnectorLines(): void {
671
+ this.parent.connectorLineModule.dependencyViewContainer.innerHTML = '';
672
+ this.parent.connectorLineIds = [];
673
+ this.parent.updatedConnectorLineCollection = [];
674
+ this.parent.predecessorModule.createConnectorLinesCollection();
675
+ this.parent.connectorLineModule.renderConnectorLines(this.parent.updatedConnectorLineCollection);
676
+ }
677
+
678
+ /**
679
+ * To collapse gantt rows
680
+ *
681
+ * @param {object} args .
682
+ * @param {boolean} isCancel .
683
+ * @returns {void} .
684
+ * @private
685
+ */
686
+ public collapseGanttRow(args: object, isCancel?: boolean): void {
687
+ if (isCancel) {
688
+ this.collapsedGanttRow(args);
689
+ } else {
690
+ this.parent.trigger('collapsing', args, (arg: object) => {
691
+ if (this.isExpandCollapseFromChart && !getValue('cancel', arg)) {
692
+ this.collapsedGanttRow(arg);
693
+ }
694
+ this.isExpandCollapseFromChart = false;
695
+ });
696
+ }
697
+ }
698
+
699
+ /**
700
+ * @returns {void} .
701
+ * @param {object} args .
702
+ * @private
703
+ */
704
+ public collapsedGanttRow(args: object): void {
705
+ const record: IGanttData = getValue('data', args);
706
+ if (this.isExpandCollapseFromChart) {
707
+ this.expandCollapseChartRows('collapse', getValue('chartRow', args), record, null);
708
+ this.parent.treeGrid.collapseRow(getValue('gridRow', args), record);
709
+ this.isExpandCollapseFromChart = false;
710
+ } else {
711
+ this.expandCollapseChartRows('collapse', getValue('chartRow', args), record, null);
712
+ }
713
+ // To render the child record on parent row after collapsing
714
+ if (this.parent.viewType === 'ResourceView') {
715
+ this.renderMultiTaskbar(record);
716
+ }
717
+ if (!this.parent.enableVirtualization) {
718
+ this.parent.updateContentHeight();
719
+ }
720
+ this.updateWidthAndHeight();
721
+ this.reRenderConnectorLines();
722
+ getValue('chartRow', args).setAttribute('aria-expanded', 'false');
723
+ this.parent.trigger('collapsed', args);
724
+ }
725
+
726
+ /**
727
+ * To expand gantt rows
728
+ *
729
+ * @returns {void} .
730
+ * @param {object} args .
731
+ * @param {boolean} isCancel .
732
+ * @private
733
+ */
734
+ public expandGanttRow(args: object, isCancel?: boolean): void {
735
+ if (isCancel) {
736
+ this.expandedGanttRow(args);
737
+ } else {
738
+ this.parent.trigger('expanding', args, (arg: object) => {
739
+ if (this.isExpandCollapseFromChart && !getValue('cancel', arg)) {
740
+ this.expandedGanttRow(arg);
741
+ }
742
+ this.isExpandCollapseFromChart = false;
743
+ });
744
+ }
745
+ }
746
+
747
+ /**
748
+ * @returns {void} .
749
+ * @param {object} args .
750
+ * @private
751
+ */
752
+ public expandedGanttRow(args: object): void {
753
+ const record: IGanttData = getValue('data', args);
754
+ if (this.isExpandCollapseFromChart) {
755
+ this.expandCollapseChartRows('expand', getValue('chartRow', args), record, null);
756
+ this.parent.treeGrid.expandRow(getValue('gridRow', args), record);
757
+ this.isExpandCollapseFromChart = false;
758
+ } else {
759
+ if (!this.parent.isExpandCollapseLevelMethod) {
760
+ this.expandCollapseChartRows('expand', getValue('chartRow', args), record, null);
761
+ }
762
+ this.parent.isExpandCollapseLevelMethod = false;
763
+ }
764
+ // To render the child record on parent row after expanding.
765
+ if (this.parent.viewType === 'ResourceView') {
766
+ this.renderMultiTaskbar(record);
767
+ }
768
+ if (!this.parent.enableVirtualization) {
769
+ this.parent.updateContentHeight();
770
+ }
771
+ this.updateWidthAndHeight();
772
+ this.reRenderConnectorLines();
773
+ getValue('chartRow', args).setAttribute('aria-expanded', 'true');
774
+ this.parent.trigger('expanded', args);
775
+ }
776
+ private renderMultiTaskbar(record: IGanttData): void {
777
+ if (this.parent.enableMultiTaskbar) {
778
+ this.parent.chartRowsModule.refreshRecords([record], true);
779
+ } else if (this.parent.showOverAllocation) {
780
+ this.parent.ganttChartModule.renderRangeContainer(this.parent.currentViewData);
781
+ }
782
+ }
783
+
784
+ /**
785
+ * On expand collapse operation row properties will be updated here.
786
+ *
787
+ * @param {string} action .
788
+ * @param {Node} rowElement .
789
+ * @param {IGanttData} record .
790
+ * @param {boolean} isChild .
791
+ * @returns {void} .
792
+ * @private
793
+ */
794
+ private expandCollapseChartRows(action: string, rowElement: Node, record: IGanttData, isChild: boolean): void {
795
+ let displayType: string;
796
+ if (action === 'expand') {
797
+ displayType = 'table-row';
798
+ if (!isChild) {
799
+ record.expanded = true;
800
+ }
801
+ const targetElement: NodeListOf<Element> = (rowElement as HTMLElement).querySelectorAll('.e-row-collapse');
802
+ for (let t: number = 0; t < targetElement.length; t++) {
803
+ addClass([targetElement[t]], 'e-row-expand');
804
+ removeClass([targetElement[t]], 'e-row-collapse');
805
+ }
806
+ } else if (action === 'collapse') {
807
+ displayType = 'none';
808
+ if (!isChild) {
809
+ record.expanded = false;
810
+ }
811
+ const targetElement: NodeListOf<Element> = (rowElement as HTMLElement).querySelectorAll('.e-row-expand');
812
+ for (let t: number = 0; t < targetElement.length; t++) {
813
+ addClass([targetElement[t]], 'e-row-collapse');
814
+ removeClass([targetElement[t]], 'e-row-expand');
815
+ }
816
+ }
817
+ const childRecords: IGanttData[] = record.childRecords;
818
+ const chartRows: NodeListOf<Element> = this.getChartRows();
819
+ const rows: HTMLElement[] = [];
820
+ for (let i: number = 0; i < chartRows.length; i++) {
821
+ if ((<HTMLElement>chartRows[i]).classList.contains('gridrowtaskId'
822
+ + record.ganttProperties.rowUniqueID + 'level' + (record.level + 1))) {
823
+ rows.push(<HTMLElement>chartRows[i]);
824
+ }
825
+ }
826
+ for (let i: number = 0; i < rows.length; i++) {
827
+ rows[i].style.display = displayType;
828
+ if ((childRecords[i].childRecords && childRecords[i].childRecords.length)
829
+ && (action === 'collapse' || childRecords[i].expanded || this.isExpandAll)) {
830
+ this.expandCollapseChartRows(action, rows[i], childRecords[i], true);
831
+ }
832
+ }
833
+ }
834
+
835
+ /**
836
+ * Public method to expand or collapse all the rows of Gantt
837
+ *
838
+ * @returns {void}
839
+ * @param {string} action .
840
+ * @private
841
+ */
842
+ public expandCollapseAll(action: string): void {
843
+ if (action === 'expand') {
844
+ this.isExpandAll = true;
845
+ this.parent.treeGrid.expandAll();
846
+ } else {
847
+ this.parent.treeGrid.collapseAll();
848
+ }
849
+ this.isExpandAll = false;
850
+ }
851
+
852
+ /**
853
+ * Public method to expand particular level of rows.
854
+ *
855
+ * @returns {void} .
856
+ * @param {number} level .
857
+ * @private
858
+ */
859
+ public expandAtLevel(level: number): void {
860
+ this.parent.treeGrid.expandAtLevel(level);
861
+ }
862
+
863
+ /**
864
+ * Public method to collapse particular level of rows.
865
+ *
866
+ * @returns {void} .
867
+ * @param {number} level .
868
+ * @private
869
+ */
870
+ public collapseAtLevel(level: number): void {
871
+ if (this.parent.enableVirtualization) {
872
+ this.parent.isExpandCollapseLevelMethod = true;
873
+ }
874
+ this.parent.treeGrid.collapseAtLevel(level);
875
+ }
876
+
877
+ /**
878
+ * Event Binding for gantt chart click
879
+ *
880
+ * @returns {void} .
881
+ */
882
+ private wireEvents(): void {
883
+ const isIE11Pointer: Boolean = Browser.isPointer; // eslint-disable-line
884
+ const mouseDown: string = Browser.touchStartEvent;
885
+ const mouseUp: string = Browser.touchEndEvent;
886
+ const mouseMove: string = Browser.touchMoveEvent;
887
+ const cancel: string = isIE11Pointer ? 'pointerleave' : 'mouseleave';
888
+ EventHandler.add(this.parent.chartPane, mouseDown, this.ganttChartMouseDown, this);
889
+ EventHandler.add(this.parent.chartPane, cancel, this.ganttChartLeave, this);
890
+ EventHandler.add(this.parent.chartPane, mouseMove, this.ganttChartMove, this);
891
+ if (this.parent.isAdaptive) {
892
+ EventHandler.add(this.parent.chartPane, click, this.ganttChartMouseClick, this);
893
+ EventHandler.add(this.parent.chartPane, mouseUp, this.ganttChartMouseUp, this);
894
+ }
895
+ if (!this.parent.isAdaptive) {
896
+ EventHandler.add(this.parent.element, mouseUp, this.documentMouseUp, this);
897
+ EventHandler.add(document, mouseUp, this.mouseUp, this);
898
+ }
899
+ EventHandler.add(this.parent.element, 'mousemove', this.mouseMoveHandler, this);
900
+ EventHandler.add(document.body, 'contextmenu', this.contextClick, this);
901
+ EventHandler.add(document, 'mouseup', this.contextClick, this);
902
+ EventHandler.add(this.parent.chartRowsModule.ganttChartTableBody, 'dblclick', this.doubleClickHandler, this);
903
+ }
904
+
905
+ private unWireEvents(): void {
906
+ const isIE11Pointer: Boolean = Browser.isPointer; // eslint-disable-line
907
+ const mouseDown: string = Browser.touchStartEvent;
908
+ const mouseUp: string = Browser.touchEndEvent;
909
+ const mouseMove: string = Browser.touchMoveEvent;
910
+ const cancel: string = isIE11Pointer ? 'pointerleave' : 'mouseleave';
911
+ EventHandler.remove(this.parent.chartRowsModule.ganttChartTableBody, mouseDown, this.ganttChartMouseDown);
912
+ EventHandler.remove(this.parent.chartPane, cancel, this.ganttChartLeave);
913
+ EventHandler.remove(this.parent.chartPane, mouseMove, this.ganttChartMove);
914
+ if (this.parent.isAdaptive) {
915
+ EventHandler.remove(this.parent.chartPane, click, this.ganttChartMouseClick);
916
+ EventHandler.remove(this.parent.chartPane, mouseUp, this.ganttChartMouseUp);
917
+ }
918
+ if (!this.parent.isAdaptive) {
919
+ EventHandler.remove(this.parent.element, mouseUp, this.documentMouseUp);
920
+ EventHandler.remove(document, mouseUp, this.mouseUp);
921
+ }
922
+ EventHandler.remove(this.parent.element, 'mousemove', this.mouseMoveHandler);
923
+ EventHandler.remove(document.body, 'contextmenu', this.contextClick);
924
+ EventHandler.remove(document, 'mouseup', this.contextClick);
925
+ EventHandler.remove(this.parent.chartRowsModule.ganttChartTableBody, 'dblclick', this.doubleClickHandler);
926
+ }
927
+
928
+ /**
929
+ * To get record by taskbar element.
930
+ *
931
+ * @param {Element} target .
932
+ * @returns {IGanttData} .
933
+ * @private
934
+ */
935
+ public getRecordByTaskBar(target: Element): IGanttData {
936
+ const item: IGanttData = this.parent.currentViewData[this.getIndexByTaskBar(target)];
937
+ return item;
938
+ }
939
+ /**
940
+ * Trigger Tab & Shift + Tab keypress to highlight active element.
941
+ *
942
+ * @param {KeyboardEventArgs} e .
943
+ * @returns {void} .
944
+ * @private
945
+ */
946
+ public onTabAction(e: KeyboardEventArgs): void {
947
+ this.parent.treeGrid.grid.enableHeaderFocus = this.parent.enableHeaderFocus;
948
+ const isInEditedState: boolean = this.parent.editModule && this.parent.editModule.cellEditModule &&
949
+ this.parent.editModule.cellEditModule.isCellEdit;
950
+ if (!this.parent.showActiveElement && !isInEditedState) {
951
+ return;
952
+ }
953
+ const $target: Element = isInEditedState ? (e.target as Element).closest('.e-rowcell') : e.target as Element;
954
+ if ($target.closest('.e-rowcell') || $target.closest('.e-chart-row')) {
955
+ this.parent.focusModule.setActiveElement($target as HTMLElement);
956
+ }
957
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
958
+ this.focusedRowIndex = $target.closest('.e-rowcell') ? ($target.parentElement as any).rowIndex :
959
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
960
+ $target.closest('.e-chart-row') ? ($target.closest('.e-chart-row') as any).rowIndex : -1;
961
+ const isTab: boolean = (e.action === 'tab') ? true : false;
962
+ const nextElement: Element | string = this.getNextElement($target, isTab, isInEditedState);
963
+ if (nextElement === 'noNextRow') {
964
+ this.manageFocus($target as HTMLElement, 'remove', true);
965
+ return;
966
+ }
967
+ if (typeof nextElement !== 'string') {
968
+ if ($target.classList.contains('e-rowcell') || $target.closest('.e-chart-row-cell') ||
969
+ $target.classList.contains('e-headercell') || $target.closest('.e-segmented-taskbar')) {
970
+ e.preventDefault();
971
+ }
972
+ if(isTab && $target.classList.contains('e-rowdragdrop')){
973
+ this.parent.treeGrid.grid.notify('key-pressed', e);
974
+ return;
975
+ }
976
+ if ($target.classList.contains('e-rowcell') && (nextElement && nextElement.classList.contains('e-rowcell')) ||
977
+ $target.classList.contains('e-headercell')){ // eslint-disable-line
978
+ if (isTab) {
979
+ if (this.parent.editSettings.allowNextRowEdit) {
980
+ const rowData: IGanttData = this.parent.currentViewData[this.focusedRowIndex];
981
+ const columnName: string = this.parent.ganttColumns[nextElement.getAttribute('aria-colindex')].field;
982
+ if (rowData.hasChildRecords) {
983
+ if (columnName === this.parent.taskFields.endDate || columnName ===
984
+ this.parent.taskFields.duration || columnName === this.parent.taskFields.dependency ||
985
+ columnName === this.parent.taskFields.progress || columnName === this.parent.taskFields.work ||
986
+ columnName === 'taskType') {
987
+ this.parent.treeGrid.grid.endEdit();
988
+ this.parent.treeGrid.grid.notify('key-pressed', e);
989
+ } else if (columnName === this.parent.taskFields.name || columnName === this.parent.taskFields.startDate) {
990
+ this.parent.treeGrid.grid.notify('key-pressed', e);
991
+ } else {
992
+ this.parent.treeGrid.grid.notify('key-pressed', e);
993
+ this.parent.treeGrid.editCell(this.focusedRowIndex,columnName); // eslint-disable-line
994
+ }
995
+ } else {
996
+ this.parent.treeGrid.grid.notify('key-pressed', e);
997
+ }
998
+ } else {
999
+ this.parent.treeGrid.grid.notify('key-pressed', e);
1000
+ }
1001
+ } else {
1002
+ this.parent.treeGrid.grid.notify('key-pressed', e);
1003
+ }
1004
+ }
1005
+ if (!this.parent.editModule.cellEditModule.isCellEdit) {
1006
+ if (nextElement) {
1007
+ if ($target.classList.contains('e-rowcell')) {
1008
+ this.manageFocus($target as HTMLElement, 'remove', false);
1009
+ } else {
1010
+ this.manageFocus($target as HTMLElement, 'remove', true);
1011
+ }
1012
+ if (nextElement.classList.contains('e-rowcell') && $target.nextElementSibling) {
1013
+ if (!$target.classList.contains('e-rowcell')) {
1014
+ this.parent.treeGrid.grid.notify('key-pressed', e);
1015
+ const fmodule: FocusStrategy = getValue('focusModule', this.parent.treeGrid.grid);
1016
+ fmodule.currentInfo.element = nextElement as HTMLElement;
1017
+ fmodule.currentInfo.elementToFocus = nextElement as HTMLElement;
1018
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
1019
+ fmodule.content.matrix.current = [(nextElement.parentElement as any).rowIndex, (nextElement as any).cellIndex];
1020
+ }
1021
+ this.manageFocus(nextElement as HTMLElement, 'add', false);
1022
+ } else {
1023
+ this.manageFocus(nextElement as HTMLElement, 'add', true);
1024
+ }
1025
+ this.parent.focusModule.setActiveElement(nextElement as HTMLElement);
1026
+ }
1027
+ }
1028
+ }
1029
+ }
1030
+ /**
1031
+ * Get next/previous sibling element.
1032
+ *
1033
+ * @param {Element} $target .
1034
+ * @param {boolean} isTab .
1035
+ * @param {boolean} isInEditedState .
1036
+ * @returns {Element | string} .
1037
+ */
1038
+ private getNextElement($target: Element, isTab: boolean, isInEditedState: boolean): Element | string {
1039
+ let nextElement: Element = isTab ? $target.nextElementSibling : $target.previousElementSibling;
1040
+ while (nextElement && nextElement.parentElement.classList.contains('e-row')) {
1041
+ if (!nextElement.matches('.e-hide') && !nextElement.matches('.e-rowdragdrop')) {
1042
+ return nextElement;
1043
+ }
1044
+ nextElement = isTab ? nextElement.nextElementSibling : nextElement.previousElementSibling;
1045
+ }
1046
+ if (!isNullOrUndefined(nextElement) && (nextElement.classList.contains('e-taskbar-main-container')
1047
+ || nextElement.classList.contains('e-right-connectorpoint-outer-div'))) {
1048
+ const record: IGanttData = this.parent.currentViewData[this.focusedRowIndex];
1049
+ if (!isNullOrUndefined(record.ganttProperties.segments) && record.ganttProperties.segments.length > 0) {
1050
+ nextElement = nextElement.classList.contains('e-right-connectorpoint-outer-div')
1051
+ ? nextElement.parentElement.nextElementSibling
1052
+ : nextElement.getElementsByClassName('e-gantt-child-taskbar-inner-div')[0];
1053
+ }
1054
+ }
1055
+ if (this.validateNextElement(nextElement)) {
1056
+ return nextElement;
1057
+ } else {
1058
+ let rowIndex: number = -1;
1059
+ let rowElement: Element = null;
1060
+ let childElement: Element | string;
1061
+ if ($target.classList.contains('e-rowcell') && isInEditedState && this.parent.editSettings.allowNextRowEdit) {
1062
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
1063
+ rowIndex = ($target.parentElement as any).rowIndex;
1064
+ rowElement = this.getNextRowElement(rowIndex, isTab, true);
1065
+ childElement = this.getChildElement(rowElement, isTab);
1066
+ return childElement;
1067
+ } else if ($target.classList.contains('e-rowcell')) {
1068
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
1069
+ rowIndex = ($target.parentElement as any).rowIndex;
1070
+ if (isTab) {
1071
+ rowElement = this.parent.getRowByIndex(rowIndex);
1072
+ if (this.validateNextElement(rowElement, 'e-left-label-container')) {
1073
+ return rowElement.getElementsByClassName('e-left-label-container')[0];
1074
+ } else if (this.validateNextElement(rowElement, 'e-taskbar-main-container')) {
1075
+ return rowElement.getElementsByClassName('e-taskbar-main-container')[0];
1076
+ } else if (this.validateNextElement(rowElement, 'e-right-label-container')) {
1077
+ return rowElement.getElementsByClassName('e-right-label-container')[0];
1078
+ }
1079
+ } else {
1080
+ rowElement = this.getNextRowElement(rowIndex, isTab, false);
1081
+ if (this.validateNextElement(rowElement, 'e-right-label-container')) {
1082
+ return rowElement.getElementsByClassName('e-right-label-container')[0];
1083
+ } else if (this.validateNextElement(rowElement, 'e-taskbar-main-container')) {
1084
+ return rowElement.getElementsByClassName('e-taskbar-main-container')[0];
1085
+ } else if (this.validateNextElement(rowElement, 'e-left-label-container')) {
1086
+ return rowElement.getElementsByClassName('e-left-label-container')[0];
1087
+ }
1088
+ }
1089
+ } else if ($target.parentElement.classList.contains('e-chart-row-cell') ||
1090
+ $target.parentElement.parentElement.classList.contains('e-chart-row-cell')) {
1091
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
1092
+ rowIndex = (closest($target, '.e-chart-row') as any).rowIndex;
1093
+ if (isTab) {
1094
+ rowElement = this.getNextRowElement(rowIndex, isTab, true);
1095
+ } else {
1096
+ rowElement = this.parent.treeGrid.grid.getRowByIndex(rowIndex);
1097
+ }
1098
+ const childElement : Element | string = this.getChildElement(rowElement, isTab);
1099
+ return childElement;
1100
+ }
1101
+ }
1102
+ return null;
1103
+ }
1104
+ /**
1105
+ * Get next/previous row element.
1106
+ *
1107
+ * @param {number} rowIndex .
1108
+ * @param {boolean} isTab .
1109
+ * @param {boolean} isChartRow .
1110
+ * @returns {Element} .
1111
+ */
1112
+ private getNextRowElement(rowIndex: number, isTab: boolean, isChartRow: boolean): Element {
1113
+ const expandedRecords: IGanttData[] = this.parent.getExpandedRecords(this.parent.currentViewData);
1114
+ const currentItem: IGanttData = this.parent.currentViewData[rowIndex];
1115
+ const expandedRecordIndex: number = expandedRecords.indexOf(currentItem);
1116
+ const nextRecord: IGanttData = isTab ? expandedRecords[expandedRecordIndex + 1] : expandedRecords[expandedRecordIndex - 1];
1117
+ const nextRowIndex: number = this.parent.currentViewData.indexOf(nextRecord);
1118
+ if (nextRecord) {
1119
+ return isChartRow ? this.parent.treeGrid.grid.getRowByIndex(nextRowIndex) : this.parent.getRowByIndex(nextRowIndex);
1120
+ } else {
1121
+ return null;
1122
+ }
1123
+ }
1124
+ /**
1125
+ * Validate next/previous sibling element haschilds.
1126
+ *
1127
+ * @param {Element} $target .
1128
+ * @param {string} className .
1129
+ * @returns {boolean} .
1130
+ */
1131
+ private validateNextElement($target: Element, className?: string): boolean {
1132
+ if ($target && $target.classList.contains('e-rowcell')) {
1133
+ return true;
1134
+ }
1135
+ if ($target && className) {
1136
+ const elementByClass: Element = $target.getElementsByClassName(className)[0];
1137
+ return (elementByClass && elementByClass.hasChildNodes()) ? true : false;
1138
+ } else if ($target) {
1139
+ return (!isNullOrUndefined($target) && $target.hasChildNodes()) ? true : false;
1140
+ }
1141
+ return false;
1142
+ }
1143
+ /**
1144
+ * Getting child element based on row element.
1145
+ *
1146
+ * @param {Element} rowElement .
1147
+ * @param {boolean} isTab .
1148
+ * @returns {Element | string} .
1149
+ */
1150
+ private getChildElement(rowElement: Element, isTab?: boolean): Element | string {
1151
+ let childElement: Element;
1152
+ if (rowElement) {
1153
+ childElement = isTab ? rowElement.children[0] : rowElement.children[rowElement.children.length - 1];
1154
+ while (childElement) {
1155
+ if (!childElement.matches('.e-hide') && !childElement.matches('.e-rowdragdrop')) {
1156
+ return childElement;
1157
+ }
1158
+ childElement = isTab ? childElement.nextElementSibling : childElement.previousElementSibling;
1159
+ }
1160
+ } else {
1161
+ return 'noNextRow';
1162
+ }
1163
+ return childElement;
1164
+ }
1165
+ /**
1166
+ * Add/Remove active element.
1167
+ *
1168
+ * @private
1169
+ * @param {HTMLElement} element .
1170
+ * @param {string} focus .
1171
+ * @param {boolean} isChartElement .
1172
+ * @returns {void} .
1173
+ */
1174
+ public manageFocus(element: HTMLElement, focus: string, isChartElement?: boolean): void {
1175
+ if (isChartElement) {
1176
+ let childElement: Element = null;
1177
+ if (element.classList.contains('e-left-label-container') ||
1178
+ element.classList.contains('e-right-label-container')) {
1179
+ childElement = element.getElementsByTagName('span')[0];
1180
+ } else if (element.classList.contains('e-taskbar-main-container')
1181
+ || element.classList.contains('e-gantt-child-taskbar-inner-div')) {
1182
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
1183
+ const rowIndex: number = (closest(element, '.e-chart-row') as any).rowIndex;
1184
+ const data: IGanttData = this.parent.currentViewData[rowIndex];
1185
+ const className: string = data.hasChildRecords ? data.ganttProperties.isAutoSchedule ? 'e-gantt-parent-taskbar' :
1186
+ 'e-manualparent-main-container' :
1187
+ data.ganttProperties.isMilestone ? 'e-gantt-milestone' : !isNullOrUndefined(data.ganttProperties.segments)
1188
+ && data.ganttProperties.segments.length > 0 ? 'e-segmented-taskbar' : 'e-gantt-child-taskbar';
1189
+ childElement = element.getElementsByClassName(className)[0];
1190
+ if (isNullOrUndefined(childElement)) {
1191
+ childElement = element;
1192
+ }
1193
+ }
1194
+ if (focus === 'add' && !isNullOrUndefined(childElement)) {
1195
+ element.setAttribute('tabIndex', '0');
1196
+ addClass([childElement], 'e-active-container');
1197
+ element.focus();
1198
+ this.focusedElement = childElement as HTMLElement;
1199
+ } else if (!isNullOrUndefined(childElement)) {
1200
+ removeClass([childElement], 'e-active-container');
1201
+ element.setAttribute('tabIndex', '-1');
1202
+ element.blur();
1203
+ }
1204
+ } else {
1205
+ if (focus === 'add') {
1206
+ element.setAttribute('tabIndex', '0');
1207
+ addClass([element], ['e-focused', 'e-focus']);
1208
+ element.focus();
1209
+ } else {
1210
+ element.setAttribute('tabIndex', '-1');
1211
+ removeClass([element], ['e-focused', 'e-focus']);
1212
+ element.blur();
1213
+ }
1214
+ }
1215
+ }
1216
+ /**
1217
+ * To get index by taskbar element.
1218
+ *
1219
+ * @param {Element} target .
1220
+ * @returns {number} .
1221
+ * @private
1222
+ */
1223
+ public getIndexByTaskBar(target: Element): number {
1224
+ let row: Element;
1225
+ let recordIndex: number;
1226
+ if (!target.classList.contains(cls.taskBarMainContainer)) {
1227
+ row = closest(target, 'div.' + cls.taskBarMainContainer);
1228
+ } else {
1229
+ row = target;
1230
+ }
1231
+ if (isNullOrUndefined(row)) {
1232
+ row = closest(target, 'tr.' + cls.chartRow);
1233
+ recordIndex = [].slice.call(this.parent.chartRowsModule.ganttChartTableBody.childNodes).indexOf(row);
1234
+ } else {
1235
+ const id: string = row.getAttribute('rowUniqueId');
1236
+ const record: IGanttData = this.parent.getRecordByID(id);
1237
+ recordIndex = this.parent.currentViewData.indexOf(record);
1238
+ }
1239
+ return recordIndex;
1240
+ }
1241
+
1242
+ private destroy(): void {
1243
+ this.removeEventListener();
1244
+ this.unWireEvents();
1245
+ this.scrollObject.destroy();
1246
+ this.scrollObject = null;
1247
+ }
1248
+ }