@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,1838 @@
1
+ import { createElement, isNullOrUndefined, extend, compile, getValue, setValue } from '@syncfusion/ej2-base';
2
+ import { formatUnit, addClass } from '@syncfusion/ej2-base';
3
+ import { Gantt } from '../base/gantt';
4
+ import { isScheduledTask } from '../base/utils';
5
+ import { DataManager, Query } from '@syncfusion/ej2-data';
6
+ import * as cls from '../base/css-constants';
7
+ import { DateProcessor } from '../base/date-processor';
8
+ import { IGanttData, IQueryTaskbarInfoEventArgs, IParent, IIndicator, ITaskData, ITaskSegment } from '../base/interface';
9
+ import { Row, Column } from '@syncfusion/ej2-grids';
10
+ import { TaskFieldsModel } from '../models/models';
11
+ import { CObject } from '../base/enum';
12
+ /**
13
+ * To render the chart rows in Gantt
14
+ */
15
+ export class ChartRows extends DateProcessor {
16
+ public ganttChartTableBody: Element;
17
+ public taskTable: HTMLElement;
18
+ protected parent: Gantt;
19
+ public taskBarHeight: number = 0;
20
+ public milestoneHeight: number = 0;
21
+ private milesStoneRadius: number = 0;
22
+ private baselineTop: number = 0;
23
+ public baselineHeight: number = 8;
24
+ private baselineColor: string;
25
+ private parentTaskbarTemplateFunction: Function;
26
+ private leftTaskLabelTemplateFunction: Function;
27
+ private rightTaskLabelTemplateFunction: Function;
28
+ private taskLabelTemplateFunction: Function;
29
+ private childTaskbarTemplateFunction: Function;
30
+ private milestoneTemplateFunction: Function;
31
+ private templateData: IGanttData;
32
+ private touchLeftConnectorpoint: string = '';
33
+ private touchRightConnectorpoint: string = '';
34
+ public connectorPointWidth: number;
35
+ private connectorPointMargin: number;
36
+ public taskBarMarginTop: number;
37
+ public milestoneMarginTop: number;
38
+ private dropSplit: boolean = false;
39
+ private refreshedTr: Element[] = [];
40
+ private refreshedData: IGanttData[] = [];
41
+ private isUpdated: boolean = true;
42
+ constructor(ganttObj?: Gantt) {
43
+ super(ganttObj);
44
+ this.parent = ganttObj;
45
+ this.initPublicProp();
46
+ this.addEventListener();
47
+ }
48
+
49
+ /**
50
+ * To initialize the public property.
51
+ *
52
+ * @returns {void}
53
+ * @private
54
+ */
55
+ private initPublicProp(): void {
56
+ this.ganttChartTableBody = null;
57
+ }
58
+
59
+ private addEventListener(): void {
60
+ this.parent.on('renderPanels', this.createChartTable, this);
61
+ this.parent.on('dataReady', this.initiateTemplates, this);
62
+ this.parent.on('destroy', this.destroy, this);
63
+ }
64
+
65
+ public refreshChartByTimeline(): void {
66
+ this.taskTable.style.width = formatUnit(this.parent.timelineModule.totalTimelineWidth);
67
+ const prevDate: Date = getValue('prevProjectStartDate', this.parent.dataOperation);
68
+ let isUpdated: boolean = false;
69
+ if (prevDate) {
70
+ isUpdated = prevDate.getTime() === this.parent.cloneProjectStartDate.getTime();
71
+ }
72
+ this.isUpdated = this.parent.isFromOnPropertyChange && isUpdated &&
73
+ getValue('mutableData', this.parent.treeGrid.grid.contentModule) ? true : false;
74
+ this.refreshGanttRows();
75
+ this.isUpdated = true;
76
+ }
77
+
78
+ /**
79
+ * To render chart rows.
80
+ *
81
+ * @returns {void}
82
+ * @private
83
+ */
84
+ private createChartTable(): void {
85
+ this.taskTable = createElement('table', {
86
+ className: cls.taskTable + ' ' + cls.zeroSpacing, id: 'GanttTaskTable' + this.parent.element.id,
87
+ styles: 'z-index: 2;position: absolute;width:' + this.parent.timelineModule.totalTimelineWidth + 'px;',
88
+ attrs: { cellspacing: '0.25px' }
89
+ });
90
+ const colgroup: Element = createElement('colgroup');
91
+ const column: Element = createElement('col', { styles: 'width:' + this.parent.timelineModule.totalTimelineWidth + 'px;' });
92
+ colgroup.appendChild(column);
93
+ this.taskTable.appendChild(colgroup);
94
+ this.ganttChartTableBody = createElement('tbody', {
95
+ id: this.parent.element.id + 'GanttTaskTableBody'
96
+ });
97
+ this.taskTable.appendChild(this.ganttChartTableBody);
98
+ this.parent.ganttChartModule.chartBodyContent.appendChild(this.taskTable);
99
+ }
100
+
101
+ public initiateTemplates(): void {
102
+ this.taskTable.style.width = formatUnit(this.parent.timelineModule.totalTimelineWidth);
103
+ this.initChartHelperPrivateVariable();
104
+ this.initializeChartTemplate();
105
+ }
106
+ /**
107
+ * To render chart rows.
108
+ *
109
+ * @returns {void}
110
+ * @private
111
+ */
112
+ public renderChartRows(): void {
113
+ this.createTaskbarTemplate();
114
+ this.parent.isGanttChartRendered = true;
115
+ }
116
+
117
+ /**
118
+ * To get gantt Indicator.
119
+ *
120
+ * @param {IIndicator} indicator .
121
+ * @returns {NodeList} .
122
+ * @private
123
+ */
124
+ private getIndicatorNode(indicator: IIndicator): NodeList {
125
+ const templateString: string = '<label class="' + cls.label + ' ' + cls.taskIndicatorDiv + '" role="LabelIndicator" style="line-height:'
126
+ + (this.parent.rowHeight) + 'px;' +
127
+ 'left:' + this.getIndicatorleft(indicator.date) + 'px;"><i class="' + indicator.iconClass + '"></i> </label>';
128
+ return this.createDivElement(templateString);
129
+ }
130
+
131
+ /**
132
+ * To get gantt Indicator.
133
+ *
134
+ * @param {Date | string} date .
135
+ * @returns {number} .
136
+ * @private
137
+ */
138
+ public getIndicatorleft(date: Date | string): number {
139
+ date = this.parent.dateValidationModule.getDateFromFormat(date);
140
+ const left: number = this.parent.dataOperation.getTaskLeft(date, false);
141
+ return left;
142
+ }
143
+
144
+ /**
145
+ * To get child taskbar Node.
146
+ *
147
+ * @param {number} i .
148
+ * @param {NodeList} rootElement .
149
+ * @returns {NodeList} .
150
+ * @private
151
+ */
152
+ private getChildTaskbarNode(i: number, rootElement?: NodeList): NodeList {
153
+ let childTaskbarNode: NodeList = null;
154
+ const data: IGanttData = this.templateData;
155
+ if (this.childTaskbarTemplateFunction) {
156
+ childTaskbarNode = this.childTaskbarTemplateFunction(
157
+ extend({ index: i }, data), this.parent, 'TaskbarTemplate',
158
+ this.getTemplateID('TaskbarTemplate'), false, undefined, rootElement[0], this.parent.treeGrid['root']);
159
+ } else {
160
+ let labelString: string = '';
161
+ let taskLabel: string = '';
162
+ let taskbarInnerDiv: NodeList;
163
+ let progressDiv: NodeList;
164
+ if (data.ganttProperties.startDate && data.ganttProperties.endDate
165
+ && data.ganttProperties.duration) {
166
+ taskbarInnerDiv = this.createDivElement('<div class="' + cls.childTaskBarInnerDiv + ' ' + cls.traceChildTaskBar +
167
+ ' ' + (data.ganttProperties.isAutoSchedule ? '' : cls.manualChildTaskBar) + '"' +
168
+ 'style="width:' + data.ganttProperties.width + 'px;height:' +
169
+ (this.taskBarHeight) + 'px;"></div>');
170
+ progressDiv = this.createDivElement('<div class="' + cls.childProgressBarInnerDiv + ' ' +
171
+ cls.traceChildProgressBar + ' ' + (data.ganttProperties.isAutoSchedule ?
172
+ '' : cls.manualChildProgressBar) + '"' +
173
+ ' style="border-style:' + (data.ganttProperties.progressWidth ? 'solid;' : 'none;') +
174
+ 'width:' + data.ganttProperties.progressWidth + 'px;height:100%;' +
175
+ 'border-top-right-radius:' + this.getBorderRadius(data.ganttProperties) + 'px;' +
176
+ 'border-bottom-right-radius:' + this.getBorderRadius(data.ganttProperties) + 'px;">' +
177
+ '</div>');
178
+
179
+ }
180
+ if (this.taskLabelTemplateFunction && !isNullOrUndefined(progressDiv) && progressDiv.length > 0) {
181
+ const taskLabelTemplateNode: NodeList = this.taskLabelTemplateFunction(
182
+ extend({ index: i }, data), this.parent, 'TaskLabelTemplate',
183
+ this.getTemplateID('TaskLabelTemplate'), false, undefined, progressDiv[0]);
184
+ if (taskLabelTemplateNode && taskLabelTemplateNode.length > 0) {
185
+ const tempDiv: Element = createElement('div');
186
+ tempDiv.appendChild(taskLabelTemplateNode[0]);
187
+ labelString = tempDiv.innerHTML;
188
+ }
189
+ } else {
190
+ labelString = this.getTaskLabel(this.parent.labelSettings.taskLabel);
191
+ labelString = labelString === 'isCustomTemplate' ? this.parent.labelSettings.taskLabel : labelString;
192
+ }
193
+ if (labelString !== 'null') {
194
+ if (isNaN(parseInt(labelString))) {
195
+ taskLabel = '<span class="' + cls.taskLabel + '" style="line-height:' +
196
+ (this.taskBarHeight - 1) + 'px; text-align: left;' +
197
+ 'display:' + 'inline-block;' +
198
+ 'width:' + (data.ganttProperties.width - 10) + 'px; height:' +
199
+ this.taskBarHeight + 'px;">' + labelString + '</span>';
200
+ } else {
201
+ taskLabel = '<span class="' + cls.taskLabel + '" style="line-height:' +
202
+ (this.taskBarHeight - 1) + 'px;' + (this.parent.viewType === 'ResourceView' ? 'text-align: left;' : '') +
203
+ + (this.parent.viewType === 'ResourceView' ? 'display:inline-flex;' : '') +
204
+ + (this.parent.viewType === 'ResourceView' ? (data.ganttProperties.width - 10) : '') + 'px; height:' +
205
+ this.taskBarHeight + 'px;">' + labelString + '</span>';
206
+ }
207
+ }
208
+ const template: string = !isNullOrUndefined(data.ganttProperties.segments) && data.ganttProperties.segments.length > 0 ?
209
+ this.splitTaskbar(data, labelString) : (data.ganttProperties.startDate && data.ganttProperties.endDate
210
+ && data.ganttProperties.duration) ? (taskLabel) :
211
+ (data.ganttProperties.startDate && !data.ganttProperties.endDate && !data.ganttProperties.duration) ? (
212
+ '<div class="' + cls.childProgressBarInnerDiv + ' ' + cls.traceChildTaskBar + ' ' +
213
+ cls.unscheduledTaskbarLeft + ' ' + (data.ganttProperties.isAutoSchedule ?
214
+ '' : cls.manualChildTaskBar) + '"' +
215
+ 'style="left:' + data.ganttProperties.left + 'px; height:' + this.taskBarHeight + 'px;"></div>') :
216
+ (data.ganttProperties.endDate && !data.ganttProperties.startDate && !data.ganttProperties.duration) ?
217
+ ('<div class="' + cls.childProgressBarInnerDiv + ' ' + cls.traceChildTaskBar + ' ' +
218
+ cls.unscheduledTaskbarRight + ' ' + (data.ganttProperties.isAutoSchedule ?
219
+ '' : cls.manualChildTaskBar) + '"' +
220
+ 'style="left:' + data.ganttProperties.left + 'px; height:' + this.taskBarHeight + 'px;"></div>') :
221
+ (data.ganttProperties.duration && !data.ganttProperties.startDate && !data.ganttProperties.endDate) ?
222
+ ('<div class="' + cls.childProgressBarInnerDiv + ' ' + cls.traceChildTaskBar + ' ' +
223
+ cls.unscheduledTaskbar + ' ' + (data.ganttProperties.isAutoSchedule ?
224
+ '' : cls.manualChildTaskBar) + '"' +
225
+ 'style="left:' + data.ganttProperties.left + 'px; width:' + data.ganttProperties.width + 'px;' +
226
+ ' height:' + this.taskBarHeight + 'px;"></div>') : '';
227
+ if (data.ganttProperties.startDate && data.ganttProperties.endDate && data.ganttProperties.duration &&
228
+ (isNullOrUndefined(data.ganttProperties.segments) || (!isNullOrUndefined(data.ganttProperties.segments) &&
229
+ data.ganttProperties.segments.length === 0))) {
230
+ if (template !== '' && !isNullOrUndefined(progressDiv) && progressDiv.length > 0) {
231
+ progressDiv[0].appendChild([].slice.call(this.createDivElement(template))[0]);
232
+ }
233
+ if (!isNullOrUndefined(taskbarInnerDiv) && taskbarInnerDiv.length > 0) {
234
+ taskbarInnerDiv[0].appendChild([].slice.call(progressDiv)[0]);
235
+ }
236
+ childTaskbarNode = taskbarInnerDiv;
237
+ } else {
238
+ childTaskbarNode = this.createDivElement(template);
239
+ }
240
+ }
241
+ return childTaskbarNode;
242
+ }
243
+
244
+ private splitTaskbar(data: IGanttData, labelString: string): string {
245
+ let splitTasks: string = '';
246
+ for (let i: number = 0; i < data.ganttProperties.segments.length; i++) {
247
+ const segment: ITaskSegment = data.ganttProperties.segments[i];
248
+ const segmentPosition: string = (i === 0) ? 'e-segment-first' : (i === data.ganttProperties.segments.length - 1)
249
+ ? 'e-segment-last' : 'e-segment-inprogress';
250
+ splitTasks += (
251
+ //split taskbar
252
+ '<div class="' + cls.childTaskBarInnerDiv + ' ' + segmentPosition + ' ' + cls.traceChildTaskBar + ' ' +
253
+ ' e-segmented-taskbar' +
254
+ '"style="width:' + segment.width + 'px;position: absolute; left:' + segment.left + 'px;height:' +
255
+ (this.taskBarHeight) + 'px; overflow: initial;" data-segment-index = "' + i + '" aria-label = "' +
256
+ this.generateSpiltTaskAriaLabel(segment, data.ganttProperties) + '"> ' +
257
+ this.getSplitTaskbarLeftResizerNode() +
258
+ //split progress bar
259
+ '<div class="' + cls.childProgressBarInnerDiv + ' ' + cls.traceChildProgressBar + ' ' +
260
+
261
+ '" style="border-style:' + (segment.progressWidth ? 'solid;' : 'none;') +
262
+ 'display:' + (segment.progressWidth >= 0 ? 'block;' : 'none;') +
263
+ 'width:' + segment.progressWidth + 'px;height:100%;' +
264
+ 'border-top-right-radius:' + this.getSplitTaskBorderRadius(segment) + 'px;' +
265
+ 'border-bottom-right-radius:' + this.getSplitTaskBorderRadius(segment) + 'px;">' +
266
+ // progress label
267
+ '<span class="' + cls.taskLabel + '" style="line-height:' +
268
+ (this.taskBarHeight - 1) + 'px;display:' + (segment.showProgress ? 'inline;' : 'none;') +
269
+ 'height:' + this.taskBarHeight + 'px;">' + labelString + '</span>' +
270
+ '</div>' +
271
+
272
+ this.getSplitTaskbarRightResizerNode(segment) +
273
+ (segment.showProgress ? this.getSplitProgressResizerNode(segment) : '') +
274
+ '</div></div>');
275
+ }
276
+ return splitTasks;
277
+ }
278
+
279
+ private getSplitTaskbarLeftResizerNode(): string {
280
+ const lResizerLeft: number = -(this.parent.isAdaptive ? 12 : 2);
281
+ const template: string = '<div class="' + cls.taskBarLeftResizer + ' ' + cls.icon + '"' +
282
+ ' style="left:' + lResizerLeft + 'px;height:' + (this.taskBarHeight) + 'px;"></div>';
283
+ return template;
284
+ }
285
+
286
+ private getSplitTaskbarRightResizerNode(segment: ITaskSegment): string {
287
+ const rResizerLeft: number = this.parent.isAdaptive ? -2 : -10;
288
+ const template: string = '<div class="' + cls.taskBarRightResizer + ' ' + cls.icon + '"' +
289
+ ' style="left:' + (segment.width + rResizerLeft) + 'px;' +
290
+ 'height:' + (this.taskBarHeight) + 'px;"></div>';
291
+ return template;
292
+ }
293
+
294
+ private getSplitProgressResizerNode(segment: ITaskSegment): string {
295
+ const template: string = '<div class="' + cls.childProgressResizer + '"' +
296
+ ' style="left:' + (segment.progressWidth - 6) + 'px;margin-top:' +
297
+ (this.taskBarHeight - 4) + 'px;"><div class="' + cls.progressBarHandler + '"' +
298
+ '><div class="' + cls.progressHandlerElement + '"></div>' +
299
+ '<div class="' + cls.progressBarHandlerAfter + '"></div></div>';
300
+ return template;
301
+ }
302
+
303
+ public getSegmentIndex(splitStartDate: Date, record: IGanttData): number {
304
+ let segmentIndex: number = -1;
305
+ const ganttProp: ITaskData = record.ganttProperties;
306
+ const segments: ITaskSegment[] = ganttProp.segments;
307
+ if (!isNullOrUndefined(segments)) {
308
+ segments.sort((a: ITaskSegment, b: ITaskSegment) => {
309
+ return a.startDate.getTime() - b.startDate.getTime();
310
+ });
311
+ const length: number = segments.length;
312
+ for (let i: number = 0; i < length; i++) {
313
+ const segment: ITaskSegment = segments[i];
314
+ // To find if user tend to split the start date of a main taskbar
315
+ // purpose of this to restrict the split action
316
+ if (splitStartDate.getTime() === ganttProp.startDate.getTime()) {
317
+ this.dropSplit = true;
318
+ segmentIndex = 0;
319
+ // To find the if user tend to split the first date of already segmented task.
320
+ // purpose of this to move on day of a segment
321
+ } else if (splitStartDate.getTime() === segment.startDate.getTime()) {
322
+ this.dropSplit = true;
323
+ let sDate: Date = segment.startDate;
324
+ sDate.setDate(sDate.getDate() + 1);
325
+ sDate = segment.startDate = this.parent.dataOperation.checkStartDate(sDate, ganttProp, false);
326
+ segment.startDate = sDate;
327
+ let eDate: Date = segment.endDate;
328
+ eDate = this.parent.dataOperation.getEndDate(
329
+ sDate, segment.duration, ganttProp.durationUnit, ganttProp, false
330
+ );
331
+ segment.endDate = eDate;
332
+ if (i === segments.length - 1) {
333
+ this.parent.setRecordValue('endDate', eDate, ganttProp, true);
334
+ }
335
+ this.incrementSegments(segments, i, record);
336
+ segmentIndex = segment.segmentIndex;
337
+ // To find if the user tend to split the segment and find the segment index
338
+ } else {
339
+ segment.endDate = this.parent.dataOperation.getEndDate(
340
+ segment.startDate, segment.duration, ganttProp.durationUnit, ganttProp, false
341
+ );
342
+ if (splitStartDate.getTime() >= segment.startDate.getTime() && splitStartDate.getTime() <= segment.endDate.getTime()) {
343
+ segmentIndex = segment.segmentIndex;
344
+ }
345
+ }
346
+ this.parent.setRecordValue('segments', ganttProp.segments, ganttProp, true);
347
+ }
348
+ }
349
+ if (segmentIndex === -1) {
350
+ this.dropSplit = true;
351
+ }
352
+ return segmentIndex;
353
+ }
354
+
355
+ public mergeTask(taskId: number | string, segmentIndexes: { firstSegmentIndex: number, secondSegmentIndex: number }[]): void {
356
+ const mergeArrayLength: number = segmentIndexes.length;
357
+ const taskFields: TaskFieldsModel = this.parent.taskFields;
358
+ const mergeData: IGanttData = this.parent.flatData.filter((x: IGanttData): IGanttData => {
359
+ if (x[taskFields.id] === taskId) {
360
+ return x;
361
+ } else {
362
+ return null;
363
+ }
364
+ })[0];
365
+ const segments: ITaskSegment[] = mergeData.ganttProperties.segments;
366
+ segmentIndexes = segmentIndexes.sort((a: { firstSegmentIndex: number, secondSegmentIndex: number },
367
+ b: { firstSegmentIndex: number, secondSegmentIndex: number }): number => {
368
+ return b.firstSegmentIndex - a.firstSegmentIndex;
369
+ });
370
+ for (let arrayLength: number = 0; arrayLength < mergeArrayLength; arrayLength++) {
371
+ const firstSegment: ITaskSegment = segments[segmentIndexes[arrayLength].firstSegmentIndex];
372
+ const secondSegment: ITaskSegment = segments[segmentIndexes[arrayLength].secondSegmentIndex];
373
+ const duration: number = firstSegment.duration + secondSegment.duration;
374
+ const endDate: Date = this.parent.dataOperation.getEndDate(
375
+ firstSegment.startDate, duration, mergeData.ganttProperties.durationUnit, mergeData.ganttProperties, false
376
+ );
377
+ const segment: ITaskSegment = {
378
+ startDate: firstSegment.startDate,
379
+ endDate: endDate,
380
+ duration: duration
381
+ };
382
+ const insertIndex: number = segmentIndexes[arrayLength].firstSegmentIndex;
383
+ segments.splice(insertIndex, 2, segment);
384
+ this.parent.setRecordValue('segments', segments, mergeData.ganttProperties, true);
385
+ this.parent.dataOperation.updateMappingData(mergeData, 'segments');
386
+ if (segments.length === 1) {
387
+ this.parent.setRecordValue('endDate', endDate, mergeData.ganttProperties, true);
388
+ this.parent.setRecordValue('segments', null, mergeData.ganttProperties, true);
389
+ this.parent.dataOperation.updateMappingData(mergeData, 'segments');
390
+ } else if (mergeData.ganttProperties.endDate !== segments[segments.length - 1].endDate) {
391
+ this.parent.setRecordValue('endDate', segments[segments.length - 1].endDate, mergeData.ganttProperties, true);
392
+ }
393
+ }
394
+ this.refreshChartAfterSegment(mergeData, 'mergeSegment');
395
+ }
396
+
397
+ private refreshChartAfterSegment(data: IGanttData, requestType: string): void {
398
+ this.parent.setRecordValue('segments', this.parent.dataOperation.setSegmentsInfo(data, false), data.ganttProperties, true);
399
+ this.parent.dataOperation.updateMappingData(data, 'segments');
400
+ this.parent.dataOperation.updateWidthLeft(data);
401
+ if (this.parent.predecessorModule && this.parent.taskFields.dependency) {
402
+ this.parent.predecessorModule.updatedRecordsDateByPredecessor();
403
+ this.parent.connectorLineModule.removePreviousConnectorLines(this.parent.flatData);
404
+ this.parent.connectorLineEditModule.refreshEditedRecordConnectorLine(this.parent.flatData);
405
+ if (data.parentItem && this.parent.getParentTask(data.parentItem).ganttProperties.isAutoSchedule
406
+ && this.parent.isInPredecessorValidation) {
407
+ this.parent.dataOperation.updateParentItems(data.parentItem);
408
+ }
409
+ this.refreshRecords(this.parent.currentViewData);
410
+ } else {
411
+ this.refreshRow(this.parent.currentViewData.indexOf(data));
412
+ }
413
+ const tr: Element = this.ganttChartTableBody.querySelectorAll('tr')[this.parent.currentViewData.indexOf(data)];
414
+ const args: CObject = {
415
+ requestType: requestType,
416
+ rowData: data
417
+ };
418
+ this.triggerQueryTaskbarInfoByIndex(tr, data);
419
+ this.parent.selectionModule.clearSelection();
420
+ const segments: ITaskSegment[] = (args.rowData as IGanttData).taskData[this.parent.taskFields.segments];
421
+ if (this.parent.timezone && segments != null) {
422
+ for (let i: number = 0; i < segments.length; i++) {
423
+ segments[i][this.parent.taskFields.startDate] = this.parent.dateValidationModule.remove(
424
+ ((args.rowData as IGanttData).ganttProperties.segments as ITaskSegment)[i].startDate, this.parent.timezone);
425
+ if (this.parent.taskFields.endDate) {
426
+ segments[i][this.parent.taskFields.endDate] = this.parent.dateValidationModule.remove(
427
+ ((args.rowData as IGanttData).ganttProperties.segments as ITaskSegment)[i].endDate, this.parent.timezone);
428
+ }
429
+ }
430
+ }
431
+
432
+ this.parent.trigger('actionComplete', args);
433
+ setValue('isEdit', false, this.parent.contextMenuModule);
434
+ setValue('isEdit', false, this.parent);
435
+ }
436
+
437
+ /**
438
+ * public method to split task bar.
439
+ *
440
+ * @public
441
+ */
442
+
443
+ public splitTask(taskId: number | string, splitDates: Date | Date[]): void {
444
+ const taskFields: TaskFieldsModel = this.parent.taskFields;
445
+ const splitDate: Date = splitDates as Date;
446
+ const splitRecord: IGanttData = this.parent.flatData.filter((x: IGanttData): IGanttData => {
447
+ if (x[taskFields.id] === taskId) {
448
+ return x;
449
+ } else {
450
+ return null;
451
+ }
452
+ })[0];
453
+ const ganttProp: ITaskData = splitRecord.ganttProperties;
454
+ this.dropSplit = false;
455
+ let segmentIndex: number = -1;
456
+ let segments: ITaskSegment[] = ganttProp.segments;
457
+ if (isNullOrUndefined((splitDates as Date[]).length) || (splitDates as Date[]).length < 0) {
458
+ const splitStartDate: Date = this.parent.dataOperation.checkStartDate(splitDate, ganttProp, false);
459
+ if (splitStartDate.getTime() !== ganttProp.startDate.getTime()) {
460
+ if (ganttProp.isAutoSchedule) {
461
+ if (!isNullOrUndefined(segments)) {
462
+ segmentIndex = this.getSegmentIndex(splitStartDate, splitRecord);
463
+ }
464
+ //check atleast one day difference is there to split
465
+ if (this.dropSplit === false && (splitDate as Date).getTime() > ganttProp.startDate.getTime() &&
466
+ (splitDate as Date).getTime() < ganttProp.endDate.getTime()) {
467
+ segments = segmentIndex !== -1 ? segments : [];
468
+ const startDate: Date = segmentIndex !== -1 ?
469
+ segments[segmentIndex].startDate : new Date(ganttProp.startDate.getTime());
470
+ const endDate: Date = segmentIndex !== -1 ? segments[segmentIndex].endDate : new Date(ganttProp.endDate.getTime());
471
+ const segmentDuration: number = this.parent.dataOperation.getDuration(
472
+ startDate, endDate, ganttProp.durationUnit, ganttProp.isAutoSchedule, ganttProp.isMilestone
473
+ );
474
+ this.parent.setRecordValue(
475
+ 'segments', this.splitSegmentedTaskbar(
476
+ startDate, endDate, splitDate, segmentIndex, segments, splitRecord, segmentDuration
477
+ ),
478
+ ganttProp, true
479
+ );
480
+ if (segmentIndex !== -1) {
481
+ this.incrementSegments(segments, segmentIndex + 1, splitRecord);
482
+ }
483
+ this.parent.setRecordValue('endDate', segments[segments.length - 1].endDate, ganttProp, true);
484
+ if (this.parent.taskFields.endDate) {
485
+ this.parent.dataOperation.updateMappingData(splitRecord, 'endDate');
486
+ }
487
+ }
488
+ this.refreshChartAfterSegment(splitRecord, 'splitTaskbar');
489
+ }
490
+ }
491
+ } else {
492
+ (splitDates as Date[]).sort((a: Date, b: Date) => {
493
+ return a.getTime() - b.getTime();
494
+ });
495
+ this.parent.setRecordValue(
496
+ 'segments', this.constructSegments(
497
+ splitDates as Date[], splitRecord.ganttProperties
498
+ ),
499
+ splitRecord.ganttProperties, true
500
+ );
501
+ this.refreshChartAfterSegment(splitRecord, 'splitTask');
502
+ }
503
+ }
504
+
505
+ private constructSegments(dates: Date[], taskData: ITaskData): ITaskSegment[] {
506
+ const segmentsArray: ITaskSegment[] = [];
507
+ let segment: ITaskSegment;
508
+ let startDate: Date = new Date();
509
+ let endDate: Date;
510
+ let duration: number;
511
+ for (let i: number = 0; i < dates.length + 1; i++) {
512
+ startDate = i === 0 ? taskData.startDate : startDate;
513
+ startDate = this.parent.dataOperation.checkStartDate(startDate, taskData, false);
514
+ endDate = i !== dates.length ? new Date(dates[i].getTime()) > taskData.endDate ? taskData.endDate
515
+ : new Date(dates[i].getTime()) : taskData.endDate;
516
+ endDate = this.parent.dataOperation.checkEndDate(endDate, taskData, false);
517
+ duration = this.parent.dataOperation.getDuration(
518
+ startDate, endDate, taskData.durationUnit, taskData.isAutoSchedule, taskData.isMilestone
519
+ );
520
+ if (endDate.getTime() >= startDate.getTime()) {
521
+ segment = {
522
+ startDate: startDate,
523
+ endDate: endDate,
524
+ duration: duration
525
+ };
526
+ segmentsArray.push(segment);
527
+ }
528
+ if (i === dates.length) {
529
+ break;
530
+ }
531
+ startDate = new Date(dates[i].getTime());
532
+ startDate.setDate(dates[i].getDate() + 1);
533
+ }
534
+ return segmentsArray;
535
+ }
536
+
537
+ private splitSegmentedTaskbar(
538
+ startDate: Date, endDate: Date, splitDate: Date, segmentIndex: number, segments: ITaskSegment[], ganttData: IGanttData,
539
+ segmentDuration: number): ITaskSegment[] {
540
+ const ganttProp: ITaskData = ganttData.ganttProperties;
541
+ const checkClickState: number = this.parent.nonWorkingDayIndex.indexOf(splitDate.getDay());
542
+ const increment: number = checkClickState === -1 ? 0 : checkClickState === 0 ? 1 : 2;
543
+ startDate = this.parent.dataOperation.checkStartDate(startDate, ganttProp, false);
544
+ let segmentEndDate: Date = new Date(splitDate.getTime());
545
+ segmentEndDate = this.parent.dataOperation.checkEndDate(segmentEndDate, ganttProp, false);
546
+ for (let i: number = 0; i < 2; i++) {
547
+ const segment: ITaskSegment = {
548
+ startDate: startDate,
549
+ endDate: segmentEndDate,
550
+ duration: this.parent.dataOperation.getDuration(
551
+ startDate, segmentEndDate, ganttProp.durationUnit,
552
+ ganttProp.isAutoSchedule, ganttProp.isMilestone),
553
+ offsetDuration: 1
554
+ };
555
+ const endDateState: number = this.parent.nonWorkingDayIndex.indexOf(segmentEndDate.getDay());
556
+ if (segmentIndex !== -1) {
557
+ segments.splice(segmentIndex, 1);
558
+ segmentIndex = -1;
559
+ }
560
+ segments.push(segment);
561
+ const mode: string = this.parent.timelineModule.customTimelineSettings.bottomTier.unit;
562
+ if (mode === 'Hour' || mode === 'Minutes') {
563
+ startDate = new Date(splitDate.getTime());
564
+ startDate = this.parent.dataOperation.checkStartDate(startDate, ganttProp, false);
565
+ const count: number = this.parent.timelineModule.customTimelineSettings.bottomTier.count;
566
+ const mode: string = this.parent.timelineModule.customTimelineSettings.bottomTier.unit;
567
+ let timeIncrement: number = this.parent.timelineModule.getIncrement(startDate, count, mode);
568
+ let newTime: number = startDate.getTime() + timeIncrement;
569
+ startDate.setTime(newTime + increment);
570
+ segmentEndDate = new Date(endDate.getTime());
571
+ timeIncrement = this.parent.timelineModule.getIncrement(segmentEndDate, count, mode);
572
+ newTime = segmentEndDate.getTime() + timeIncrement;
573
+ segmentEndDate.setTime(newTime + increment);
574
+ } else {
575
+ startDate = new Date(splitDate.getTime());
576
+ startDate.setDate(startDate.getDate() + 1 + increment);
577
+ startDate = this.parent.dataOperation.checkStartDate(startDate, ganttProp, false);
578
+ segmentEndDate = new Date(endDate.getTime());
579
+ segmentEndDate.setDate(segmentEndDate.getDate() + 1);
580
+ }
581
+ if (endDateState !== -1) {
582
+ const diff: number = segmentDuration - segment.duration;
583
+ segmentEndDate =
584
+ this.parent.dataOperation.getEndDate(startDate, diff, ganttProp.durationUnit, ganttProp, false);
585
+ } else {
586
+ segmentEndDate = this.parent.dataOperation.checkEndDate(segmentEndDate, ganttProp, false);
587
+ }
588
+ }
589
+ segments.sort((a: ITaskSegment, b: ITaskSegment) => {
590
+ return a.startDate.getTime() - b.startDate.getTime();
591
+ });
592
+ return segments;
593
+ }
594
+
595
+ public incrementSegments(segments: ITaskSegment[], segmentIndex: number, ganttData: IGanttData): void {
596
+ const ganttProp: ITaskData = ganttData.ganttProperties;
597
+ for (let i: number = segmentIndex + 1; i < segments.length; i++) {
598
+ const segment: ITaskSegment = segments[i];
599
+ let startDate: Date = i !== 0 ? new Date(segments[i - 1].endDate.getTime()) : new Date(segment.startDate.getTime());
600
+ startDate = this.parent.dataOperation.getEndDate(startDate, segment.offsetDuration, ganttProp.durationUnit, ganttProp, false);
601
+ startDate = this.parent.dataOperation.checkStartDate(startDate, ganttProp, false);
602
+ segment.startDate = startDate;
603
+ const endDate: Date = segment.endDate = this.parent.dataOperation.getEndDate(
604
+ startDate, segment.duration, ganttProp.durationUnit, ganttProp, false
605
+ );
606
+ segment.endDate = endDate;
607
+ if (i === segments.length - 1) {
608
+ this.parent.setRecordValue('endDate', endDate, ganttProp, true);
609
+ if (this.parent.taskFields.endDate) {
610
+ this.parent.dataOperation.updateMappingData(ganttData, 'endDate');
611
+ }
612
+ }
613
+ }
614
+ segments.sort((a: ITaskSegment, b: ITaskSegment) => {
615
+ return a.startDate.getTime() - b.startDate.getTime();
616
+ });
617
+ this.parent.setRecordValue('segments', segments, ganttProp, true);
618
+ this.parent.dataOperation.updateMappingData(ganttData, 'segments');
619
+ }
620
+
621
+ /**
622
+ * To get milestone node.
623
+ *
624
+ * @param {number} i .
625
+ * @param {NodeList} rootElement .
626
+ * @returns {NodeList} .
627
+ * @private
628
+ */
629
+ private getMilestoneNode(i: number, rootElement?: NodeList): NodeList {
630
+ let milestoneNode: NodeList = null;
631
+ const data: IGanttData = this.templateData;
632
+ if (this.milestoneTemplateFunction) {
633
+ milestoneNode = this.milestoneTemplateFunction(
634
+ extend({ index: i }, data), this.parent, 'MilestoneTemplate',
635
+ this.getTemplateID('MilestoneTemplate'), false, undefined, rootElement[0], this.parent.treeGrid['root']);
636
+ } else {
637
+ const template: string = '<div class="' + cls.traceMilestone + '" style="position:absolute;">' +
638
+ '<div class="' + cls.milestoneTop + ' ' + ((!data.ganttProperties.startDate && !data.ganttProperties.endDate) ?
639
+ cls.unscheduledMilestoneTop : '') + '" style="border-right-width:' +
640
+ this.milesStoneRadius + 'px;border-left-width:' + this.milesStoneRadius + 'px;border-bottom-width:' +
641
+ this.milesStoneRadius + 'px;"></div>' +
642
+ '<div class="' + cls.milestoneBottom + ' ' + ((!data.ganttProperties.startDate && !data.ganttProperties.endDate) ?
643
+ cls.unscheduledMilestoneBottom : '') + '" style="top:' +
644
+ (this.milesStoneRadius) + 'px;border-right-width:' + this.milesStoneRadius + 'px; border-left-width:' +
645
+ this.milesStoneRadius + 'px; border-top-width:' + this.milesStoneRadius + 'px;"></div></div>';
646
+ milestoneNode = this.createDivElement(template);
647
+ }
648
+ return milestoneNode;
649
+ }
650
+
651
+ /**
652
+ * To get task baseline Node.
653
+ *
654
+ * @returns {NodeList} .
655
+ * @private
656
+ */
657
+ private getTaskBaselineNode(): NodeList {
658
+ const data: IGanttData = this.templateData;
659
+ const template: string = '<div class="' + cls.baselineBar + ' ' + '" role="BaselineBar" style="margin-top:' + this.baselineTop +
660
+ 'px;left:' + data.ganttProperties.baselineLeft + 'px;' +
661
+ 'width:' + data.ganttProperties.baselineWidth + 'px;height:' +
662
+ this.baselineHeight + 'px;' + (this.baselineColor ? 'background-color: ' + this.baselineColor + ';' : '') + '"></div>';
663
+ return this.createDivElement(template);
664
+ }
665
+
666
+ /**
667
+ * To get milestone baseline node.
668
+ *
669
+ * @returns {NodeList} .
670
+ * @private
671
+ */
672
+ private getMilestoneBaselineNode(): NodeList {
673
+ const data: IGanttData = this.templateData;
674
+ let baselineMilestoneHeight = this.parent.renderBaseline ? 5 : 2;
675
+ const template: string = '<div class="' + cls.baselineMilestoneContainer + ' ' + '" style="' +
676
+ 'left:' + (data.ganttProperties.baselineLeft - this.milesStoneRadius) + 'px;' +
677
+ 'margin-top:' + (-Math.floor(this.parent.rowHeight - this.milestoneMarginTop) + baselineMilestoneHeight) +
678
+ 'px">' + '<div class="' + cls.baselineMilestoneDiv + '">' + '<div class="' + cls.baselineMilestoneDiv +
679
+ ' ' + cls.baselineMilestoneTop + '" ' +
680
+ 'style="top:' + (- this.milestoneHeight) + 'px;border-right:' + this.milesStoneRadius +
681
+ 'px solid transparent;border-left:' + this.milesStoneRadius +
682
+ 'px solid transparent;border-top:0px' +
683
+ 'solid transparent;border-bottom-width:' + this.milesStoneRadius + 'px;' +
684
+ 'border-bottom-style: solid;' + (this.baselineColor ? 'border-bottom-color: ' + this.baselineColor + ';' : '') +
685
+ '"></div>' +
686
+ '<div class="' + cls.baselineMilestoneDiv + ' ' + cls.baselineMilestoneBottom + '" ' +
687
+ 'style="top:' + (this.milesStoneRadius - this.milestoneHeight) + 'px;border-right:' + this.milesStoneRadius +
688
+ 'px solid transparent;border-left:' + this.milesStoneRadius +
689
+ 'px solid transparent;border-bottom:0px' +
690
+ 'solid transparent;border-top-width:' + this.milesStoneRadius + 'px;' +
691
+ 'border-top-style: solid;' +
692
+ (this.baselineColor ? 'border-top-color: ' + this.baselineColor + ';' : '') + '"></div>' +
693
+ '</div></div>';
694
+ return this.createDivElement(template);
695
+ }
696
+
697
+ /**
698
+ * To get left label node.
699
+ *
700
+ * @param {number} i .
701
+ * @returns {NodeList} .
702
+ * @private
703
+ */
704
+ private getLeftLabelNode(i: number): NodeList {
705
+ const leftLabelNode: NodeList = this.leftLabelContainer();
706
+ if(this.generateTaskLabelAriaLabel('left') !== "") {
707
+ (<HTMLElement>leftLabelNode[0]).setAttribute('aria-label', this.generateTaskLabelAriaLabel('left'));
708
+ }
709
+ let leftLabelTemplateNode: NodeList = null;
710
+ if (this.leftTaskLabelTemplateFunction) {
711
+ leftLabelTemplateNode = this.leftTaskLabelTemplateFunction(
712
+ extend({ index: i }, this.templateData), this.parent, 'LeftLabelTemplate',
713
+ this.getTemplateID('LeftLabelTemplate'), false, undefined, leftLabelNode[0],this.parent.treeGrid['root']);
714
+ } else {
715
+ const field: string = this.parent.labelSettings.leftLabel;
716
+ let labelString: string = this.getTaskLabel(field);
717
+ if (labelString) {
718
+ labelString = labelString === 'isCustomTemplate' ? field : labelString;
719
+ leftLabelTemplateNode = this.getLableText(labelString, cls.leftLabelInnerDiv);
720
+ }
721
+ }
722
+ if (leftLabelTemplateNode && leftLabelTemplateNode.length > 0) {
723
+ if (leftLabelTemplateNode[0]['data'] === 'null') {
724
+ leftLabelTemplateNode[0]['data'] = '';
725
+ }
726
+ leftLabelNode[0].appendChild([].slice.call(leftLabelTemplateNode)[0]);
727
+ }
728
+ return leftLabelNode;
729
+ }
730
+ private getLableText(labelString: string, labelDiv: string): NodeList {
731
+ let leftLabelHeight = this.parent.renderBaseline ? ((this.parent.rowHeight - this.taskBarHeight) / 2) : this.taskBarMarginTop;
732
+ const templateString: HTMLElement = createElement('div', {
733
+ className: labelDiv, styles: 'height:' + (this.taskBarHeight) + 'px;' +
734
+ 'margin-top:' + leftLabelHeight + 'px;'
735
+ });
736
+ const spanElem: HTMLElement = createElement('span', { className: cls.label });
737
+ const property: string = this.parent.disableHtmlEncode ? 'textContent' : 'innerHTML';
738
+ spanElem[property] = labelString;
739
+ templateString.appendChild(spanElem);
740
+ const div: HTMLElement = createElement('div');
741
+ div.appendChild(templateString);
742
+ return div.childNodes;
743
+ }
744
+ /**
745
+ * To get right label node.
746
+ *
747
+ * @param {number} i .
748
+ * @returns {NodeList} .
749
+ * @private
750
+ */
751
+ private getRightLabelNode(i: number): NodeList {
752
+ const rightLabelNode: NodeList = this.rightLabelContainer();
753
+ if(this.generateTaskLabelAriaLabel('right') !== "") {
754
+ (<HTMLElement>rightLabelNode[0]).setAttribute('aria-label', this.generateTaskLabelAriaLabel('right'));
755
+ }
756
+ let rightLabelTemplateNode: NodeList = null;
757
+ if (this.rightTaskLabelTemplateFunction) {
758
+ rightLabelTemplateNode = this.rightTaskLabelTemplateFunction(
759
+ extend({ index: i }, this.templateData), this.parent, 'RightLabelTemplate',
760
+ this.getTemplateID('RightLabelTemplate'), false, undefined, rightLabelNode[0], this.parent.treeGrid['root']);
761
+ } else {
762
+ const field: string = this.parent.labelSettings.rightLabel;
763
+ let labelString: string = this.getTaskLabel(field);
764
+ if (labelString) {
765
+ labelString = labelString === 'isCustomTemplate' ? field : labelString;
766
+ rightLabelTemplateNode = this.getLableText(labelString, cls.rightLabelInnerDiv);
767
+ }
768
+ }
769
+ if (rightLabelTemplateNode && rightLabelTemplateNode.length > 0) {
770
+ if (rightLabelTemplateNode[0]['data'] === 'null') {
771
+ rightLabelTemplateNode[0]['data'] = '';
772
+ }
773
+ rightLabelNode[0].appendChild([].slice.call(rightLabelTemplateNode)[0]);
774
+ }
775
+ return rightLabelNode;
776
+ }
777
+
778
+ private getManualTaskbar(): NodeList {
779
+ const data: IGanttData = this.templateData;
780
+ const taskbarHeight: number = (this.taskBarHeight / 2 - 1);
781
+ const innerDiv: string = (data.ganttProperties.startDate && data.ganttProperties.endDate && data.ganttProperties.duration) ?
782
+ ('<div class="' + cls.manualParentTaskBar + '" style="width:' + data.ganttProperties.width + 'px;' + 'height:' +
783
+ taskbarHeight / 5 + 'px;border-left-width:' + taskbarHeight / 5 +
784
+ 'px; border-bottom:' + taskbarHeight / 5 + 'px solid transparent;"></div>') :
785
+ (!data.ganttProperties.startDate && !data.ganttProperties.endDate && data.ganttProperties.duration) ?
786
+ ('<div class="' + cls.manualParentTaskBar + ' ' + cls.traceManualUnscheduledTask +
787
+ '" style="width:' + data.ganttProperties.width + 'px;' + 'height:' +
788
+ (taskbarHeight / 5 + 1) + 'px;border-left-width:' + taskbarHeight / 5 +
789
+ 'px; border-bottom:' + taskbarHeight / 5 + 'px solid transparent;"></div>') : ('<div class="' +
790
+ cls.manualParentTaskBar + ' ' + (data.ganttProperties.startDate ? cls.unscheduledTaskbarLeft : cls.unscheduledTaskbarRight) +
791
+ '" style="width:' + data.ganttProperties.width + 'px;' + 'height:' +
792
+ taskbarHeight * 2 + 'px;border-left-width:' + taskbarHeight / 5 +
793
+ 'px; border-bottom:' + taskbarHeight / 5 + 'px solid transparent;"></div>');
794
+ const template: string = '<div class="' + cls.manualParentMainContainer + '"' +
795
+ 'style=left:' + (data.ganttProperties.left - data.ganttProperties.autoLeft) + 'px;' +
796
+ 'width:' + data.ganttProperties.width + 'px;' +
797
+ 'height:' + taskbarHeight + 'px;>' + innerDiv + ((data.ganttProperties.startDate && data.ganttProperties.endDate &&
798
+ data.ganttProperties.duration) || data.ganttProperties.duration ? '<div class="e-gantt-manualparenttaskbar-left" style=' +
799
+ '"height:' + taskbarHeight + 'px;border-left-width:' + taskbarHeight / 5 +
800
+ 'px; border-bottom:' + taskbarHeight / 5 + 'px solid transparent;"></div>' +
801
+ '<div class="e-gantt-manualparenttaskbar-right" style=' +
802
+ 'left:' + (data.ganttProperties.width - taskbarHeight / 5) + 'px;height:' +
803
+ (taskbarHeight) + 'px;border-right-width:' + taskbarHeight / 5 + 'px;border-bottom:' +
804
+ taskbarHeight / 5 + 'px solid transparent;>' + '</div></div>' : '');
805
+ const milestoneTemplate: string = '<div class="' + cls.manualParentMilestone + '" style="position:absolute;left:' +
806
+ (data.ganttProperties.left - data.ganttProperties.autoLeft - (this.milestoneHeight / 2)) +
807
+ 'px;width:' + (this.milesStoneRadius * 2) +
808
+ 'px;">' + '<div class="' + cls.manualParentMilestoneTop + '" style="border-right-width:' +
809
+ this.milesStoneRadius + 'px;border-left-width:' + this.milesStoneRadius + 'px;border-bottom-width:' +
810
+ this.milesStoneRadius + 'px;"></div>' +
811
+ '<div class="' + cls.manualParentMilestoneBottom + '" style="top:' +
812
+ (this.milesStoneRadius) + 'px;border-right-width:' + this.milesStoneRadius + 'px; border-left-width:' +
813
+ this.milesStoneRadius + 'px; border-top-width:' + this.milesStoneRadius + 'px;"></div></div>';
814
+ return this.createDivElement(data.ganttProperties.width === 0 ? milestoneTemplate : template);
815
+ }
816
+ /**
817
+ * To get parent taskbar node.
818
+ *
819
+ * @param {number} i .
820
+ * @param {NodeList} rootElement .
821
+ * @returns {NodeList} .
822
+ * @private
823
+ */
824
+ private getParentTaskbarNode(i: number, rootElement?: NodeList): NodeList {
825
+ let parentTaskbarNode: NodeList = null;
826
+ const data: IGanttData = this.templateData;
827
+ if (this.parentTaskbarTemplateFunction) {
828
+ parentTaskbarNode = this.parentTaskbarTemplateFunction(
829
+ extend({ index: i }, data), this.parent, 'ParentTaskbarTemplate',
830
+ this.getTemplateID('ParentTaskbarTemplate'), false, undefined, rootElement[0], this.parent.treeGrid['root']);
831
+ } else {
832
+ let labelString: string = ''; let labelDiv: NodeList;
833
+ const tHeight: number = this.taskBarHeight / 5;
834
+ const template: NodeList = this.createDivElement('<div class="' + cls.parentTaskBarInnerDiv + ' ' +
835
+ this.getExpandClass(data) + ' ' + cls.traceParentTaskBar + '"' +
836
+ ' style="width:' + (data.ganttProperties.isAutoSchedule ? data.ganttProperties.width :
837
+ data.ganttProperties.autoWidth) + 'px;height:' + (data.ganttProperties.isAutoSchedule ? this.taskBarHeight :
838
+ (tHeight * 3)) + 'px;margin-top:' + (data.ganttProperties.isAutoSchedule ? '' :
839
+ (tHeight * 2)) + 'px;">' +
840
+ '</div>');
841
+ const progressBarInnerDiv: NodeList = this.createDivElement('<div class="' + cls.parentProgressBarInnerDiv + ' ' +
842
+ this.getExpandClass(data) + ' ' + cls.traceParentProgressBar + '"' +
843
+ ' style="border-style:' + (data.ganttProperties.progressWidth ? 'solid;' : 'none;') +
844
+ 'width:' + data.ganttProperties.progressWidth + 'px;' +
845
+ 'border-top-right-radius:' + this.getBorderRadius(data) + 'px;' +
846
+ 'border-bottom-right-radius:' + this.getBorderRadius(data) + 'px;height:100%;"></div>');
847
+ if (this.taskLabelTemplateFunction) {
848
+ const parentTaskLabelNode: NodeList = this.taskLabelTemplateFunction(
849
+ extend({ index: i }, data), this.parent, 'TaskLabelTemplate',
850
+ this.getTemplateID('TaskLabelTemplate'), false, undefined, progressBarInnerDiv[0]);
851
+ if (parentTaskLabelNode && parentTaskLabelNode.length > 0) {
852
+ const div: Element = createElement('div');
853
+ div.appendChild(parentTaskLabelNode[0]);
854
+ labelString = div.innerHTML;
855
+ }
856
+ } else {
857
+ labelString = this.getTaskLabel(this.parent.labelSettings.taskLabel);
858
+ labelString = labelString === 'isCustomTemplate' ? this.parent.labelSettings.taskLabel : labelString;
859
+ }
860
+ if (labelString !== 'null') {
861
+ if (isNaN(parseInt(labelString))) {
862
+ labelDiv = this.createDivElement('<span class="' + cls.taskLabel + '" style="line-height:' +
863
+ (this.taskBarHeight - 1) + 'px; text-align: left;' +
864
+ 'display:' + 'inline-block;' +
865
+ 'width:' + (data.ganttProperties.width - 10) + 'px; height:' +
866
+ this.taskBarHeight + 'px;">' + labelString + '</span>');
867
+ } else {
868
+ labelDiv = this.createDivElement('<span class="' +
869
+ cls.taskLabel + '" style="line-height:' +
870
+ (this.taskBarHeight - 1) + 'px;' + (this.parent.viewType === 'ResourceView' ? 'display:inline-flex;' : '') +
871
+ (this.parent.viewType === 'ResourceView' ? 'width:' + (data.ganttProperties.width - 10) : '') + 'px; height:' +
872
+ (this.taskBarHeight - 1) + 'px;' + (this.parent.viewType === 'ResourceView' ? 'display: inline-flex;' : '') +
873
+ (this.parent.viewType === 'ResourceView' ? 'width:' + (data.ganttProperties.width - 10) : '') + 'px; height:' +
874
+ this.taskBarHeight + 'px;">' + labelString + '</span>');
875
+ }
876
+ progressBarInnerDiv[0].appendChild([].slice.call(labelDiv)[0]);
877
+ }
878
+ const milestoneTemplate: string = '<div class="' + cls.parentMilestone + '" style="position:absolute;">' +
879
+ '<div class="' + cls.parentMilestoneTop + '" style="border-right-width:' +
880
+ this.milesStoneRadius + 'px;border-left-width:' + this.milesStoneRadius + 'px;border-bottom-width:' +
881
+ this.milesStoneRadius + 'px;"></div>' +
882
+ '<div class="' + cls.parentMilestoneBottom + '" style="top:' +
883
+ (this.milesStoneRadius) + 'px;border-right-width:' + this.milesStoneRadius + 'px; border-left-width:' +
884
+ this.milesStoneRadius + 'px; border-top-width:' + this.milesStoneRadius + 'px;"></div></div>';
885
+ template[0].appendChild([].slice.call(progressBarInnerDiv)[0]);
886
+
887
+ parentTaskbarNode = data.ganttProperties.isMilestone ?
888
+ this.createDivElement(data.ganttProperties.isAutoSchedule ? milestoneTemplate : '') : template;
889
+ }
890
+ return parentTaskbarNode;
891
+ }
892
+ /**
893
+ * To get taskbar row('TR') node
894
+ *
895
+ * @returns {NodeList} .
896
+ * @private
897
+ */
898
+ private getTableTrNode(): NodeList {
899
+ const table: Element = createElement('table');
900
+ const className: string = (this.parent.gridLines === 'Horizontal' || this.parent.gridLines === 'Both') ?
901
+ 'e-chart-row-border' : '';
902
+ table.innerHTML = '<tr class="' + this.getRowClassName(this.templateData) + ' ' + cls.chartRow + '"' +
903
+ 'role="ChartRow" style="display:' + this.getExpandDisplayProp(this.templateData) + ';height:' +
904
+ this.parent.rowHeight + 'px;">' +
905
+ '<td class="' + cls.chartRowCell + ' ' + className
906
+ + '" role="ChartCell" style="width:' + this.parent.timelineModule.totalTimelineWidth + 'px;"></td></tr>';
907
+ return table.childNodes;
908
+ }
909
+
910
+ /**
911
+ * To initialize chart templates.
912
+ *
913
+ * @returns {void}
914
+ * @private
915
+ */
916
+ private initializeChartTemplate(): void {
917
+ if (!isNullOrUndefined(this.parent.parentTaskbarTemplate)) {
918
+ this.parentTaskbarTemplateFunction = this.templateCompiler(this.parent.parentTaskbarTemplate);
919
+ }
920
+ if (!isNullOrUndefined(this.parent.labelSettings.leftLabel) &&
921
+ this.isTemplate(this.parent.labelSettings.leftLabel)) {
922
+ this.leftTaskLabelTemplateFunction = this.templateCompiler(this.parent.labelSettings.leftLabel);
923
+ }
924
+ if (!isNullOrUndefined(this.parent.labelSettings.rightLabel) &&
925
+ this.isTemplate(this.parent.labelSettings.rightLabel)) {
926
+ this.rightTaskLabelTemplateFunction = this.templateCompiler(this.parent.labelSettings.rightLabel);
927
+ }
928
+ if (!isNullOrUndefined(this.parent.labelSettings.taskLabel) &&
929
+ this.isTemplate(this.parent.labelSettings.taskLabel)) {
930
+ this.taskLabelTemplateFunction = this.templateCompiler(this.parent.labelSettings.taskLabel);
931
+ }
932
+ if (!isNullOrUndefined(this.parent.taskbarTemplate)) {
933
+ this.childTaskbarTemplateFunction = this.templateCompiler(this.parent.taskbarTemplate);
934
+ }
935
+ if (!isNullOrUndefined(this.parent.milestoneTemplate)) {
936
+ this.milestoneTemplateFunction = this.templateCompiler(this.parent.milestoneTemplate);
937
+ }
938
+ }
939
+
940
+ private createDivElement(template: string): NodeList {
941
+ const div: Element = createElement('div');
942
+ div.innerHTML = template;
943
+ return div.childNodes;
944
+ }
945
+
946
+ private isTemplate(template: string): boolean {
947
+ let result: boolean = false;
948
+ for (let i: number = 0; i < this.parent.ganttColumns.length; i++) {
949
+ if (template === this.parent.ganttColumns[i].field) {
950
+ result = true;
951
+ break;
952
+ }
953
+ }
954
+ if (typeof template !== 'string' || template.indexOf('#') === 0 || template.indexOf('<') > -1
955
+ || template.indexOf('$') > -1 || !result) {
956
+ result = true;
957
+ } else {
958
+ result = false
959
+ }
960
+ return result;
961
+ }
962
+ /**
963
+ * @param {string} templateName .
964
+ * @returns {string} .
965
+ * @private
966
+ */
967
+ public getTemplateID(templateName: string): string {
968
+ const ganttID: string = this.parent.element.id;
969
+ return ganttID + templateName;
970
+ }
971
+
972
+ private leftLabelContainer(): NodeList {
973
+ const template: string = '<div class="' + ((this.leftTaskLabelTemplateFunction) ? cls.leftLabelTempContainer :
974
+ cls.leftLabelContainer) + ' ' + '" tabindex="-1" role="LeftLabel" style="height:' +
975
+ (this.parent.rowHeight - 2) + 'px;width:' + this.taskNameWidth(this.templateData) + '"></div>';
976
+ return this.createDivElement(template);
977
+ }
978
+
979
+ private taskbarContainer(): NodeList {
980
+ const data: IGanttData = this.templateData;
981
+ const manualParent: boolean = this.parent.editModule && this.parent.editSettings.allowTaskbarEditing &&
982
+ this.parent.editModule.taskbarEditModule.taskBarEditAction === 'ParentResizing' ?
983
+ true : false;
984
+ const template: string = '<div class="' + cls.taskBarMainContainer + ' ' +
985
+ this.parent.getUnscheduledTaskClass(data.ganttProperties) + ' ' +
986
+ ((data.ganttProperties.cssClass) ? data.ganttProperties.cssClass : '') + '" ' +
987
+ ' tabindex="-1" role="TaskBar" style="' + ((data.ganttProperties.isMilestone && !manualParent) ?
988
+ ('width:' + this.milestoneHeight + 'px;height:' +
989
+ this.milestoneHeight + 'px;margin-top:' + this.milestoneMarginTop + 'px;left:' + (data.ganttProperties.left -
990
+ (this.milestoneHeight / 2)) + 'px;') : ('width:' + data.ganttProperties.width +
991
+ 'px;margin-top:' + this.taskBarMarginTop + 'px;left:' + (!data.hasChildRecords || data.ganttProperties.isAutoSchedule ?
992
+ data.ganttProperties.left : data.ganttProperties.autoLeft) + 'px;height:' +
993
+ this.taskBarHeight + 'px;cursor:' + (data.ganttProperties.isAutoSchedule ? 'move;' : 'auto;'))) + '"></div>';
994
+ return this.createDivElement(template);
995
+ }
996
+
997
+ private rightLabelContainer(): NodeList {
998
+ const template: string = '<div class="' + ((this.rightTaskLabelTemplateFunction) ? cls.rightLabelTempContainer :
999
+ cls.rightLabelContainer) + '" ' + ' tabindex="-1" role="RightLabel" style="left:' + this.getRightLabelLeft(this.templateData) + 'px; height:'
1000
+ + (this.parent.rowHeight - 2) + 'px;"></div>';
1001
+ return this.createDivElement(template);
1002
+ }
1003
+
1004
+ private childTaskbarLeftResizer(): NodeList {
1005
+ const lResizerLeft: number = -(this.parent.isAdaptive ? 12 : 2);
1006
+ const template: string = '<div class="' + cls.taskBarLeftResizer + ' ' + cls.icon + '"' +
1007
+ ' role="LeftResizer" style="left:' + lResizerLeft + 'px;height:' + (this.taskBarHeight) + 'px;"></div>';
1008
+ return this.createDivElement(template);
1009
+ }
1010
+
1011
+ private childTaskbarRightResizer(): NodeList {
1012
+ const rResizerLeft: number = this.parent.isAdaptive ? -2 : -10;
1013
+ const template: string = '<div class="' + cls.taskBarRightResizer + ' ' + cls.icon + '"' +
1014
+ ' role="RightResizer" style="left:' + (this.templateData.ganttProperties.width + rResizerLeft) + 'px;' +
1015
+ 'height:' + (this.taskBarHeight) + 'px;"></div>';
1016
+ return this.createDivElement(template);
1017
+ }
1018
+
1019
+ private childTaskbarProgressResizer(): NodeList {
1020
+ const template: string = '<div class="' + cls.childProgressResizer + '"' +
1021
+ ' role="ProgressResizer" style="left:' + (this.templateData.ganttProperties.progressWidth - 6) + 'px;margin-top:' +
1022
+ (this.taskBarHeight - 4) + 'px;"><div class="' + cls.progressBarHandler + '"' +
1023
+ '><div class="' + cls.progressHandlerElement + '"></div>' +
1024
+ '<div class="' + cls.progressBarHandlerAfter + '"></div></div>';
1025
+ return this.createDivElement(template);
1026
+ }
1027
+
1028
+ private getLeftPointNode(): NodeList {
1029
+ const data: IGanttData = this.templateData;
1030
+ const pointerLeft: number = -((this.parent.isAdaptive ? 14 : 2) + this.connectorPointWidth);
1031
+ const mileStoneLeft: number = -(this.connectorPointWidth + 2);
1032
+ const pointerTop: number = Math.floor(this.milesStoneRadius - (this.connectorPointWidth / 2));
1033
+ const template: string = '<div class="' + cls.leftConnectorPointOuterDiv + '" style="' +
1034
+ ((data.ganttProperties.isMilestone) ? ('margin-top:' + pointerTop + 'px;left:' + mileStoneLeft +
1035
+ 'px;') : ('margin-top:' + this.connectorPointMargin + 'px;left:' + pointerLeft + 'px;')) + '">' +
1036
+ '<div class="' + cls.connectorPointLeft + ' ' + this.parent.getUnscheduledTaskClass(data.ganttProperties) +
1037
+ '" style="width: ' + this.connectorPointWidth + 'px;' +
1038
+ 'height: ' + this.connectorPointWidth + 'px;">' + this.touchLeftConnectorpoint + '</div></div>';
1039
+ return this.createDivElement(template);
1040
+ }
1041
+
1042
+ private getRightPointNode(): NodeList {
1043
+ const data: IGanttData = this.templateData;
1044
+ const pointerRight: number = this.parent.isAdaptive ? 10 : -2;
1045
+ const pointerTop: number = Math.floor(this.milesStoneRadius - (this.connectorPointWidth / 2));
1046
+ const template: string = '<div class="' + cls.rightConnectorPointOuterDiv + '" style="' +
1047
+ ((data.ganttProperties.isMilestone) ? ('left:' + (this.milestoneHeight - 2) + 'px;margin-top:' +
1048
+ pointerTop + 'px;') : ('left:' + (data.ganttProperties.width + pointerRight) + 'px;margin-top:' +
1049
+ this.connectorPointMargin + 'px;')) + '">' +
1050
+ '<div class="' + cls.connectorPointRight + ' ' + this.parent.getUnscheduledTaskClass(data.ganttProperties) +
1051
+ '" style="width:' + this.connectorPointWidth + 'px;height:' + this.connectorPointWidth + 'px;">' +
1052
+ this.touchRightConnectorpoint + '</div></div>';
1053
+ return this.createDivElement(template);
1054
+ }
1055
+
1056
+ /**
1057
+ * To get task label.
1058
+ *
1059
+ * @param {string} field .
1060
+ * @returns {string} .
1061
+ * @private
1062
+ */
1063
+ private getTaskLabel(field: string): string {
1064
+ const length: number = this.parent.ganttColumns.length;
1065
+ let resultString: string = null;
1066
+ if (!isNullOrUndefined(field) && field !== '') {
1067
+ if (field === this.parent.taskFields.resourceInfo) {
1068
+ resultString = this.getResourceName(this.templateData);
1069
+ } else {
1070
+ for (let i: number = 0; i < length; i++) {
1071
+ if (field === this.parent.ganttColumns[i].field) {
1072
+ resultString = this.getFieldValue(this.templateData[field]).toString();
1073
+ break;
1074
+ }
1075
+ }
1076
+ if (isNullOrUndefined(resultString)) {
1077
+ return 'isCustomTemplate';
1078
+ }
1079
+ }
1080
+ } else {
1081
+ resultString = '';
1082
+ }
1083
+ return resultString;
1084
+ }
1085
+
1086
+ private getExpandDisplayProp(data: IGanttData): string {
1087
+ data = this.templateData;
1088
+ if (this.parent.getExpandStatus(data)) {
1089
+ return 'table-row';
1090
+ }
1091
+ return 'none';
1092
+ }
1093
+ private getRowClassName(data: IGanttData): string {
1094
+ data = this.templateData;
1095
+ let rowClass: string = 'gridrowtaskId';
1096
+ const parentItem: IParent = data.parentItem;
1097
+ if (parentItem) {
1098
+ rowClass += parentItem.taskId.toString();
1099
+ }
1100
+ rowClass += 'level';
1101
+ rowClass += data.level.toString();
1102
+ return rowClass;
1103
+ }
1104
+
1105
+ private getBorderRadius(data: IGanttData): number {
1106
+ data = this.templateData;
1107
+ const diff: number = data.ganttProperties.width - data.ganttProperties.progressWidth;
1108
+ if (diff <= 4) {
1109
+ return 4 - diff;
1110
+ } else {
1111
+ return 0;
1112
+ }
1113
+ }
1114
+
1115
+ private getSplitTaskBorderRadius(data: ITaskSegment): number {
1116
+ const diff: number = data.width - data.progressWidth;
1117
+ if (diff <= 4) {
1118
+ return 4 - diff;
1119
+ } else {
1120
+ return 0;
1121
+ }
1122
+ }
1123
+ private taskNameWidth(ganttData: IGanttData): string {
1124
+ ganttData = this.templateData;
1125
+ const ganttProp: ITaskData = ganttData.ganttProperties;
1126
+ let width: number;
1127
+ if (ganttData.ganttProperties.isMilestone) {
1128
+ width = (ganttData.ganttProperties.left - (this.parent.getTaskbarHeight() / 2));
1129
+ } else if (ganttData.hasChildRecords && !ganttProp.isAutoSchedule) {
1130
+ if (!this.parent.allowUnscheduledTasks) {
1131
+ width = (ganttProp.autoStartDate.getTime() < ganttProp.startDate.getTime()) ?
1132
+ ganttProp.autoLeft : ganttProp.left;
1133
+ } else {
1134
+ width = ganttProp.left < ganttProp.autoLeft ? ganttProp.left : ganttProp.autoLeft;
1135
+ }
1136
+ } else {
1137
+ width = ganttData.ganttProperties.left;
1138
+ }
1139
+ if (width < 0) {
1140
+ width = 0;
1141
+ }
1142
+ return width + 'px';
1143
+ }
1144
+
1145
+ private getRightLabelLeft(ganttData: IGanttData): number {
1146
+ ganttData = this.templateData;
1147
+ const ganttProp: ITaskData = ganttData.ganttProperties;
1148
+ let left: number;
1149
+ let endLeft: number;
1150
+ let width: number;
1151
+ if (ganttData.ganttProperties.isMilestone) {
1152
+ return ganttData.ganttProperties.left + (this.parent.getTaskbarHeight() / 2);
1153
+ } else if (ganttData.hasChildRecords && !ganttProp.isAutoSchedule) {
1154
+ if (!this.parent.allowUnscheduledTasks) {
1155
+ left = ganttProp.autoStartDate.getTime() < ganttProp.startDate.getTime() ? ganttProp.autoLeft : ganttProp.left;
1156
+ endLeft = ganttProp.autoEndDate.getTime() < ganttProp.endDate.getTime() ?
1157
+ this.parent.dataOperation.getTaskLeft(ganttProp.endDate, ganttProp.isMilestone) :
1158
+ this.parent.dataOperation.getTaskLeft(ganttProp.autoEndDate, ganttProp.isMilestone);
1159
+ width = endLeft - left;
1160
+ } else {
1161
+ left = ganttProp.left < ganttProp.autoLeft ? ganttProp.left : ganttProp.autoLeft;
1162
+ width = ganttProp.autoWidth;
1163
+ }
1164
+ return left + width;
1165
+ } else {
1166
+ return ganttData.ganttProperties.left + ganttData.ganttProperties.width;
1167
+ }
1168
+ }
1169
+
1170
+ private getExpandClass(data: IGanttData): string {
1171
+ data = this.templateData;
1172
+ if (data.expanded) {
1173
+ return cls.rowExpand;
1174
+ } else if (!data.expanded && data.hasChildRecords) {
1175
+ return cls.rowCollapse;
1176
+ }
1177
+ return '';
1178
+ }
1179
+
1180
+ private getFieldValue(field: string | number): string | number {
1181
+ return isNullOrUndefined(field) ? '' : field;
1182
+ }
1183
+
1184
+ private getResourceName(ganttData: IGanttData): string {
1185
+ ganttData = this.templateData;
1186
+ let resource: string = null;
1187
+ if (!isNullOrUndefined(ganttData.ganttProperties.resourceInfo)) {
1188
+ const length: number = ganttData.ganttProperties.resourceInfo.length;
1189
+ if (length > 0) {
1190
+ for (let i: number = 0; i < length; i++) {
1191
+ let resourceName: string = ganttData.ganttProperties.resourceInfo[i][this.parent.resourceFields.name];
1192
+ const resourceUnit: number = ganttData.ganttProperties.resourceInfo[i][this.parent.resourceFields.unit];
1193
+ if (resourceUnit !== 100) {
1194
+ resourceName += '[' + resourceUnit + '%' + ']';
1195
+ }
1196
+ if (isNullOrUndefined(resource)) {
1197
+ resource = resourceName;
1198
+ } else {
1199
+ resource += ' , ' + resourceName;
1200
+ }
1201
+ }
1202
+ return resource;
1203
+ } else {
1204
+ return '';
1205
+ }
1206
+ }
1207
+ return '';
1208
+ }
1209
+
1210
+ /**
1211
+ * To initialize private variable help to render task bars.
1212
+ *
1213
+ * @returns {void}
1214
+ * @private
1215
+ */
1216
+ private initChartHelperPrivateVariable(): void {
1217
+ let taskbarHeightValue = this.parent.renderBaseline ? 0.45 : 0.62;
1218
+ let taskBarMarginTopValue = this.parent.renderBaseline ? 4 : 2;
1219
+ let milestoneHeightValue = this.parent.renderBaseline ? 1.13 : 0.82;
1220
+ this.baselineColor = !isNullOrUndefined(this.parent.baselineColor) &&
1221
+ this.parent.baselineColor !== '' ? this.parent.baselineColor : null;
1222
+ this.taskBarHeight = isNullOrUndefined(this.parent.taskbarHeight) || this.parent.taskbarHeight >= this.parent.rowHeight ?
1223
+ Math.floor(this.parent.rowHeight * taskbarHeightValue) : this.parent.taskbarHeight; // 0.62 -- Standard Ratio.
1224
+ if (this.parent.renderBaseline) {
1225
+ let height: number;
1226
+ if ((this.taskBarHeight + this.baselineHeight) <= this.parent.rowHeight) {
1227
+ height = this.taskBarHeight;
1228
+ } else {
1229
+ height = this.taskBarHeight - (this.baselineHeight + 1);
1230
+ }
1231
+ this.taskBarHeight = height;
1232
+ }
1233
+ this.milestoneHeight = Math.floor(this.taskBarHeight * milestoneHeightValue); // 0.82 -- Standard Ratio.
1234
+ this.taskBarMarginTop = Math.floor((this.parent.rowHeight - this.taskBarHeight) / taskBarMarginTopValue);
1235
+ this.milestoneMarginTop = Math.floor((this.parent.rowHeight - this.milestoneHeight) / 2);
1236
+ this.milesStoneRadius = Math.floor((this.milestoneHeight) / 2);
1237
+ this.baselineTop = -(Math.floor((this.parent.rowHeight - (this.taskBarHeight + this.taskBarMarginTop))) - 4);
1238
+ this.connectorPointWidth = this.parent.isAdaptive ? Math.round(this.taskBarHeight / 2) : 8;
1239
+ this.connectorPointMargin = Math.floor((this.taskBarHeight / 2) - (this.connectorPointWidth / 2));
1240
+ }
1241
+
1242
+ /**
1243
+ * Function used to refresh Gantt rows.
1244
+ *
1245
+ * @returns {void}
1246
+ * @private
1247
+ */
1248
+ public refreshGanttRows(): void {
1249
+ this.parent.currentViewData = this.parent.treeGrid.getCurrentViewRecords().slice();
1250
+ this.createTaskbarTemplate();
1251
+ if (this.parent.viewType === 'ResourceView' && this.parent.showOverAllocation) {
1252
+ for (let i: number = 0; i < this.parent.currentViewData.length; i++) {
1253
+ const data: IGanttData = this.parent.currentViewData[i];
1254
+ if (data.childRecords.length > 0) {
1255
+ this.parent.setRecordValue('workTimelineRanges', this.parent.dataOperation.mergeRangeCollections(data.ganttProperties.workTimelineRanges, true), data.ganttProperties, true);
1256
+ this.parent.dataOperation.calculateRangeLeftWidth(data.ganttProperties.workTimelineRanges);
1257
+ }
1258
+ }
1259
+ this.parent.ganttChartModule.renderRangeContainer(this.parent.currentViewData);
1260
+ }
1261
+ }
1262
+
1263
+ /**
1264
+ * To render taskbars.
1265
+ *
1266
+ * @returns {void}
1267
+ * @private
1268
+ */
1269
+ private createTaskbarTemplate(): void {
1270
+ const trs: Element[] = [].slice.call(this.ganttChartTableBody.querySelectorAll('tr'));
1271
+ this.ganttChartTableBody.innerHTML = '';
1272
+ const collapsedResourceRecord: IGanttData[] = [];
1273
+ const prevCurrentView: Object[] = this.parent.treeGridModule.prevCurrentView as object[];
1274
+ this.refreshedTr = []; this.refreshedData = [];
1275
+ if (this.parent.enableImmutableMode && prevCurrentView && prevCurrentView.length > 0 && this.isUpdated) {
1276
+ const oldKeys: object = {};
1277
+ const oldRowElements: Element[] = [];
1278
+ const key: string = this.parent.treeGrid.getPrimaryKeyFieldNames()[0];
1279
+ for (let i: number = 0; i < prevCurrentView.length; i++) {
1280
+ oldRowElements[i] = trs[i];
1281
+ oldKeys[prevCurrentView[i][key]] = i;
1282
+ }
1283
+ for (let index: number = 0; index < this.parent.currentViewData.length; index++) {
1284
+ const oldIndex: number = oldKeys[this.parent.currentViewData[index][key]];
1285
+ const modifiedRecIndex: number = this.parent.modifiedRecords.indexOf(this.parent.currentViewData[index]);
1286
+ if (isNullOrUndefined(oldIndex) || modifiedRecIndex !== -1) {
1287
+ const tRow: Node = this.getGanttChartRow(index, this.parent.currentViewData[index]);
1288
+ this.ganttChartTableBody.appendChild(tRow);
1289
+ this.refreshedTr.push(this.ganttChartTableBody.querySelectorAll('tr')[index]);
1290
+ this.refreshedData.push(this.parent.currentViewData[index]);
1291
+ } else {
1292
+ this.ganttChartTableBody.appendChild(oldRowElements[oldIndex]);
1293
+ }
1294
+ this.ganttChartTableBody.querySelectorAll('tr')[index].setAttribute('aria-rowindex', index.toString());
1295
+ }
1296
+ } else {
1297
+ for (let i: number = 0; i < this.parent.currentViewData.length; i++) {
1298
+ const tempTemplateData: IGanttData = this.parent.currentViewData[i];
1299
+ if (this.parent.viewType === 'ResourceView' && !tempTemplateData.expanded && this.parent.enableMultiTaskbar) {
1300
+ collapsedResourceRecord.push(tempTemplateData);
1301
+ }
1302
+ const tRow: Node = this.getGanttChartRow(i, tempTemplateData);
1303
+ this.ganttChartTableBody.appendChild(tRow);
1304
+ if (this.parent.enableImmutableMode) {
1305
+ this.refreshedTr.push(this.ganttChartTableBody.querySelectorAll('tr')[i]);
1306
+ this.refreshedData.push(this.parent.currentViewData[i]);
1307
+ }
1308
+ // To maintain selection when virtualization is enabled
1309
+ if (this.parent.selectionModule && this.parent.allowSelection) {
1310
+ this.parent.selectionModule.maintainSelectedRecords(parseInt((tRow as Element).getAttribute('aria-rowindex'), 10));
1311
+ }
1312
+ }
1313
+ }
1314
+ this.parent.renderTemplates();
1315
+ this.triggerQueryTaskbarInfo();
1316
+ this.parent.modifiedRecords = [];
1317
+ if (collapsedResourceRecord.length) {
1318
+ for (let j: number = 0; j < collapsedResourceRecord.length; j++) {
1319
+ if (collapsedResourceRecord[j].hasChildRecords) {
1320
+ this.parent.isGanttChartRendered = true;
1321
+ this.parent.chartRowsModule.refreshRecords([collapsedResourceRecord[j]]);
1322
+ }
1323
+ }
1324
+ }
1325
+ this.parent.renderTemplates();
1326
+ }
1327
+
1328
+ /**
1329
+ * To render taskbars.
1330
+ *
1331
+ * @param {number} i .
1332
+ * @param {IGanttData} tempTemplateData .
1333
+ * @returns {Node} .
1334
+ * @private
1335
+ */
1336
+ public getGanttChartRow(i: number, tempTemplateData: IGanttData): Node {
1337
+ this.templateData = tempTemplateData;
1338
+ let taskBaselineTemplateNode: NodeList = null;
1339
+ const parentTrNode: NodeList = this.getTableTrNode();
1340
+ const leftLabelNode: NodeList = this.getLeftLabelNode(i);
1341
+ const taskbarContainerNode: NodeList = this.taskbarContainer();
1342
+ (<HTMLElement>taskbarContainerNode[0]).setAttribute('aria-label', this.generateAriaLabel(this.templateData));
1343
+ (<HTMLElement>taskbarContainerNode[0]).setAttribute('rowUniqueId', this.templateData.ganttProperties.rowUniqueID);
1344
+ if (!this.templateData.hasChildRecords) {
1345
+ const connectorLineLeftNode: NodeList = this.getLeftPointNode();
1346
+ taskbarContainerNode[0].appendChild([].slice.call(connectorLineLeftNode)[0]);
1347
+ }
1348
+ if (this.templateData.hasChildRecords) {
1349
+ const parentTaskbarTemplateNode: NodeList = this.getParentTaskbarNode(i, taskbarContainerNode);
1350
+ if (!this.templateData.ganttProperties.isAutoSchedule) {
1351
+ const manualTaskbar: NodeList = this.getManualTaskbar();
1352
+ taskbarContainerNode[0].appendChild([].slice.call(manualTaskbar)[0]);
1353
+ }
1354
+ if (parentTaskbarTemplateNode && parentTaskbarTemplateNode.length > 0) {
1355
+ taskbarContainerNode[0].appendChild([].slice.call(parentTaskbarTemplateNode)[0]);
1356
+ }
1357
+ if (this.parent.renderBaseline && this.templateData.ganttProperties.baselineStartDate &&
1358
+ this.templateData.ganttProperties.baselineEndDate) {
1359
+ taskBaselineTemplateNode = this.getTaskBaselineNode();
1360
+ }
1361
+ } else if (this.templateData.ganttProperties.isMilestone) {
1362
+ const milestoneTemplateNode: NodeList = this.getMilestoneNode(i, taskbarContainerNode);
1363
+ if (milestoneTemplateNode && milestoneTemplateNode.length > 0) {
1364
+ taskbarContainerNode[0].appendChild([].slice.call(milestoneTemplateNode)[0]);
1365
+ }
1366
+ if (this.parent.renderBaseline && this.templateData.ganttProperties.baselineStartDate &&
1367
+ this.templateData.ganttProperties.baselineEndDate) {
1368
+ taskBaselineTemplateNode = this.getMilestoneBaselineNode();
1369
+ }
1370
+ } else {
1371
+ const scheduledTask: Boolean = isScheduledTask(this.templateData.ganttProperties);// eslint-disable-line
1372
+ let childTaskbarProgressResizeNode: NodeList = null; let childTaskbarRightResizeNode: NodeList = null;
1373
+ let childTaskbarLeftResizeNode: NodeList = null;
1374
+ if (!isNullOrUndefined(scheduledTask)) {
1375
+ if (scheduledTask || this.templateData.ganttProperties.duration) {
1376
+ if (scheduledTask && (isNullOrUndefined(this.templateData.ganttProperties.segments)
1377
+ || this.templateData.ganttProperties.segments.length <= 0)) {
1378
+ childTaskbarProgressResizeNode = this.childTaskbarProgressResizer();
1379
+ childTaskbarLeftResizeNode = this.childTaskbarLeftResizer();
1380
+ childTaskbarRightResizeNode = this.childTaskbarRightResizer();
1381
+ }
1382
+ }
1383
+ const childTaskbarTemplateNode: NodeList = this.getChildTaskbarNode(i, taskbarContainerNode);
1384
+ if (childTaskbarLeftResizeNode) {
1385
+ taskbarContainerNode[0].appendChild([].slice.call(childTaskbarLeftResizeNode)[0]);
1386
+ }
1387
+ if (childTaskbarTemplateNode && childTaskbarTemplateNode.length > 0) {
1388
+ if (this.templateData.ganttProperties.segments && this.templateData.ganttProperties.segments.length > 0) {
1389
+ const length: number = this.templateData.ganttProperties.segments.length;
1390
+ const connector: string = ('<div class="e-gantt-split-container-line"></div>');
1391
+ let segmentConnector: NodeList = null;
1392
+ segmentConnector = this.createDivElement(connector);
1393
+ taskbarContainerNode[0].appendChild([].slice.call(segmentConnector)[0]);
1394
+ for (let i: number = 0; i < length; i++) {
1395
+ taskbarContainerNode[0].appendChild([].slice.call(childTaskbarTemplateNode)[0]);
1396
+ }
1397
+ } else {
1398
+ taskbarContainerNode[0].appendChild([].slice.call(childTaskbarTemplateNode)[0]);
1399
+ }
1400
+ }
1401
+ if (childTaskbarProgressResizeNode) {
1402
+ taskbarContainerNode[0].appendChild([].slice.call(childTaskbarProgressResizeNode)[0]);
1403
+ }
1404
+ if (childTaskbarRightResizeNode) {
1405
+ taskbarContainerNode[0].appendChild([].slice.call(childTaskbarRightResizeNode)[0]);
1406
+ }
1407
+ }
1408
+ if (this.parent.renderBaseline && this.templateData.ganttProperties.baselineStartDate &&
1409
+ this.templateData.ganttProperties.baselineEndDate) {
1410
+ taskBaselineTemplateNode = this.getTaskBaselineNode();
1411
+ }
1412
+ }
1413
+ if (!this.templateData.hasChildRecords) {
1414
+ const connectorLineRightNode: NodeList = this.getRightPointNode();
1415
+ taskbarContainerNode[0].appendChild([].slice.call(connectorLineRightNode)[0]);
1416
+ }
1417
+ const rightLabelNode: NodeList = this.getRightLabelNode(i);
1418
+ parentTrNode[0].childNodes[0].childNodes[0].appendChild([].slice.call(leftLabelNode)[0]);
1419
+ parentTrNode[0].childNodes[0].childNodes[0].appendChild([].slice.call(taskbarContainerNode)[0]);
1420
+ if (this.templateData.ganttProperties.indicators && this.templateData.ganttProperties.indicators.length > 0) {
1421
+ let taskIndicatorNode: NodeList;
1422
+ let taskIndicatorTextFunction: Function;
1423
+ let taskIndicatorTextNode: NodeList;
1424
+ const indicators: IIndicator[] = this.templateData.ganttProperties.indicators;
1425
+ for (let indicatorIndex: number = 0; indicatorIndex < indicators.length; indicatorIndex++) {
1426
+ taskIndicatorNode = this.getIndicatorNode(indicators[indicatorIndex]);
1427
+ (<HTMLElement>taskIndicatorNode[0]).setAttribute('aria-label',indicators[indicatorIndex].name);
1428
+ if (indicators[indicatorIndex].name.indexOf('$') > -1 || indicators[indicatorIndex].name.indexOf('#') > -1) {
1429
+ taskIndicatorTextFunction = this.templateCompiler(indicators[indicatorIndex].name);
1430
+ taskIndicatorTextNode = taskIndicatorTextFunction(
1431
+ extend({ index: i }, this.templateData), this.parent, 'indicatorLabelText');
1432
+ } else {
1433
+ const text: Element = createElement('Text');
1434
+ text.innerHTML = indicators[indicatorIndex].name;
1435
+ taskIndicatorTextNode = text.childNodes;
1436
+ }
1437
+ taskIndicatorNode[0].appendChild([].slice.call(taskIndicatorTextNode)[0]);
1438
+ (taskIndicatorNode[0] as HTMLElement).title =
1439
+ !isNullOrUndefined(indicators[indicatorIndex].tooltip) ? indicators[indicatorIndex].tooltip : '';
1440
+ parentTrNode[0].childNodes[0].childNodes[0].appendChild([].slice.call(taskIndicatorNode)[0]);
1441
+ }
1442
+ }
1443
+ if (rightLabelNode && rightLabelNode.length > 0) {
1444
+ parentTrNode[0].childNodes[0].childNodes[0].appendChild([].slice.call(rightLabelNode)[0]);
1445
+ }
1446
+ if (!isNullOrUndefined(taskBaselineTemplateNode)) {
1447
+ parentTrNode[0].childNodes[0].childNodes[0].appendChild([].slice.call(taskBaselineTemplateNode)[0]);
1448
+ }
1449
+ const tRow: Node = parentTrNode[0].childNodes[0];
1450
+ this.setAriaRowIndex(tempTemplateData, tRow);
1451
+ return tRow;
1452
+ }
1453
+ /**
1454
+ * To set aria-rowindex for chart rows
1455
+ *
1456
+ * @returns {void} .
1457
+ * @private
1458
+ */
1459
+
1460
+ public setAriaRowIndex(tempTemplateData: IGanttData, tRow: Node): void {
1461
+ const dataSource: IGanttData[] = this.parent.treeGrid.getCurrentViewRecords() as IGanttData[];
1462
+ const visualData: IGanttData[] = this.parent.virtualScrollModule && this.parent.enableVirtualization ?
1463
+ getValue('virtualScrollModule.visualData', this.parent.treeGrid) : dataSource;
1464
+ const index: number = visualData.indexOf(tempTemplateData);
1465
+ (tRow as Element).setAttribute('aria-rowindex', index.toString());
1466
+ }
1467
+ /**
1468
+ * To trigger query taskbar info event.
1469
+ *
1470
+ * @returns {void}
1471
+ * @private
1472
+ */
1473
+ public triggerQueryTaskbarInfo(): void {
1474
+ if (!this.parent.queryTaskbarInfo) {
1475
+ return;
1476
+ }
1477
+ const length: number = this.parent.enableImmutableMode ?
1478
+ this.refreshedTr.length : this.ganttChartTableBody.querySelectorAll('tr').length;
1479
+ let trElement: Element;
1480
+ let data: IGanttData;
1481
+ for (let index: number = 0; index < length; index++) {
1482
+ trElement = this.parent.enableImmutableMode ? this.refreshedTr[index] : this.ganttChartTableBody.querySelectorAll('tr')[index];
1483
+ data = this.refreshedData.length > 0 ? this.refreshedData[index] : this.parent.currentViewData[index];
1484
+ const segmentLength: number = !isNullOrUndefined(data.ganttProperties.segments) && data.ganttProperties.segments.length;
1485
+ if (segmentLength > 0) {
1486
+ for (let i: number = 0; i < segmentLength; i++) {
1487
+ const segmentedTasks: HTMLCollectionOf<HTMLElement> =
1488
+ trElement.getElementsByClassName('e-segmented-taskbar') as HTMLCollectionOf<HTMLElement>;
1489
+ const segmentElement: HTMLElement = segmentedTasks[i] as HTMLElement;
1490
+ this.triggerQueryTaskbarInfoByIndex(segmentElement, data);
1491
+ }
1492
+ } else if (trElement) {
1493
+ this.triggerQueryTaskbarInfoByIndex(trElement, data);
1494
+ }
1495
+ }
1496
+ }
1497
+ /**
1498
+ *
1499
+ * @param {Element} trElement .
1500
+ * @param {IGanttData} data .
1501
+ * @returns {void} .
1502
+ * @private
1503
+ */
1504
+ public triggerQueryTaskbarInfoByIndex(trElement: Element, data: IGanttData): void {
1505
+ // eslint-disable-next-line
1506
+ const taskbarElement: Element = !isNullOrUndefined(data.ganttProperties.segments) && data.ganttProperties.segments.length > 0 ? trElement :
1507
+ trElement.querySelector('.' + cls.taskBarMainContainer);
1508
+ let rowElement: Element;
1509
+ let triggerTaskbarElement: Element;
1510
+ const args: IQueryTaskbarInfoEventArgs = {
1511
+ data: data,
1512
+ rowElement: trElement,
1513
+ taskbarElement: taskbarElement,
1514
+ taskbarType: data.hasChildRecords ? 'ParentTask' : data.ganttProperties.isMilestone ? 'Milestone' : 'ChildTask'
1515
+ };
1516
+ const classCollections: string[] = this.getClassName(args);
1517
+ if (args.taskbarType === 'Milestone') {
1518
+ args.milestoneColor = taskbarElement.querySelector(classCollections[0]) ?
1519
+ getComputedStyle(taskbarElement.querySelector(classCollections[0])).borderBottomColor : null;
1520
+ args.baselineColor = trElement.querySelector(classCollections[1]) ?
1521
+ getComputedStyle(trElement.querySelector(classCollections[1])).borderBottomColor : null;
1522
+ } else {
1523
+ const childTask: HTMLElement = taskbarElement.querySelector(classCollections[0]);
1524
+ const progressTask: HTMLElement = taskbarElement.querySelector(classCollections[1]);
1525
+ args.taskbarBgColor = isNullOrUndefined(childTask) ? null : taskbarElement.classList.contains(cls.traceChildTaskBar) ?
1526
+ getComputedStyle(taskbarElement).backgroundColor :
1527
+ getComputedStyle(taskbarElement.querySelector(classCollections[0])).backgroundColor;
1528
+ args.taskbarBorderColor = isNullOrUndefined(childTask) ? null : taskbarElement.classList.contains(cls.traceChildTaskBar) ?
1529
+ getComputedStyle(taskbarElement).backgroundColor :
1530
+ getComputedStyle(taskbarElement.querySelector(classCollections[0])).borderColor;
1531
+ args.progressBarBgColor = isNullOrUndefined(progressTask) ? null :
1532
+ taskbarElement.classList.contains(cls.traceChildProgressBar) ?
1533
+ getComputedStyle(taskbarElement).backgroundColor :
1534
+ getComputedStyle(taskbarElement.querySelector(classCollections[1])).backgroundColor;
1535
+ // args.progressBarBorderColor = taskbarElement.querySelector(progressBarClass) ?
1536
+ // getComputedStyle(taskbarElement.querySelector(progressBarClass)).borderColor : null;
1537
+ args.baselineColor = trElement.querySelector('.' + cls.baselineBar) ?
1538
+ getComputedStyle(trElement.querySelector('.' + cls.baselineBar)).backgroundColor : null;
1539
+ args.taskLabelColor = taskbarElement.querySelector('.' + cls.taskLabel) ?
1540
+ getComputedStyle(taskbarElement.querySelector('.' + cls.taskLabel)).color : null;
1541
+ }
1542
+ args.rightLabelColor = trElement.querySelector('.' + cls.rightLabelContainer) &&
1543
+ (trElement.querySelector('.' + cls.rightLabelContainer)).querySelector('.' + cls.label) ?
1544
+ getComputedStyle((trElement.querySelector('.' + cls.rightLabelContainer)).querySelector('.' + cls.label)).color : null;
1545
+ args.leftLabelColor = trElement.querySelector('.' + cls.leftLabelContainer) &&
1546
+ (trElement.querySelector('.' + cls.leftLabelContainer)).querySelector('.' + cls.label) ?
1547
+ getComputedStyle((trElement.querySelector('.' + cls.leftLabelContainer)).querySelector('.' + cls.label)).color : null;
1548
+ this.parent.trigger('queryTaskbarInfo', args, (taskbarArgs: IQueryTaskbarInfoEventArgs) => {
1549
+ this.updateQueryTaskbarInfoArgs(taskbarArgs, rowElement, triggerTaskbarElement);
1550
+ });
1551
+ }
1552
+
1553
+ /**
1554
+ * To update query taskbar info args.
1555
+ *
1556
+ * @param {IQueryTaskbarInfoEventArgs} args .
1557
+ * @param {Element} rowElement .
1558
+ * @param {Element} taskBarElement .
1559
+ * @returns {void}
1560
+ * @private
1561
+ */
1562
+ private updateQueryTaskbarInfoArgs(args: IQueryTaskbarInfoEventArgs, rowElement?: Element, taskBarElement?: Element): void {
1563
+ const trElement: Element = args.rowElement;
1564
+ const taskbarElement: Element = args.taskbarElement;
1565
+ const classCollections: string[] = this.getClassName(args);
1566
+ if (args.taskbarType === 'Milestone') {
1567
+ if (taskbarElement.querySelector(classCollections[0]) &&
1568
+ getComputedStyle(taskbarElement.querySelector(classCollections[0])).borderBottomColor !== args.milestoneColor) {
1569
+ (taskbarElement.querySelector(classCollections[0]) as HTMLElement).style.borderBottomColor = args.milestoneColor;
1570
+ (taskbarElement.querySelector('.' + cls.milestoneBottom) as HTMLElement).style.borderTopColor = args.milestoneColor;
1571
+ }
1572
+ if (trElement.querySelector(classCollections[1]) &&
1573
+ getComputedStyle(trElement.querySelector(classCollections[1])).borderTopColor !== args.baselineColor) {
1574
+ (trElement.querySelector(classCollections[1]) as HTMLElement).style.borderBottomColor = args.baselineColor;
1575
+ (trElement.querySelector('.' + cls.baselineMilestoneBottom) as HTMLElement).style.borderTopColor = args.baselineColor;
1576
+ }
1577
+ } else {
1578
+ if (taskbarElement.querySelector(classCollections[0]) &&
1579
+ getComputedStyle(taskbarElement.querySelector(classCollections[0])).backgroundColor !== args.taskbarBgColor) {
1580
+ (taskbarElement.querySelector(classCollections[0]) as HTMLElement).style.backgroundColor = args.taskbarBgColor;
1581
+ }
1582
+ if (taskbarElement.querySelector(classCollections[0]) &&
1583
+ getComputedStyle(taskbarElement.querySelector(classCollections[0])).borderColor !== args.taskbarBorderColor) {
1584
+ (taskbarElement.querySelector(classCollections[0]) as HTMLElement).style.borderColor = args.taskbarBorderColor;
1585
+ }
1586
+ if (taskbarElement.querySelector(classCollections[1]) &&
1587
+ getComputedStyle(taskbarElement.querySelector(classCollections[1])).backgroundColor !== args.progressBarBgColor) {
1588
+ (taskbarElement.querySelector(classCollections[1]) as HTMLElement).style.backgroundColor = args.progressBarBgColor;
1589
+ }
1590
+
1591
+ if (taskbarElement.classList.contains(cls.traceChildTaskBar) &&
1592
+ getComputedStyle(taskbarElement).backgroundColor !== args.taskbarBgColor) {
1593
+ (taskbarElement as HTMLElement).style.backgroundColor = args.taskbarBgColor;
1594
+ }
1595
+
1596
+ if (taskbarElement.classList.contains(cls.traceChildTaskBar) &&
1597
+ getComputedStyle(taskbarElement).borderColor !== args.taskbarBorderColor) {
1598
+ (taskbarElement as HTMLElement).style.borderColor = args.taskbarBorderColor;
1599
+ }
1600
+
1601
+ if (taskbarElement.classList.contains(cls.traceChildProgressBar) &&
1602
+ getComputedStyle(taskbarElement).backgroundColor !== args.progressBarBgColor) {
1603
+ (taskbarElement as HTMLElement).style.backgroundColor = args.progressBarBgColor;
1604
+ }
1605
+ // if (taskbarElement.querySelector(progressBarClass) &&
1606
+ // getComputedStyle(taskbarElement.querySelector(progressBarClass)).borderColor !== args.progressBarBorderColor) {
1607
+ // (taskbarElement.querySelector(progressBarClass) as HTMLElement).style.borderColor = args.progressBarBorderColor;
1608
+ // }
1609
+ if (taskbarElement.querySelector('.' + cls.taskLabel) &&
1610
+ getComputedStyle(taskbarElement.querySelector('.' + cls.taskLabel)).color !== args.taskLabelColor) {
1611
+ (taskbarElement.querySelector('.' + cls.taskLabel) as HTMLElement).style.color = args.taskLabelColor;
1612
+ }
1613
+ if (trElement.querySelector('.' + cls.baselineBar) &&
1614
+ getComputedStyle(trElement.querySelector('.' + cls.baselineBar)).backgroundColor !== args.baselineColor) {
1615
+ (trElement.querySelector('.' + cls.baselineBar) as HTMLElement).style.backgroundColor = args.baselineColor;
1616
+ }
1617
+ }
1618
+ if (trElement.querySelector('.' + cls.leftLabelContainer) &&
1619
+ (trElement.querySelector('.' + cls.leftLabelContainer)).querySelector('.' + cls.label) &&
1620
+ getComputedStyle(
1621
+ (trElement.querySelector('.' + cls.leftLabelContainer)).querySelector('.' + cls.label)).color !== args.leftLabelColor) {
1622
+ ((trElement.querySelector(
1623
+ '.' + cls.leftLabelContainer)).querySelector('.' + cls.label) as HTMLElement).style.color = args.leftLabelColor;
1624
+ }
1625
+ if (trElement.querySelector('.' + cls.rightLabelContainer) &&
1626
+ (trElement.querySelector('.' + cls.rightLabelContainer)).querySelector('.' + cls.label) &&
1627
+ getComputedStyle(
1628
+ (trElement.querySelector('.' + cls.rightLabelContainer)).querySelector('.' + cls.label)).color !== args.rightLabelColor) {
1629
+ ((trElement.querySelector(
1630
+ '.' + cls.rightLabelContainer)).querySelector('.' + cls.label) as HTMLElement).style.color = args.rightLabelColor;
1631
+ }
1632
+ }
1633
+ private getClassName(args: IQueryTaskbarInfoEventArgs): string[] {
1634
+ const classCollection: string[] = [];
1635
+ classCollection.push('.' + (args.taskbarType === 'ParentTask' ?
1636
+ cls.traceParentTaskBar : args.taskbarType === 'ChildTask' ? cls.traceChildTaskBar : cls.milestoneTop));
1637
+ classCollection.push('.' + (args.taskbarType === 'ParentTask' ?
1638
+ cls.traceParentProgressBar : args.taskbarType === 'ChildTask' ? cls.traceChildProgressBar : cls.baselineMilestoneTop));
1639
+ return classCollection;
1640
+ }
1641
+ /**
1642
+ * To compile template string.
1643
+ *
1644
+ * @param {string} template .
1645
+ * @returns {Function} .
1646
+ * @private
1647
+ */
1648
+ public templateCompiler(template: string): Function {
1649
+ if (!isNullOrUndefined(template) && template !== '') {
1650
+ try {
1651
+ if (document.querySelectorAll(template).length) {
1652
+ return compile(document.querySelector(template).innerHTML.trim(), this.parent);
1653
+ } else {
1654
+ return compile(template, this.parent);
1655
+ }
1656
+ } catch (e) {
1657
+ return compile(template, this.parent);
1658
+ }
1659
+ }
1660
+ return null;
1661
+ }
1662
+
1663
+ /**
1664
+ * To refresh edited TR
1665
+ *
1666
+ * @param {number} index .
1667
+ * @param {boolean} isValidateRange .
1668
+ * @returns {void} .
1669
+ * @private
1670
+ */
1671
+ public refreshRow(index: number, isValidateRange?: boolean): void {
1672
+ const tr: Node = this.ganttChartTableBody.childNodes[index];
1673
+ const selectedItem: IGanttData = this.parent.currentViewData[index];
1674
+ if (index !== -1 && selectedItem) {
1675
+ const data: IGanttData = selectedItem;
1676
+ if (this.parent.viewType === 'ResourceView' && data.hasChildRecords && !data.expanded && this.parent.enableMultiTaskbar) {
1677
+ tr.replaceChild(this.getResourceParent(data).childNodes[0], tr.childNodes[0]);
1678
+ } else {
1679
+ tr.replaceChild(this.getGanttChartRow(index, data).childNodes[0], tr.childNodes[0]);
1680
+ }
1681
+ this.parent.renderTemplates();
1682
+ if (this.parent.viewType === 'ResourceView' && data.hasChildRecords && this.parent.showOverAllocation) {
1683
+ if (isValidateRange) {
1684
+ this.parent.ganttChartModule.renderRangeContainer(this.parent.currentViewData);
1685
+ } else {
1686
+ this.parent.dataOperation.updateOverlappingValues(data);
1687
+ this.parent.ganttChartModule.renderRangeContainer([data]);
1688
+ }
1689
+ }
1690
+ const segmentLength: number = !isNullOrUndefined(data.ganttProperties.segments) && data.ganttProperties.segments.length;
1691
+ if (segmentLength > 0) {
1692
+ for (let i: number = 0; i < segmentLength; i++) {
1693
+ const segmentedTasks: HTMLCollectionOf<HTMLElement> =
1694
+ (tr as Element).getElementsByClassName('e-segmented-taskbar') as HTMLCollectionOf<HTMLElement>;
1695
+ const segmentElement: HTMLElement = segmentedTasks[i] as HTMLElement;
1696
+ this.triggerQueryTaskbarInfoByIndex(segmentElement, data);
1697
+ }
1698
+ } else {
1699
+ this.triggerQueryTaskbarInfoByIndex(tr as Element, data);
1700
+ }
1701
+ const dataId: number | string = this.parent.viewType === 'ProjectView' ? data.ganttProperties.taskId : data.ganttProperties.rowUniqueID;
1702
+ this.parent.treeGrid.grid.setRowData(dataId, data);
1703
+ const row: Row<Column> = this.parent.treeGrid.grid.getRowObjectFromUID(
1704
+ this.parent.treeGrid.grid.getDataRows()[index].getAttribute('data-uid'));
1705
+ row.data = data;
1706
+ }
1707
+ }
1708
+
1709
+ private getResourceParent(record: IGanttData): Node {
1710
+ const chartRows: NodeListOf<Element> = this.parent.ganttChartModule.getChartRows();
1711
+ this.templateData = record;
1712
+ const parentTrNode: NodeList = this.getTableTrNode();
1713
+ const leftLabelNode: NodeList = this.leftLabelContainer();
1714
+ const collapseParent: HTMLElement = createElement('div', {
1715
+ className: 'e-collapse-parent'
1716
+ });
1717
+ parentTrNode[0].childNodes[0].childNodes[0].appendChild(collapseParent);
1718
+ const tasks: IGanttData[] = this.parent.dataOperation.setSortedChildTasks(record);
1719
+ this.parent.dataOperation.updateOverlappingIndex(tasks);
1720
+ for (let i: number = 0; i < chartRows.length; i++) {
1721
+ if ((<HTMLElement>chartRows[i]).classList.contains('gridrowtaskId'
1722
+ + record.ganttProperties.rowUniqueID + 'level' + (record.level + 1))) {
1723
+ const cloneElement: HTMLElement = chartRows[i].querySelector('.e-taskbar-main-container');
1724
+ addClass([cloneElement], 'collpse-parent-border');
1725
+ const id: string = chartRows[i].querySelector('.' + cls.taskBarMainContainer).getAttribute('rowUniqueId');
1726
+ const ganttData: IGanttData = this.parent.getRecordByID(id);
1727
+ const zIndex: string = (ganttData.ganttProperties.eOverlapIndex).toString();
1728
+ const cloneChildElement: HTMLElement = cloneElement.cloneNode(true) as HTMLElement;
1729
+ cloneChildElement.style.zIndex = zIndex;
1730
+ parentTrNode[0].childNodes[0].childNodes[0].childNodes[0].appendChild(cloneChildElement);
1731
+ }
1732
+ }
1733
+ parentTrNode[0].childNodes[0].childNodes[0].appendChild([].slice.call(leftLabelNode)[0]);
1734
+ return parentTrNode[0].childNodes[0];
1735
+ }
1736
+ /**
1737
+ * To refresh all edited records
1738
+ *
1739
+ * @param {IGanttData} items .
1740
+ * @param {boolean} isValidateRange .
1741
+ * @returns {void} .
1742
+ * @private
1743
+ */
1744
+ public refreshRecords(items: IGanttData[], isValidateRange?: boolean): void {
1745
+ if (this.parent.isGanttChartRendered) {
1746
+ this.parent.renderTemplates();
1747
+ if (this.parent.viewType === 'ResourceView' && this.parent.enableMultiTaskbar) {
1748
+ let sortedRecords: IGanttData[] = [];
1749
+ sortedRecords = new DataManager(items).executeLocal(new Query()
1750
+ .sortBy('expanded', 'Descending'));
1751
+ items = sortedRecords;
1752
+ }
1753
+ for (let i: number = 0; i < items.length; i++) {
1754
+ const index: number = this.parent.currentViewData.indexOf(items[i]);
1755
+ this.refreshRow(index, isValidateRange);
1756
+ }
1757
+ this.parent.ganttChartModule.updateLastRowBottomWidth();
1758
+ }
1759
+ }
1760
+
1761
+ private removeEventListener(): void {
1762
+ if (this.parent.isDestroyed) {
1763
+ return;
1764
+ }
1765
+ this.parent.off('renderPanels', this.createChartTable);
1766
+ this.parent.off('dataReady', this.initiateTemplates);
1767
+ this.parent.off('destroy', this.destroy);
1768
+ }
1769
+ private destroy(): void {
1770
+ this.removeEventListener();
1771
+ }
1772
+
1773
+ private generateAriaLabel(data: IGanttData): string {
1774
+ data = this.templateData;
1775
+ let defaultValue: string = '';
1776
+ const nameConstant: string = this.parent.localeObj.getConstant('name');
1777
+ const startDateConstant: string = this.parent.localeObj.getConstant('startDate');
1778
+ const endDateConstant: string = this.parent.localeObj.getConstant('endDate');
1779
+ const durationConstant: string = this.parent.localeObj.getConstant('duration');
1780
+ const taskNameVal: string = data.ganttProperties.taskName;
1781
+ const startDateVal: Date = data.ganttProperties.startDate;
1782
+ const endDateVal: Date = data.ganttProperties.endDate;
1783
+ const durationVal: number = data.ganttProperties.duration;
1784
+
1785
+ if (data.ganttProperties.isMilestone) {
1786
+ defaultValue = nameConstant + ' ' + taskNameVal + ' ' + startDateConstant + ' '
1787
+ + this.parent.getFormatedDate(startDateVal);
1788
+ } else {
1789
+ if (taskNameVal) {
1790
+ defaultValue += nameConstant + ' ' + taskNameVal + ' ';
1791
+ }
1792
+ if (startDateVal) {
1793
+ defaultValue += startDateConstant + ' ' + this.parent.getFormatedDate(startDateVal) + ' ';
1794
+ }
1795
+ if (endDateVal) {
1796
+ defaultValue += endDateConstant + ' ' + this.parent.getFormatedDate(endDateVal) + ' ';
1797
+ }
1798
+ if (durationVal) {
1799
+ defaultValue += durationConstant + ' '
1800
+ + this.parent.getDurationString(durationVal, data.ganttProperties.durationUnit);
1801
+ }
1802
+ }
1803
+ return defaultValue;
1804
+ }
1805
+
1806
+ private generateSpiltTaskAriaLabel(data: ITaskSegment, ganttProp: ITaskData): string {
1807
+ let defaultValue: string = '';
1808
+ const startDateConstant: string = this.parent.localeObj.getConstant('startDate');
1809
+ const endDateConstant: string = this.parent.localeObj.getConstant('endDate');
1810
+ const durationConstant: string = this.parent.localeObj.getConstant('duration');
1811
+ const startDateVal: Date = data.startDate;
1812
+ const endDateVal: Date = data.endDate;
1813
+ const durationVal: number = data.duration;
1814
+ if (startDateVal) {
1815
+ defaultValue += startDateConstant + ' ' + this.parent.getFormatedDate(startDateVal) + ' ';
1816
+ }
1817
+ if (endDateVal) {
1818
+ defaultValue += endDateConstant + ' ' + this.parent.getFormatedDate(endDateVal) + ' ';
1819
+ }
1820
+ if (durationVal) {
1821
+ defaultValue += durationConstant + ' '
1822
+ + this.parent.getDurationString(durationVal, ganttProp.durationUnit);
1823
+ }
1824
+ return defaultValue;
1825
+ }
1826
+
1827
+ private generateTaskLabelAriaLabel(type: string): string {
1828
+ let label: string = '';
1829
+ if (type === 'left' && this.parent.labelSettings.leftLabel && !this.leftTaskLabelTemplateFunction) {
1830
+ label += this.parent.localeObj.getConstant('leftTaskLabel') +
1831
+ ' ' + this.getTaskLabel(this.parent.labelSettings.leftLabel);
1832
+ } else if (type === 'right' && this.parent.labelSettings.rightLabel && !this.rightTaskLabelTemplateFunction) {
1833
+ label += this.parent.localeObj.getConstant('rightTaskLabel') +
1834
+ ' ' + this.getTaskLabel(this.parent.labelSettings.rightLabel);
1835
+ }
1836
+ return label;
1837
+ }
1838
+ }