@progress/kendo-angular-gantt 0.3.0-dev.202112141015 → 1.0.0-dev.202201191538

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 (151) hide show
  1. package/dist/cdn/js/kendo-angular-gantt.js +2 -2
  2. package/dist/cdn/main.js +1 -23
  3. package/dist/es/common/touch-enabled.js +9 -0
  4. package/dist/es/dependencies/utils.js +40 -5
  5. package/dist/es/dragging/dependency-drag-create.directive.js +347 -0
  6. package/dist/es/dragging/drag-validation-tooltip.component.js +27 -0
  7. package/dist/es/editing/dependencies-table.component.js +131 -0
  8. package/dist/es/editing/edit-dialog.component.js +39 -8
  9. package/dist/es/editing/edit.service.js +91 -8
  10. package/dist/es/editing/task-fields.component.js +43 -0
  11. package/dist/es/editing/{util.js → utils.js} +0 -0
  12. package/dist/es/gantt.component.js +352 -44
  13. package/dist/es/gantt.module.js +35 -9
  14. package/dist/es/index.js +8 -0
  15. package/dist/es/localization/gantt-localization.service.js +26 -0
  16. package/dist/es/main.js +1 -0
  17. package/dist/es/models/dependency-type.enum.js +16 -0
  18. package/dist/es/models/events/{edit-event.interface.js → dependency-add-event.interface.js} +0 -0
  19. package/dist/es/models/events/{remove-event.interface.js → task-delete-event.interface.js} +0 -0
  20. package/dist/es/models/models.js +1 -0
  21. package/dist/{es2015/models/events/edit-event.interface.js → es/models/view-item.interface.js} +0 -0
  22. package/dist/{es2015/models/events/remove-event.interface.js → es/navigation/navigation-models.js} +0 -0
  23. package/dist/es/navigation/navigation.service.js +390 -0
  24. package/dist/es/navigation/utils.js +77 -0
  25. package/dist/es/package-metadata.js +1 -1
  26. package/dist/es/rendering/gantt-milestone-task.component.js +12 -6
  27. package/dist/es/rendering/gantt-summary-task.component.js +27 -6
  28. package/dist/es/rendering/gantt-task-base.js +84 -22
  29. package/dist/es/rendering/gantt-task.component.js +13 -8
  30. package/dist/es/rendering/gantt-tasks-table-body.component.js +13 -5
  31. package/dist/es/scrolling/drag-scroll-settings.js +20 -0
  32. package/dist/es/scrolling/timeline-scroll.directive.js +89 -0
  33. package/dist/es/scrolling/timeline-scroll.service.js +39 -0
  34. package/dist/es/scrolling/utils.js +80 -0
  35. package/dist/es/timeline/gantt-timeline.component.js +50 -4
  36. package/dist/es/toolbar/toolbar.component.js +12 -13
  37. package/dist/es/toolbar/view-selector.component.js +1 -1
  38. package/dist/es/utils.js +153 -12
  39. package/dist/es2015/common/touch-enabled.d.ts +9 -0
  40. package/dist/es2015/common/touch-enabled.js +9 -0
  41. package/dist/es2015/dependencies/utils.d.ts +15 -0
  42. package/dist/es2015/dependencies/utils.js +40 -5
  43. package/dist/es2015/dragging/dependency-drag-create.directive.d.ts +72 -0
  44. package/dist/es2015/dragging/dependency-drag-create.directive.js +324 -0
  45. package/dist/es2015/dragging/drag-validation-tooltip.component.d.ts +29 -0
  46. package/dist/es2015/dragging/drag-validation-tooltip.component.js +76 -0
  47. package/dist/es2015/editing/dependencies-table.component.d.ts +39 -0
  48. package/dist/es2015/editing/dependencies-table.component.js +160 -0
  49. package/dist/es2015/editing/edit-dialog.component.d.ts +11 -4
  50. package/dist/es2015/editing/edit-dialog.component.js +66 -36
  51. package/dist/es2015/editing/edit.service.d.ts +22 -5
  52. package/dist/es2015/editing/edit.service.js +80 -11
  53. package/dist/es2015/editing/task-fields.component.d.ts +22 -0
  54. package/dist/es2015/editing/task-fields.component.js +67 -0
  55. package/dist/es2015/editing/{util.d.ts → utils.d.ts} +2 -2
  56. package/dist/es2015/editing/{util.js → utils.js} +0 -0
  57. package/dist/es2015/gantt.component.d.ts +116 -23
  58. package/dist/es2015/gantt.component.js +329 -48
  59. package/dist/es2015/gantt.module.js +35 -9
  60. package/dist/es2015/index.d.ts +8 -0
  61. package/dist/es2015/index.js +8 -0
  62. package/dist/es2015/index.metadata.json +1 -1
  63. package/dist/es2015/{models/events/remove-event.interface.d.ts → localization/gantt-localization.service.d.ts} +6 -7
  64. package/dist/es2015/localization/gantt-localization.service.js +25 -0
  65. package/dist/es2015/main.d.ts +1 -0
  66. package/dist/es2015/main.js +1 -0
  67. package/dist/es2015/models/dependency-type.enum.d.ts +1 -1
  68. package/dist/es2015/models/dependency-type.enum.js +16 -0
  69. package/dist/es2015/models/events/dependency-add-event.interface.d.ts +26 -0
  70. package/dist/es2015/models/events/dependency-add-event.interface.js +4 -0
  71. package/dist/es2015/models/events/task-click-event.interface.d.ts +3 -3
  72. package/dist/es2015/models/events/task-delete-event.interface.d.ts +21 -0
  73. package/dist/es2015/models/events/task-delete-event.interface.js +4 -0
  74. package/dist/es2015/models/events/task-edit-event.interface.d.ts +36 -6
  75. package/dist/es2015/models/models.d.ts +4 -2
  76. package/dist/es2015/models/models.js +1 -0
  77. package/dist/es2015/models/view-item.interface.d.ts +35 -0
  78. package/dist/es2015/models/view-item.interface.js +4 -0
  79. package/dist/es2015/navigation/navigation-models.d.ts +34 -0
  80. package/dist/es2015/navigation/navigation-models.js +4 -0
  81. package/dist/es2015/navigation/navigation.service.d.ts +126 -0
  82. package/dist/es2015/navigation/navigation.service.js +355 -0
  83. package/dist/es2015/navigation/utils.d.ts +26 -0
  84. package/dist/es2015/navigation/utils.js +69 -0
  85. package/dist/es2015/package-metadata.js +1 -1
  86. package/dist/es2015/rendering/gantt-milestone-task.component.d.ts +3 -1
  87. package/dist/es2015/rendering/gantt-milestone-task.component.js +35 -8
  88. package/dist/es2015/rendering/gantt-summary-task.component.d.ts +5 -1
  89. package/dist/es2015/rendering/gantt-summary-task.component.js +47 -8
  90. package/dist/es2015/rendering/gantt-task-base.d.ts +20 -6
  91. package/dist/es2015/rendering/gantt-task-base.js +75 -22
  92. package/dist/es2015/rendering/gantt-task.component.d.ts +4 -2
  93. package/dist/es2015/rendering/gantt-task.component.js +47 -13
  94. package/dist/es2015/rendering/gantt-tasks-table-body.component.d.ts +6 -3
  95. package/dist/es2015/rendering/gantt-tasks-table-body.component.js +27 -9
  96. package/dist/es2015/scrolling/drag-scroll-settings.d.ts +47 -0
  97. package/dist/es2015/scrolling/drag-scroll-settings.js +20 -0
  98. package/dist/es2015/scrolling/scroll-sync.service.d.ts +1 -1
  99. package/dist/es2015/scrolling/timeline-scroll.directive.d.ts +24 -0
  100. package/dist/es2015/scrolling/timeline-scroll.directive.js +78 -0
  101. package/dist/es2015/scrolling/timeline-scroll.service.d.ts +20 -0
  102. package/dist/es2015/scrolling/timeline-scroll.service.js +44 -0
  103. package/dist/es2015/scrolling/utils.d.ts +29 -0
  104. package/dist/es2015/scrolling/utils.js +80 -0
  105. package/dist/es2015/timeline/gantt-timeline.component.d.ts +29 -4
  106. package/dist/es2015/timeline/gantt-timeline.component.js +67 -5
  107. package/dist/es2015/toolbar/toolbar.component.d.ts +4 -5
  108. package/dist/es2015/toolbar/toolbar.component.js +12 -13
  109. package/dist/es2015/toolbar/view-selector.component.js +3 -1
  110. package/dist/es2015/utils.d.ts +77 -8
  111. package/dist/es2015/utils.js +153 -12
  112. package/dist/fesm2015/index.js +2807 -788
  113. package/dist/fesm5/index.js +2633 -688
  114. package/dist/{es2015/models/events/edit-event.interface.d.ts → npm/common/touch-enabled.js} +4 -12
  115. package/dist/npm/dependencies/utils.js +40 -5
  116. package/dist/npm/dragging/dependency-drag-create.directive.js +349 -0
  117. package/dist/npm/dragging/drag-validation-tooltip.component.js +29 -0
  118. package/dist/npm/editing/dependencies-table.component.js +133 -0
  119. package/dist/npm/editing/edit-dialog.component.js +38 -7
  120. package/dist/npm/editing/edit.service.js +90 -7
  121. package/dist/npm/editing/task-fields.component.js +45 -0
  122. package/dist/npm/editing/{util.js → utils.js} +0 -0
  123. package/dist/npm/gantt.component.js +354 -46
  124. package/dist/npm/gantt.module.js +33 -7
  125. package/dist/npm/index.js +16 -0
  126. package/dist/npm/localization/gantt-localization.service.js +28 -0
  127. package/dist/npm/main.js +2 -0
  128. package/dist/npm/models/dependency-type.enum.js +16 -0
  129. package/dist/npm/models/events/{edit-event.interface.js → dependency-add-event.interface.js} +0 -0
  130. package/dist/npm/models/events/{remove-event.interface.js → task-delete-event.interface.js} +0 -0
  131. package/dist/npm/models/models.js +2 -0
  132. package/dist/npm/models/view-item.interface.js +6 -0
  133. package/dist/npm/navigation/navigation-models.js +6 -0
  134. package/dist/npm/navigation/navigation.service.js +392 -0
  135. package/dist/npm/navigation/utils.js +79 -0
  136. package/dist/npm/package-metadata.js +1 -1
  137. package/dist/npm/rendering/gantt-milestone-task.component.js +11 -5
  138. package/dist/npm/rendering/gantt-summary-task.component.js +26 -5
  139. package/dist/npm/rendering/gantt-task-base.js +84 -22
  140. package/dist/npm/rendering/gantt-task.component.js +12 -7
  141. package/dist/npm/rendering/gantt-tasks-table-body.component.js +13 -5
  142. package/dist/npm/scrolling/drag-scroll-settings.js +22 -0
  143. package/dist/npm/scrolling/timeline-scroll.directive.js +91 -0
  144. package/dist/npm/scrolling/timeline-scroll.service.js +41 -0
  145. package/dist/npm/scrolling/utils.js +83 -0
  146. package/dist/npm/timeline/gantt-timeline.component.js +49 -3
  147. package/dist/npm/toolbar/toolbar.component.js +10 -11
  148. package/dist/npm/toolbar/view-selector.component.js +1 -1
  149. package/dist/npm/utils.js +153 -12
  150. package/dist/systemjs/kendo-angular-gantt.js +1 -1
  151. package/package.json +23 -19
@@ -2,26 +2,29 @@
2
2
  * Copyright © 2021 Progress Software Corporation. All rights reserved.
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
- import { __extends, __decorate, __metadata, __param, __assign } from 'tslib';
6
- import { Input, Injectable, EventEmitter, Directive, Optional, TemplateRef, QueryList, ContentChildren, ContentChild, Component, forwardRef, SkipSelf, Host, Injector, NgZone, isDevMode, ViewChild, HostBinding, Output, Renderer2, ElementRef, ChangeDetectorRef, NgModule } from '@angular/core';
5
+ import { __decorate, __metadata, __assign, __extends, __param } from 'tslib';
6
+ import { Injectable, NgZone, ViewChild, ElementRef, ViewContainerRef, HostBinding, Input, TemplateRef, Output, EventEmitter, Component, Renderer2, Directive, Optional, QueryList, ContentChildren, ContentChild, forwardRef, SkipSelf, Host, Injector, isDevMode, InjectionToken, Inject, ChangeDetectorRef, NgModule } from '@angular/core';
7
7
  import { ColumnBase, ColumnComponent, ColumnGroupComponent, SpanColumnComponent, TreeListComponent, DataBoundTreeComponent, ExpandableTreeComponent, FlatBindingDirective, HierarchyBindingDirective, ExpandableDirective, TreeListModule } from '@progress/kendo-angular-treelist';
8
8
  import { cloneDate, addWeeks, firstDayInWeek, addDays, getDate, lastDayOfMonth, firstDayOfMonth, addMonths, isEqual, MS_PER_HOUR, MS_PER_DAY } from '@progress/kendo-date-math';
9
- import { of, fromEvent, Subject, Subscription } from 'rxjs';
9
+ import { fromEvent, Subject, Subscription, of, forkJoin, EMPTY, isObservable } from 'rxjs';
10
10
  import { validatePackage } from '@progress/kendo-licensing';
11
- import { isDocumentAvailable, closestInScope, matchesClasses, anyChanged, hasObservers, EventsModule } from '@progress/kendo-angular-common';
11
+ import { closestInScope, matchesClasses, isDocumentAvailable, Keys, hasObservers, anyChanged, EventsModule, DraggableModule } from '@progress/kendo-angular-common';
12
+ import { map, distinctUntilChanged, take, filter, switchMap, expand, reduce } from 'rxjs/operators';
13
+ import { getter, touchEnabled } from '@progress/kendo-common';
14
+ import { LocalizationService, ComponentMessages, L10N_PREFIX } from '@progress/kendo-angular-l10n';
12
15
  import { IntlService } from '@progress/kendo-angular-intl';
13
16
  import { orderBy } from '@progress/kendo-data-query';
14
- import { getter } from '@progress/kendo-common';
15
- import { map, distinctUntilChanged, take, filter, switchMap } from 'rxjs/operators';
16
- import { LocalizationService, ComponentMessages, L10N_PREFIX } from '@progress/kendo-angular-l10n';
17
17
  import { CommonModule } from '@angular/common';
18
- import { SplitterModule } from '@progress/kendo-angular-layout';
18
+ import { FormGroup, FormControl, Validators, FormArray, ReactiveFormsModule } from '@angular/forms';
19
+ import { SplitterModule, TabStripModule } from '@progress/kendo-angular-layout';
19
20
  import { ButtonsModule } from '@progress/kendo-angular-buttons';
20
21
  import { DialogModule } from '@progress/kendo-angular-dialog';
21
- import { FormGroup, ReactiveFormsModule } from '@angular/forms';
22
22
  import { LabelModule } from '@progress/kendo-angular-label';
23
23
  import { InputsModule } from '@progress/kendo-angular-inputs';
24
24
  import { DateInputsModule } from '@progress/kendo-angular-dateinputs';
25
+ import { PopupService, PopupModule } from '@progress/kendo-angular-popup';
26
+ import { GridModule } from '@progress/kendo-angular-grid';
27
+ import { DropDownsModule } from '@progress/kendo-angular-dropdowns';
25
28
 
26
29
  /**
27
30
  * @hidden
@@ -30,11 +33,704 @@ var packageMetadata = {
30
33
  name: '@progress/kendo-angular-gantt',
31
34
  productName: 'Kendo UI for Angular',
32
35
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
33
- publishDate: 1639476447,
36
+ publishDate: 1642606197,
34
37
  version: '',
35
38
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/?utm_medium=product&utm_source=kendoangular&utm_campaign=kendo-ui-angular-purchase-license-keys-warning'
36
39
  };
37
40
 
41
+ /**
42
+ * @hidden
43
+ */
44
+ var ScrollSyncService = /** @class */ (function () {
45
+ function ScrollSyncService(ngZone) {
46
+ var _this = this;
47
+ this.ngZone = ngZone;
48
+ this.changes = new Subject();
49
+ this.elements = [];
50
+ this.subscriptions = new Subscription();
51
+ this.subscriptions.add(this.changes.subscribe(function (args) {
52
+ _this.scroll(args);
53
+ }));
54
+ }
55
+ ScrollSyncService.prototype.registerElement = function (el, sourceType) {
56
+ var _this = this;
57
+ this.elements.push({ element: el, sourceType: sourceType });
58
+ if (sourceType === "timeline" || sourceType === "treelist") {
59
+ this.ngZone.runOutsideAngular(function () {
60
+ var obs = fromEvent(el, 'scroll').pipe(map(function (_a) {
61
+ var _b = _a.target, scrollTop = _b.scrollTop, scrollLeft = _b.scrollLeft;
62
+ return ({
63
+ scrollTop: scrollTop,
64
+ scrollLeft: scrollLeft,
65
+ sourceType: sourceType
66
+ });
67
+ }));
68
+ var comparisonFn = sourceType === 'timeline' ?
69
+ function (x, y) { return (x.scrollTop === y.scrollTop) && (x.scrollLeft === y.scrollLeft); } :
70
+ function (x, y) { return (x.scrollTop === y.scrollTop); };
71
+ _this.subscriptions.add(obs.pipe(distinctUntilChanged(comparisonFn))
72
+ .subscribe(function (event) { return _this.changes.next(event); }));
73
+ });
74
+ }
75
+ };
76
+ ScrollSyncService.prototype.ngOnDestroy = function () {
77
+ this.subscriptions.unsubscribe();
78
+ this.elements = null;
79
+ };
80
+ ScrollSyncService.prototype.syncScrollTop = function (sourceType, targetType) {
81
+ var source = this.elements.find(function (element) { return element.sourceType === sourceType; });
82
+ var target = this.elements.find(function (element) { return element.sourceType === targetType; });
83
+ // Need to wait for the splitter pane's content to be rendered
84
+ this.ngZone.onStable.pipe(take(1)).subscribe(function () { return target.element.scrollTop = source.element.scrollTop; });
85
+ };
86
+ ScrollSyncService.prototype.resetTimelineScrollLeft = function () {
87
+ var source = this.elements.find(function (element) { return element.sourceType === 'timeline'; });
88
+ source.element.scrollLeft = 0;
89
+ };
90
+ ScrollSyncService.prototype.scroll = function (_a) {
91
+ var _this = this;
92
+ var scrollTop = _a.scrollTop, scrollLeft = _a.scrollLeft, sourceType = _a.sourceType;
93
+ this.ngZone.runOutsideAngular(function () {
94
+ if (sourceType === 'timeline') {
95
+ var header = _this.elements.find(function (element) { return element.sourceType === 'header'; }).element;
96
+ header.scrollLeft = scrollLeft;
97
+ if (!_this.syncingTimeline) {
98
+ _this.syncingTreeList = true;
99
+ var treelist = _this.elements.find(function (element) { return element.sourceType === 'treelist'; }).element;
100
+ treelist.scrollTop = scrollTop;
101
+ }
102
+ _this.syncingTimeline = false;
103
+ }
104
+ if (sourceType === 'treelist') {
105
+ if (!_this.syncingTreeList) {
106
+ _this.syncingTimeline = true;
107
+ var timeline = _this.elements.find(function (element) { return element.sourceType === 'timeline'; }).element;
108
+ timeline.scrollTop = scrollTop;
109
+ }
110
+ _this.syncingTreeList = false;
111
+ }
112
+ });
113
+ };
114
+ ScrollSyncService = __decorate([
115
+ Injectable(),
116
+ __metadata("design:paramtypes", [NgZone])
117
+ ], ScrollSyncService);
118
+ return ScrollSyncService;
119
+ }());
120
+
121
+ /**
122
+ * @hidden
123
+ */
124
+ var DEFAULT_DEPENDENCY_MODEL_FIELDS = Object.freeze({
125
+ toId: 'toId',
126
+ fromId: 'fromId',
127
+ id: 'id',
128
+ type: 'type'
129
+ });
130
+
131
+ /**
132
+ * @hidden
133
+ */
134
+ var DEFAULT_TASK_MODEL_FIELDS = Object.freeze({
135
+ id: 'id',
136
+ start: 'start',
137
+ end: 'end',
138
+ title: 'title',
139
+ completionRatio: 'completionRatio',
140
+ children: 'children'
141
+ });
142
+
143
+ /**
144
+ * The dependency type when two tasks are connected.
145
+ *
146
+ * The supported values are:
147
+ * * `FF`—from 'finish' to 'finish'
148
+ * * `FS`—from 'finish' to 'start'
149
+ * * `SS`—from 'start' to 'start'
150
+ * * `SF`—from 'start' to 'finish'
151
+ */
152
+ var DependencyType;
153
+ (function (DependencyType) {
154
+ DependencyType[DependencyType["FF"] = 0] = "FF";
155
+ DependencyType[DependencyType["FS"] = 1] = "FS";
156
+ DependencyType[DependencyType["SF"] = 2] = "SF";
157
+ DependencyType[DependencyType["SS"] = 3] = "SS"; // task B can't start before task A starts
158
+ })(DependencyType || (DependencyType = {}));
159
+
160
+ /**
161
+ * @hidden
162
+ */
163
+ var isWorkDay = function (date, start, end) {
164
+ return date.getDay() >= start && date.getDay() <= end;
165
+ };
166
+ /**
167
+ * @hidden
168
+ */
169
+ var isWorkHour = function (date, start, end) {
170
+ return date.getHours() >= start && date.getHours() <= end;
171
+ };
172
+ /**
173
+ * @hidden
174
+ */
175
+ var isPresent = function (item) { return item !== null && item !== undefined; };
176
+ /**
177
+ * @hidden
178
+ *
179
+ * Normalized the data to an array in case a falsy value is passed
180
+ * or a TreeListDataResult object (applicable for the data-binding directives).
181
+ */
182
+ var normalizeGanttData = function (data) {
183
+ if (!isPresent(data)) {
184
+ return [];
185
+ }
186
+ else if (Array.isArray(data.data)) {
187
+ return data.data;
188
+ }
189
+ else {
190
+ return data;
191
+ }
192
+ };
193
+ /**
194
+ * @hidden
195
+ *
196
+ * Returns a new date with the specified hours, minutes, seconds and millliseconds set.
197
+ * Only the hours are required, the rest of the params are set to `0` by default.
198
+ */
199
+ var setTime = function (date, hours, minutes, seconds, milliseconds) {
200
+ if (minutes === void 0) { minutes = 0; }
201
+ if (seconds === void 0) { seconds = 0; }
202
+ if (milliseconds === void 0) { milliseconds = 0; }
203
+ if (!isPresent(date)) {
204
+ return null;
205
+ }
206
+ var result = cloneDate(date);
207
+ result.setHours(hours);
208
+ result.setMinutes(minutes);
209
+ result.setSeconds(seconds);
210
+ result.setMilliseconds(milliseconds);
211
+ return result;
212
+ };
213
+ /**
214
+ * @hidden
215
+ *
216
+ * Returns the last day of a week.
217
+ * @param standingPoint - Any day of the target week.
218
+ * @param firstWeekDay - The week's starting day (e.g. Monday, Tuesday, etc.)
219
+ */
220
+ var lastDayOfWeek = function (standingPoint, firstWeekDay) {
221
+ var followingWeek = addWeeks(standingPoint, 1);
222
+ var firstDayOfFollowingWeek = firstDayInWeek(followingWeek, firstWeekDay);
223
+ var lastDayOfTargetWeek = addDays(firstDayOfFollowingWeek, -1);
224
+ return lastDayOfTargetWeek;
225
+ };
226
+ /**
227
+ * Persists the intially resolved scrollbar width value.
228
+ */
229
+ var SCROLLBAR_WIDTH;
230
+ /**
231
+ * @hidden
232
+ *
233
+ * Gets the default scrollbar width accoring to the current environment.
234
+ */
235
+ var scrollbarWidth = function () {
236
+ if (!isDocumentAvailable()) {
237
+ return;
238
+ }
239
+ // calculate scrollbar width only once, then return the cached value
240
+ if (isNaN(SCROLLBAR_WIDTH)) {
241
+ var div = document.createElement('div');
242
+ div.style.cssText = 'overflow: scroll; overflow-x: hidden; zoom: 1; clear: both; display: block;';
243
+ div.innerHTML = '&nbsp;';
244
+ document.body.appendChild(div);
245
+ SCROLLBAR_WIDTH = div.offsetWidth - div.scrollWidth;
246
+ document.body.removeChild(div);
247
+ }
248
+ return SCROLLBAR_WIDTH;
249
+ };
250
+ /**
251
+ * @hidden
252
+ */
253
+ var isColumnGroup = function (column) { return column.isColumnGroup; };
254
+ /**
255
+ * @hidden
256
+ */
257
+ var isNumber = function (contender) { return typeof contender === 'number' && !isNaN(contender); };
258
+ /**
259
+ * @hidden
260
+ */
261
+ var isString = function (contender) { return typeof contender === 'string'; };
262
+ /**
263
+ * @hidden
264
+ *
265
+ * Gets the closest timeline task wrapper element from an event target.
266
+ * Restricts the search up to the provided parent element from the second param.
267
+ */
268
+ var getClosestTaskWrapper = function (element, parentScope) {
269
+ return closestInScope(element, matchesClasses('k-task-wrap'), parentScope);
270
+ };
271
+ /**
272
+ * @hidden
273
+ *
274
+ * Checks whether the queried item or its parent items has a `k-task-wrap` selector.
275
+ * Restricts the search up to the provided parent element from the second param.
276
+ */
277
+ var isTaskWrapper = function (contender, parentScope) {
278
+ var taskWrapper = closestInScope(contender, matchesClasses('k-task-wrap'), parentScope);
279
+ return isPresent(taskWrapper);
280
+ };
281
+ /**
282
+ * @hidden
283
+ *
284
+ * Gets the closest timeline task element index from an event target.
285
+ * Uses the `data-task-index` attribute assigned to each task.
286
+ * Restricts the search up to the provided parent element from the second param.
287
+ */
288
+ var getClosestTaskIndex = function (element, parentScope) {
289
+ var task = closestInScope(element, matchesClasses('k-task-wrap'), parentScope);
290
+ if (!isPresent(task)) {
291
+ return null;
292
+ }
293
+ return Number(task.getAttribute('data-task-index'));
294
+ };
295
+ /**
296
+ * @hidden
297
+ *
298
+ * Checks whether the queried item or its parent items has a `k-task` selector.
299
+ * Restricts the search up to the provided parent element from the second param.
300
+ */
301
+ var isTask = function (contender, parentScope) {
302
+ var task = closestInScope(contender, matchesClasses('k-task'), parentScope);
303
+ return isPresent(task);
304
+ };
305
+ /**
306
+ * @hidden
307
+ *
308
+ * Checks whether the queried item or its parent items has a `k-toolbar` selector.
309
+ * Restricts the search up to the provided parent element from the second param.
310
+ */
311
+ var isToolbar = function (contender, parentScope) {
312
+ var toolbar = closestInScope(contender, matchesClasses('k-gantt-toolbar'), parentScope);
313
+ return isPresent(toolbar);
314
+ };
315
+ /**
316
+ * @hidden
317
+ *
318
+ * Checks whether the queried item or its parent items has a `k-task-actions` selector - used for the clear button.
319
+ * Restricts the search up to the provided parent element from the second param.
320
+ */
321
+ var isClearButton = function (contender, parentScope) {
322
+ var clearButtonContainer = closestInScope(contender, matchesClasses('k-task-actions'), parentScope);
323
+ return isPresent(clearButtonContainer);
324
+ };
325
+ /**
326
+ * @hidden
327
+ *
328
+ * Checks whether the queried item has a `k-task-dot` selector - used for the dependency drag clues.
329
+ */
330
+ var isDependencyDragClue = function (element) {
331
+ if (!isPresent(element)) {
332
+ return false;
333
+ }
334
+ return element.classList.contains('k-task-dot');
335
+ };
336
+ /**
337
+ * @hidden
338
+ *
339
+ * Checks whether the queried item has a `k-task-dot` & `k-task-start` selector - used for the dependency drag start clues.
340
+ */
341
+ var isDependencyDragStartClue = function (element) {
342
+ if (!isPresent(element)) {
343
+ return false;
344
+ }
345
+ return element.classList.contains('k-task-dot') && element.classList.contains('k-task-start');
346
+ };
347
+ /**
348
+ * @hidden
349
+ *
350
+ * Gets the `DependencyType` for an attempted dependency create from the provided two elements.
351
+ * The two linked drag clue HTML elements are used to extract this data (via their CSS classes).
352
+ */
353
+ var getDependencyTypeFromTargetTasks = function (fromTaskClue, toTaskClue) {
354
+ if (!isDependencyDragClue(fromTaskClue) || !isDependencyDragClue(toTaskClue)) {
355
+ return null;
356
+ }
357
+ var fromTaskType = isDependencyDragStartClue(fromTaskClue) ? 'S' : 'F';
358
+ var toTaskType = isDependencyDragStartClue(toTaskClue) ? 'S' : 'F';
359
+ var dependencyTypeName = "" + fromTaskType + toTaskType;
360
+ switch (dependencyTypeName) {
361
+ case 'FF': return DependencyType.FF;
362
+ case 'FS': return DependencyType.FS;
363
+ case 'SF': return DependencyType.SF;
364
+ case 'SS': return DependencyType.SS;
365
+ default: return null;
366
+ }
367
+ };
368
+ /**
369
+ * @hidden
370
+ *
371
+ * Checks whether the two provided drag clues belong to the same task element.
372
+ */
373
+ var sameTaskClues = function (fromTaskClue, toTaskClue, parentScope) {
374
+ if (!isPresent(fromTaskClue) || !isPresent(toTaskClue)) {
375
+ return false;
376
+ }
377
+ var fromTaskWrapper = getClosestTaskWrapper(fromTaskClue, parentScope);
378
+ var toTaskWrapper = getClosestTaskWrapper(toTaskClue, parentScope);
379
+ return fromTaskWrapper === toTaskWrapper;
380
+ };
381
+ /**
382
+ * @hidden
383
+ *
384
+ * Fits a contender number between a min and max range.
385
+ * If the contender is below the min value, the min value is returned.
386
+ * If the contender is above the max value, the max value is returned.
387
+ */
388
+ var fitToRange = function (contender, min, max) {
389
+ if (!isPresent(contender) || contender < min) {
390
+ return min;
391
+ }
392
+ else if (contender > max) {
393
+ return max;
394
+ }
395
+ else {
396
+ return contender;
397
+ }
398
+ };
399
+ /**
400
+ * @hidden
401
+ *
402
+ * Checks whether either of the two provided tasks is a parent of the other.
403
+ */
404
+ var areParentChild = function (taskA, taskB) {
405
+ var parentChildRelationship = false;
406
+ var taskAParent = taskA;
407
+ while (isPresent(taskAParent) && isPresent(taskAParent.data)) {
408
+ if (taskAParent.data === taskB.data) {
409
+ parentChildRelationship = true;
410
+ break;
411
+ }
412
+ taskAParent = taskAParent.parent;
413
+ }
414
+ var taskBParent = taskB;
415
+ while (!parentChildRelationship && isPresent(taskBParent) && isPresent(taskBParent.data)) {
416
+ if (taskBParent.data === taskA.data) {
417
+ parentChildRelationship = true;
418
+ break;
419
+ }
420
+ taskBParent = taskBParent.parent;
421
+ }
422
+ return parentChildRelationship;
423
+ };
424
+ /**
425
+ * @hidden
426
+ *
427
+ * Extracts an element from the provided client coords.
428
+ * Using the `event.target` is not reliable under mobile devices with the current implementation of the draggable, so use this instead.
429
+ */
430
+ var elementFromPoint = function (clientX, clientY) {
431
+ if (!isDocumentAvailable()) {
432
+ return null;
433
+ }
434
+ return document.elementFromPoint(clientX, clientY);
435
+ };
436
+
437
+ /**
438
+ * @hidden
439
+ */
440
+ var MappingService = /** @class */ (function () {
441
+ function MappingService() {
442
+ this._taskFields = __assign({}, DEFAULT_TASK_MODEL_FIELDS);
443
+ this._dependencyFields = __assign({}, DEFAULT_DEPENDENCY_MODEL_FIELDS);
444
+ }
445
+ Object.defineProperty(MappingService.prototype, "taskFields", {
446
+ get: function () {
447
+ return this._taskFields;
448
+ },
449
+ /**
450
+ * Gets or sets the model fields for the task data items.
451
+ * Uses the default values for fields which are not specified.
452
+ */
453
+ set: function (fields) {
454
+ this._taskFields = __assign({}, DEFAULT_TASK_MODEL_FIELDS, fields);
455
+ },
456
+ enumerable: true,
457
+ configurable: true
458
+ });
459
+ Object.defineProperty(MappingService.prototype, "dependencyFields", {
460
+ get: function () {
461
+ return this._dependencyFields;
462
+ },
463
+ /**
464
+ * Gets or sets the model fields for the depenency data items.
465
+ * Uses the default values for fields which are not specified.
466
+ */
467
+ set: function (fields) {
468
+ this._dependencyFields = __assign({}, DEFAULT_DEPENDENCY_MODEL_FIELDS, fields);
469
+ },
470
+ enumerable: true,
471
+ configurable: true
472
+ });
473
+ /**
474
+ * Retrieves the value for the specified task field.
475
+ * Supports nested fields as well (e.g. 'manager.id').
476
+ */
477
+ MappingService.prototype.extractFromTask = function (dataItem, field) {
478
+ if (!isPresent(this.taskFields)) {
479
+ return null;
480
+ }
481
+ return getter(this.taskFields[field])(dataItem);
482
+ };
483
+ /**
484
+ * Retrieves the value for the specified dependency field.
485
+ * Supports nested fields as well (e.g. 'manager.id').
486
+ */
487
+ MappingService.prototype.extractFromDependency = function (dataItem, field) {
488
+ if (!isPresent(this.dependencyFields)) {
489
+ return null;
490
+ }
491
+ return getter(this.dependencyFields[field])(dataItem);
492
+ };
493
+ MappingService = __decorate([
494
+ Injectable()
495
+ ], MappingService);
496
+ return MappingService;
497
+ }());
498
+
499
+ /**
500
+ * @hidden
501
+ */
502
+ var DependencyDomService = /** @class */ (function () {
503
+ function DependencyDomService(mapper) {
504
+ this.mapper = mapper;
505
+ this.notifier = new Subject();
506
+ /**
507
+ * Maps each rendered task to its HTML element.
508
+ * Uses the task ID field value as key.
509
+ */
510
+ this.tasks = new Map();
511
+ }
512
+ Object.defineProperty(DependencyDomService.prototype, "taskChanges", {
513
+ /**
514
+ * Emits each time some of the tasks or the view have changed.
515
+ * Fires also on the first change of the table rows and the parent container.
516
+ */
517
+ get: function () {
518
+ return this.notifier.asObservable();
519
+ },
520
+ enumerable: true,
521
+ configurable: true
522
+ });
523
+ Object.defineProperty(DependencyDomService.prototype, "dependencyDomArgs", {
524
+ get: function () {
525
+ return {
526
+ tasks: this.tasks,
527
+ contentContainer: this.contentContainer,
528
+ timelineRow: this.timelineRow
529
+ };
530
+ },
531
+ enumerable: true,
532
+ configurable: true
533
+ });
534
+ DependencyDomService.prototype.ngOnDestroy = function () {
535
+ this.tasks.clear();
536
+ this.tasks = null;
537
+ this.contentContainer = null;
538
+ };
539
+ DependencyDomService.prototype.registerTimelineRow = function (timelineRow) {
540
+ this.timelineRow = timelineRow;
541
+ this.notifyChanges();
542
+ };
543
+ DependencyDomService.prototype.registerContentContainer = function (contentContainer) {
544
+ this.contentContainer = contentContainer;
545
+ this.notifyChanges();
546
+ };
547
+ DependencyDomService.prototype.registerTask = function (task, element) {
548
+ var id = this.mapper.extractFromTask(task, 'id');
549
+ this.tasks.set(id, element);
550
+ this.notifyChanges();
551
+ };
552
+ DependencyDomService.prototype.unregisterTask = function (task) {
553
+ var id = this.mapper.extractFromTask(task, 'id');
554
+ this.tasks.delete(id);
555
+ this.notifyChanges();
556
+ };
557
+ /**
558
+ * Notifies all dependency directives that a change in one of the elements has occured.
559
+ */
560
+ DependencyDomService.prototype.notifyChanges = function () {
561
+ this.notifier.next(this.dependencyDomArgs);
562
+ };
563
+ DependencyDomService = __decorate([
564
+ Injectable(),
565
+ __metadata("design:paramtypes", [MappingService])
566
+ ], DependencyDomService);
567
+ return DependencyDomService;
568
+ }());
569
+
570
+ /**
571
+ * @hidden
572
+ */
573
+ var GanttTimelineComponent = /** @class */ (function () {
574
+ function GanttTimelineComponent(scrollSyncService, dependencyDomService, renderer, zone) {
575
+ var _this = this;
576
+ this.scrollSyncService = scrollSyncService;
577
+ this.dependencyDomService = dependencyDomService;
578
+ this.renderer = renderer;
579
+ this.zone = zone;
580
+ this.hostClass = true;
581
+ this.dependencies = [];
582
+ // as all drag-and-drop operations are on the timeline container, use a single draggable instance
583
+ this.timelineContainerPress = new EventEmitter();
584
+ this.timelineContainerDrag = new EventEmitter();
585
+ this.timelineContainerRelease = new EventEmitter();
586
+ this.subscriptions = new Subscription();
587
+ this.subscriptions.add(
588
+ // task changes indicates change in row content, number, height, etc.
589
+ this.dependencyDomService.taskChanges
590
+ .pipe(filter(function (args) { return isPresent(args.timelineRow); }), switchMap(function (args) { return _this.zone.onStable.pipe(take(1), map(function () { return args; })); }) // ensure the content is rendered
591
+ )
592
+ .subscribe(function (_a) {
593
+ var timelineRow = _a.timelineRow;
594
+ var timelineRowHeight = isDocumentAvailable() ? timelineRow.getBoundingClientRect().height : 0;
595
+ _this.renderer.setStyle(_this.timelineColumns.nativeElement, 'height', (_this.rows || []).length * timelineRowHeight + "px");
596
+ }));
597
+ }
598
+ Object.defineProperty(GanttTimelineComponent.prototype, "draggableEnabled", {
599
+ /**
600
+ * Specifies whether the draggable will attach or detach its pointer event listeners.
601
+ */
602
+ get: function () {
603
+ return this.renderDependencyDragClues;
604
+ },
605
+ enumerable: true,
606
+ configurable: true
607
+ });
608
+ GanttTimelineComponent.prototype.ngAfterViewInit = function () {
609
+ var timelineHeader = this.timelineHeaderWrap.nativeElement;
610
+ var rightContainer = this.timelineContent.nativeElement;
611
+ this.scrollSyncService.registerElement(rightContainer, 'timeline');
612
+ this.scrollSyncService.registerElement(timelineHeader, 'header');
613
+ this.dependencyDomService.registerContentContainer(this.tasksContainer.nativeElement);
614
+ };
615
+ GanttTimelineComponent.prototype.ngOnDestroy = function () {
616
+ this.subscriptions.unsubscribe();
617
+ };
618
+ GanttTimelineComponent.prototype.isNonWorking = function (item) {
619
+ return item.hasOwnProperty('isWorking') && !item.isWorking;
620
+ };
621
+ __decorate([
622
+ ViewChild('timelineContent', { static: true }),
623
+ __metadata("design:type", ElementRef)
624
+ ], GanttTimelineComponent.prototype, "timelineContent", void 0);
625
+ __decorate([
626
+ ViewChild('timelineColumns', { static: true }),
627
+ __metadata("design:type", ElementRef)
628
+ ], GanttTimelineComponent.prototype, "timelineColumns", void 0);
629
+ __decorate([
630
+ ViewChild('timelineHeaderWrap', { static: true }),
631
+ __metadata("design:type", ElementRef)
632
+ ], GanttTimelineComponent.prototype, "timelineHeaderWrap", void 0);
633
+ __decorate([
634
+ ViewChild('tasksContainer', { static: true }),
635
+ __metadata("design:type", ElementRef)
636
+ ], GanttTimelineComponent.prototype, "tasksContainer", void 0);
637
+ __decorate([
638
+ ViewChild('dragPopupContainer', { static: false, read: ViewContainerRef }),
639
+ __metadata("design:type", ViewContainerRef)
640
+ ], GanttTimelineComponent.prototype, "dragPopupContainer", void 0);
641
+ __decorate([
642
+ ViewChild('dependencyDragCreatePolyline', { static: false }),
643
+ __metadata("design:type", ElementRef)
644
+ ], GanttTimelineComponent.prototype, "dependencyDragCreatePolyline", void 0);
645
+ __decorate([
646
+ HostBinding('class.k-gantt-timeline'),
647
+ __metadata("design:type", Boolean)
648
+ ], GanttTimelineComponent.prototype, "hostClass", void 0);
649
+ __decorate([
650
+ Input(),
651
+ __metadata("design:type", Array)
652
+ ], GanttTimelineComponent.prototype, "rows", void 0);
653
+ __decorate([
654
+ Input(),
655
+ __metadata("design:type", Array)
656
+ ], GanttTimelineComponent.prototype, "slots", void 0);
657
+ __decorate([
658
+ Input(),
659
+ __metadata("design:type", Array)
660
+ ], GanttTimelineComponent.prototype, "groupSlots", void 0);
661
+ __decorate([
662
+ Input(),
663
+ __metadata("design:type", Number)
664
+ ], GanttTimelineComponent.prototype, "tableWidth", void 0);
665
+ __decorate([
666
+ Input(),
667
+ __metadata("design:type", String)
668
+ ], GanttTimelineComponent.prototype, "activeView", void 0);
669
+ __decorate([
670
+ Input(),
671
+ __metadata("design:type", TemplateRef)
672
+ ], GanttTimelineComponent.prototype, "taskContentTemplate", void 0);
673
+ __decorate([
674
+ Input(),
675
+ __metadata("design:type", TemplateRef)
676
+ ], GanttTimelineComponent.prototype, "taskTemplate", void 0);
677
+ __decorate([
678
+ Input(),
679
+ __metadata("design:type", TemplateRef)
680
+ ], GanttTimelineComponent.prototype, "summaryTaskTemplate", void 0);
681
+ __decorate([
682
+ Input(),
683
+ __metadata("design:type", Function)
684
+ ], GanttTimelineComponent.prototype, "taskClass", void 0);
685
+ __decorate([
686
+ Input(),
687
+ __metadata("design:type", Boolean)
688
+ ], GanttTimelineComponent.prototype, "renderDependencyDragClues", void 0);
689
+ __decorate([
690
+ Input(),
691
+ __metadata("design:type", Object)
692
+ ], GanttTimelineComponent.prototype, "dragScrollSettings", void 0);
693
+ __decorate([
694
+ Input(),
695
+ __metadata("design:type", Boolean)
696
+ ], GanttTimelineComponent.prototype, "selectable", void 0);
697
+ __decorate([
698
+ Input(),
699
+ __metadata("design:type", Function)
700
+ ], GanttTimelineComponent.prototype, "isTaskSelected", void 0);
701
+ __decorate([
702
+ Input(),
703
+ __metadata("design:type", Function)
704
+ ], GanttTimelineComponent.prototype, "isExpanded", void 0);
705
+ __decorate([
706
+ Input(),
707
+ __metadata("design:type", Array)
708
+ ], GanttTimelineComponent.prototype, "dependencies", void 0);
709
+ __decorate([
710
+ Output(),
711
+ __metadata("design:type", EventEmitter)
712
+ ], GanttTimelineComponent.prototype, "timelineContainerPress", void 0);
713
+ __decorate([
714
+ Output(),
715
+ __metadata("design:type", EventEmitter)
716
+ ], GanttTimelineComponent.prototype, "timelineContainerDrag", void 0);
717
+ __decorate([
718
+ Output(),
719
+ __metadata("design:type", EventEmitter)
720
+ ], GanttTimelineComponent.prototype, "timelineContainerRelease", void 0);
721
+ GanttTimelineComponent = __decorate([
722
+ Component({
723
+ selector: 'kendo-gantt-timeline',
724
+ template: "\n <div class=\"k-timeline k-grid k-widget\">\n <div class=\"k-grid-header\">\n <div #timelineHeaderWrap class=\"k-grid-header-wrap\">\n <table\n role=\"presentation\"\n [style.width.px]=\"tableWidth\"\n >\n <tbody\n kendoGanttHeaderTableBody\n [groupSlots]=\"groupSlots\"\n [slots]=\"slots\">\n </tbody>\n </table>\n </div>\n </div>\n <!-- tabindex=\"-1\" required for https://bugzilla.mozilla.org/show_bug.cgi?id=1069739 -->\n <div\n #timelineContent\n class=\"k-grid-content\"\n tabindex=\"-1\"\n role=\"tree\"\n aria-roledescription=\"Timeline\"\n kendoGanttTimelineScrollable\n [scrollSettings]=\"dragScrollSettings\"\n kendoDraggable\n [enableDrag]=\"draggableEnabled\"\n (kendoPress)=\"timelineContainerPress.emit($event)\"\n (kendoDrag)=\"timelineContainerDrag.emit($event)\"\n (kendoRelease)=\"timelineContainerRelease.emit($event)\"\n >\n <div class=\"k-gantt-tables\">\n <table\n class=\"k-gantt-rows\"\n [style.width.px]=\"tableWidth\"\n role=\"presentation\"\n >\n <tbody>\n <tr *ngFor=\"let item of rows; let i = index;\"\n [class.k-alt]=\"i % 2\"\n >\n <td></td>\n </tr>\n </tbody>\n </table>\n\n <table\n #timelineColumns\n class=\"k-gantt-columns\"\n role=\"presentation\"\n [style.width.px]=\"tableWidth\"\n >\n <colgroup>\n <col *ngFor=\"let item of slots\">\n </colgroup>\n\n <tbody>\n <tr>\n <td *ngFor=\"let item of slots\"\n [class.k-nonwork-hour]=\"isNonWorking(item)\"\n >\n </td>\n </tr>\n </tbody>\n </table>\n\n <table\n #tasksContainer\n class=\"k-gantt-tasks\"\n role=\"presentation\"\n style=\"border-collapse: collapse;\"\n [style.width.px]=\"tableWidth\"\n >\n <tbody\n kendoGanttTasksTableBody\n [rows]=\"rows\"\n [activeView]=\"activeView\"\n [taskContentTemplate]=\"taskContentTemplate\"\n [taskTemplate]=\"taskTemplate\"\n [summaryTaskTemplate]=\"summaryTaskTemplate\"\n [taskClass]=\"taskClass\"\n [isExpanded]=\"isExpanded\"\n [selectable]=\"selectable\"\n [isTaskSelected]=\"isTaskSelected\"\n [renderDependencyDragClues]=\"renderDependencyDragClues\"\n >\n </tbody>\n </table>\n </div>\n <svg class=\"k-gantt-dependencies-svg\">\n <polyline\n *ngFor=\"let dependency of dependencies\"\n kendoGanttDependency\n [dependency]=\"dependency\"\n />\n <polyline #dependencyDragCreatePolyline />\n </svg>\n\n <!-- placeholder for the dependency drag popup; its position is not arbitrary - the popup is intended to be absolutely positioned inside the .k-grid-content element -->\n <ng-container #dragPopupContainer></ng-container>\n </div>\n </div>\n "
725
+ }),
726
+ __metadata("design:paramtypes", [ScrollSyncService,
727
+ DependencyDomService,
728
+ Renderer2,
729
+ NgZone])
730
+ ], GanttTimelineComponent);
731
+ return GanttTimelineComponent;
732
+ }());
733
+
38
734
  /**
39
735
  * The base class for the column components of the Gantt.
40
736
  */
@@ -655,139 +1351,43 @@ var isSelected = function () { return false; };
655
1351
  /**
656
1352
  * @hidden
657
1353
  */
658
- var isWorkDay = function (date, start, end) {
659
- return date.getDay() >= start && date.getDay() <= end;
660
- };
661
- /**
662
- * @hidden
663
- */
664
- var isWorkHour = function (date, start, end) {
665
- return date.getHours() >= start && date.getHours() <= end;
666
- };
667
- /**
668
- * @hidden
669
- */
670
- var isPresent = function (item) { return item !== null && item !== undefined; };
671
- /**
672
- * @hidden
673
- *
674
- * Normalized the data to an array in case a falsy value is passed
675
- * or a TreeListDataResult object (applicable for the data-binding directives).
676
- */
677
- var normalizeGanttData = function (data) {
678
- if (!isPresent(data)) {
679
- return [];
680
- }
681
- else if (Array.isArray(data.data)) {
682
- return data.data;
683
- }
684
- else {
685
- return data;
686
- }
687
- };
688
- /**
689
- * @hidden
690
- *
691
- * Returns a new date with the specified hours, minutes, seconds and millliseconds set.
692
- * Only the hours are required, the rest of the params are set to `0` by default.
693
- */
694
- var setTime = function (date, hours, minutes, seconds, milliseconds) {
695
- if (minutes === void 0) { minutes = 0; }
696
- if (seconds === void 0) { seconds = 0; }
697
- if (milliseconds === void 0) { milliseconds = 0; }
698
- if (!isPresent(date)) {
699
- return null;
700
- }
701
- var result = cloneDate(date);
702
- result.setHours(hours);
703
- result.setMinutes(minutes);
704
- result.setSeconds(seconds);
705
- result.setMilliseconds(milliseconds);
706
- return result;
707
- };
708
- /**
709
- * @hidden
710
- *
711
- * Returns the last day of a week.
712
- * @param standingPoint - Any day of the target week.
713
- * @param firstWeekDay - The week's starting day (e.g. Monday, Tuesday, etc.)
714
- */
715
- var lastDayOfWeek = function (standingPoint, firstWeekDay) {
716
- var followingWeek = addWeeks(standingPoint, 1);
717
- var firstDayOfFollowingWeek = firstDayInWeek(followingWeek, firstWeekDay);
718
- var lastDayOfTargetWeek = addDays(firstDayOfFollowingWeek, -1);
719
- return lastDayOfTargetWeek;
720
- };
721
- /**
722
- * Persists the intially resolved scrollbar width value.
723
- */
724
- var SCROLLBAR_WIDTH;
725
- /**
726
- * @hidden
727
- *
728
- * Gets the default scrollbar width accoring to the current environment.
729
- */
730
- var scrollbarWidth = function () {
731
- if (!isDocumentAvailable()) {
732
- return;
733
- }
734
- // calculate scrollbar width only once, then return the cached value
735
- if (isNaN(SCROLLBAR_WIDTH)) {
736
- var div = document.createElement('div');
737
- div.style.cssText = 'overflow: scroll; overflow-x: hidden; zoom: 1; clear: both; display: block;';
738
- div.innerHTML = '&nbsp;';
739
- document.body.appendChild(div);
740
- SCROLLBAR_WIDTH = div.offsetWidth - div.scrollWidth;
741
- document.body.removeChild(div);
742
- }
743
- return SCROLLBAR_WIDTH;
744
- };
745
- /**
746
- * @hidden
747
- */
748
- var isColumnGroup = function (column) { return column.isColumnGroup; };
749
- /**
750
- * @hidden
751
- */
752
- var isNumber = function (contender) { return typeof contender === 'number' && !isNaN(contender); };
753
- /**
754
- * @hidden
755
- */
756
- var isString = function (contender) { return typeof contender === 'string'; };
757
- /**
758
- * @hidden
759
- *
760
- * Gets the closest timeline task element index from an event target.
761
- * Uses the `data-task-index` attribute assigned to each task.
762
- * Restricts the search up to the provided gantt element from the second param.
763
- */
764
- var getClosestTaskIndex = function (element, gantt) {
765
- var task = closestInScope(element, matchesClasses('k-task'), gantt);
766
- if (!isPresent(task)) {
767
- return null;
1354
+ var PreventableEvent = /** @class */ (function () {
1355
+ function PreventableEvent() {
1356
+ this.prevented = false;
768
1357
  }
769
- return Number(task.getAttribute('data-task-index'));
770
- };
771
- /**
772
- * @hidden
773
- *
774
- * Checks whether the queried item or its parent items has a `k-task` selector.
775
- * Restricts the search up to the provided gantt element from the second param.
776
- */
777
- var isTask = function (contender, gantt) {
778
- var task = closestInScope(contender, matchesClasses('k-task'), gantt);
779
- return isPresent(task);
780
- };
1358
+ /**
1359
+ * Prevents the default action for a specified event.
1360
+ * In this way, the source component suppresses
1361
+ * the built-in behavior that follows the event.
1362
+ */
1363
+ PreventableEvent.prototype.preventDefault = function () {
1364
+ this.prevented = true;
1365
+ };
1366
+ /**
1367
+ * Returns `true` if the event was prevented
1368
+ * by any of its subscribers.
1369
+ *
1370
+ * @returns `true` if the default action was prevented.
1371
+ * Otherwise, returns `false`.
1372
+ */
1373
+ PreventableEvent.prototype.isDefaultPrevented = function () {
1374
+ return this.prevented;
1375
+ };
1376
+ return PreventableEvent;
1377
+ }());
1378
+
781
1379
  /**
782
- * @hidden
783
- *
784
- * Checks whether the queried item or its parent items has a `k-task-actions` selector - used for the clear button.
785
- * Restricts the search up to the provided gantt element from the second param.
1380
+ * Called every time a user leaves an edited cell.
786
1381
  */
787
- var isClearButton = function (contender, gantt) {
788
- var clearButtonContainer = closestInScope(contender, matchesClasses('k-task-actions'), gantt);
789
- return isPresent(clearButtonContainer);
790
- };
1382
+ var CellCloseEvent = /** @class */ (function (_super) {
1383
+ __extends(CellCloseEvent, _super);
1384
+ function CellCloseEvent(options) {
1385
+ var _this = _super.call(this) || this;
1386
+ Object.assign(_this, options);
1387
+ return _this;
1388
+ }
1389
+ return CellCloseEvent;
1390
+ }(PreventableEvent));
791
1391
 
792
1392
  /**
793
1393
  * @hidden
@@ -948,90 +1548,6 @@ var TimelineBaseViewService = /** @class */ (function () {
948
1548
  return TimelineBaseViewService;
949
1549
  }());
950
1550
 
951
- /**
952
- * @hidden
953
- */
954
- var DEFAULT_DEPENDENCY_MODEL_FIELDS = Object.freeze({
955
- toId: 'toId',
956
- fromId: 'fromId',
957
- id: 'id',
958
- type: 'type'
959
- });
960
-
961
- /**
962
- * @hidden
963
- */
964
- var DEFAULT_TASK_MODEL_FIELDS = Object.freeze({
965
- id: 'id',
966
- start: 'start',
967
- end: 'end',
968
- title: 'title',
969
- completionRatio: 'completionRatio',
970
- children: 'children'
971
- });
972
-
973
- /**
974
- * @hidden
975
- */
976
- var MappingService = /** @class */ (function () {
977
- function MappingService() {
978
- this._taskFields = __assign({}, DEFAULT_TASK_MODEL_FIELDS);
979
- this._dependencyFields = __assign({}, DEFAULT_DEPENDENCY_MODEL_FIELDS);
980
- }
981
- Object.defineProperty(MappingService.prototype, "taskFields", {
982
- get: function () {
983
- return this._taskFields;
984
- },
985
- /**
986
- * Gets or sets the model fields for the task data items.
987
- * Uses the default values for fields which are not specified.
988
- */
989
- set: function (fields) {
990
- this._taskFields = __assign({}, DEFAULT_TASK_MODEL_FIELDS, fields);
991
- },
992
- enumerable: true,
993
- configurable: true
994
- });
995
- Object.defineProperty(MappingService.prototype, "dependencyFields", {
996
- get: function () {
997
- return this._dependencyFields;
998
- },
999
- /**
1000
- * Gets or sets the model fields for the depenency data items.
1001
- * Uses the default values for fields which are not specified.
1002
- */
1003
- set: function (fields) {
1004
- this._dependencyFields = __assign({}, DEFAULT_DEPENDENCY_MODEL_FIELDS, fields);
1005
- },
1006
- enumerable: true,
1007
- configurable: true
1008
- });
1009
- /**
1010
- * Retrieves the value for the specified task field.
1011
- * Supports nested fields as well (e.g. 'manager.id').
1012
- */
1013
- MappingService.prototype.extractFromTask = function (dataItem, field) {
1014
- if (!isPresent(this.taskFields)) {
1015
- return null;
1016
- }
1017
- return getter(this.taskFields[field])(dataItem);
1018
- };
1019
- /**
1020
- * Retrieves the value for the specified dependency field.
1021
- * Supports nested fields as well (e.g. 'manager.id').
1022
- */
1023
- MappingService.prototype.extractFromDependency = function (dataItem, field) {
1024
- if (!isPresent(this.dependencyFields)) {
1025
- return null;
1026
- }
1027
- return getter(this.dependencyFields[field])(dataItem);
1028
- };
1029
- MappingService = __decorate([
1030
- Injectable()
1031
- ], MappingService);
1032
- return MappingService;
1033
- }());
1034
-
1035
1551
  /**
1036
1552
  * @hidden
1037
1553
  */
@@ -1228,185 +1744,617 @@ var TimelineViewService = /** @class */ (function () {
1228
1744
  /**
1229
1745
  * @hidden
1230
1746
  */
1231
- var ScrollSyncService = /** @class */ (function () {
1232
- function ScrollSyncService(ngZone) {
1747
+ var EditService = /** @class */ (function () {
1748
+ function EditService(mapper) {
1233
1749
  var _this = this;
1234
- this.ngZone = ngZone;
1235
- this.changes = new Subject();
1236
- this.elements = [];
1237
- this.subscriptions = new Subscription();
1238
- this.subscriptions.add(this.changes.subscribe(function (args) {
1239
- _this.scroll(args);
1240
- }));
1750
+ this.mapper = mapper;
1751
+ this.showEditingDialog = new Subject();
1752
+ this.taskDelete = new Subject();
1753
+ this.editEvent = new Subject();
1754
+ this.addEvent = new Subject();
1755
+ this.predecessors = [];
1756
+ this.successors = [];
1757
+ this.updatedItems = [];
1758
+ this.deletedItems = [];
1759
+ this.itemIndex = function (item, data) {
1760
+ return data.findIndex(function (dataItem) { return _this.mapper.extractFromTask(dataItem, 'id') === _this.mapper.extractFromTask(item, 'id'); });
1761
+ };
1241
1762
  }
1242
- ScrollSyncService.prototype.registerElement = function (el, sourceType) {
1243
- var _this = this;
1244
- this.elements.push({ element: el, sourceType: sourceType });
1245
- if (sourceType === "timeline" || sourceType === "treelist") {
1246
- this.ngZone.runOutsideAngular(function () {
1247
- var obs = fromEvent(el, 'scroll').pipe(map(function (_a) {
1248
- var _b = _a.target, scrollTop = _b.scrollTop, scrollLeft = _b.scrollLeft;
1249
- return ({
1250
- scrollTop: scrollTop,
1251
- scrollLeft: scrollLeft,
1252
- sourceType: sourceType
1253
- });
1254
- }));
1255
- var comparisonFn = sourceType === 'timeline' ?
1256
- function (x, y) { return (x.scrollTop === y.scrollTop) && (x.scrollLeft === y.scrollLeft); } :
1257
- function (x, y) { return (x.scrollTop === y.scrollTop); };
1258
- _this.subscriptions.add(obs.pipe(distinctUntilChanged(comparisonFn))
1259
- .subscribe(function (event) { return _this.changes.next(event); }));
1260
- });
1261
- }
1763
+ Object.defineProperty(EditService.prototype, "dependencies", {
1764
+ get: function () {
1765
+ return this.predecessors.concat(this.successors);
1766
+ },
1767
+ set: function (items) {
1768
+ var _this = this;
1769
+ // Can this whole thing be moved to edit-dialog? Dependencies might not be needed here
1770
+ var dataItemId = this.mapper.extractFromTask(this.dataItem, 'id');
1771
+ this.predecessors = items.filter(function (item) { return _this.mapper.extractFromDependency(item, 'toId') === dataItemId; });
1772
+ this.successors = items.filter(function (item) { return _this.mapper.extractFromDependency(item, 'fromId') === dataItemId; });
1773
+ },
1774
+ enumerable: true,
1775
+ configurable: true
1776
+ });
1777
+ EditService.prototype.createEditDialog = function (dataItem, taskFormGroup, dependencies) {
1778
+ this.dataItem = dataItem;
1779
+ this.taskFormGroup = taskFormGroup;
1780
+ this.dependencies = dependencies;
1781
+ this.showEditingDialog.next(true);
1262
1782
  };
1263
- ScrollSyncService.prototype.ngOnDestroy = function () {
1264
- this.subscriptions.unsubscribe();
1265
- this.elements = null;
1783
+ EditService.prototype.closeEditDialog = function () {
1784
+ this.showEditingDialog.next(false);
1785
+ this.dataItem = undefined;
1786
+ this.taskFormGroup = undefined;
1787
+ this.dependencies = [];
1788
+ this.updatedItems = [];
1789
+ this.deletedItems = [];
1266
1790
  };
1267
- ScrollSyncService.prototype.syncScrollTop = function (sourceType, targetType) {
1268
- var source = this.elements.find(function (element) { return element.sourceType === sourceType; });
1269
- var target = this.elements.find(function (element) { return element.sourceType === targetType; });
1270
- // Need to wait for the splitter pane's content to be rendered
1271
- this.ngZone.onStable.pipe(take(1)).subscribe(function () { return target.element.scrollTop = source.element.scrollTop; });
1791
+ EditService.prototype.triggerEditEvent = function (editResultType) {
1792
+ this.editEvent.next({
1793
+ taskFormGroup: this.taskFormGroup,
1794
+ dataItem: this.dataItem,
1795
+ dependencies: {
1796
+ createdItems: this.getCreatedDependencies(),
1797
+ updatedItems: this.updatedItems,
1798
+ deletedItems: this.deletedItems
1799
+ },
1800
+ editResultType: editResultType
1801
+ });
1272
1802
  };
1273
- ScrollSyncService.prototype.resetTimelineScrollLeft = function () {
1274
- var source = this.elements.find(function (element) { return element.sourceType === 'timeline'; });
1275
- source.element.scrollLeft = 0;
1803
+ EditService.prototype.updateDependencies = function (item) {
1804
+ if (!this.isNew(item)) {
1805
+ // update
1806
+ var index = this.itemIndex(item, this.updatedItems);
1807
+ if (index !== -1) {
1808
+ this.updatedItems.splice(index, 1, item);
1809
+ }
1810
+ else {
1811
+ this.updatedItems.push(item);
1812
+ }
1813
+ }
1276
1814
  };
1277
- ScrollSyncService.prototype.scroll = function (_a) {
1815
+ EditService.prototype.getCreatedDependencies = function () {
1278
1816
  var _this = this;
1279
- var scrollTop = _a.scrollTop, scrollLeft = _a.scrollLeft, sourceType = _a.sourceType;
1280
- this.ngZone.runOutsideAngular(function () {
1281
- if (sourceType === 'timeline') {
1282
- var header = _this.elements.find(function (element) { return element.sourceType === 'header'; }).element;
1283
- header.scrollLeft = scrollLeft;
1284
- if (!_this.syncingTimeline) {
1285
- _this.syncingTreeList = true;
1286
- var treelist = _this.elements.find(function (element) { return element.sourceType === 'treelist'; }).element;
1287
- treelist.scrollTop = scrollTop;
1288
- }
1289
- _this.syncingTimeline = false;
1290
- }
1291
- if (sourceType === 'treelist') {
1292
- if (!_this.syncingTreeList) {
1293
- _this.syncingTimeline = true;
1294
- var timeline = _this.elements.find(function (element) { return element.sourceType === 'timeline'; }).element;
1295
- timeline.scrollTop = scrollTop;
1296
- }
1297
- _this.syncingTreeList = false;
1817
+ return this.dependencies.filter(function (item) { return _this.mapper.extractFromDependency(item, 'id') === null; });
1818
+ };
1819
+ EditService.prototype.deleteDependency = function (item) {
1820
+ var updatedIndex = this.itemIndex(item, this.updatedItems);
1821
+ if (updatedIndex !== -1) {
1822
+ this.updatedItems.splice(updatedIndex, 1);
1823
+ }
1824
+ if (!this.isNew(item)) {
1825
+ this.deletedItems.push(item);
1826
+ }
1827
+ };
1828
+ EditService.prototype.loadTasks = function (initialValues, isInitializer) {
1829
+ var _this = this;
1830
+ if (isInitializer === void 0) { isInitializer = true; }
1831
+ return forkJoin(initialValues.map(function (v) { return _this.getElementById(v); })).pipe(map(function (value) {
1832
+ return value.reduce(function (acc, item) { return acc = acc.concat(normalizeGanttData(item)); }, []);
1833
+ }), expand(function (values) {
1834
+ if (values.some(function (el) { return _this.hasChildren(el); })) {
1835
+ return _this.loadTasks(values, false);
1298
1836
  }
1299
- });
1837
+ return EMPTY;
1838
+ }), reduce(function (acc, values) { return acc.concat(values); }, isInitializer ? initialValues.slice() : []));
1300
1839
  };
1301
- ScrollSyncService = __decorate([
1840
+ EditService.prototype.getElementById = function (item) {
1841
+ var children = this.fetchChildren(item);
1842
+ if (isObservable(children)) {
1843
+ return children;
1844
+ }
1845
+ return of(children);
1846
+ };
1847
+ EditService.prototype.isNew = function (item) {
1848
+ return !isPresent(this.mapper.extractFromDependency(item, 'id'));
1849
+ };
1850
+ EditService = __decorate([
1302
1851
  Injectable(),
1303
- __metadata("design:paramtypes", [NgZone])
1304
- ], ScrollSyncService);
1305
- return ScrollSyncService;
1852
+ __metadata("design:paramtypes", [MappingService])
1853
+ ], EditService);
1854
+ return EditService;
1855
+ }());
1856
+
1857
+ /**
1858
+ * @hidden
1859
+ *
1860
+ * Notifies the timeline-scroll.directive to scroll into view to requested coordinates.
1861
+ * The scrolling is performed based on client (viewport) coordinates.
1862
+ */
1863
+ var TimelineScrollService = /** @class */ (function () {
1864
+ function TimelineScrollService() {
1865
+ this.horizontalScroll = new Subject();
1866
+ this.verticalScroll = new Subject();
1867
+ this.scrollCancel = new Subject();
1868
+ }
1869
+ TimelineScrollService.prototype.ngOnDestroy = function () {
1870
+ this.horizontalScroll.complete();
1871
+ this.verticalScroll.complete();
1872
+ this.scrollCancel.complete();
1873
+ };
1874
+ TimelineScrollService.prototype.requestHorizontalScroll = function (clientTop) {
1875
+ this.horizontalScroll.next(clientTop);
1876
+ };
1877
+ TimelineScrollService.prototype.requestVerticalScroll = function (clientLeft) {
1878
+ this.verticalScroll.next(clientLeft);
1879
+ };
1880
+ TimelineScrollService.prototype.requestScrollCancel = function () {
1881
+ this.scrollCancel.next();
1882
+ };
1883
+ TimelineScrollService = __decorate([
1884
+ Injectable()
1885
+ ], TimelineScrollService);
1886
+ return TimelineScrollService;
1887
+ }());
1888
+
1889
+ /**
1890
+ * @hidden
1891
+ *
1892
+ * Needed to keep the Gantt's LocalizationService reference and be able to use it component's inside the TabStrip
1893
+ */
1894
+ var GanttLocalizationService = /** @class */ (function () {
1895
+ function GanttLocalizationService(localizationService) {
1896
+ this.localizationService = localizationService;
1897
+ }
1898
+ GanttLocalizationService.prototype.get = function (token) {
1899
+ return this.localizationService.get(token);
1900
+ };
1901
+ GanttLocalizationService = __decorate([
1902
+ Injectable(),
1903
+ __metadata("design:paramtypes", [LocalizationService])
1904
+ ], GanttLocalizationService);
1905
+ return GanttLocalizationService;
1306
1906
  }());
1307
1907
 
1908
+ // TODO: add those keys to `import { Keys } from '@progress/kendo-angular-common';`
1909
+ var NumpadKeys;
1910
+ (function (NumpadKeys) {
1911
+ NumpadKeys[NumpadKeys["Digit1"] = 97] = "Digit1";
1912
+ NumpadKeys[NumpadKeys["Digit2"] = 98] = "Digit2";
1913
+ NumpadKeys[NumpadKeys["Digit3"] = 99] = "Digit3";
1914
+ NumpadKeys[NumpadKeys["Digit4"] = 100] = "Digit4";
1915
+ })(NumpadKeys || (NumpadKeys = {}));
1916
+ /**
1917
+ * @hidden
1918
+ */
1919
+ var isArrowUpDownKey = function (keyCode) { return [
1920
+ Keys.ArrowUp,
1921
+ Keys.ArrowDown
1922
+ ].some(function (arrowKeyCode) {
1923
+ return keyCode === arrowKeyCode;
1924
+ }); };
1925
+ /**
1926
+ * @hidden
1927
+ */
1928
+ var isNavigationKey = function (keyCode) { return [
1929
+ Keys.ArrowUp,
1930
+ Keys.ArrowDown,
1931
+ Keys.Home,
1932
+ Keys.End
1933
+ ].some(function (navigationKeyCode) {
1934
+ return keyCode === navigationKeyCode;
1935
+ }); };
1936
+ /**
1937
+ * @hidden
1938
+ */
1939
+ var isExpandCollapseKey = function (keyCode, altKey) {
1940
+ return altKey && [
1941
+ Keys.ArrowLeft,
1942
+ Keys.ArrowRight
1943
+ ].some(function (navigationKeyCode) {
1944
+ return keyCode === navigationKeyCode;
1945
+ });
1946
+ };
1947
+ /**
1948
+ * @hidden
1949
+ */
1950
+ var isViewDigitKey = function (keyCode) { return [
1951
+ Keys.Digit1,
1952
+ NumpadKeys.Digit1,
1953
+ Keys.Digit2,
1954
+ NumpadKeys.Digit2,
1955
+ Keys.Digit3,
1956
+ NumpadKeys.Digit3,
1957
+ Keys.Digit4,
1958
+ NumpadKeys.Digit4
1959
+ ].some(function (digitKeyCode) {
1960
+ return keyCode === digitKeyCode;
1961
+ }); };
1962
+ /**
1963
+ * @hidden
1964
+ *
1965
+ * Returns the corresponding view index for the pressed digit key (Digit 1 => 0, Digit 2 => 1, etc.).
1966
+ */
1967
+ var getIndexFromViewDigitKeyCode = function (keyCode) {
1968
+ switch (keyCode) {
1969
+ case NumpadKeys.Digit1:
1970
+ case Keys.Digit1: return 0;
1971
+ case NumpadKeys.Digit2:
1972
+ case Keys.Digit2: return 1;
1973
+ case NumpadKeys.Digit3:
1974
+ case Keys.Digit3: return 2;
1975
+ case NumpadKeys.Digit4:
1976
+ case Keys.Digit4: return 3;
1977
+ default: return null;
1978
+ }
1979
+ };
1980
+
1308
1981
  /**
1309
1982
  * @hidden
1310
1983
  */
1311
- var DependencyDomService = /** @class */ (function () {
1312
- function DependencyDomService(mapper) {
1313
- this.mapper = mapper;
1314
- this.notifier = new Subject();
1984
+ var NavigationService = /** @class */ (function () {
1985
+ function NavigationService(zone, renderer, scrollSyncService) {
1986
+ this.zone = zone;
1987
+ this.renderer = renderer;
1988
+ this.scrollSyncService = scrollSyncService;
1315
1989
  /**
1316
- * Maps each rendered task to its HTML element.
1317
- * Uses the task ID field value as key.
1990
+ * Notifies when the tasks' focused and interactive (tabindex) state has changed.
1991
+ *
1992
+ * All tasks are rendered with tabindex="-1".
1993
+ * When one is clicked, or when some navigation key keyboard key is pressed, it should be focused, assigned the focus class, and its tabindex updated to 0.
1994
+ * All other tasks should get -1 tabindex and have the focus class removed from them.
1318
1995
  */
1319
- this.tasks = new Map();
1996
+ this.taskStatusChanges = new Subject();
1997
+ /**
1998
+ * Keeps track of whether the Timeline part is focused.
1999
+ * Used when the index of the task elements change (tasks are changed, pushed to, spliced from, etc.)
2000
+ * and their status should be updated accordingly.
2001
+ */
2002
+ this.isTimelineFocused = false;
2003
+ /**
2004
+ * Keeps track of which part has last been focused.
2005
+ * Used when calling `gantt.focus()` to determine which part of the component should receive focus.
2006
+ */
2007
+ this.treeListLastActive = false;
2008
+ /**
2009
+ * Keeps track of which part has last been focused.
2010
+ * Used when calling `gantt.focus()` to determine which part of the component should receive focus.
2011
+ */
2012
+ this.timelineLastActive = false;
2013
+ this._enabled = false;
2014
+ this._activeTimelineIndex = 0;
2015
+ this._activeTreeListCell = { rowIndex: 0, colIndex: 0 };
1320
2016
  }
1321
- Object.defineProperty(DependencyDomService.prototype, "taskChanges", {
2017
+ Object.defineProperty(NavigationService.prototype, "enabled", {
1322
2018
  /**
1323
- * Emits each time some of the tasks or the view have changed.
1324
- * Fires also on the first change of the table rows and the parent container.
2019
+ * Specifies whether navigation is enabled.
1325
2020
  */
1326
2021
  get: function () {
1327
- return this.notifier.asObservable();
2022
+ return this._enabled;
1328
2023
  },
1329
2024
  enumerable: true,
1330
2025
  configurable: true
1331
2026
  });
1332
- Object.defineProperty(DependencyDomService.prototype, "dependencyDomArgs", {
2027
+ Object.defineProperty(NavigationService.prototype, "activeTask", {
2028
+ /**
2029
+ * Used to retrieve read-only data about the currently active task.
2030
+ */
1333
2031
  get: function () {
1334
2032
  return {
1335
- tasks: this.tasks,
1336
- contentContainer: this.contentContainer,
1337
- timelineRow: this.timelineRow
2033
+ activeIndex: this.activeTimelineIndex,
2034
+ isFocused: this.isTimelineFocused
1338
2035
  };
1339
2036
  },
1340
2037
  enumerable: true,
1341
2038
  configurable: true
1342
2039
  });
1343
- DependencyDomService.prototype.ngOnDestroy = function () {
1344
- this.tasks.clear();
1345
- this.tasks = null;
1346
- this.contentContainer = null;
2040
+ Object.defineProperty(NavigationService.prototype, "activeTreeListCell", {
2041
+ get: function () {
2042
+ var firstAvailableIndex = 0;
2043
+ var lastAvailableRowIndex = this.treeListHeaderRowsCount + this.gantt.treeList.view.data.length - 1;
2044
+ var rowIndex = fitToRange(this._activeTreeListCell.rowIndex, firstAvailableIndex, lastAvailableRowIndex);
2045
+ var lastAvailableColIndex = this.gantt.columns.length;
2046
+ var colIndex = fitToRange(this._activeTreeListCell.colIndex, firstAvailableIndex, lastAvailableColIndex);
2047
+ return { rowIndex: rowIndex, colIndex: colIndex };
2048
+ },
2049
+ /**
2050
+ * Persists the expected TreeList focused cell coords.
2051
+ * When the tasks in the Timeline are navigated through, the expected TreeList focus target should also change,
2052
+ * in order to allow back-tabbing from the Timeline to the same row in the TreeList.
2053
+ */
2054
+ set: function (cell) {
2055
+ this._activeTreeListCell = cell;
2056
+ },
2057
+ enumerable: true,
2058
+ configurable: true
2059
+ });
2060
+ Object.defineProperty(NavigationService.prototype, "activeTimelineIndex", {
2061
+ get: function () {
2062
+ var firstAvailableIndex = 0;
2063
+ var lastAvailableIndex = this.gantt.treeList.view.data.length - 1;
2064
+ return fitToRange(this._activeTimelineIndex, firstAvailableIndex, lastAvailableIndex);
2065
+ },
2066
+ /**
2067
+ * Persists the expected Timeline focused task index.
2068
+ * When the cells in the TreeList are navigated through, the expected Timeline focus target should also change,
2069
+ * in order to allow tabbing from the TreeList to the same row in the Timeline.
2070
+ */
2071
+ set: function (index) {
2072
+ this._activeTimelineIndex = index;
2073
+ },
2074
+ enumerable: true,
2075
+ configurable: true
2076
+ });
2077
+ Object.defineProperty(NavigationService.prototype, "treeListHeaderRowsCount", {
2078
+ /**
2079
+ * The TreeList row index takes into account the header and filter rows.
2080
+ * Used when translating Timeline task indices to TreeList row indices.
2081
+ */
2082
+ get: function () {
2083
+ // captures nested group header rows + filter row if we start supporting it at some point
2084
+ return this.treeListElement.querySelectorAll('.k-grid-header tr').length;
2085
+ },
2086
+ enumerable: true,
2087
+ configurable: true
2088
+ });
2089
+ NavigationService.prototype.initialize = function (_a) {
2090
+ var _this = this;
2091
+ var gantt = _a.gantt, host = _a.host, treeListElement = _a.treeListElement, timelineElement = _a.timelineElement;
2092
+ // no private property setters in TypeScript, so use a getter and a poorly named private prop for this value
2093
+ this._enabled = true;
2094
+ this.gantt = gantt;
2095
+ this.host = host;
2096
+ this.treeListElement = treeListElement;
2097
+ this.timelineElement = timelineElement;
2098
+ // TODO: fix in the splitter package and remove
2099
+ // move the splitbar HTML element between the two panes to keep the visial tabbing order in tact
2100
+ var splitbar = this.host.querySelector('.k-splitbar');
2101
+ if (isPresent(splitbar) && isPresent(splitbar.previousElementSibling) && isPresent(splitbar.after)) {
2102
+ splitbar.after(splitbar.previousElementSibling);
2103
+ }
2104
+ this.zone.runOutsideAngular(function () {
2105
+ _this.eventListenerDisposers = [
2106
+ _this.renderer.listen(_this.host, 'keydown', _this.handleKeydown.bind(_this)),
2107
+ _this.renderer.listen(_this.treeListElement, 'mousedown', _this.focusTreeList.bind(_this)),
2108
+ _this.renderer.listen(_this.treeListElement, 'focusin', _this.handleTreeListFocusIn.bind(_this)),
2109
+ _this.renderer.listen(_this.timelineElement, 'mousedown', _this.handleTimelineMousedown.bind(_this)),
2110
+ _this.renderer.listen(_this.timelineElement, 'focusin', _this.handleTimelineFocusIn.bind(_this)),
2111
+ _this.renderer.listen(_this.timelineElement, 'focusout', _this.handleTimelineFocusOut.bind(_this))
2112
+ ];
2113
+ });
1347
2114
  };
1348
- DependencyDomService.prototype.registerTimelineRow = function (timelineRow) {
1349
- this.timelineRow = timelineRow;
1350
- this.notifyChanges();
2115
+ NavigationService.prototype.ngOnDestroy = function () {
2116
+ if (isPresent(this.eventListenerDisposers)) {
2117
+ this.eventListenerDisposers.forEach(function (removeListener) { return removeListener(); });
2118
+ this.eventListenerDisposers = null;
2119
+ }
2120
+ this.gantt = null;
2121
+ this.host = null;
2122
+ this.treeListElement = null;
2123
+ this.timelineElement = null;
1351
2124
  };
1352
- DependencyDomService.prototype.registerContentContainer = function (contentContainer) {
1353
- this.contentContainer = contentContainer;
1354
- this.notifyChanges();
2125
+ /**
2126
+ * Focuses either the last active TreeList cell, or the last active Timeline task,
2127
+ * dependening on which of the two last held focus.
2128
+ *
2129
+ * Focuses the first TreeList cell by default.
2130
+ */
2131
+ NavigationService.prototype.focusLastActiveItem = function () {
2132
+ if (this.gantt.data.length === 0 || (!this.treeListLastActive && !this.timelineLastActive)) {
2133
+ this.focusCell(0, 0);
2134
+ }
2135
+ else if (this.treeListLastActive) {
2136
+ var _a = this.activeTreeListCell, rowIndex = _a.rowIndex, colIndex = _a.colIndex;
2137
+ this.gantt.treeList.focusCell(rowIndex, colIndex);
2138
+ }
2139
+ else if (this.timelineLastActive) {
2140
+ this.focusTask(this.activeTimelineIndex);
2141
+ }
1355
2142
  };
1356
- DependencyDomService.prototype.registerTask = function (task, element) {
1357
- var id = this.mapper.extractFromTask(task, 'id');
1358
- this.tasks.set(id, element);
1359
- this.notifyChanges();
2143
+ /**
2144
+ * Focuses the targeted TreeList cell regardless of the last peresisted target.
2145
+ */
2146
+ NavigationService.prototype.focusCell = function (rowIndex, colIndex) {
2147
+ this.activeTreeListCell = { rowIndex: rowIndex, colIndex: colIndex };
2148
+ this.activeTimelineIndex = rowIndex - this.treeListHeaderRowsCount;
2149
+ this.gantt.treeList.focusCell(this.activeTreeListCell.rowIndex, this.activeTreeListCell.colIndex);
1360
2150
  };
1361
- DependencyDomService.prototype.unregisterTask = function (task) {
1362
- var id = this.mapper.extractFromTask(task, 'id');
1363
- this.tasks.delete(id);
1364
- this.notifyChanges();
2151
+ /**
2152
+ * Focuses the targeted Timeline task regardless of the last peresisted target.
2153
+ */
2154
+ NavigationService.prototype.focusTask = function (index) {
2155
+ this.activeTimelineIndex = index;
2156
+ this.isTimelineFocused = true;
2157
+ this.activeTreeListCell = {
2158
+ rowIndex: index + this.treeListHeaderRowsCount,
2159
+ colIndex: this.activeTreeListCell.colIndex
2160
+ };
2161
+ this.notifyTaskStatusChange();
1365
2162
  };
1366
2163
  /**
1367
- * Notifies all dependency directives that a change in one of the elements has occured.
2164
+ * Updates the focus target flags and notifies the active task to update its focused state.
1368
2165
  */
1369
- DependencyDomService.prototype.notifyChanges = function () {
1370
- this.notifier.next(this.dependencyDomArgs);
2166
+ NavigationService.prototype.handleTimelineFocusIn = function (_a) {
2167
+ var target = _a.target;
2168
+ this.treeListLastActive = false;
2169
+ this.timelineLastActive = true;
2170
+ this.isTimelineFocused = true;
2171
+ if (isTask(target, this.timelineElement)) {
2172
+ this.notifyTaskStatusChange();
2173
+ }
1371
2174
  };
1372
- DependencyDomService = __decorate([
1373
- Injectable(),
1374
- __metadata("design:paramtypes", [MappingService])
1375
- ], DependencyDomService);
1376
- return DependencyDomService;
1377
- }());
1378
-
1379
- /**
1380
- * @hidden
1381
- */
1382
- var EditService = /** @class */ (function () {
1383
- function EditService() {
1384
- this.showEditingDialog = new Subject();
1385
- this.showConfirmationDialog = new Subject();
1386
- this.editEvent = new Subject();
1387
- this.addEvent = new Subject();
1388
- }
1389
- EditService.prototype.createEditDialog = function (dataItem, formGroup) {
1390
- this.dataItem = dataItem;
1391
- this.formGroup = formGroup;
1392
- this.showEditingDialog.next(true);
2175
+ /**
2176
+ * Updates the timeline focus state flag and notifies the active task to update its focused state.
2177
+ */
2178
+ NavigationService.prototype.handleTimelineFocusOut = function (_a) {
2179
+ var relatedTarget = _a.relatedTarget;
2180
+ this.isTimelineFocused = this.timelineElement.contains(relatedTarget);
2181
+ // update the task element only if the new focus target is not in the Timeline - focus change between tasks is handled in the focusin handler
2182
+ if (!isTask(relatedTarget, this.timelineElement)) {
2183
+ this.notifyTaskStatusChange();
2184
+ }
1393
2185
  };
1394
- EditService.prototype.closeEditDialog = function () {
1395
- this.showEditingDialog.next(false);
1396
- this.dataItem = undefined;
1397
- this.formGroup = undefined;
2186
+ /**
2187
+ * Updates the focus target flags and corrects the TreeList focus target if needed.
2188
+ * As the TreeList will keep its last focused cell with tabindex="0",
2189
+ * this methods forcefully focuses the correct cell,
2190
+ * when navigating in the Timeline has updated the expected TreeList focus target.
2191
+ */
2192
+ NavigationService.prototype.handleTreeListFocusIn = function (event) {
2193
+ this.treeListLastActive = true;
2194
+ this.timelineLastActive = false;
2195
+ // if the previous focus target was in the TreeList, rely on its component navigation and just record the focused item index
2196
+ if (this.treeListElement.contains(event.relatedTarget)) {
2197
+ var _a = this.gantt.treeList.activeCell, colIndex = _a.colIndex, rowIndex = _a.rowIndex;
2198
+ this.activeTreeListCell = { colIndex: colIndex, rowIndex: rowIndex };
2199
+ }
2200
+ else {
2201
+ // if the previous focus target was outside the TreeList, ensure the expected focus coords are used
2202
+ var _b = this.activeTreeListCell, rowIndex = _b.rowIndex, colIndex = _b.colIndex;
2203
+ this.gantt.treeList.focusCell(rowIndex, colIndex); // activates the target cell even if it has tabindex="-1"
2204
+ }
2205
+ this.activeTimelineIndex = this.gantt.treeList.activeCell.dataRowIndex;
2206
+ this.notifyTaskStatusChange();
2207
+ if (this.gantt.treeList.activeCell.dataRowIndex >= 0) {
2208
+ this.scrollHorizontallyToTask(this.activeTimelineIndex);
2209
+ this.scrollSyncService.syncScrollTop('treelist', 'timeline');
2210
+ }
1398
2211
  };
1399
- EditService.prototype.triggerEditEvent = function (editResultType) {
1400
- this.editEvent.next({
1401
- formGroup: this.formGroup,
1402
- dataItem: this.dataItem,
1403
- editResultType: editResultType
1404
- });
2212
+ NavigationService.prototype.handleKeydown = function (event) {
2213
+ var _this = this;
2214
+ var _a = event, keyCode = _a.keyCode, target = _a.target, altKey = _a.altKey;
2215
+ var isTimelineActive = this.timelineElement.contains(target);
2216
+ if (isTimelineActive) {
2217
+ if (isArrowUpDownKey(keyCode)) {
2218
+ var direction = keyCode === Keys.ArrowUp ? -1 : 1;
2219
+ this.activeTimelineIndex = this.activeTimelineIndex + direction;
2220
+ this.activeTreeListCell = {
2221
+ rowIndex: this.activeTimelineIndex + this.treeListHeaderRowsCount,
2222
+ colIndex: this.activeTreeListCell.colIndex
2223
+ };
2224
+ }
2225
+ else if (keyCode === Keys.Home) {
2226
+ this.activeTimelineIndex = 0;
2227
+ this.activeTreeListCell = {
2228
+ rowIndex: this.activeTimelineIndex + this.treeListHeaderRowsCount,
2229
+ colIndex: this.activeTreeListCell.colIndex
2230
+ };
2231
+ }
2232
+ else if (keyCode === Keys.End) {
2233
+ var lastAvailableIndex = this.gantt.treeList.view.data.length - 1;
2234
+ this.activeTimelineIndex = lastAvailableIndex;
2235
+ this.activeTreeListCell = {
2236
+ rowIndex: this.activeTimelineIndex + this.treeListHeaderRowsCount,
2237
+ colIndex: this.activeTreeListCell.colIndex
2238
+ };
2239
+ }
2240
+ if (isNavigationKey(keyCode)) {
2241
+ this.scrollHorizontallyToTask(this.activeTimelineIndex);
2242
+ this.scrollSyncService.syncScrollTop('timeline', 'treelist');
2243
+ this.notifyTaskStatusChange();
2244
+ event.preventDefault();
2245
+ }
2246
+ if (keyCode === Keys.Space && hasObservers(this.gantt.selectionChange)) {
2247
+ var task_1 = this.gantt.renderedTreeListItems[this.activeTimelineIndex];
2248
+ var selectionAction_1 = this.gantt.getSelectionAction(event, task_1);
2249
+ if (isPresent(task_1) && !this.gantt.isSameSelection(selectionAction_1, task_1)) {
2250
+ this.zone.run(function () {
2251
+ return _this.gantt.notifySelectionChange(task_1, selectionAction_1);
2252
+ });
2253
+ }
2254
+ event.preventDefault();
2255
+ }
2256
+ if (keyCode === Keys.Enter && hasObservers(this.gantt.taskClick)) {
2257
+ var task_2 = this.gantt.renderedTreeListItems[this.activeTimelineIndex];
2258
+ if (isPresent(task_2)) {
2259
+ this.zone.run(function () {
2260
+ return _this.gantt.notifyTaskClick(event, task_2, _this.activeTimelineIndex);
2261
+ });
2262
+ }
2263
+ event.preventDefault();
2264
+ }
2265
+ if (isExpandCollapseKey(keyCode, altKey)) {
2266
+ var task_3 = this.gantt.renderedTreeListItems[this.activeTimelineIndex];
2267
+ if (isPresent(task_3) && this.gantt.hasChildren(task_3)) {
2268
+ var shouldExpand_1 = keyCode === Keys.ArrowRight;
2269
+ var isExpanded = this.gantt.isExpanded(task_3);
2270
+ var sameState = shouldExpand_1 === isExpanded;
2271
+ if (!sameState) {
2272
+ this.zone.run(function () {
2273
+ var expandEvent = { dataItem: task_3 };
2274
+ // order is not arbitrary
2275
+ // the TreeList emits the individual events first, then the combined `expandStateChange` event
2276
+ var individualEmitter = shouldExpand_1 ? _this.gantt.rowExpand : _this.gantt.rowCollapse;
2277
+ individualEmitter.emit(expandEvent);
2278
+ _this.gantt.expandStateChange.emit(__assign({}, expandEvent, { expand: shouldExpand_1 }));
2279
+ _this.gantt.updateView();
2280
+ _this.scrollHorizontallyToTask(_this.activeTimelineIndex);
2281
+ });
2282
+ }
2283
+ }
2284
+ event.preventDefault();
2285
+ }
2286
+ }
2287
+ var isTreeListActive = this.treeListElement.contains(target);
2288
+ if (keyCode === Keys.Delete && (isTimelineActive || isTreeListActive) && hasObservers(this.gantt.taskDelete)) {
2289
+ var taskIndex = isTreeListActive ?
2290
+ this.gantt.treeList.activeCell.dataRowIndex :
2291
+ this.activeTimelineIndex;
2292
+ var task_4 = this.gantt.renderedTreeListItems[taskIndex];
2293
+ if (isPresent(task_4)) {
2294
+ this.zone.run(function () {
2295
+ return _this.gantt.notifyTaskDelete(task_4);
2296
+ });
2297
+ }
2298
+ }
2299
+ if (isViewDigitKey(keyCode) && !isToolbar(target, this.host) && !this.gantt.isInEditMode) {
2300
+ var targetViewIndex = getIndexFromViewDigitKeyCode(keyCode);
2301
+ var availableViews = this.gantt.views.toArray();
2302
+ var targetView_1 = availableViews[targetViewIndex];
2303
+ if (isPresent(targetView_1) && targetView_1.type !== this.gantt.activeView) {
2304
+ this.zone.run(function () {
2305
+ return _this.gantt.changeActiveView(targetView_1.type);
2306
+ });
2307
+ }
2308
+ }
1405
2309
  };
1406
- EditService = __decorate([
1407
- Injectable()
1408
- ], EditService);
1409
- return EditService;
2310
+ /**
2311
+ * Filters for task mousedown in the Timeline.
2312
+ */
2313
+ NavigationService.prototype.handleTimelineMousedown = function (_a) {
2314
+ var target = _a.target;
2315
+ if (isTask(target, this.host) && !isClearButton(target, this.host)) {
2316
+ var taskIndex = getClosestTaskIndex(target, this.host);
2317
+ this.focusTask(taskIndex);
2318
+ }
2319
+ };
2320
+ /**
2321
+ * Scrolls horizontally to the beginning of the target task if the beginning of its content is not in the viewport.
2322
+ */
2323
+ NavigationService.prototype.scrollHorizontallyToTask = function (index) {
2324
+ var task = this.timelineElement.querySelectorAll('.k-task-wrap').item(index);
2325
+ if (!isPresent(task)) {
2326
+ return;
2327
+ }
2328
+ // scroll horizontally to the item if less than 200px from the beginning of its content are visible
2329
+ var targetVisibleWidth = 200;
2330
+ var isScrollBeforeTask = (this.timelineElement.clientWidth + this.timelineElement.scrollLeft) < (task.offsetLeft + targetVisibleWidth);
2331
+ var isScrollAfterTask = this.timelineElement.scrollLeft > task.offsetLeft;
2332
+ if (isScrollBeforeTask || isScrollAfterTask) {
2333
+ this.timelineElement.scrollLeft = task.offsetLeft;
2334
+ }
2335
+ };
2336
+ /**
2337
+ * Focus the TreeList on TreeList mousedown.
2338
+ * A nasty hack to trick `handleTreeListFocusIn` into regarding the previous focus target as again the TreeList.
2339
+ * Otherwise cell clicks are wrongly overwritten in `handleTreeListFocusIn` and the click focus target is not respected.
2340
+ */
2341
+ NavigationService.prototype.focusTreeList = function () {
2342
+ this.gantt.treeList.focus();
2343
+ };
2344
+ /**
2345
+ * Fires the `taskStatusChanges` event with active and focused status retrieved from
2346
+ * `this.activeTimelineIndex` and `this.isTimelineFocused`.
2347
+ */
2348
+ NavigationService.prototype.notifyTaskStatusChange = function () {
2349
+ this.taskStatusChanges.next(this.activeTask);
2350
+ };
2351
+ NavigationService = __decorate([
2352
+ Injectable(),
2353
+ __metadata("design:paramtypes", [NgZone,
2354
+ Renderer2,
2355
+ ScrollSyncService])
2356
+ ], NavigationService);
2357
+ return NavigationService;
1410
2358
  }());
1411
2359
 
1412
2360
  /**
@@ -1719,6 +2667,12 @@ var mapPath = function (item) { return ({
1719
2667
 
1720
2668
  var TREELIST_GROUP_COLUMNS_CLASS = 'k-gantt-treelist-nested-columns';
1721
2669
  var DEFAULT_VIEW = 'week';
2670
+ var DEFAULT_DRAG_SCROLL_SETTINGS = {
2671
+ enabled: true,
2672
+ step: 3,
2673
+ interval: 1,
2674
+ threshold: 10
2675
+ };
1722
2676
  /**
1723
2677
  * Represents the Kendo UI Gantt component for Angular.
1724
2678
  *
@@ -1791,7 +2745,7 @@ var DEFAULT_VIEW = 'week';
1791
2745
  * ```
1792
2746
  */
1793
2747
  var GanttComponent = /** @class */ (function () {
1794
- function GanttComponent(timelineViewService, scrollSyncService, renderer, mapper, optionChangesService, dependencyDomService, editService, localizationService, hostElement, zone) {
2748
+ function GanttComponent(timelineViewService, scrollSyncService, renderer, mapper, optionChangesService, dependencyDomService, editService, localizationService, hostElement, zone, navigationService) {
1795
2749
  var _this = this;
1796
2750
  this.timelineViewService = timelineViewService;
1797
2751
  this.scrollSyncService = scrollSyncService;
@@ -1803,13 +2757,33 @@ var GanttComponent = /** @class */ (function () {
1803
2757
  this.localizationService = localizationService;
1804
2758
  this.hostElement = hostElement;
1805
2759
  this.zone = zone;
2760
+ this.navigationService = navigationService;
2761
+ /**
2762
+ * @hidden
2763
+ */
2764
+ this.roleDescription = 'Gantt Chart';
2765
+ /**
2766
+ * @hidden
2767
+ */
2768
+ this.role = 'application';
1806
2769
  this.hostClasses = true;
1807
2770
  /**
1808
- * Provides a callback that determines if the given task is selected ([see example]({% slug selection_gantt %}#toc-custom-selection))
2771
+ * Specifies a callback that determines if the given task is selected ([see example]({% slug selection_gantt %}#toc-custom-selection)).
1809
2772
  *
1810
2773
  * > The [`selectable`]({% slug api_gantt_ganttcomponent %}#toc-selectable) prop has to be set to `true` in order for this callback to be executed.
1811
2774
  */
1812
2775
  this.isSelected = isSelected;
2776
+ /**
2777
+ * Specifies a callback that determines if a new dependency is valid.
2778
+ * Used when evaluating if an attempt to create a new dependency will result in a valid link between the two tasks
2779
+ * [see example]({% slug editing_drag_create_dependencies_gantt %}#toc-validation).
2780
+ *
2781
+ * By defalut, dependencies are deemed invalid when:
2782
+ * - The two tasks are in a parent-child relationship.
2783
+ * - The two tasks are already dependent on one another. Only one dependency is allowed per pair.
2784
+ * - The start or end times of the two tasks are incompatible with the attempted dependency type.
2785
+ */
2786
+ this.validateNewDependency = this.defaultValidateNewDependencyCallback.bind(this);
1813
2787
  /**
1814
2788
  * Fires when the Gantt selection is changed through user interaction.
1815
2789
  *
@@ -1825,14 +2799,6 @@ var GanttComponent = /** @class */ (function () {
1825
2799
  * > When applied, the [`SelectableDirective`]({% slug api_gantt_selectabledirective %}) sets `selectable` to `true` internally.
1826
2800
  */
1827
2801
  this.selectable = false;
1828
- /**
1829
- * Gets or sets the callback function that retrieves the child items for a particular item.
1830
- */
1831
- this.fetchChildren = fetchChildren;
1832
- /**
1833
- * Gets or sets the callback function that indicates if a particular item has child items.
1834
- */
1835
- this.hasChildren = hasChildren;
1836
2802
  /**
1837
2803
  * Defines the dependencies that will be drawn between the rendered tasks.
1838
2804
  *
@@ -1871,6 +2837,12 @@ var GanttComponent = /** @class */ (function () {
1871
2837
  * The end of the work week (index based).
1872
2838
  */
1873
2839
  this.workWeekEnd = 5;
2840
+ /**
2841
+ * If set to `true`, the user can use dedicated shortcuts to interact with the Gantt.
2842
+ * By default, navigation is disabled for the TreeList and Timeline parts of the component,
2843
+ * ([see example]({% slug keyboard_navigation_gantt %})).
2844
+ */
2845
+ this.navigable = false;
1874
2846
  /**
1875
2847
  * Indicates whether the Gantt columns will be resized during initialization so that they fit their headers and row content.
1876
2848
  * Columns with autoSize set to false are excluded.
@@ -1914,7 +2886,8 @@ var GanttComponent = /** @class */ (function () {
1914
2886
  */
1915
2887
  this.cellClose = new EventEmitter();
1916
2888
  /**
1917
- * Fires when the end user clicks the `Delete` button in the task editing dialog or the task delete icon.
2889
+ * Fires when the end user clicks the `Delete` button in the task editing dialog,
2890
+ * the task delete icon, or presses the `Delete` key on the keyboard when a task in the timeline is focused.
1918
2891
  * Use the event handler to open a confirmation dialog when necessary.
1919
2892
  */
1920
2893
  this.taskDelete = new EventEmitter();
@@ -1938,6 +2911,11 @@ var GanttComponent = /** @class */ (function () {
1938
2911
  * Fires when the user adds a task.
1939
2912
  */
1940
2913
  this.taskAdd = new EventEmitter();
2914
+ /**
2915
+ * Fires when the user adds a dependency via dragging
2916
+ * [see example]({% slug editing_drag_create_dependencies_gantt %}#toc-basic-concepts).
2917
+ */
2918
+ this.dependencyAdd = new EventEmitter();
1941
2919
  /**
1942
2920
  * Fires when the sorting of the Gantt is changed.
1943
2921
  * You have to handle the event yourself and sort the data.
@@ -1994,6 +2972,15 @@ var GanttComponent = /** @class */ (function () {
1994
2972
  * Fires when a task is clicked.
1995
2973
  */
1996
2974
  this.taskClick = new EventEmitter();
2975
+ /**
2976
+ * @hidden
2977
+ *
2978
+ * Specifies whether the dependency drag clues will be rendered.
2979
+ * Set internally by the dependency-drag-create directive.
2980
+ *
2981
+ * @default false
2982
+ */
2983
+ this.renderDependencyDragClues = false;
1997
2984
  /**
1998
2985
  * @hidden
1999
2986
  *
@@ -2010,6 +2997,7 @@ var GanttComponent = /** @class */ (function () {
2010
2997
  this.showConfirmationDialog = false;
2011
2998
  this._columns = new QueryList();
2012
2999
  this._data = [];
3000
+ this._dragScrollSettings = __assign({}, DEFAULT_DRAG_SCROLL_SETTINGS);
2013
3001
  this._timelinePaneOptions = __assign({}, DEFAULT_TIMELINE_PANE_SETTINGS);
2014
3002
  this._treeListPaneOptions = __assign({}, DEFAULT_TREELIST_PANE_SETTINGS);
2015
3003
  this._rowClass = rowClassCallback;
@@ -2020,6 +3008,8 @@ var GanttComponent = /** @class */ (function () {
2020
3008
  addTaskTool: 'none',
2021
3009
  viewSelectorTool: 'top'
2022
3010
  };
3011
+ this._fetchChildren = fetchChildren;
3012
+ this._hasChildren = hasChildren;
2023
3013
  this.rtl = false;
2024
3014
  this.optionChangesSubscriptions = new Subscription();
2025
3015
  this.editServiceSubscription = new Subscription();
@@ -2032,16 +3022,26 @@ var GanttComponent = /** @class */ (function () {
2032
3022
  }));
2033
3023
  this.editService.getSelectedItem = this.getFirstSelectedItem.bind(this);
2034
3024
  this.editServiceSubscription.add(this.editService.showEditingDialog.subscribe(function (show) { return _this.showEditingDialog = show; }));
2035
- this.editServiceSubscription.add(this.editService.showConfirmationDialog.subscribe(function () { return _this.taskDelete.emit(); }));
3025
+ this.editServiceSubscription.add(this.editService.taskDelete.subscribe(function (task) {
3026
+ if (hasObservers(_this.taskDelete)) {
3027
+ _this.zone.run(function () {
3028
+ return _this.notifyTaskDelete(task);
3029
+ });
3030
+ }
3031
+ }));
2036
3032
  this.editServiceSubscription.add(this.editService.editEvent.subscribe(function (args) {
2037
3033
  _this[args.editResultType].emit({
2038
- formGroup: args.formGroup,
3034
+ taskFormGroup: args.taskFormGroup,
2039
3035
  item: getEditItem(args.dataItem, _this.treeList.view.data, _this.mapper),
3036
+ dependencies: args.dependencies,
2040
3037
  sender: _this
2041
3038
  });
2042
3039
  _this.showConfirmationDialog = _this.showEditingDialog = false;
2043
- _this.editService.dataItem = _this.editService.formGroup = null;
3040
+ _this.editService.dataItem = _this.editService.taskFormGroup = null;
2044
3041
  _this.updateView();
3042
+ if (_this.navigable) {
3043
+ _this.focus();
3044
+ }
2045
3045
  }));
2046
3046
  this.editServiceSubscription.add(this.editService.addEvent.subscribe(function (args) {
2047
3047
  var selectedItem = _this.getFirstSelectedItem();
@@ -2071,6 +3071,20 @@ var GanttComponent = /** @class */ (function () {
2071
3071
  enumerable: true,
2072
3072
  configurable: true
2073
3073
  });
3074
+ Object.defineProperty(GanttComponent.prototype, "hostRoleDescriptionAttr", {
3075
+ get: function () {
3076
+ return this.roleDescription;
3077
+ },
3078
+ enumerable: true,
3079
+ configurable: true
3080
+ });
3081
+ Object.defineProperty(GanttComponent.prototype, "hostRoleAttr", {
3082
+ get: function () {
3083
+ return this.role;
3084
+ },
3085
+ enumerable: true,
3086
+ configurable: true
3087
+ });
2074
3088
  Object.defineProperty(GanttComponent.prototype, "dir", {
2075
3089
  get: function () {
2076
3090
  return this.direction;
@@ -2182,6 +3196,34 @@ var GanttComponent = /** @class */ (function () {
2182
3196
  enumerable: true,
2183
3197
  configurable: true
2184
3198
  });
3199
+ Object.defineProperty(GanttComponent.prototype, "fetchChildren", {
3200
+ get: function () {
3201
+ return this._fetchChildren;
3202
+ },
3203
+ /**
3204
+ * Gets or sets the callback function that retrieves the child items for a particular item.
3205
+ */
3206
+ set: function (fn) {
3207
+ this._fetchChildren = fn;
3208
+ this.editService.fetchChildren = fn;
3209
+ },
3210
+ enumerable: true,
3211
+ configurable: true
3212
+ });
3213
+ Object.defineProperty(GanttComponent.prototype, "hasChildren", {
3214
+ get: function () {
3215
+ return this._hasChildren;
3216
+ },
3217
+ /**
3218
+ * Gets or sets the callback function that indicates if a particular item has child items.
3219
+ */
3220
+ set: function (fn) {
3221
+ this._hasChildren = fn;
3222
+ this.editService.hasChildren = fn;
3223
+ },
3224
+ enumerable: true,
3225
+ configurable: true
3226
+ });
2185
3227
  Object.defineProperty(GanttComponent.prototype, "timelinePaneOptions", {
2186
3228
  get: function () {
2187
3229
  return __assign({}, this._timelinePaneOptions, { size: this.treeListPaneOptions.collapsed ? '100%' : this._timelinePaneOptions.size });
@@ -2257,7 +3299,35 @@ var GanttComponent = /** @class */ (function () {
2257
3299
  enumerable: true,
2258
3300
  configurable: true
2259
3301
  });
2260
- Object.defineProperty(GanttComponent.prototype, "renderedTreeListItems", {
3302
+ Object.defineProperty(GanttComponent.prototype, "dragScrollSettings", {
3303
+ get: function () {
3304
+ return this._dragScrollSettings;
3305
+ },
3306
+ /**
3307
+ * Specifies the settings for auto-scrolling during dragging
3308
+ * when the pointer moves outside of the container bounderies
3309
+ * [see example]({% slug editing_drag_create_dependencies_gantt %}#toc-auto-scrolling).
3310
+ */
3311
+ set: function (settings) {
3312
+ this._dragScrollSettings = __assign({}, DEFAULT_DRAG_SCROLL_SETTINGS, settings);
3313
+ },
3314
+ enumerable: true,
3315
+ configurable: true
3316
+ });
3317
+ Object.defineProperty(GanttComponent.prototype, "renderedTreeListItems", {
3318
+ /**
3319
+ * @hidden
3320
+ */
3321
+ get: function () {
3322
+ if (!isPresent(this.treeList)) {
3323
+ return [];
3324
+ }
3325
+ return this.treeList.view.data.map(function (item) { return item.data; });
3326
+ },
3327
+ enumerable: true,
3328
+ configurable: true
3329
+ });
3330
+ Object.defineProperty(GanttComponent.prototype, "viewItems", {
2261
3331
  /**
2262
3332
  * @hidden
2263
3333
  */
@@ -2265,7 +3335,7 @@ var GanttComponent = /** @class */ (function () {
2265
3335
  if (!isPresent(this.treeList)) {
2266
3336
  return [];
2267
3337
  }
2268
- return this.treeList.view.data.map(function (item) { return item.data; });
3338
+ return this.treeList.view.data;
2269
3339
  },
2270
3340
  enumerable: true,
2271
3341
  configurable: true
@@ -2333,12 +3403,12 @@ var GanttComponent = /** @class */ (function () {
2333
3403
  enumerable: true,
2334
3404
  configurable: true
2335
3405
  });
2336
- Object.defineProperty(GanttComponent.prototype, "editDialogFormGroup", {
3406
+ Object.defineProperty(GanttComponent.prototype, "isInEditMode", {
2337
3407
  /**
2338
3408
  * @hidden
2339
3409
  */
2340
3410
  get: function () {
2341
- return this.editService.formGroup;
3411
+ return this.showEditingDialog || this.showConfirmationDialog || this.treeList.isEditing();
2342
3412
  },
2343
3413
  enumerable: true,
2344
3414
  configurable: true
@@ -2350,6 +3420,14 @@ var GanttComponent = /** @class */ (function () {
2350
3420
  };
2351
3421
  GanttComponent.prototype.ngAfterViewInit = function () {
2352
3422
  this.updateTreeListMargin();
3423
+ if (this.navigable) {
3424
+ this.navigationService.initialize({
3425
+ gantt: this,
3426
+ host: this.hostElement.nativeElement,
3427
+ treeListElement: this.treeList.wrapper.nativeElement,
3428
+ timelineElement: this.timeline.timelineContent.nativeElement
3429
+ });
3430
+ }
2353
3431
  var leftContainer = this.treeList.wrapper.nativeElement.querySelector('kendo-treelist-list > div');
2354
3432
  this.scrollSyncService.registerElement(leftContainer, 'treelist');
2355
3433
  };
@@ -2367,6 +3445,34 @@ var GanttComponent = /** @class */ (function () {
2367
3445
  this.localizationSubscription.unsubscribe();
2368
3446
  }
2369
3447
  };
3448
+ /**
3449
+ * Focuses the last active cell or task in the Gantt.
3450
+ * If no item has previously been focused, the first cell of the TreeList part will receive focus,
3451
+ * ([see example]({% slug keyboard_navigation_gantt %}#toc-controlling-the-focus)).
3452
+ */
3453
+ GanttComponent.prototype.focus = function () {
3454
+ if (this.navigable) {
3455
+ this.navigationService.focusLastActiveItem();
3456
+ }
3457
+ };
3458
+ /**
3459
+ * Focuses the targeted cell in the TreeList part of the component,
3460
+ * ([see example]({% slug keyboard_navigation_gantt %}#toc-controlling-the-focus)).
3461
+ */
3462
+ GanttComponent.prototype.focusCell = function (rowIndex, colIndex) {
3463
+ if (this.navigable) {
3464
+ this.navigationService.focusCell(rowIndex, colIndex);
3465
+ }
3466
+ };
3467
+ /**
3468
+ * Focuses the targeted task in the Timeline part of the component,
3469
+ * ([see example]({% slug keyboard_navigation_gantt %}#toc-controlling-the-focus)).
3470
+ */
3471
+ GanttComponent.prototype.focusTask = function (taskIndex) {
3472
+ if (this.navigable) {
3473
+ this.navigationService.focusTask(taskIndex);
3474
+ }
3475
+ };
2370
3476
  /**
2371
3477
  * Applies the minimum possible width for the specified column,
2372
3478
  * so that the whole text fits without wrapping. This method expects the Gantt
@@ -2432,8 +3538,14 @@ var GanttComponent = /** @class */ (function () {
2432
3538
  * Opens the task editing dialog.
2433
3539
  */
2434
3540
  GanttComponent.prototype.editTask = function (dataItem, formGroup) {
3541
+ var _this = this;
2435
3542
  if (!this.showEditingDialog) {
2436
- this.editService.createEditDialog(dataItem, formGroup);
3543
+ var taskId_1 = this.mapper.extractFromTask(dataItem, 'id');
3544
+ var dependencies = this.dependencies.filter(function (item) {
3545
+ return _this.mapper.extractFromDependency(item, 'toId') === taskId_1
3546
+ || _this.mapper.extractFromDependency(item, 'fromId') === taskId_1;
3547
+ });
3548
+ this.editService.createEditDialog(dataItem, formGroup, dependencies);
2437
3549
  }
2438
3550
  };
2439
3551
  /**
@@ -2450,6 +3562,15 @@ var GanttComponent = /** @class */ (function () {
2450
3562
  GanttComponent.prototype.openConfirmationDialog = function () {
2451
3563
  this.showConfirmationDialog = true;
2452
3564
  };
3565
+ /**
3566
+ * @hidden
3567
+ */
3568
+ GanttComponent.prototype.handleConfirmationDialogClose = function () {
3569
+ this.showConfirmationDialog = false;
3570
+ if (this.navigable) {
3571
+ this.focus();
3572
+ }
3573
+ };
2453
3574
  /**
2454
3575
  * Opens a cell for editing.
2455
3576
  */
@@ -2535,7 +3656,7 @@ var GanttComponent = /** @class */ (function () {
2535
3656
  if (hasObservers(this.taskClick)) {
2536
3657
  var taskIndex_1 = getClosestTaskIndex(target, gantt);
2537
3658
  var task_1 = this.renderedTreeListItems[taskIndex_1];
2538
- this.zone.run(function () { return _this.emitTaskClick(event, task_1, taskIndex_1); });
3659
+ this.zone.run(function () { return _this.notifyTaskClick(event, task_1, taskIndex_1); });
2539
3660
  }
2540
3661
  };
2541
3662
  /**
@@ -2554,8 +3675,8 @@ var GanttComponent = /** @class */ (function () {
2554
3675
  if ((hasObservers(this.selectionChange) && !this.isSameSelection(selectionAction, task)) ||
2555
3676
  hasObservers(this.taskClick)) {
2556
3677
  this.zone.run(function () {
2557
- _this.emitSelectionChange(task, selectionAction);
2558
- _this.emitTaskClick(event, task, taskIndex);
3678
+ _this.notifySelectionChange(task, selectionAction);
3679
+ _this.notifyTaskClick(event, task, taskIndex);
2559
3680
  });
2560
3681
  }
2561
3682
  };
@@ -2593,7 +3714,7 @@ var GanttComponent = /** @class */ (function () {
2593
3714
  }
2594
3715
  var task = event.items.map(function (item) { return item.dataItem; })[0]; // single selection only currently available
2595
3716
  var action = event.action;
2596
- this.emitSelectionChange(task, action);
3717
+ this.notifySelectionChange(task, action);
2597
3718
  };
2598
3719
  /**
2599
3720
  * @hidden
@@ -2645,7 +3766,7 @@ var GanttComponent = /** @class */ (function () {
2645
3766
  dataItem: task_2,
2646
3767
  originalEvent: event,
2647
3768
  sender: _this,
2648
- rowIndex: taskIndex_2,
3769
+ index: taskIndex_2,
2649
3770
  type: 'dblclick'
2650
3771
  }); });
2651
3772
  }
@@ -2656,16 +3777,35 @@ var GanttComponent = /** @class */ (function () {
2656
3777
  GanttComponent.prototype.getText = function (token) {
2657
3778
  return this.localizationService.get(token);
2658
3779
  };
2659
- GanttComponent.prototype.emitTaskClick = function (event, dataItem, itemIndex) {
3780
+ /**
3781
+ * @hidden
3782
+ */
3783
+ GanttComponent.prototype.changeActiveView = function (view) {
3784
+ if (view !== this.activeView) {
3785
+ this.activeView = view;
3786
+ this.loadTimelineData();
3787
+ this.scrollSyncService.resetTimelineScrollLeft();
3788
+ this.activeViewChange.emit(view);
3789
+ }
3790
+ };
3791
+ /**
3792
+ * @hidden
3793
+ */
3794
+ GanttComponent.prototype.notifyTaskClick = function (event, dataItem, itemIndex) {
3795
+ // simulates the TreeList `cellClick` event triggered by enter press (type: 'click')
3796
+ var type = event instanceof KeyboardEvent ? 'click' : event.type;
2660
3797
  this.taskClick.emit({
2661
3798
  originalEvent: event,
2662
3799
  dataItem: dataItem,
2663
- rowIndex: itemIndex,
2664
- type: event.type,
3800
+ index: itemIndex,
3801
+ type: type,
2665
3802
  sender: this
2666
3803
  });
2667
3804
  };
2668
- GanttComponent.prototype.emitSelectionChange = function (dataItem, action) {
3805
+ /**
3806
+ * @hidden
3807
+ */
3808
+ GanttComponent.prototype.notifySelectionChange = function (dataItem, action) {
2669
3809
  if (this.isSameSelection(action, dataItem)) {
2670
3810
  return;
2671
3811
  }
@@ -2676,6 +3816,30 @@ var GanttComponent = /** @class */ (function () {
2676
3816
  });
2677
3817
  this.treeList.updateView();
2678
3818
  };
3819
+ /**
3820
+ * @hidden
3821
+ */
3822
+ GanttComponent.prototype.notifyTaskDelete = function (task) {
3823
+ this.editService.dataItem = task;
3824
+ this.taskDelete.emit({
3825
+ item: getEditItem(task, this.treeList.view.data, this.mapper),
3826
+ sender: this
3827
+ });
3828
+ };
3829
+ /**
3830
+ * @hidden
3831
+ */
3832
+ GanttComponent.prototype.isSameSelection = function (action, dataItem) {
3833
+ return action === 'select' && this.isSelected(dataItem);
3834
+ };
3835
+ /**
3836
+ * @hidden
3837
+ */
3838
+ GanttComponent.prototype.getSelectionAction = function (_a, dataItem) {
3839
+ var ctrlKey = _a.ctrlKey, metaKey = _a.metaKey;
3840
+ var shouldToggleSelection = ctrlKey || metaKey;
3841
+ return (shouldToggleSelection && this.isSelected(dataItem)) ? 'remove' : 'select';
3842
+ };
2679
3843
  GanttComponent.prototype.updateTreeListGroupClass = function (columns) {
2680
3844
  if (columns === void 0) { columns = this.columns; }
2681
3845
  if (!isPresent(this.treeList)) {
@@ -2706,24 +3870,70 @@ var GanttComponent = /** @class */ (function () {
2706
3870
  }
2707
3871
  return this.views.find(function (view) { return view.type === _this.activeView; });
2708
3872
  };
2709
- GanttComponent.prototype.isSameSelection = function (action, dataItem) {
2710
- return action === 'select' && this.isSelected(dataItem);
2711
- };
2712
- GanttComponent.prototype.getSelectionAction = function (_a, dataItem) {
2713
- var ctrlKey = _a.ctrlKey, metaKey = _a.metaKey;
2714
- var shouldToggleSelection = ctrlKey || metaKey;
2715
- return (shouldToggleSelection && this.isSelected(dataItem)) ? 'remove' : 'select';
2716
- };
2717
3873
  GanttComponent.prototype.getFirstSelectedItem = function () {
2718
3874
  var isSelectedCallback = this.isSelected || isSelected;
2719
3875
  var loadedItems = this.renderedTreeListItems || [];
2720
3876
  return loadedItems.find(isSelectedCallback);
2721
3877
  };
3878
+ GanttComponent.prototype.defaultValidateNewDependencyCallback = function (dependency) {
3879
+ var _this = this;
3880
+ var fromTaskId = this.mapper.extractFromDependency(dependency, 'fromId');
3881
+ var toTaskId = this.mapper.extractFromDependency(dependency, 'toId');
3882
+ var fromTask = this.treeList.view.data.find(function (task) {
3883
+ return _this.mapper.extractFromTask(task.data, 'id') === fromTaskId;
3884
+ });
3885
+ var toTask = this.treeList.view.data.find(function (task) {
3886
+ return _this.mapper.extractFromTask(task.data, 'id') === toTaskId;
3887
+ });
3888
+ // mark as invalid if the attempted dependency is lacking valid from- and to-tasks
3889
+ // or when the from- and to-tasks are actually the same task
3890
+ if (!isPresent(fromTask) || !isPresent(fromTask.data) ||
3891
+ !isPresent(toTask) || !isPresent(toTask.data) ||
3892
+ fromTask.data === toTask.data) {
3893
+ return false;
3894
+ }
3895
+ var tasksDependentOnOneAnother = this.dependencies.some(function (current) {
3896
+ var currentFromId = _this.mapper.extractFromDependency(current, 'fromId');
3897
+ var currentToId = _this.mapper.extractFromDependency(current, 'toId');
3898
+ return (fromTaskId === currentFromId && toTaskId === currentToId) ||
3899
+ (toTaskId === currentFromId && fromTaskId === currentToId);
3900
+ });
3901
+ // mark as invalid if the attempted dependency is trying to connect already dependent tasks
3902
+ // mark as invalid if the two tasks are in parent-child relationship
3903
+ if (tasksDependentOnOneAnother || areParentChild(fromTask, toTask)) {
3904
+ return false;
3905
+ }
3906
+ var fromTaskStart = this.mapper.extractFromTask(fromTask.data, 'start');
3907
+ var fromTaskEnd = this.mapper.extractFromTask(fromTask.data, 'end');
3908
+ var toTaskStart = this.mapper.extractFromTask(toTask.data, 'start');
3909
+ var toTaskEnd = this.mapper.extractFromTask(toTask.data, 'end');
3910
+ // if the two tasks are available to be connected via a dependency,
3911
+ // check if their start and end time allow for the attempted dependency type
3912
+ switch (this.mapper.extractFromDependency(dependency, 'type')) {
3913
+ // finish to finish (FF) — the from-task ends before the to-task can end
3914
+ case DependencyType.FF:
3915
+ return fromTaskEnd <= toTaskEnd;
3916
+ // finish to start (FS) — the from-task ends before the to-task can begin
3917
+ case DependencyType.FS:
3918
+ return fromTaskEnd <= toTaskStart;
3919
+ // start to finish (SF) — the from-task begins before the to-task can end
3920
+ case DependencyType.SF:
3921
+ return fromTaskStart <= toTaskEnd;
3922
+ // start to start (SS) — the from-task begins before the to-task can begin
3923
+ case DependencyType.SS:
3924
+ return fromTaskStart <= toTaskStart;
3925
+ default: return false;
3926
+ }
3927
+ };
2722
3928
  var GanttComponent_1;
2723
3929
  __decorate([
2724
3930
  ViewChild(TreeListComponent, { static: true }),
2725
3931
  __metadata("design:type", TreeListComponent)
2726
3932
  ], GanttComponent.prototype, "treeList", void 0);
3933
+ __decorate([
3934
+ ViewChild(GanttTimelineComponent, { static: false }),
3935
+ __metadata("design:type", GanttTimelineComponent)
3936
+ ], GanttComponent.prototype, "timeline", void 0);
2727
3937
  __decorate([
2728
3938
  ContentChild(GanttTaskContentTemplateDirective, { static: true }),
2729
3939
  __metadata("design:type", GanttTaskContentTemplateDirective)
@@ -2740,6 +3950,24 @@ var GanttComponent = /** @class */ (function () {
2740
3950
  ContentChildren(ToolbarTemplateDirective),
2741
3951
  __metadata("design:type", QueryList)
2742
3952
  ], GanttComponent.prototype, "toolbarTemplateChildren", void 0);
3953
+ __decorate([
3954
+ Input('aria-roledescription'),
3955
+ __metadata("design:type", String)
3956
+ ], GanttComponent.prototype, "roleDescription", void 0);
3957
+ __decorate([
3958
+ HostBinding('attr.aria-roledescription'),
3959
+ __metadata("design:type", String),
3960
+ __metadata("design:paramtypes", [])
3961
+ ], GanttComponent.prototype, "hostRoleDescriptionAttr", null);
3962
+ __decorate([
3963
+ Input('role'),
3964
+ __metadata("design:type", String)
3965
+ ], GanttComponent.prototype, "role", void 0);
3966
+ __decorate([
3967
+ HostBinding('attr.role'),
3968
+ __metadata("design:type", String),
3969
+ __metadata("design:paramtypes", [])
3970
+ ], GanttComponent.prototype, "hostRoleAttr", null);
2743
3971
  __decorate([
2744
3972
  HostBinding('class.k-gantt'),
2745
3973
  __metadata("design:type", Boolean)
@@ -2782,6 +4010,10 @@ var GanttComponent = /** @class */ (function () {
2782
4010
  Input(),
2783
4011
  __metadata("design:type", Function)
2784
4012
  ], GanttComponent.prototype, "isSelected", void 0);
4013
+ __decorate([
4014
+ Input(),
4015
+ __metadata("design:type", Function)
4016
+ ], GanttComponent.prototype, "validateNewDependency", void 0);
2785
4017
  __decorate([
2786
4018
  Output(),
2787
4019
  __metadata("design:type", EventEmitter)
@@ -2797,12 +4029,14 @@ var GanttComponent = /** @class */ (function () {
2797
4029
  ], GanttComponent.prototype, "toolbarSettings", null);
2798
4030
  __decorate([
2799
4031
  Input(),
2800
- __metadata("design:type", Function)
2801
- ], GanttComponent.prototype, "fetchChildren", void 0);
4032
+ __metadata("design:type", Function),
4033
+ __metadata("design:paramtypes", [Function])
4034
+ ], GanttComponent.prototype, "fetchChildren", null);
2802
4035
  __decorate([
2803
4036
  Input(),
2804
- __metadata("design:type", Function)
2805
- ], GanttComponent.prototype, "hasChildren", void 0);
4037
+ __metadata("design:type", Function),
4038
+ __metadata("design:paramtypes", [Function])
4039
+ ], GanttComponent.prototype, "hasChildren", null);
2806
4040
  __decorate([
2807
4041
  Input(),
2808
4042
  __metadata("design:type", Array)
@@ -2839,6 +4073,10 @@ var GanttComponent = /** @class */ (function () {
2839
4073
  Input(),
2840
4074
  __metadata("design:type", Number)
2841
4075
  ], GanttComponent.prototype, "workWeekEnd", void 0);
4076
+ __decorate([
4077
+ Input(),
4078
+ __metadata("design:type", Boolean)
4079
+ ], GanttComponent.prototype, "navigable", void 0);
2842
4080
  __decorate([
2843
4081
  Input(),
2844
4082
  __metadata("design:type", Object),
@@ -2879,6 +4117,11 @@ var GanttComponent = /** @class */ (function () {
2879
4117
  Input(),
2880
4118
  __metadata("design:type", Boolean)
2881
4119
  ], GanttComponent.prototype, "columnsResizable", void 0);
4120
+ __decorate([
4121
+ Input(),
4122
+ __metadata("design:type", Object),
4123
+ __metadata("design:paramtypes", [Object])
4124
+ ], GanttComponent.prototype, "dragScrollSettings", null);
2882
4125
  __decorate([
2883
4126
  Output(),
2884
4127
  __metadata("design:type", EventEmitter)
@@ -2919,6 +4162,10 @@ var GanttComponent = /** @class */ (function () {
2919
4162
  Output(),
2920
4163
  __metadata("design:type", EventEmitter)
2921
4164
  ], GanttComponent.prototype, "taskAdd", void 0);
4165
+ __decorate([
4166
+ Output(),
4167
+ __metadata("design:type", EventEmitter)
4168
+ ], GanttComponent.prototype, "dependencyAdd", void 0);
2922
4169
  __decorate([
2923
4170
  Output(),
2924
4171
  __metadata("design:type", EventEmitter)
@@ -2976,6 +4223,7 @@ var GanttComponent = /** @class */ (function () {
2976
4223
  selector: 'kendo-gantt',
2977
4224
  exportAs: 'kendoGantt',
2978
4225
  providers: [
4226
+ GanttLocalizationService,
2979
4227
  LocalizationService,
2980
4228
  {
2981
4229
  provide: DataBoundTreeComponent,
@@ -2993,9 +4241,11 @@ var GanttComponent = /** @class */ (function () {
2993
4241
  DependencyDomService,
2994
4242
  MappingService,
2995
4243
  OptionChangesService,
2996
- EditService
4244
+ EditService,
4245
+ TimelineScrollService,
4246
+ NavigationService
2997
4247
  ],
2998
- template: "\n <ng-container kendoGanttLocalizedMessages\n i18n-taskEditingGeneralTabTitle=\"kendo.gantt.taskEditingGeneralTabTitle|The title of the 'General' tab of the editing dialog TabStrip\"\n taskEditingGeneralTabTitle=\"General\"\n\n i18n-taskEditingPredecessorsTabTitle=\"kendo.gantt.taskEditingPredecessorsTabTitle|The title of the 'Predecessors' dependencies tab of the editing dialog TabStrip\"\n taskEditingPredecessorsTabTitle=\"Predecessors\"\n\n i18n-taskEditingSuccessorsTabTitle=\"kendo.gantt.taskEditingSuccessorsTabTitle|The title of the 'Successors' dependencies tab of the editing dialog TabStrip\"\n taskEditingSuccessorsTabTitle=\"Successors\"\n\n i18n-taskEditingDependenciesAddButtonText=\"kendo.gantt.taskEditingDependenciesAddButtonText|The text of the 'Add' button in the dependencies tabs of the editing dialog TabStrip\"\n taskEditingDependenciesAddButtonText=\"Add\"\n\n i18n-taskEditingDependenciesRemoveButtonText=\"kendo.gantt.taskEditingDependenciesRemoveButtonText|The text of the 'Remove' button in the dependencies tabs of the editing dialog TabStrip\"\n taskEditingDependenciesRemoveButtonText=\"Remove\"\n\n i18n-taskEditingDependenciesGridNameColumnTitle=\"kendo.gantt.taskEditingDependenciesGridNameColumnTitle|The title of the 'Task Title' Grid column in the dependencies tabs of the editing dialog TabStrip\"\n taskEditingDependenciesGridNameColumnTitle=\"Task Title\"\n\n i18n-taskEditingDependenciesGridTypeColumnTitle=\"kendo.gantt.taskEditingDependenciesGridTypeColumnTitle|The title of the 'Type' Grid column in the dependencies tabs of the editing dialog TabStrip\"\n taskEditingDependenciesGridTypeColumnTitle=\"Type\"\n\n i18n-taskDeleteLabel=\"kendo.gantt.taskDeleteLabel|The label of the task delete icon\"\n taskDeleteLabel=\"Delete\"\n\n i18n-taskEditingDialogTitle=\"kendo.gantt.taskEditingDialogTitle|The title of the task editing dialog\"\n taskEditingDialogTitle=\"Editing Task\"\n\n i18n-taskEditingDialogCloseTitle=\"kendo.gantt.taskEditingDialogCloseTitle|The title of the task editing dialog close button\"\n taskEditingDialogCloseTitle=\"Close\"\n\n i18n-confirmationDialogCloseTitle=\"kendo.gantt.confirmationDialogCloseTitle|The title of the confirmation dialog close button\"\n confirmationDialogCloseTitle=\"Close\"\n\n i18n-confirmationDialogTitle=\"kendo.gantt.confirmationDialogTitle|The title of the delete task confirmation dialog\"\n confirmationDialogTitle=\"Delete Task\"\n\n i18n-confirmationDialogContent=\"kendo.gantt.confirmationDialogContent|The content of the delete task confirmation dialog\"\n confirmationDialogContent=\"Are you sure you want to delete this task?\"\n\n i18n-deleteButtonText=\"kendo.gantt.deleteButtonText|The text of the task editing dialog 'Delete' button\"\n deleteButtonText=\"Delete\"\n\n i18n-cancelButtonText=\"kendo.gantt.cancelButtonText|The text of the task editing dialog 'Cancel' button\"\n cancelButtonText=\"Cancel\"\n\n i18n-saveButtonText=\"kendo.gantt.saveButtonText|The text of the task editing dialog 'Save' button\"\n saveButtonText=\"Save\"\n\n i18n-titleFieldInputLabel=\"kendo.gantt.titleFieldInputLabel|The label of the 'title' field input in editing mode\"\n titleFieldInputLabel=\"Title\"\n\n i18n-startFieldInputLabel=\"kendo.gantt.startFieldInputLabel|The label of the 'start' field input in editing mode\"\n startFieldInputLabel=\"Start\"\n\n i18n-endFieldInputLabel=\"kendo.gantt.endFieldInputLabel|The label of the 'end' field input in editing mode\"\n endFieldInputLabel=\"End\"\n\n i18n-completionRatioFieldInputLabel=\"kendo.gantt.completionRatioFieldInputLabel|The label of the 'completionRatio' field input in editing mode\"\n completionRatioFieldInputLabel=\"Progress\"\n\n i18n-dayViewText=\"kendo.gantt.dayViewText|The text of the day view in the ViewSelector component\"\n dayViewText=\"Day\"\n\n i18n-weekViewText=\"kendo.gantt.weekViewText|The text of the week view in the ViewSelector component\"\n weekViewText=\"Week\"\n\n i18n-monthViewText=\"kendo.gantt.monthViewText|The text of the month view in the ViewSelector component\"\n monthViewText=\"Month\"\n\n i18n-yearViewText-disabled=\"kendo.gantt.yearViewText|The text of the year view in the ViewSelector component\"\n yearViewText=\"Year\"\n\n i18n-addTaskText=\"kendo.gantt.addTaskText|The text of the DropDownButton in the AddTask component\"\n addTaskText=\"Add Task\"\n\n i18n-addChildText=\"kendo.gantt.addChildText|The text of the 'Add Child' option in the AddTask component\"\n addChildText=\"Add Child\"\n\n i18n-addAboveText=\"kendo.gantt.addAboveText|The text of the 'Add Above' option in the AddTask component\"\n addAboveText=\"Add Above\"\n\n i18n-addBelowText=\"kendo.gantt.addBelowText|The text of the 'Add Below' option in the AddTask component\"\n addBelowText=\"Add Below\"\n\n i18n-noRecords=\"kendo.gantt.noRecords|The label visible in the TreeList when there are no records\"\n noRecords=\"No records available.\"\n\n i18n-filter=\"kendo.gantt.filter|The label of the filter cell or icon\"\n filter=\"Filter\"\n\n i18n-filterEqOperator=\"kendo.gantt.filterEqOperator|The text of the equal filter operator\"\n filterEqOperator=\"Is equal to\"\n\n i18n-filterNotEqOperator=\"kendo.gantt.filterNotEqOperator|The text of the not equal filter operator\"\n filterNotEqOperator=\"Is not equal to\"\n\n i18n-filterIsNullOperator=\"kendo.gantt.filterIsNullOperator|The text of the is null filter operator\"\n filterIsNullOperator=\"Is null\"\n\n i18n-filterIsNotNullOperator=\"kendo.gantt.filterIsNotNullOperator|The text of the is not null filter operator\"\n filterIsNotNullOperator=\"Is not null\"\n\n i18n-filterIsEmptyOperator=\"kendo.gantt.filterIsEmptyOperator|The text of the is empty filter operator\"\n filterIsEmptyOperator=\"Is empty\"\n\n i18n-filterIsNotEmptyOperator=\"kendo.gantt.filterIsNotEmptyOperator|The text of the is not empty filter operator\"\n filterIsNotEmptyOperator=\"Is not empty\"\n\n i18n-filterStartsWithOperator=\"kendo.gantt.filterStartsWithOperator|The text of the starts with filter operator\"\n filterStartsWithOperator=\"Starts with\"\n\n i18n-filterContainsOperator=\"kendo.gantt.filterContainsOperator|The text of the contains filter operator\"\n filterContainsOperator=\"Contains\"\n\n i18n-filterNotContainsOperator=\"kendo.gantt.filterNotContainsOperator|The text of the does not contain filter operator\"\n filterNotContainsOperator=\"Does not contain\"\n\n i18n-filterEndsWithOperator=\"kendo.gantt.filterEndsWithOperator|The text of the ends with filter operator\"\n filterEndsWithOperator=\"Ends with\"\n\n i18n-filterGteOperator=\"kendo.gantt.filterGteOperator|The text of the greater than or equal filter operator\"\n filterGteOperator=\"Is greater than or equal to\"\n\n i18n-filterGtOperator=\"kendo.gantt.filterGtOperator|The text of the greater than filter operator\"\n filterGtOperator=\"Is greater than\"\n\n i18n-filterLteOperator=\"kendo.gantt.filterLteOperator|The text of the less than or equal filter operator\"\n filterLteOperator=\"Is less than or equal to\"\n\n i18n-filterLtOperator=\"kendo.gantt.filterLtOperator|The text of the less than filter operator\"\n filterLtOperator=\"Is less than\"\n\n i18n-filterIsTrue=\"kendo.gantt.filterIsTrue|The text of the IsTrue boolean filter option\"\n filterIsTrue=\"Is True\"\n\n i18n-filterIsFalse=\"kendo.gantt.filterIsFalse|The text of the IsFalse boolean filter option\"\n filterIsFalse=\"Is False\"\n\n i18n-filterBooleanAll=\"kendo.gantt.filterBooleanAll|The text of the (All) boolean filter option\"\n filterBooleanAll=\"(All)\"\n\n i18n-filterAfterOrEqualOperator=\"kendo.gantt.filterAfterOrEqualOperator|The text of the after or equal date filter operator\"\n filterAfterOrEqualOperator=\"Is after or equal to\"\n\n i18n-filterAfterOperator=\"kendo.gantt.filterAfterOperator|The text of the after date filter operator\"\n filterAfterOperator=\"Is after\"\n\n i18n-filterBeforeOperator=\"kendo.gantt.filterBeforeOperator|The text of the before date filter operator\"\n filterBeforeOperator=\"Is before\"\n\n i18n-filterBeforeOrEqualOperator=\"kendo.gantt.filterBeforeOrEqualOperator|The text of the before or equal date filter operator\"\n filterBeforeOrEqualOperator=\"Is before or equal to\"\n\n i18n-filterFilterButton=\"kendo.gantt.filterFilterButton|The text of the filter button\"\n filterFilterButton=\"Filter\"\n\n i18n-filterClearButton=\"kendo.gantt.filterClearButton|The text of the clear filter button\"\n filterClearButton=\"Clear\"\n\n i18n-filterAndLogic=\"kendo.gantt.filterAndLogic|The text of the And filter logic\"\n filterAndLogic=\"And\"\n\n i18n-filterOrLogic=\"kendo.gantt.filterOrLogic|The text of the Or filter logic\"\n filterOrLogic=\"Or\"\n\n i18n-loading=\"kendo.gantt.loading|The loading text\"\n loading=\"Loading\"\n\n i18n-columnMenu=\"kendo.gantt.columnMenu|The title of the column menu icon\"\n columnMenu=\"Column Menu\"\n\n i18n-columns=\"kendo.gantt.columns|The text shown in the column menu for the columns item\"\n columns=\"Columns\"\n\n i18n-lock-disabled=\"kendo.gantt.lock|The text shown in the column menu for the lock item\"\n lock-disabled=\"Lock\"\n\n i18n-unlock-disabled=\"kendo.gantt.unlock|The text shown in the column menu for the unlock item\"\n unlock-disabled=\"Unlock\"\n\n i18n-sortable=\"kendo.gantt.sortable|The label of the sort icon\"\n sortable=\"Sortable\"\n\n i18n-sortAscending=\"kendo.gantt.sortAscending|The text shown in the column menu for the sort ascending item\"\n sortAscending=\"Sort Ascending\"\n\n i18n-sortDescending=\"kendo.gantt.sortDescending|The text shown in the column menu for the sort descending item\"\n sortDescending=\"Sort Descending\"\n\n i18n-sortedAscending=\"kendo.gantt.sortedAscending|The status announcement when a column is sorted ascending\"\n sortedAscending=\"Sorted Ascending\"\n\n i18n-sortedDescending=\"kendo.gantt.sortedDescending|The status announcement when a column is sorted descending\"\n sortedDescending=\"Sorted Descending\"\n\n i18n-sortedDefault=\"kendo.gantt.sortedDefault|The status announcement when a column is no longer sorted\"\n sortedDefault=\"Not Sorted\"\n\n i18n-columnsApply=\"kendo.gantt.columnsApply|The text shown in the column menu or column chooser for the columns apply button\"\n columnsApply=\"Apply\"\n\n i18n-columnsReset=\"kendo.gantt.columnsReset|The text shown in the column menu or column chooser for the columns reset button\"\n columnsReset=\"Reset\"></ng-container>\n <kendo-gantt-toolbar\n *ngIf=\"showToolbar('top')\"\n [showAddTask]=\"toolbarSettings.addTaskTool === 'top' || toolbarSettings.addTaskTool === 'both'\"\n [showViewSelector]=\"toolbarSettings.viewSelectorTool === 'top' || toolbarSettings.viewSelectorTool === 'both'\"\n class=\"k-gantt-header k-toolbar k-gantt-toolbar\"\n position=\"top\"></kendo-gantt-toolbar>\n <div class=\"k-gantt-content\">\n <kendo-splitter [style.border]=\"0\">\n <kendo-splitter-pane\n class=\"k-gantt-treelist k-gantt-treelist-scrollable\"\n [collapsible]=\"treeListPaneOptions?.collapsible\"\n [collapsed]=\"treeListPaneOptions?.collapsed\"\n (collapsedChange)=\"onTreeListCollapsedChange($event)\"\n [scrollable]=\"false\">\n <kendo-treelist\n [idField]=\"taskIdField\"\n [columns]=\"columns\"\n [data]=\"data\"\n [hasChildren]=\"hasChildren\"\n [fetchChildren]=\"fetchChildren\"\n [isExpanded]=\"isExpanded\"\n [autoSize]=\"columnsAutoSize\"\n [columnMenu]=\"columnMenu\"\n [reorderable]=\"columnsReorderable\"\n [resizable]=\"columnsResizable\"\n [rowClass]=\"rowClass\"\n [isSelected]=\"isSelected\"\n [selectable]=\"selectable\"\n [sortable]=\"sortable\"\n [sort]=\"sort\"\n [filterable]=\"filterMenu\"\n [filter]=\"filter\"\n (filterChange)=\"filterChange.emit($event)\"\n (sortChange)=\"sortChange.emit($event)\"\n (dataStateChange)=\"dataStateChange.emit({\n filter: $event.filter,\n sort: $event.sort\n })\"\n (expandStateChange)=\"expandStateChange.emit($event)\"\n (expand)=\"rowExpand.emit({ dataItem: $event.dataItem })\"\n (collapse)=\"rowCollapse.emit({ dataItem: $event.dataItem })\"\n (columnReorder)=\"columnReorder.emit($event)\"\n (columnResize)=\"columnResize.emit($event)\"\n (columnVisibilityChange)=\"handleColumnVisibilityChange($event)\"\n (columnLockedChange)=\"columnLockedChange.emit($event)\"\n (selectionChange)=\"handleTreeListSelectionChange($event)\"\n (cellClick)=\"handleTreeListCellClick($event)\"\n (cellClose)=\"handleCellClose($event)\"\n [kendoEventsOutsideAngular]=\"{\n dblclick: handleTreeListDoubleClick\n }\"\n [scope]=\"this\"\n >\n <kendo-treelist-messages\n [noRecords]=\"getText('noRecords')\"\n [filter]=\"getText('filter')\"\n [filterEqOperator]=\"getText('filterEqOperator')\"\n [filterNotEqOperator]=\"getText('filterNotEqOperator')\"\n [filterIsNullOperator]=\"getText('filterIsNullOperator')\"\n [filterIsNotNullOperator]=\"getText('filterIsNotNullOperator')\"\n [filterIsEmptyOperator]=\"getText('filterIsEmptyOperator')\"\n [filterIsNotEmptyOperator]=\"getText('filterIsNotEmptyOperator')\"\n [filterStartsWithOperator]=\"getText('filterStartsWithOperator')\"\n [filterContainsOperator]=\"getText('filterContainsOperator')\"\n [filterNotContainsOperator]=\"getText('filterNotContainsOperator')\"\n [filterEndsWithOperator]=\"getText('filterEndsWithOperator')\"\n [filterGteOperator]=\"getText('filterGteOperator')\"\n [filterGtOperator]=\"getText('filterGtOperator')\"\n [filterLteOperator]=\"getText('filterLteOperator')\"\n [filterLtOperator]=\"getText('filterLtOperator')\"\n [filterIsTrue]=\"getText('filterIsTrue')\"\n [filterIsFalse]=\"getText('filterIsFalse')\"\n [filterBooleanAll]=\"getText('filterBooleanAll')\"\n [filterAfterOrEqualOperator]=\"getText('filterAfterOrEqualOperator')\"\n [filterAfterOperator]=\"getText('filterAfterOperator')\"\n [filterBeforeOperator]=\"getText('filterBeforeOperator')\"\n [filterBeforeOrEqualOperator]=\"getText('filterBeforeOrEqualOperator')\"\n [filterFilterButton]=\"getText('filterFilterButton')\"\n [filterClearButton]=\"getText('filterClearButton')\"\n [filterAndLogic]=\"getText('filterAndLogic')\"\n [filterOrLogic]=\"getText('filterOrLogic')\"\n [loading]=\"getText('loading')\"\n [columnMenu]=\"getText('columnMenu')\"\n [columns]=\"getText('columns')\"\n [sortable]=\"getText('sortable')\"\n [sortAscending]=\"getText('sortAscending')\"\n [sortDescending]=\"getText('sortDescending')\"\n [sortedAscending]=\"getText('sortedAscending')\"\n [sortedDescending]=\"getText('sortedDescending')\"\n [sortedDefault]=\"getText('sortedDefault')\"\n [columnsApply]=\"getText('columnsApply')\"\n [columnsReset]=\"getText('columnsReset')\"\n >\n </kendo-treelist-messages>\n </kendo-treelist>\n </kendo-splitter-pane>\n <kendo-splitter-pane\n [collapsible]=\"timelinePaneOptions?.collapsible\"\n [resizable]=\"timelinePaneOptions?.resizable\"\n [collapsed]=\"timelinePaneOptions?.collapsed\"\n [min]=\"timelinePaneOptions?.min\"\n [max]=\"timelinePaneOptions?.max\"\n [size]=\"timelinePaneOptions?.size\"\n (collapsedChange)=\"onTimelineCollapsedChange($event)\"\n (sizeChange)=\"onTimelinePaneSizeChange($event)\"\n [scrollable]=\"false\">\n <kendo-gantt-timeline\n *ngIf=\"views && views.length\"\n [rows]=\"renderedTreeListItems\"\n [slots]=\"timelineSlots\"\n [groupSlots]=\"timelineGroupSlots\"\n [tableWidth]=\"tableWidth\"\n [activeView]=\"activeView\"\n [taskContentTemplate]=\"taskContentTemplate?.templateRef\"\n [taskTemplate]=\"taskTemplate?.templateRef\"\n [summaryTaskTemplate]=\"summaryTaskTemplate?.templateRef\"\n [taskClass]=\"taskClass\"\n [dependencies]=\"dependencies\"\n [hasChildren]=\"hasChildren\"\n [isTaskSelected]=\"isTaskSelected\"\n [kendoEventsOutsideAngular]=\"{\n click: handleTimelineClick,\n contextmenu: handleTimelineRightClick,\n dblclick: handleTimelineDblClick,\n mousedown: handleTimelineMouseDown\n }\"\n [scope]=\"this\"\n ></kendo-gantt-timeline>\n </kendo-splitter-pane>\n </kendo-splitter>\n </div>\n <kendo-gantt-toolbar\n *ngIf=\"showToolbar('bottom')\"\n [showAddTask]=\"toolbarSettings.addTaskTool === 'bottom' || toolbarSettings.addTaskTool === 'both'\"\n [showViewSelector]=\"toolbarSettings.viewSelectorTool === 'bottom' || toolbarSettings.viewSelectorTool === 'both'\"\n class=\"k-gantt-footer k-toolbar k-gantt-toolbar\"\n position=\"bottom\"></kendo-gantt-toolbar>\n <kendo-gantt-edit-dialog *ngIf=\"showEditingDialog\" [formGroup]=\"editDialogFormGroup\"></kendo-gantt-edit-dialog>\n <kendo-dialog\n *ngIf=\"showConfirmationDialog\"\n [width]=\"575\"\n [height]=\"170\"\n [title]=\"getText('confirmationDialogTitle')\"\n (close)=\"showConfirmationDialog = false;\">\n <span>{{getText('confirmationDialogContent')}}</span>\n <kendo-dialog-actions layout=\"normal\">\n <kendo-treelist-spacer></kendo-treelist-spacer>\n <button kendoButton [primary]=\"true\" (click)=\"handleDeleteConfirmation()\">{{ getText('deleteButtonText') }}</button>\n <button kendoButton (click)=\"showConfirmationDialog = false;\">{{ getText('cancelButtonText') }}</button>\n </kendo-dialog-actions>\n </kendo-dialog>\n "
4248
+ template: "\n <ng-container kendoGanttLocalizedMessages\n i18n-taskEditingGeneralTabTitle=\"kendo.gantt.taskEditingGeneralTabTitle|The title of the 'General' tab of the editing dialog TabStrip\"\n taskEditingGeneralTabTitle=\"General\"\n\n i18n-taskEditingPredecessorsTabTitle=\"kendo.gantt.taskEditingPredecessorsTabTitle|The title of the 'Predecessors' dependencies tab of the editing dialog TabStrip\"\n taskEditingPredecessorsTabTitle=\"Predecessors\"\n\n i18n-taskEditingSuccessorsTabTitle=\"kendo.gantt.taskEditingSuccessorsTabTitle|The title of the 'Successors' dependencies tab of the editing dialog TabStrip\"\n taskEditingSuccessorsTabTitle=\"Successors\"\n\n i18n-taskEditingDependenciesAddButtonText=\"kendo.gantt.taskEditingDependenciesAddButtonText|The text of the 'Add' button in the dependencies tabs of the editing dialog TabStrip\"\n taskEditingDependenciesAddButtonText=\"Add\"\n\n i18n-taskEditingDependenciesRemoveButtonText=\"kendo.gantt.taskEditingDependenciesRemoveButtonText|The text of the 'Remove' button in the dependencies tabs of the editing dialog TabStrip\"\n taskEditingDependenciesRemoveButtonText=\"Remove\"\n\n i18n-taskEditingDependenciesGridNameColumnTitle=\"kendo.gantt.taskEditingDependenciesGridNameColumnTitle|The title of the 'Task Title' Grid column in the dependencies tabs of the editing dialog TabStrip\"\n taskEditingDependenciesGridNameColumnTitle=\"Task Title\"\n\n i18n-taskEditingDependenciesGridTypeColumnTitle=\"kendo.gantt.taskEditingDependenciesGridTypeColumnTitle|The title of the 'Type' Grid column in the dependencies tabs of the editing dialog TabStrip\"\n taskEditingDependenciesGridTypeColumnTitle=\"Type\"\n\n i18n-taskDeleteLabel=\"kendo.gantt.taskDeleteLabel|The label of the task delete icon\"\n taskDeleteLabel=\"Delete\"\n\n i18n-taskEditingDialogTitle=\"kendo.gantt.taskEditingDialogTitle|The title of the task editing dialog\"\n taskEditingDialogTitle=\"Editing Task\"\n\n i18n-taskEditingDialogCloseTitle=\"kendo.gantt.taskEditingDialogCloseTitle|The title of the task editing dialog close button\"\n taskEditingDialogCloseTitle=\"Close\"\n\n i18n-confirmationDialogCloseTitle=\"kendo.gantt.confirmationDialogCloseTitle|The title of the confirmation dialog close button\"\n confirmationDialogCloseTitle=\"Close\"\n\n i18n-confirmationDialogTitle=\"kendo.gantt.confirmationDialogTitle|The title of the delete task confirmation dialog\"\n confirmationDialogTitle=\"Delete Task\"\n\n i18n-confirmationDialogContent=\"kendo.gantt.confirmationDialogContent|The content of the delete task confirmation dialog\"\n confirmationDialogContent=\"Are you sure you want to delete this task?\"\n\n i18n-deleteButtonText=\"kendo.gantt.deleteButtonText|The text of the task editing dialog 'Delete' button\"\n deleteButtonText=\"Delete\"\n\n i18n-cancelButtonText=\"kendo.gantt.cancelButtonText|The text of the task editing dialog 'Cancel' button\"\n cancelButtonText=\"Cancel\"\n\n i18n-saveButtonText=\"kendo.gantt.saveButtonText|The text of the task editing dialog 'Save' button\"\n saveButtonText=\"Save\"\n\n i18n-titleFieldInputLabel=\"kendo.gantt.titleFieldInputLabel|The label of the 'title' field input in editing mode\"\n titleFieldInputLabel=\"Title\"\n\n i18n-startFieldInputLabel=\"kendo.gantt.startFieldInputLabel|The label of the 'start' field input in editing mode\"\n startFieldInputLabel=\"Start\"\n\n i18n-endFieldInputLabel=\"kendo.gantt.endFieldInputLabel|The label of the 'end' field input in editing mode\"\n endFieldInputLabel=\"End\"\n\n i18n-completionRatioFieldInputLabel=\"kendo.gantt.completionRatioFieldInputLabel|The label of the 'completionRatio' field input in editing mode\"\n completionRatioFieldInputLabel=\"Progress\"\n\n i18n-dayViewText=\"kendo.gantt.dayViewText|The text of the day view in the ViewSelector component\"\n dayViewText=\"Day\"\n\n i18n-weekViewText=\"kendo.gantt.weekViewText|The text of the week view in the ViewSelector component\"\n weekViewText=\"Week\"\n\n i18n-monthViewText=\"kendo.gantt.monthViewText|The text of the month view in the ViewSelector component\"\n monthViewText=\"Month\"\n\n i18n-yearViewText-disabled=\"kendo.gantt.yearViewText|The text of the year view in the ViewSelector component\"\n yearViewText=\"Year\"\n\n i18n-addTaskText=\"kendo.gantt.addTaskText|The text of the DropDownButton in the AddTask component\"\n addTaskText=\"Add Task\"\n\n i18n-addChildText=\"kendo.gantt.addChildText|The text of the 'Add Child' option in the AddTask component\"\n addChildText=\"Add Child\"\n\n i18n-addAboveText=\"kendo.gantt.addAboveText|The text of the 'Add Above' option in the AddTask component\"\n addAboveText=\"Add Above\"\n\n i18n-addBelowText=\"kendo.gantt.addBelowText|The text of the 'Add Below' option in the AddTask component\"\n addBelowText=\"Add Below\"\n\n i18n-noRecords=\"kendo.gantt.noRecords|The label visible in the TreeList when there are no records\"\n noRecords=\"No records available.\"\n\n i18n-filter=\"kendo.gantt.filter|The label of the filter cell or icon\"\n filter=\"Filter\"\n\n i18n-filterEqOperator=\"kendo.gantt.filterEqOperator|The text of the equal filter operator\"\n filterEqOperator=\"Is equal to\"\n\n i18n-filterNotEqOperator=\"kendo.gantt.filterNotEqOperator|The text of the not equal filter operator\"\n filterNotEqOperator=\"Is not equal to\"\n\n i18n-filterIsNullOperator=\"kendo.gantt.filterIsNullOperator|The text of the is null filter operator\"\n filterIsNullOperator=\"Is null\"\n\n i18n-filterIsNotNullOperator=\"kendo.gantt.filterIsNotNullOperator|The text of the is not null filter operator\"\n filterIsNotNullOperator=\"Is not null\"\n\n i18n-filterIsEmptyOperator=\"kendo.gantt.filterIsEmptyOperator|The text of the is empty filter operator\"\n filterIsEmptyOperator=\"Is empty\"\n\n i18n-filterIsNotEmptyOperator=\"kendo.gantt.filterIsNotEmptyOperator|The text of the is not empty filter operator\"\n filterIsNotEmptyOperator=\"Is not empty\"\n\n i18n-filterStartsWithOperator=\"kendo.gantt.filterStartsWithOperator|The text of the starts with filter operator\"\n filterStartsWithOperator=\"Starts with\"\n\n i18n-filterContainsOperator=\"kendo.gantt.filterContainsOperator|The text of the contains filter operator\"\n filterContainsOperator=\"Contains\"\n\n i18n-filterNotContainsOperator=\"kendo.gantt.filterNotContainsOperator|The text of the does not contain filter operator\"\n filterNotContainsOperator=\"Does not contain\"\n\n i18n-filterEndsWithOperator=\"kendo.gantt.filterEndsWithOperator|The text of the ends with filter operator\"\n filterEndsWithOperator=\"Ends with\"\n\n i18n-filterGteOperator=\"kendo.gantt.filterGteOperator|The text of the greater than or equal filter operator\"\n filterGteOperator=\"Is greater than or equal to\"\n\n i18n-filterGtOperator=\"kendo.gantt.filterGtOperator|The text of the greater than filter operator\"\n filterGtOperator=\"Is greater than\"\n\n i18n-filterLteOperator=\"kendo.gantt.filterLteOperator|The text of the less than or equal filter operator\"\n filterLteOperator=\"Is less than or equal to\"\n\n i18n-filterLtOperator=\"kendo.gantt.filterLtOperator|The text of the less than filter operator\"\n filterLtOperator=\"Is less than\"\n\n i18n-filterIsTrue=\"kendo.gantt.filterIsTrue|The text of the IsTrue boolean filter option\"\n filterIsTrue=\"Is True\"\n\n i18n-filterIsFalse=\"kendo.gantt.filterIsFalse|The text of the IsFalse boolean filter option\"\n filterIsFalse=\"Is False\"\n\n i18n-filterBooleanAll=\"kendo.gantt.filterBooleanAll|The text of the (All) boolean filter option\"\n filterBooleanAll=\"(All)\"\n\n i18n-filterAfterOrEqualOperator=\"kendo.gantt.filterAfterOrEqualOperator|The text of the after or equal date filter operator\"\n filterAfterOrEqualOperator=\"Is after or equal to\"\n\n i18n-filterAfterOperator=\"kendo.gantt.filterAfterOperator|The text of the after date filter operator\"\n filterAfterOperator=\"Is after\"\n\n i18n-filterBeforeOperator=\"kendo.gantt.filterBeforeOperator|The text of the before date filter operator\"\n filterBeforeOperator=\"Is before\"\n\n i18n-filterBeforeOrEqualOperator=\"kendo.gantt.filterBeforeOrEqualOperator|The text of the before or equal date filter operator\"\n filterBeforeOrEqualOperator=\"Is before or equal to\"\n\n i18n-filterFilterButton=\"kendo.gantt.filterFilterButton|The text of the filter button\"\n filterFilterButton=\"Filter\"\n\n i18n-filterClearButton=\"kendo.gantt.filterClearButton|The text of the clear filter button\"\n filterClearButton=\"Clear\"\n\n i18n-filterAndLogic=\"kendo.gantt.filterAndLogic|The text of the And filter logic\"\n filterAndLogic=\"And\"\n\n i18n-filterOrLogic=\"kendo.gantt.filterOrLogic|The text of the Or filter logic\"\n filterOrLogic=\"Or\"\n\n i18n-loading=\"kendo.gantt.loading|The loading text\"\n loading=\"Loading\"\n\n i18n-columnMenu=\"kendo.gantt.columnMenu|The title of the column menu icon\"\n columnMenu=\"Column Menu\"\n\n i18n-columns=\"kendo.gantt.columns|The text shown in the column menu for the columns item\"\n columns=\"Columns\"\n\n i18n-lock-disabled=\"kendo.gantt.lock|The text shown in the column menu for the lock item\"\n lock-disabled=\"Lock\"\n\n i18n-unlock-disabled=\"kendo.gantt.unlock|The text shown in the column menu for the unlock item\"\n unlock-disabled=\"Unlock\"\n\n i18n-sortable=\"kendo.gantt.sortable|The label of the sort icon\"\n sortable=\"Sortable\"\n\n i18n-sortAscending=\"kendo.gantt.sortAscending|The text shown in the column menu for the sort ascending item\"\n sortAscending=\"Sort Ascending\"\n\n i18n-sortDescending=\"kendo.gantt.sortDescending|The text shown in the column menu for the sort descending item\"\n sortDescending=\"Sort Descending\"\n\n i18n-sortedAscending=\"kendo.gantt.sortedAscending|The status announcement when a column is sorted ascending\"\n sortedAscending=\"Sorted Ascending\"\n\n i18n-sortedDescending=\"kendo.gantt.sortedDescending|The status announcement when a column is sorted descending\"\n sortedDescending=\"Sorted Descending\"\n\n i18n-sortedDefault=\"kendo.gantt.sortedDefault|The status announcement when a column is no longer sorted\"\n sortedDefault=\"Not Sorted\"\n\n i18n-columnsApply=\"kendo.gantt.columnsApply|The text shown in the column menu or column chooser for the columns apply button\"\n columnsApply=\"Apply\"\n\n i18n-columnsReset=\"kendo.gantt.columnsReset|The text shown in the column menu or column chooser for the columns reset button\"\n columnsReset=\"Reset\"></ng-container>\n <kendo-gantt-toolbar\n *ngIf=\"showToolbar('top')\"\n [showAddTask]=\"toolbarSettings.addTaskTool === 'top' || toolbarSettings.addTaskTool === 'both'\"\n [showViewSelector]=\"toolbarSettings.viewSelectorTool === 'top' || toolbarSettings.viewSelectorTool === 'both'\"\n class=\"k-gantt-header k-toolbar k-gantt-toolbar\"\n position=\"top\"></kendo-gantt-toolbar>\n <div class=\"k-gantt-content\">\n <kendo-splitter [style.border]=\"0\">\n <kendo-splitter-pane\n class=\"k-gantt-treelist k-gantt-treelist-scrollable\"\n [collapsible]=\"treeListPaneOptions?.collapsible\"\n [collapsed]=\"treeListPaneOptions?.collapsed\"\n (collapsedChange)=\"onTreeListCollapsedChange($event)\"\n [scrollable]=\"false\">\n <kendo-treelist\n [idField]=\"taskIdField\"\n [columns]=\"columns\"\n [data]=\"data\"\n [hasChildren]=\"hasChildren\"\n [fetchChildren]=\"fetchChildren\"\n [navigable]=\"navigable\"\n [isExpanded]=\"isExpanded\"\n [autoSize]=\"columnsAutoSize\"\n [columnMenu]=\"columnMenu\"\n [reorderable]=\"columnsReorderable\"\n [resizable]=\"columnsResizable\"\n [rowClass]=\"rowClass\"\n [isSelected]=\"isSelected\"\n [selectable]=\"selectable\"\n [sortable]=\"sortable\"\n [sort]=\"sort\"\n [filterable]=\"filterMenu\"\n [filter]=\"filter\"\n (filterChange)=\"filterChange.emit($event)\"\n (sortChange)=\"sortChange.emit($event)\"\n (dataStateChange)=\"dataStateChange.emit({\n filter: $event.filter,\n sort: $event.sort\n })\"\n (expandStateChange)=\"expandStateChange.emit($event)\"\n (expand)=\"rowExpand.emit({ dataItem: $event.dataItem })\"\n (collapse)=\"rowCollapse.emit({ dataItem: $event.dataItem })\"\n (columnReorder)=\"columnReorder.emit($event)\"\n (columnResize)=\"columnResize.emit($event)\"\n (columnVisibilityChange)=\"handleColumnVisibilityChange($event)\"\n (columnLockedChange)=\"columnLockedChange.emit($event)\"\n (selectionChange)=\"handleTreeListSelectionChange($event)\"\n (cellClick)=\"handleTreeListCellClick($event)\"\n (cellClose)=\"handleCellClose($event)\"\n [kendoEventsOutsideAngular]=\"{\n dblclick: handleTreeListDoubleClick\n }\"\n [scope]=\"this\"\n >\n <kendo-treelist-messages\n [noRecords]=\"getText('noRecords')\"\n [filter]=\"getText('filter')\"\n [filterEqOperator]=\"getText('filterEqOperator')\"\n [filterNotEqOperator]=\"getText('filterNotEqOperator')\"\n [filterIsNullOperator]=\"getText('filterIsNullOperator')\"\n [filterIsNotNullOperator]=\"getText('filterIsNotNullOperator')\"\n [filterIsEmptyOperator]=\"getText('filterIsEmptyOperator')\"\n [filterIsNotEmptyOperator]=\"getText('filterIsNotEmptyOperator')\"\n [filterStartsWithOperator]=\"getText('filterStartsWithOperator')\"\n [filterContainsOperator]=\"getText('filterContainsOperator')\"\n [filterNotContainsOperator]=\"getText('filterNotContainsOperator')\"\n [filterEndsWithOperator]=\"getText('filterEndsWithOperator')\"\n [filterGteOperator]=\"getText('filterGteOperator')\"\n [filterGtOperator]=\"getText('filterGtOperator')\"\n [filterLteOperator]=\"getText('filterLteOperator')\"\n [filterLtOperator]=\"getText('filterLtOperator')\"\n [filterIsTrue]=\"getText('filterIsTrue')\"\n [filterIsFalse]=\"getText('filterIsFalse')\"\n [filterBooleanAll]=\"getText('filterBooleanAll')\"\n [filterAfterOrEqualOperator]=\"getText('filterAfterOrEqualOperator')\"\n [filterAfterOperator]=\"getText('filterAfterOperator')\"\n [filterBeforeOperator]=\"getText('filterBeforeOperator')\"\n [filterBeforeOrEqualOperator]=\"getText('filterBeforeOrEqualOperator')\"\n [filterFilterButton]=\"getText('filterFilterButton')\"\n [filterClearButton]=\"getText('filterClearButton')\"\n [filterAndLogic]=\"getText('filterAndLogic')\"\n [filterOrLogic]=\"getText('filterOrLogic')\"\n [loading]=\"getText('loading')\"\n [columnMenu]=\"getText('columnMenu')\"\n [columns]=\"getText('columns')\"\n [sortable]=\"getText('sortable')\"\n [sortAscending]=\"getText('sortAscending')\"\n [sortDescending]=\"getText('sortDescending')\"\n [sortedAscending]=\"getText('sortedAscending')\"\n [sortedDescending]=\"getText('sortedDescending')\"\n [sortedDefault]=\"getText('sortedDefault')\"\n [columnsApply]=\"getText('columnsApply')\"\n [columnsReset]=\"getText('columnsReset')\"\n >\n </kendo-treelist-messages>\n </kendo-treelist>\n </kendo-splitter-pane>\n <kendo-splitter-pane\n [collapsible]=\"timelinePaneOptions?.collapsible\"\n [resizable]=\"timelinePaneOptions?.resizable\"\n [collapsed]=\"timelinePaneOptions?.collapsed\"\n [min]=\"timelinePaneOptions?.min\"\n [max]=\"timelinePaneOptions?.max\"\n [size]=\"timelinePaneOptions?.size\"\n (collapsedChange)=\"onTimelineCollapsedChange($event)\"\n (sizeChange)=\"onTimelinePaneSizeChange($event)\"\n [scrollable]=\"false\">\n <kendo-gantt-timeline\n *ngIf=\"views && views.length\"\n [renderDependencyDragClues]=\"renderDependencyDragClues\"\n [dragScrollSettings]=\"dragScrollSettings\"\n [rows]=\"viewItems\"\n [slots]=\"timelineSlots\"\n [groupSlots]=\"timelineGroupSlots\"\n [tableWidth]=\"tableWidth\"\n [activeView]=\"activeView\"\n [taskContentTemplate]=\"taskContentTemplate?.templateRef\"\n [taskTemplate]=\"taskTemplate?.templateRef\"\n [summaryTaskTemplate]=\"summaryTaskTemplate?.templateRef\"\n [taskClass]=\"taskClass\"\n [dependencies]=\"dependencies\"\n [isExpanded]=\"isExpanded\"\n [selectable]=\"selectable\"\n [isTaskSelected]=\"isTaskSelected\"\n [kendoEventsOutsideAngular]=\"{\n click: handleTimelineClick,\n contextmenu: handleTimelineRightClick,\n dblclick: handleTimelineDblClick,\n mousedown: handleTimelineMouseDown\n }\"\n [scope]=\"this\"\n ></kendo-gantt-timeline>\n </kendo-splitter-pane>\n </kendo-splitter>\n </div>\n <kendo-gantt-toolbar\n *ngIf=\"showToolbar('bottom')\"\n [showAddTask]=\"toolbarSettings.addTaskTool === 'bottom' || toolbarSettings.addTaskTool === 'both'\"\n [showViewSelector]=\"toolbarSettings.viewSelectorTool === 'bottom' || toolbarSettings.viewSelectorTool === 'both'\"\n class=\"k-gantt-footer k-toolbar k-gantt-toolbar\"\n position=\"bottom\"></kendo-gantt-toolbar>\n <kendo-gantt-edit-dialog\n *ngIf=\"showEditingDialog\"\n [data]=\"data\">\n </kendo-gantt-edit-dialog>\n <kendo-dialog\n *ngIf=\"showConfirmationDialog\"\n [width]=\"575\"\n [height]=\"170\"\n [title]=\"getText('confirmationDialogTitle')\"\n (close)=\"handleConfirmationDialogClose()\">\n <span>{{ getText('confirmationDialogContent') }}</span>\n <kendo-dialog-actions layout=\"normal\">\n <kendo-treelist-spacer></kendo-treelist-spacer>\n <button kendoButton [primary]=\"true\" (click)=\"handleDeleteConfirmation()\">{{ getText('deleteButtonText') }}</button>\n <button kendoButton (click)=\"handleConfirmationDialogClose()\">{{ getText('cancelButtonText') }}</button>\n </kendo-dialog-actions>\n </kendo-dialog>\n "
2999
4249
  }),
3000
4250
  __metadata("design:paramtypes", [TimelineViewService,
3001
4251
  ScrollSyncService,
@@ -3006,7 +4256,8 @@ var GanttComponent = /** @class */ (function () {
3006
4256
  EditService,
3007
4257
  LocalizationService,
3008
4258
  ElementRef,
3009
- NgZone])
4259
+ NgZone,
4260
+ NavigationService])
3010
4261
  ], GanttComponent);
3011
4262
  return GanttComponent;
3012
4263
  }());
@@ -3014,120 +4265,7 @@ var GanttComponent = /** @class */ (function () {
3014
4265
  /**
3015
4266
  * @hidden
3016
4267
  */
3017
- var GanttTimelineComponent = /** @class */ (function () {
3018
- function GanttTimelineComponent(scrollSyncService, dependencyDomService, renderer, zone) {
3019
- var _this = this;
3020
- this.scrollSyncService = scrollSyncService;
3021
- this.dependencyDomService = dependencyDomService;
3022
- this.renderer = renderer;
3023
- this.zone = zone;
3024
- this.hostClass = true;
3025
- this.dependencies = [];
3026
- this.subscriptions = new Subscription();
3027
- this.subscriptions.add(
3028
- // task changes indicates change in row content, number, height, etc.
3029
- this.dependencyDomService.taskChanges
3030
- .pipe(filter(function (args) { return isPresent(args.timelineRow); }), switchMap(function (args) { return _this.zone.onStable.pipe(take(1), map(function () { return args; })); }) // ensure the content is rendered
3031
- )
3032
- .subscribe(function (_a) {
3033
- var timelineRow = _a.timelineRow;
3034
- var timelineRowHeight = isDocumentAvailable() ? timelineRow.getBoundingClientRect().height : 0;
3035
- _this.renderer.setStyle(_this.timelineColumns.nativeElement, 'height', (_this.rows || []).length * timelineRowHeight + "px");
3036
- }));
3037
- }
3038
- GanttTimelineComponent.prototype.ngAfterViewInit = function () {
3039
- var timelineHeader = this.timelineHeaderWrap.nativeElement;
3040
- var rightContainer = this.timelineContent.nativeElement;
3041
- this.scrollSyncService.registerElement(rightContainer, 'timeline');
3042
- this.scrollSyncService.registerElement(timelineHeader, 'header');
3043
- this.dependencyDomService.registerContentContainer(this.tasksContainer.nativeElement);
3044
- };
3045
- GanttTimelineComponent.prototype.ngOnDestroy = function () {
3046
- this.subscriptions.unsubscribe();
3047
- };
3048
- GanttTimelineComponent.prototype.isNonWorking = function (item) {
3049
- return item.hasOwnProperty('isWorking') && !item.isWorking;
3050
- };
3051
- __decorate([
3052
- ViewChild('timelineContent', { static: true }),
3053
- __metadata("design:type", ElementRef)
3054
- ], GanttTimelineComponent.prototype, "timelineContent", void 0);
3055
- __decorate([
3056
- ViewChild('timelineColumns', { static: true }),
3057
- __metadata("design:type", ElementRef)
3058
- ], GanttTimelineComponent.prototype, "timelineColumns", void 0);
3059
- __decorate([
3060
- ViewChild('timelineHeaderWrap', { static: true }),
3061
- __metadata("design:type", ElementRef)
3062
- ], GanttTimelineComponent.prototype, "timelineHeaderWrap", void 0);
3063
- __decorate([
3064
- ViewChild('tasksContainer', { static: true }),
3065
- __metadata("design:type", ElementRef)
3066
- ], GanttTimelineComponent.prototype, "tasksContainer", void 0);
3067
- __decorate([
3068
- HostBinding('class.k-gantt-timeline'),
3069
- __metadata("design:type", Boolean)
3070
- ], GanttTimelineComponent.prototype, "hostClass", void 0);
3071
- __decorate([
3072
- Input(),
3073
- __metadata("design:type", Array)
3074
- ], GanttTimelineComponent.prototype, "rows", void 0);
3075
- __decorate([
3076
- Input(),
3077
- __metadata("design:type", Array)
3078
- ], GanttTimelineComponent.prototype, "slots", void 0);
3079
- __decorate([
3080
- Input(),
3081
- __metadata("design:type", Array)
3082
- ], GanttTimelineComponent.prototype, "groupSlots", void 0);
3083
- __decorate([
3084
- Input(),
3085
- __metadata("design:type", Number)
3086
- ], GanttTimelineComponent.prototype, "tableWidth", void 0);
3087
- __decorate([
3088
- Input(),
3089
- __metadata("design:type", String)
3090
- ], GanttTimelineComponent.prototype, "activeView", void 0);
3091
- __decorate([
3092
- Input(),
3093
- __metadata("design:type", TemplateRef)
3094
- ], GanttTimelineComponent.prototype, "taskContentTemplate", void 0);
3095
- __decorate([
3096
- Input(),
3097
- __metadata("design:type", TemplateRef)
3098
- ], GanttTimelineComponent.prototype, "taskTemplate", void 0);
3099
- __decorate([
3100
- Input(),
3101
- __metadata("design:type", TemplateRef)
3102
- ], GanttTimelineComponent.prototype, "summaryTaskTemplate", void 0);
3103
- __decorate([
3104
- Input(),
3105
- __metadata("design:type", Function)
3106
- ], GanttTimelineComponent.prototype, "taskClass", void 0);
3107
- __decorate([
3108
- Input(),
3109
- __metadata("design:type", Function)
3110
- ], GanttTimelineComponent.prototype, "isTaskSelected", void 0);
3111
- __decorate([
3112
- Input(),
3113
- __metadata("design:type", Function)
3114
- ], GanttTimelineComponent.prototype, "hasChildren", void 0);
3115
- __decorate([
3116
- Input(),
3117
- __metadata("design:type", Array)
3118
- ], GanttTimelineComponent.prototype, "dependencies", void 0);
3119
- GanttTimelineComponent = __decorate([
3120
- Component({
3121
- selector: 'kendo-gantt-timeline',
3122
- template: "\n <div class=\"k-timeline k-grid k-widget\">\n <div class=\"k-grid-header\">\n <div #timelineHeaderWrap class=\"k-grid-header-wrap\">\n <table\n role=\"presentation\"\n [style.width.px]=\"tableWidth\"\n >\n <tbody\n kendoGanttHeaderTableBody\n [groupSlots]=\"groupSlots\"\n [slots]=\"slots\">\n </tbody>\n </table>\n </div>\n </div>\n <div #timelineContent class=\"k-grid-content\">\n <div class=\"k-gantt-tables\">\n <table\n class=\"k-gantt-rows\"\n [style.width.px]=\"tableWidth\"\n role=\"presentation\"\n >\n <tbody>\n <tr *ngFor=\"let item of rows; let i = index;\"\n [class.k-alt]=\"i % 2\"\n >\n <td></td>\n </tr>\n </tbody>\n </table>\n\n <table\n #timelineColumns\n class=\"k-gantt-columns\"\n role=\"presentation\"\n [style.width.px]=\"tableWidth\"\n >\n <colgroup>\n <col *ngFor=\"let item of slots\">\n </colgroup>\n\n <tbody>\n <tr>\n <td *ngFor=\"let item of slots\"\n [class.k-nonwork-hour]=\"isNonWorking(item)\"\n >\n </td>\n </tr>\n </tbody>\n </table>\n\n <table\n #tasksContainer\n class=\"k-gantt-tasks\"\n role=\"presentation\"\n style=\"border-collapse: collapse;\"\n [style.width.px]=\"tableWidth\"\n >\n <tbody\n kendoGanttTasksTableBody\n [rows]=\"rows\"\n [activeView]=\"activeView\"\n [taskContentTemplate]=\"taskContentTemplate\"\n [taskTemplate]=\"taskTemplate\"\n [summaryTaskTemplate]=\"summaryTaskTemplate\"\n [taskClass]=\"taskClass\"\n [hasChildren]=\"hasChildren\"\n [isTaskSelected]=\"isTaskSelected\"\n >\n </tbody>\n </table>\n </div>\n <svg class=\"k-gantt-dependencies-svg\">\n <polyline\n *ngFor=\"let dependency of dependencies\"\n kendoGanttDependency\n [dependency]=\"dependency\"\n />\n </svg>\n </div>\n </div>\n "
3123
- }),
3124
- __metadata("design:paramtypes", [ScrollSyncService,
3125
- DependencyDomService,
3126
- Renderer2,
3127
- NgZone])
3128
- ], GanttTimelineComponent);
3129
- return GanttTimelineComponent;
3130
- }());
4268
+ var TOUCH_ENABLED = new InjectionToken('gantt-touch-enabled');
3131
4269
 
3132
4270
  /**
3133
4271
  * @hidden
@@ -3148,14 +4286,18 @@ var GanttTasksTableBodyComponent = /** @class */ (function () {
3148
4286
  enumerable: true,
3149
4287
  configurable: true
3150
4288
  });
3151
- GanttTasksTableBodyComponent.prototype.isMileStone = function (task) {
3152
- return !this.hasChildren(task) && isEqual(this.mapper.extractFromTask(task, 'start'), this.mapper.extractFromTask(task, 'end'));
4289
+ GanttTasksTableBodyComponent.prototype.isMileStone = function (item) {
4290
+ return !item.hasChildren && isEqual(this.mapper.extractFromTask(item.data, 'start'), this.mapper.extractFromTask(item.data, 'end'));
3153
4291
  };
3154
4292
  __decorate([
3155
4293
  ViewChild('timelineRow', { static: false }),
3156
4294
  __metadata("design:type", ElementRef),
3157
4295
  __metadata("design:paramtypes", [ElementRef])
3158
4296
  ], GanttTasksTableBodyComponent.prototype, "timelineRow", null);
4297
+ __decorate([
4298
+ Input(),
4299
+ __metadata("design:type", Boolean)
4300
+ ], GanttTasksTableBodyComponent.prototype, "selectable", void 0);
3159
4301
  __decorate([
3160
4302
  Input(),
3161
4303
  __metadata("design:type", Array)
@@ -3183,15 +4325,19 @@ var GanttTasksTableBodyComponent = /** @class */ (function () {
3183
4325
  __decorate([
3184
4326
  Input(),
3185
4327
  __metadata("design:type", Function)
3186
- ], GanttTasksTableBodyComponent.prototype, "hasChildren", void 0);
4328
+ ], GanttTasksTableBodyComponent.prototype, "isExpanded", void 0);
3187
4329
  __decorate([
3188
4330
  Input(),
3189
4331
  __metadata("design:type", Function)
3190
4332
  ], GanttTasksTableBodyComponent.prototype, "isTaskSelected", void 0);
4333
+ __decorate([
4334
+ Input(),
4335
+ __metadata("design:type", Boolean)
4336
+ ], GanttTasksTableBodyComponent.prototype, "renderDependencyDragClues", void 0);
3191
4337
  GanttTasksTableBodyComponent = __decorate([
3192
4338
  Component({
3193
4339
  selector: '[kendoGanttTasksTableBody]',
3194
- template: "\n <tr #timelineRow *ngFor=\"let item of rows; let index = index\">\n <td>\n <kendo-gantt-milestone-task\n *ngIf=\"isMileStone(item); else task\"\n [dataItem]=\"item\"\n [activeView]=\"activeView\"\n [taskClass]=\"taskClass\"\n [isSelected]=\"isTaskSelected\"\n [index]=\"index\"\n >\n </kendo-gantt-milestone-task>\n <ng-template #task>\n <kendo-gantt-summary-task\n *ngIf=\"hasChildren(item)\"\n [dataItem]=\"item\"\n [template]=\"summaryTaskTemplate\"\n [activeView]=\"activeView\"\n [taskClass]=\"taskClass\"\n [isSelected]=\"isTaskSelected\"\n [index]=\"index\"\n >\n </kendo-gantt-summary-task>\n <kendo-gantt-task\n *ngIf=\"!hasChildren(item)\"\n [dataItem]=\"item\"\n [taskContentTemplate]=\"taskContentTemplate\"\n [taskTemplate]=\"taskTemplate\"\n [activeView]=\"activeView\"\n [taskClass]=\"taskClass\"\n [isSelected]=\"isTaskSelected\"\n [index]=\"index\"\n >\n </kendo-gantt-task>\n </ng-template>\n </td>\n </tr>\n "
4340
+ template: "\n <tr #timelineRow *ngFor=\"let item of rows; let index = index\">\n <td>\n <kendo-gantt-milestone-task\n *ngIf=\"isMileStone(item); else task\"\n [dataItem]=\"item.data\"\n [level]=\"item.level\"\n [activeView]=\"activeView\"\n [taskClass]=\"taskClass\"\n [selectable]=\"selectable\"\n [isSelected]=\"isTaskSelected\"\n [index]=\"index\"\n [renderDependencyDragClues]=\"renderDependencyDragClues\"\n >\n </kendo-gantt-milestone-task>\n <ng-template #task>\n <kendo-gantt-summary-task\n *ngIf=\"item.hasChildren\"\n [dataItem]=\"item.data\"\n [level]=\"item.level\"\n [template]=\"summaryTaskTemplate\"\n [activeView]=\"activeView\"\n [taskClass]=\"taskClass\"\n [selectable]=\"selectable\"\n [isSelected]=\"isTaskSelected\"\n [isExpanded]=\"isExpanded\"\n [index]=\"index\"\n [renderDependencyDragClues]=\"renderDependencyDragClues\"\n >\n </kendo-gantt-summary-task>\n <kendo-gantt-task\n *ngIf=\"!item.hasChildren\"\n [dataItem]=\"item.data\"\n [level]=\"item.level\"\n [taskContentTemplate]=\"taskContentTemplate\"\n [taskTemplate]=\"taskTemplate\"\n [activeView]=\"activeView\"\n [taskClass]=\"taskClass\"\n [selectable]=\"selectable\"\n [isSelected]=\"isTaskSelected\"\n [index]=\"index\"\n [renderDependencyDragClues]=\"renderDependencyDragClues\"\n >\n </kendo-gantt-task>\n </ng-template>\n </td>\n </tr>\n "
3195
4341
  }),
3196
4342
  __metadata("design:paramtypes", [DependencyDomService,
3197
4343
  MappingService])
@@ -3227,62 +4373,63 @@ var slotUnitDuration = {
3227
4373
  week: MS_PER_DAY,
3228
4374
  month: MS_PER_DAY * 7
3229
4375
  };
4376
+ var FOCUSED_CLASS = 'k-focus';
3230
4377
  /**
3231
4378
  * @hidden
3232
4379
  */
3233
4380
  var GanttTaskBase = /** @class */ (function () {
3234
4381
  function GanttTaskBase(mapper, // left public to be available for usage in the templates
3235
- timelineViewService, dependencyDomService, optionChangesService, cdr) {
4382
+ timelineViewService, dependencyDomService, optionChangesService, cdr, navigationService) {
3236
4383
  var _this = this;
3237
4384
  this.mapper = mapper;
3238
4385
  this.timelineViewService = timelineViewService;
3239
4386
  this.dependencyDomService = dependencyDomService;
3240
4387
  this.optionChangesService = optionChangesService;
3241
4388
  this.cdr = cdr;
4389
+ this.navigationService = navigationService;
3242
4390
  this.wrapperClass = true;
3243
- this.viewChangesSubscription = new Subscription();
3244
- this.viewChangesSubscription.add(this.optionChangesService.viewChanges.subscribe(function () {
3245
- _this.cdr.markForCheck();
3246
- }));
4391
+ this.subscriptions = new Subscription();
4392
+ this.subscriptions.add(this.optionChangesService.viewChanges
4393
+ .subscribe(function () { return _this.cdr.markForCheck(); }));
4394
+ this.subscriptions.add(this.navigationService.taskStatusChanges
4395
+ .subscribe(this.updateActiveState.bind(this)));
3247
4396
  }
3248
- Object.defineProperty(GanttTaskBase.prototype, "slotUnitDuration", {
4397
+ Object.defineProperty(GanttTaskBase.prototype, "taskIndexAttribute", {
3249
4398
  get: function () {
3250
- return slotUnitDuration[this.activeView];
4399
+ return this.index;
3251
4400
  },
3252
4401
  enumerable: true,
3253
4402
  configurable: true
3254
4403
  });
3255
- Object.defineProperty(GanttTaskBase.prototype, "viewService", {
4404
+ Object.defineProperty(GanttTaskBase.prototype, "ariaSelected", {
3256
4405
  get: function () {
3257
- return this.timelineViewService.service(this.activeView);
4406
+ // assinging null will not render the attribute at all (desired in selectable="false" mode)
4407
+ return this.selectable ? String(this.isSelected(this.dataItem)) : null;
3258
4408
  },
3259
4409
  enumerable: true,
3260
4410
  configurable: true
3261
4411
  });
3262
- Object.defineProperty(GanttTaskBase.prototype, "slotWidth", {
4412
+ Object.defineProperty(GanttTaskBase.prototype, "slotUnitDuration", {
3263
4413
  get: function () {
3264
- return this.viewService.options.slotWidth;
4414
+ return slotUnitDuration[this.activeView];
4415
+ },
4416
+ enumerable: true,
4417
+ configurable: true
4418
+ });
4419
+ Object.defineProperty(GanttTaskBase.prototype, "viewService", {
4420
+ get: function () {
4421
+ return this.timelineViewService.service(this.activeView);
4422
+ },
4423
+ enumerable: true,
4424
+ configurable: true
4425
+ });
4426
+ Object.defineProperty(GanttTaskBase.prototype, "slotWidth", {
4427
+ get: function () {
4428
+ return this.viewService.options.slotWidth;
3265
4429
  },
3266
4430
  enumerable: true,
3267
4431
  configurable: true
3268
4432
  });
3269
- GanttTaskBase.prototype.ngOnChanges = function (changes) {
3270
- if (isPresent(changes.dataItem)) {
3271
- if (isPresent(changes.dataItem.previousValue)) {
3272
- this.dependencyDomService.unregisterTask(changes.dataItem.previousValue);
3273
- }
3274
- this.dependencyDomService.registerTask(this.dataItem, this.taskElement.nativeElement);
3275
- }
3276
- else if (isPresent(changes.activeView)) {
3277
- this.dependencyDomService.notifyChanges();
3278
- }
3279
- };
3280
- GanttTaskBase.prototype.ngOnDestroy = function () {
3281
- if (isPresent(this.dataItem)) {
3282
- this.dependencyDomService.unregisterTask(this.dataItem);
3283
- }
3284
- this.viewChangesSubscription.unsubscribe();
3285
- };
3286
4433
  Object.defineProperty(GanttTaskBase.prototype, "taskWidth", {
3287
4434
  get: function () {
3288
4435
  var itemDuration = this.mapper.extractFromTask(this.dataItem, 'end') - this.mapper.extractFromTask(this.dataItem, 'start');
@@ -3294,6 +4441,12 @@ var GanttTaskBase = /** @class */ (function () {
3294
4441
  configurable: true
3295
4442
  });
3296
4443
  Object.defineProperty(GanttTaskBase.prototype, "taskOffset", {
4444
+ /**
4445
+ * The `left` style prop has to be applied to the host element (.k-task-wrap), as the drag clue elements are displayed on .k-task-wrap hover.
4446
+ * Applying the `left` offset to the inner .k-task element leaves the .k-task-wrap element rendered with an offset of 0 somewhere on the left
4447
+ * and hovering just the .k-task element doesn't expose the drag clues.
4448
+ * Additionally, positioning the entire container takes care of positioning the hints as well.
4449
+ */
3297
4450
  get: function () {
3298
4451
  var timeAfterViewStart = this.mapper.extractFromTask(this.dataItem, 'start') - this.viewService.viewStart;
3299
4452
  var offsetInSlotUnits = timeAfterViewStart / this.slotUnitDuration;
@@ -3312,10 +4465,48 @@ var GanttTaskBase = /** @class */ (function () {
3312
4465
  enumerable: true,
3313
4466
  configurable: true
3314
4467
  });
4468
+ GanttTaskBase.prototype.ngOnChanges = function (changes) {
4469
+ if (isPresent(changes.dataItem)) {
4470
+ if (isPresent(changes.dataItem.previousValue)) {
4471
+ this.dependencyDomService.unregisterTask(changes.dataItem.previousValue);
4472
+ }
4473
+ this.dependencyDomService.registerTask(this.dataItem, this.taskElement.nativeElement);
4474
+ }
4475
+ else if (isPresent(changes.activeView)) {
4476
+ this.dependencyDomService.notifyChanges();
4477
+ }
4478
+ if (this.navigationService.enabled && isPresent(changes.index)) {
4479
+ this.updateActiveState(this.navigationService.activeTask);
4480
+ }
4481
+ };
4482
+ GanttTaskBase.prototype.ngOnDestroy = function () {
4483
+ if (isPresent(this.dataItem)) {
4484
+ this.dependencyDomService.unregisterTask(this.dataItem);
4485
+ }
4486
+ this.subscriptions.unsubscribe();
4487
+ };
4488
+ GanttTaskBase.prototype.updateActiveState = function (_a) {
4489
+ var activeIndex = _a.activeIndex, isFocused = _a.isFocused;
4490
+ var isActive = activeIndex === this.index;
4491
+ var tabindex = isActive ? '0' : '-1';
4492
+ this.taskElement.nativeElement.setAttribute('tabindex', tabindex);
4493
+ if (isActive && isFocused) {
4494
+ this.taskElement.nativeElement.focus();
4495
+ this.taskElement.nativeElement.classList.add(FOCUSED_CLASS);
4496
+ }
4497
+ else {
4498
+ this.taskElement.nativeElement.classList.remove(FOCUSED_CLASS);
4499
+ }
4500
+ };
3315
4501
  __decorate([
3316
4502
  HostBinding('class.k-task-wrap'),
3317
4503
  __metadata("design:type", Boolean)
3318
4504
  ], GanttTaskBase.prototype, "wrapperClass", void 0);
4505
+ __decorate([
4506
+ HostBinding('attr.data-task-index'),
4507
+ __metadata("design:type", Number),
4508
+ __metadata("design:paramtypes", [])
4509
+ ], GanttTaskBase.prototype, "taskIndexAttribute", null);
3319
4510
  __decorate([
3320
4511
  ViewChild('task', { static: true }),
3321
4512
  __metadata("design:type", ElementRef)
@@ -3328,6 +4519,18 @@ var GanttTaskBase = /** @class */ (function () {
3328
4519
  Input(),
3329
4520
  __metadata("design:type", Number)
3330
4521
  ], GanttTaskBase.prototype, "index", void 0);
4522
+ __decorate([
4523
+ Input(),
4524
+ __metadata("design:type", Number)
4525
+ ], GanttTaskBase.prototype, "level", void 0);
4526
+ __decorate([
4527
+ Input(),
4528
+ __metadata("design:type", Boolean)
4529
+ ], GanttTaskBase.prototype, "renderDependencyDragClues", void 0);
4530
+ __decorate([
4531
+ Input(),
4532
+ __metadata("design:type", Boolean)
4533
+ ], GanttTaskBase.prototype, "selectable", void 0);
3331
4534
  __decorate([
3332
4535
  Input(),
3333
4536
  __metadata("design:type", Function)
@@ -3340,6 +4543,11 @@ var GanttTaskBase = /** @class */ (function () {
3340
4543
  Input(),
3341
4544
  __metadata("design:type", Function)
3342
4545
  ], GanttTaskBase.prototype, "taskClass", void 0);
4546
+ __decorate([
4547
+ HostBinding('style.left.px'),
4548
+ __metadata("design:type", Number),
4549
+ __metadata("design:paramtypes", [])
4550
+ ], GanttTaskBase.prototype, "taskOffset", null);
3343
4551
  return GanttTaskBase;
3344
4552
  }());
3345
4553
 
@@ -3348,15 +4556,16 @@ var GanttTaskBase = /** @class */ (function () {
3348
4556
  */
3349
4557
  var GanttTaskComponent = /** @class */ (function (_super) {
3350
4558
  __extends(GanttTaskComponent, _super);
3351
- function GanttTaskComponent(mapper, timelineViewService, dependencyDomService, optionChangesService, cdr, editService) {
3352
- var _this = _super.call(this, mapper, timelineViewService, dependencyDomService, optionChangesService, cdr) || this;
4559
+ function GanttTaskComponent(editService, touchEnabled$$1, mapper, timelineViewService, dependencyDomService, optionChangesService, cdr, navigationService) {
4560
+ var _this = _super.call(this, mapper, timelineViewService, dependencyDomService, optionChangesService, cdr, navigationService) || this;
3353
4561
  _this.editService = editService;
4562
+ _this.touchEnabled = touchEnabled$$1;
3354
4563
  return _this;
3355
4564
  }
3356
4565
  GanttTaskComponent_1 = GanttTaskComponent;
3357
4566
  GanttTaskComponent.prototype.onTaskDelete = function () {
3358
4567
  this.editService.dataItem = this.dataItem;
3359
- this.editService.showConfirmationDialog.next();
4568
+ this.editService.taskDelete.next(this.dataItem);
3360
4569
  };
3361
4570
  var GanttTaskComponent_1;
3362
4571
  __decorate([
@@ -3376,14 +4585,16 @@ var GanttTaskComponent = /** @class */ (function (_super) {
3376
4585
  useExisting: forwardRef(function () { return GanttTaskComponent_1; })
3377
4586
  }
3378
4587
  ],
3379
- template: "\n <div\n #task\n class=\"k-task k-task-single\"\n [ngClass]=\"taskClass(dataItem)\"\n [style.width.px]=\"taskWidth\"\n [style.left.px]=\"taskOffset\"\n [attr.title]=\"mapper.extractFromTask(dataItem, 'title')\"\n [attr.data-task-index]=\"index\"\n [class.k-state-selected]=\"isSelected(dataItem)\"\n >\n <ng-container *ngIf=\"!taskTemplate\">\n <div\n class=\"k-task-complete\"\n [style.width.px]=\"completionOverlayWidth\"\n >\n </div>\n <div class=\"k-task-content\">\n <div class=\"k-task-template\">\n <ng-container *ngIf=\"!taskContentTemplate; else taskContent\">\n {{ mapper.extractFromTask(dataItem, 'title') }}\n </ng-container>\n <ng-template\n #taskContent\n [ngTemplateOutlet]=\"taskContentTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: dataItem }\"\n >\n </ng-template>\n </div>\n <span class=\"k-task-actions\">\n <span\n (click)=\"onTaskDelete()\"\n class=\"k-link k-task-delete\">\n <span class=\"k-icon k-i-close\"></span>\n </span>\n </span>\n </div>\n </ng-container>\n <ng-template\n *ngIf=\"taskTemplate\"\n [ngTemplateOutlet]=\"taskTemplate\"\n [ngTemplateOutletContext]=\"{\n $implicit: dataItem,\n elementWidth: taskWidth\n }\"\n >\n </ng-template>\n </div>\n "
4588
+ template: "\n <div\n #task\n class=\"k-task k-task-single\"\n role=\"treeitem\"\n [ngClass]=\"taskClass(dataItem)\"\n [style.width.px]=\"taskWidth\"\n [attr.title]=\"mapper.extractFromTask(dataItem, 'title')\"\n [class.k-state-selected]=\"isSelected(dataItem)\"\n [attr.aria-selected]=\"ariaSelected\"\n [attr.aria-level]=\"level + 1\"\n >\n <ng-container *ngIf=\"!taskTemplate\">\n <div\n class=\"k-task-complete\"\n [style.width.px]=\"completionOverlayWidth\"\n aria-hidden=\"true\"\n >\n </div>\n <div class=\"k-task-content\">\n <div class=\"k-task-template\">\n <ng-container *ngIf=\"!taskContentTemplate; else taskContent\">\n {{ mapper.extractFromTask(dataItem, 'title') }}\n </ng-container>\n <ng-template\n #taskContent\n [ngTemplateOutlet]=\"taskContentTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: dataItem }\"\n >\n </ng-template>\n </div>\n <span\n class=\"k-task-actions\"\n aria-hidden=\"true\"\n >\n <span\n class=\"k-link k-task-delete\"\n [kendoEventsOutsideAngular]=\"{\n click: onTaskDelete\n }\"\n [scope]=\"this\"\n >\n <span class=\"k-icon k-i-close\"></span>\n </span>\n </span>\n </div>\n </ng-container>\n <ng-template\n *ngIf=\"taskTemplate\"\n [ngTemplateOutlet]=\"taskTemplate\"\n [ngTemplateOutletContext]=\"{\n $implicit: dataItem,\n elementWidth: taskWidth\n }\"\n >\n </ng-template>\n </div>\n <ng-container *ngIf=\"renderDependencyDragClues\">\n <div\n class=\"k-task-dot k-task-start k-touch-action-none\"\n [class.k-display-block]=\"touchEnabled\"\n >\n </div>\n <div\n class=\"k-task-dot k-task-end k-touch-action-none\"\n [class.k-display-block]=\"touchEnabled\"\n >\n </div>\n </ng-container>\n ",
4589
+ styles: ["\n .k-task.k-focus {\n box-shadow: 0 0 4px 3px grey;\n outline: none;\n }\n .k-task.k-focus.k-state-selected {\n box-shadow: 0 0 4px 3px #ffaea8;\n }\n "]
3380
4590
  }),
3381
- __metadata("design:paramtypes", [MappingService,
4591
+ __param(1, Inject(TOUCH_ENABLED)),
4592
+ __metadata("design:paramtypes", [EditService, Boolean, MappingService,
3382
4593
  TimelineViewService,
3383
4594
  DependencyDomService,
3384
4595
  OptionChangesService,
3385
4596
  ChangeDetectorRef,
3386
- EditService])
4597
+ NavigationService])
3387
4598
  ], GanttTaskComponent);
3388
4599
  return GanttTaskComponent;
3389
4600
  }(GanttTaskBase));
@@ -3393,12 +4604,23 @@ var GanttTaskComponent = /** @class */ (function (_super) {
3393
4604
  */
3394
4605
  var GanttSummaryTaskComponent = /** @class */ (function (_super) {
3395
4606
  __extends(GanttSummaryTaskComponent, _super);
3396
- function GanttSummaryTaskComponent(mapper, timelineViewService, dependencyDomService, optionChangesService, cdr) {
3397
- var _this = _super.call(this, mapper, timelineViewService, dependencyDomService, optionChangesService, cdr) || this;
4607
+ function GanttSummaryTaskComponent(touchEnabled$$1, mapper, timelineViewService, dependencyDomService, optionChangesService, cdr, navigationService) {
4608
+ var _this = _super.call(this, mapper, timelineViewService, dependencyDomService, optionChangesService, cdr, navigationService) || this;
4609
+ _this.touchEnabled = touchEnabled$$1;
3398
4610
  _this.summaryWrapperClass = true;
3399
4611
  return _this;
3400
4612
  }
3401
4613
  GanttSummaryTaskComponent_1 = GanttSummaryTaskComponent;
4614
+ Object.defineProperty(GanttSummaryTaskComponent.prototype, "ariaExpanded", {
4615
+ get: function () {
4616
+ // if no callback is provided, all child items are displayed and the item is regarded as expanded
4617
+ // replicates the TreeList aria-expanded behavior
4618
+ var isExpanded = !isPresent(this.isExpanded) || this.isExpanded(this.dataItem);
4619
+ return String(isExpanded);
4620
+ },
4621
+ enumerable: true,
4622
+ configurable: true
4623
+ });
3402
4624
  var GanttSummaryTaskComponent_1;
3403
4625
  __decorate([
3404
4626
  HostBinding('class.k-summary-wrap'),
@@ -3408,6 +4630,10 @@ var GanttSummaryTaskComponent = /** @class */ (function (_super) {
3408
4630
  Input(),
3409
4631
  __metadata("design:type", TemplateRef)
3410
4632
  ], GanttSummaryTaskComponent.prototype, "template", void 0);
4633
+ __decorate([
4634
+ Input(),
4635
+ __metadata("design:type", Function)
4636
+ ], GanttSummaryTaskComponent.prototype, "isExpanded", void 0);
3411
4637
  GanttSummaryTaskComponent = GanttSummaryTaskComponent_1 = __decorate([
3412
4638
  Component({
3413
4639
  selector: 'kendo-gantt-summary-task',
@@ -3417,13 +4643,16 @@ var GanttSummaryTaskComponent = /** @class */ (function (_super) {
3417
4643
  useExisting: forwardRef(function () { return GanttSummaryTaskComponent_1; })
3418
4644
  }
3419
4645
  ],
3420
- template: "\n <div\n #task\n class=\"k-task k-task-summary\"\n [ngClass]=\"taskClass(dataItem)\"\n [style.width.px]=\"taskWidth\"\n [style.left.px]=\"taskOffset\"\n [attr.title]=\"mapper.extractFromTask(dataItem, 'title')\"\n [attr.data-task-index]=\"index\"\n [class.k-state-selected]=\"isSelected(dataItem)\"\n >\n <div *ngIf=\"!template; else summaryTemplate\"\n class=\"k-task-summary-progress\"\n [style.width.px]=\"taskWidth\">\n <div\n class=\"k-task-summary-complete\"\n [style.width.px]=\"completionOverlayWidth\"\n >\n </div>\n </div>\n <ng-template\n #summaryTemplate\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{\n $implicit: dataItem,\n elementWidth: taskWidth\n }\"\n >\n </ng-template>\n </div>\n "
4646
+ template: "\n <div\n #task\n role=\"treeitem\"\n class=\"k-task k-task-summary\"\n [ngClass]=\"taskClass(dataItem)\"\n [style.width.px]=\"taskWidth\"\n [attr.title]=\"mapper.extractFromTask(dataItem, 'title')\"\n [class.k-state-selected]=\"isSelected(dataItem)\"\n [attr.aria-selected]=\"ariaSelected\"\n [attr.aria-expanded]=\"ariaExpanded\"\n [attr.aria-level]=\"level + 1\"\n >\n <div *ngIf=\"!template; else summaryTemplate\"\n class=\"k-task-summary-progress\"\n [style.width.px]=\"taskWidth\">\n <div\n class=\"k-task-summary-complete\"\n [style.width.px]=\"completionOverlayWidth\"\n >\n </div>\n </div>\n <ng-template\n #summaryTemplate\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{\n $implicit: dataItem,\n elementWidth: taskWidth\n }\"\n >\n </ng-template>\n </div>\n <ng-container *ngIf=\"renderDependencyDragClues\">\n <div\n class=\"k-task-dot k-task-start k-touch-action-none\"\n [class.k-display-block]=\"touchEnabled\"\n >\n </div>\n <div\n class=\"k-task-dot k-task-end k-touch-action-none\"\n [class.k-display-block]=\"touchEnabled\"\n >\n </div>\n </ng-container>\n ",
4647
+ styles: ["\n .k-task.k-focus {\n box-shadow: 0 0 4px 3px grey;\n outline: none;\n }\n .k-task.k-focus.k-state-selected {\n box-shadow: 0 0 4px 3px #ffaea8;\n }\n "]
3421
4648
  }),
3422
- __metadata("design:paramtypes", [MappingService,
4649
+ __param(0, Inject(TOUCH_ENABLED)),
4650
+ __metadata("design:paramtypes", [Boolean, MappingService,
3423
4651
  TimelineViewService,
3424
4652
  DependencyDomService,
3425
4653
  OptionChangesService,
3426
- ChangeDetectorRef])
4654
+ ChangeDetectorRef,
4655
+ NavigationService])
3427
4656
  ], GanttSummaryTaskComponent);
3428
4657
  return GanttSummaryTaskComponent;
3429
4658
  }(GanttTaskBase));
@@ -3433,8 +4662,9 @@ var GanttSummaryTaskComponent = /** @class */ (function (_super) {
3433
4662
  */
3434
4663
  var GanttMilestoneTaskComponent = /** @class */ (function (_super) {
3435
4664
  __extends(GanttMilestoneTaskComponent, _super);
3436
- function GanttMilestoneTaskComponent(mapper, timelineViewService, dependencyDomService, optionChangesService, cdr) {
3437
- var _this = _super.call(this, mapper, timelineViewService, dependencyDomService, optionChangesService, cdr) || this;
4665
+ function GanttMilestoneTaskComponent(touchEnabled$$1, mapper, timelineViewService, dependencyDomService, optionChangesService, cdr, navigationService) {
4666
+ var _this = _super.call(this, mapper, timelineViewService, dependencyDomService, optionChangesService, cdr, navigationService) || this;
4667
+ _this.touchEnabled = touchEnabled$$1;
3438
4668
  _this.milestoneWrapperClass = true;
3439
4669
  return _this;
3440
4670
  }
@@ -3453,13 +4683,16 @@ var GanttMilestoneTaskComponent = /** @class */ (function (_super) {
3453
4683
  useExisting: forwardRef(function () { return GanttMilestoneTaskComponent_1; })
3454
4684
  }
3455
4685
  ],
3456
- template: "\n <div\n #task\n class=\"k-task k-task-milestone\"\n [ngClass]=\"taskClass(dataItem)\"\n [style.left.px]=\"taskOffset\"\n [attr.title]=\"mapper.extractFromTask(dataItem, 'title')\"\n [class.k-state-selected]=\"isSelected(dataItem)\"\n [attr.data-task-index]=\"index\"\n >\n </div>\n "
4686
+ template: "\n <div\n #task\n role=\"treeitem\"\n class=\"k-task k-task-milestone\"\n [ngClass]=\"taskClass(dataItem)\"\n [attr.title]=\"mapper.extractFromTask(dataItem, 'title')\"\n [class.k-state-selected]=\"isSelected(dataItem)\"\n [attr.aria-selected]=\"ariaSelected\"\n [attr.aria-level]=\"level + 1\"\n >\n </div>\n <ng-container *ngIf=\"renderDependencyDragClues\">\n <div\n class=\"k-task-dot k-task-start k-touch-action-none\"\n [class.k-display-block]=\"touchEnabled\"\n >\n </div>\n <div\n class=\"k-task-dot k-task-end k-touch-action-none\"\n [class.k-display-block]=\"touchEnabled\"\n >\n </div>\n </ng-container>\n ",
4687
+ styles: ["\n .k-task.k-focus {\n box-shadow: 0 0 4px 3px grey;\n outline: none;\n }\n .k-task.k-focus.k-state-selected {\n box-shadow: 0 0 4px 3px #ffaea8;\n }\n "]
3457
4688
  }),
3458
- __metadata("design:paramtypes", [MappingService,
4689
+ __param(0, Inject(TOUCH_ENABLED)),
4690
+ __metadata("design:paramtypes", [Boolean, MappingService,
3459
4691
  TimelineViewService,
3460
4692
  DependencyDomService,
3461
4693
  OptionChangesService,
3462
- ChangeDetectorRef])
4694
+ ChangeDetectorRef,
4695
+ NavigationService])
3463
4696
  ], GanttMilestoneTaskComponent);
3464
4697
  return GanttMilestoneTaskComponent;
3465
4698
  }(GanttTaskBase));
@@ -3677,10 +4910,10 @@ var SelectableDirective = /** @class */ (function () {
3677
4910
  * @hidden
3678
4911
  */
3679
4912
  var ToolbarComponent = /** @class */ (function () {
3680
- function ToolbarComponent(gantt, scrollSyncService) {
4913
+ function ToolbarComponent(gantt) {
3681
4914
  this.gantt = gantt;
3682
- this.scrollSyncService = scrollSyncService;
3683
4915
  this.context = {};
4916
+ this.role = 'toolbar';
3684
4917
  }
3685
4918
  Object.defineProperty(ToolbarComponent.prototype, "position", {
3686
4919
  get: function () {
@@ -3708,12 +4941,13 @@ var ToolbarComponent = /** @class */ (function () {
3708
4941
  enumerable: true,
3709
4942
  configurable: true
3710
4943
  });
3711
- ToolbarComponent.prototype.onViewChange = function (e) {
3712
- this.gantt.activeView = e; // TODO: may be load the timeline data directly in an activeView setter?
3713
- this.gantt.loadTimelineData();
3714
- this.gantt.activeViewChange.emit(e);
3715
- this.scrollSyncService.resetTimelineScrollLeft();
4944
+ ToolbarComponent.prototype.handleViewChange = function (view) {
4945
+ this.gantt.changeActiveView(view);
3716
4946
  };
4947
+ __decorate([
4948
+ HostBinding('attr.role'),
4949
+ __metadata("design:type", String)
4950
+ ], ToolbarComponent.prototype, "role", void 0);
3717
4951
  __decorate([
3718
4952
  Input(),
3719
4953
  __metadata("design:type", Boolean)
@@ -3730,10 +4964,9 @@ var ToolbarComponent = /** @class */ (function () {
3730
4964
  ToolbarComponent = __decorate([
3731
4965
  Component({
3732
4966
  selector: 'kendo-gantt-toolbar',
3733
- template: "\n <ng-container *ngIf=\"!renderTemplate\">\n <kendo-gantt-add-task *ngIf=\"showAddTask\"></kendo-gantt-add-task>\n <span class=\"k-spacer k-toolbar-spacer\"></span>\n <kendo-gantt-view-selector\n *ngIf=\"showViewSelector\"\n [views]=\"gantt.viewTypes\"\n [activeView]=\"gantt.activeView\"\n (activeViewChange)=\"onViewChange($event)\"></kendo-gantt-view-selector>\n </ng-container>\n <ng-template\n *ngIf=\"renderTemplate\"\n [ngTemplateOutlet]=\"toolbarTemplateRef\"\n [ngTemplateOutletContext]=\"context\"\n >\n </ng-template>\n "
4967
+ template: "\n <ng-container *ngIf=\"!renderTemplate\">\n <kendo-gantt-add-task *ngIf=\"showAddTask\"></kendo-gantt-add-task>\n <span class=\"k-spacer k-toolbar-spacer\"></span>\n <kendo-gantt-view-selector\n *ngIf=\"showViewSelector\"\n [views]=\"gantt.viewTypes\"\n [activeView]=\"gantt.activeView\"\n (activeViewChange)=\"handleViewChange($event)\"></kendo-gantt-view-selector>\n </ng-container>\n <ng-template\n *ngIf=\"renderTemplate\"\n [ngTemplateOutlet]=\"toolbarTemplateRef\"\n [ngTemplateOutletContext]=\"context\"\n >\n </ng-template>\n "
3734
4968
  }),
3735
- __metadata("design:paramtypes", [GanttComponent,
3736
- ScrollSyncService])
4969
+ __metadata("design:paramtypes", [GanttComponent])
3737
4970
  ], ToolbarComponent);
3738
4971
  return ToolbarComponent;
3739
4972
  }());
@@ -3788,7 +5021,7 @@ var ViewSelectorComponent = /** @class */ (function () {
3788
5021
  ViewSelectorComponent = __decorate([
3789
5022
  Component({
3790
5023
  selector: 'kendo-gantt-view-selector',
3791
- template: "\n <select class=\"k-dropdown k-views-dropdown\"\n [value]=\"activeView\"\n (change)=\"activeViewChange.emit($event.target.value)\">\n <option *ngFor=\"let view of views\" [value]=\"view\">{{getViewTypeText(view)}}</option>\n </select>\n <kendo-buttongroup class=\"k-gantt-views\" selection=\"single\">\n <button *ngFor=\"let view of views\"\n kendoButton\n type=\"button\"\n [selected]=\"view === activeView\"\n (click)=\"onClick(view)\">{{getViewTypeText(view)}}</button>\n </kendo-buttongroup>\n "
5024
+ template: "\n <select\n class=\"k-dropdownlist k-picker k-rounded-md k-views-dropdown\"\n aria-label=\"View Selector\"\n [value]=\"activeView\"\n (change)=\"activeViewChange.emit($event.target.value)\">\n <option *ngFor=\"let view of views\" [value]=\"view\">{{getViewTypeText(view)}}</option>\n </select>\n <kendo-buttongroup class=\"k-gantt-views\" selection=\"single\">\n <button *ngFor=\"let view of views\"\n kendoButton\n type=\"button\"\n [selected]=\"view === activeView\"\n (click)=\"onClick(view)\">{{getViewTypeText(view)}}</button>\n </kendo-buttongroup>\n "
3792
5025
  }),
3793
5026
  __metadata("design:paramtypes", [LocalizationService])
3794
5027
  ], ViewSelectorComponent);
@@ -3805,6 +5038,9 @@ var getOffsetRelativeToParent = function (element, targetParent) {
3805
5038
  top: 0,
3806
5039
  left: 0
3807
5040
  };
5041
+ if (!targetParent.contains(element)) {
5042
+ return offset;
5043
+ }
3808
5044
  var offsetParent = element;
3809
5045
  while (offsetParent && offsetParent !== targetParent) {
3810
5046
  offset.top += offsetParent.offsetTop;
@@ -3838,9 +5074,9 @@ var dependencyCoordinates = function (from, to, rowHeight, type, minDistanceBefo
3838
5074
  | |
3839
5075
  [[[]]]- -[[[]]]
3840
5076
  */
3841
- if (type === 0 /* FF */ || type === 3 /* SS */) {
5077
+ if (type === DependencyType.FF || type === DependencyType.SS) {
3842
5078
  // polyline start from first task
3843
- var dir = type === 3 /* SS */ ? 'left' : 'right';
5079
+ var dir = type === DependencyType.SS ? 'left' : 'right';
3844
5080
  top = from.top;
3845
5081
  left = from[dir];
3846
5082
  points.push({ top: top, left: left });
@@ -3866,9 +5102,9 @@ var dependencyCoordinates = function (from, to, rowHeight, type, minDistanceBefo
3866
5102
  |
3867
5103
  -[[[]]]
3868
5104
  */
3869
- var startDir = type === 2 /* SF */ ? 'left' : 'right';
3870
- var endDir = type === 2 /* SF */ ? 'right' : 'left';
3871
- var additionalTurn = type === 2 /* SF */
5105
+ var startDir = type === DependencyType.SF ? 'left' : 'right';
5106
+ var endDir = type === DependencyType.SF ? 'right' : 'left';
5107
+ var additionalTurn = type === DependencyType.SF
3872
5108
  ? from[startDir] - minDistanceBeforeTurn * 2 < to[endDir]
3873
5109
  : from[startDir] + minDistanceBeforeTurn * 2 > to[endDir];
3874
5110
  // polyline start from first task
@@ -3951,86 +5187,636 @@ var getArrowEast = function (top, left, arrowSize) {
3951
5187
  });
3952
5188
  return points;
3953
5189
  };
5190
+ /**
5191
+ * @hidden
5192
+ *
5193
+ * Translates the provided client `left` and `top` coords to coords relative to the provided container.
5194
+ * https://developer.mozilla.org/en-US/docs/Web/CSS/CSSOM_View/Coordinate_systems#standard_cssom_coordinate_systems
5195
+ */
5196
+ var clientToOffsetCoords = function (clientLeft, clientTop, offsetContainer) {
5197
+ // client (viewport) coordinates of the target container
5198
+ // https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect#value
5199
+ var offsetContainerClientRect = offsetContainer.getBoundingClientRect();
5200
+ return {
5201
+ left: clientLeft - offsetContainerClientRect.left + offsetContainer.scrollLeft,
5202
+ top: clientTop - offsetContainerClientRect.top + offsetContainer.scrollTop
5203
+ };
5204
+ };
5205
+ /**
5206
+ * @hidden
5207
+ *
5208
+ * Retrieves the `left` and `top` values of the center of the provided element.
5209
+ * The retrieved values are relative to the current viewport (client values).
5210
+ * https://developer.mozilla.org/en-US/docs/Web/CSS/CSSOM_View/Coordinate_systems#standard_cssom_coordinate_systems
5211
+ */
5212
+ var getElementClientCenterCoords = function (element) {
5213
+ // client (viewport) coordinates of the targeted element
5214
+ // https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect#value
5215
+ var _a = element.getBoundingClientRect(), left = _a.left, top = _a.top, width = _a.width, height = _a.height;
5216
+ return {
5217
+ left: left + (width / 2),
5218
+ top: top + (height / 2)
5219
+ };
5220
+ };
5221
+
5222
+ /**
5223
+ * Defines the size of the arrow that will be drawn at the end of each Gantt dependency.
5224
+ */
5225
+ var ARROW_SIZE = 4;
5226
+ /**
5227
+ * Defines the distance the polyline will cover from the task element before making a turn.
5228
+ */
5229
+ var MIN_DISTANCE_BEFORE_TURN = 10;
5230
+ /**
5231
+ * @hidden
5232
+ */
5233
+ var GanttDependencyDirective = /** @class */ (function () {
5234
+ function GanttDependencyDirective(polyline, zone, renderer, mapper, dependencyDomService) {
5235
+ var _this = this;
5236
+ this.polyline = polyline;
5237
+ this.zone = zone;
5238
+ this.renderer = renderer;
5239
+ this.mapper = mapper;
5240
+ this.dependencyDomService = dependencyDomService;
5241
+ this.subscriptions = new Subscription();
5242
+ this.subscriptions.add(dependencyDomService.taskChanges
5243
+ .pipe(switchMap(function (changes) {
5244
+ // reacts only on the very last event emission,
5245
+ // ensures that the tasks are drawn in the DOM
5246
+ return _this.zone.onStable.pipe(take(1), map(function () { return changes; }));
5247
+ }))
5248
+ .subscribe(function (changes) { return _this.updatePoints(changes); }));
5249
+ }
5250
+ GanttDependencyDirective.prototype.ngOnDestroy = function () {
5251
+ this.subscriptions.unsubscribe();
5252
+ };
5253
+ GanttDependencyDirective.prototype.ngOnChanges = function (changes) {
5254
+ if (isPresent(changes.dependency)) {
5255
+ this.updatePoints(this.dependencyDomService.dependencyDomArgs);
5256
+ }
5257
+ };
5258
+ GanttDependencyDirective.prototype.updatePoints = function (_a) {
5259
+ var timelineRow = _a.timelineRow, contentContainer = _a.contentContainer, tasks = _a.tasks;
5260
+ if (!isPresent(timelineRow) || !isPresent(contentContainer) ||
5261
+ !isPresent(tasks) || tasks.size === 0 ||
5262
+ !tasks.has(this.mapper.extractFromDependency(this.dependency, 'fromId')) || !tasks.has(this.mapper.extractFromDependency(this.dependency, 'toId'))) {
5263
+ this.clearPoints();
5264
+ return;
5265
+ }
5266
+ var fromCoordinates = getElementRect(tasks.get(this.mapper.extractFromDependency(this.dependency, 'fromId')), contentContainer);
5267
+ var toCoordinates = getElementRect(tasks.get(this.mapper.extractFromDependency(this.dependency, 'toId')), contentContainer);
5268
+ var timelineRowHeight = isDocumentAvailable() ? timelineRow.getBoundingClientRect().height : 0;
5269
+ var points = dependencyCoordinates(fromCoordinates, toCoordinates, timelineRowHeight, this.dependency.type, MIN_DISTANCE_BEFORE_TURN, ARROW_SIZE);
5270
+ this.drawPoints(points);
5271
+ };
5272
+ GanttDependencyDirective.prototype.clearPoints = function () {
5273
+ this.renderer.setAttribute(this.polyline.nativeElement, 'points', '');
5274
+ };
5275
+ GanttDependencyDirective.prototype.drawPoints = function (points) {
5276
+ if (!isPresent(points) || points.length === 0) {
5277
+ this.clearPoints();
5278
+ return;
5279
+ }
5280
+ var parsedCoords = points.map(function (_a) {
5281
+ var left = _a.left, top = _a.top;
5282
+ return left + "," + top;
5283
+ }).join(' ');
5284
+ this.renderer.setAttribute(this.polyline.nativeElement, 'points', parsedCoords);
5285
+ };
5286
+ __decorate([
5287
+ Input(),
5288
+ __metadata("design:type", Object)
5289
+ ], GanttDependencyDirective.prototype, "dependency", void 0);
5290
+ GanttDependencyDirective = __decorate([
5291
+ Directive({
5292
+ selector: '[kendoGanttDependency]'
5293
+ }),
5294
+ __metadata("design:paramtypes", [ElementRef,
5295
+ NgZone,
5296
+ Renderer2,
5297
+ MappingService,
5298
+ DependencyDomService])
5299
+ ], GanttDependencyDirective);
5300
+ return GanttDependencyDirective;
5301
+ }());
5302
+
5303
+ /**
5304
+ * @hidden
5305
+ */
5306
+ var DragValidationTooltipComponent = /** @class */ (function () {
5307
+ function DragValidationTooltipComponent() {
5308
+ /**
5309
+ * Sets the status class of the attempted operation.
5310
+ * Note that the status will be ignored and the `neutral` status class will be rendered,
5311
+ * if the any of the fromTaskName or toTaskName are not populated.
5312
+ */
5313
+ this.isValid = false;
5314
+ }
5315
+ DragValidationTooltipComponent = __decorate([
5316
+ Component({
5317
+ template: "\n <div\n class=\"k-tooltip k-gantt-tooltip-validation\"\n [class.k-gantt-tooltip-valid]=\"showValidityStatus && isValid\"\n [class.k-gantt-tooltip-invalid]=\"showValidityStatus && !isValid\"\n >\n <div class=\"k-gantt-tooltip-validation-row\">\n <span class=\"k-gantt-tooltip-validation-label\">From:</span>\n <span class=\"k-gantt-tooltip-validation-value\">{{ fromTaskName }}</span>\n </div>\n <div class=\"k-gantt-tooltip-validation-row\">\n <span class=\"k-gantt-tooltip-validation-label\">To:</span>\n <span class=\"k-gantt-tooltip-validation-value\">{{ toTaskName }}</span>\n </div>\n </div>\n ",
5318
+ styles: ["\n .k-gantt-tooltip-validation {\n max-width: 200px;\n display: block;\n }\n .k-gantt-tooltip-validation::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 4px;\n height: 100%;\n background: #656565;\n }\n .k-gantt-tooltip-validation.k-gantt-tooltip-valid::before {\n background: #37B400;\n }\n .k-gantt-tooltip-validation.k-gantt-tooltip-invalid::before {\n background: #F31700;\n }\n .k-gantt-tooltip-validation-row {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .k-gantt-tooltip-validation-label {\n display: inline-flex;\n width: 50px;\n }\n .k-gantt-tooltip-validation-value {\n font-weight: bold;\n }\n "]
5319
+ })
5320
+ ], DragValidationTooltipComponent);
5321
+ return DragValidationTooltipComponent;
5322
+ }());
5323
+
5324
+ /**
5325
+ * When added to the .k-task-dot, the element will be kept with hover styles.
5326
+ * Used for the drag clue from which the dragging has started.
5327
+ */
5328
+ var DRAG_CLUE_HOVER_CLASS = 'k-state-hover';
5329
+ /**
5330
+ * Add the selection disabling class to the enitre container.
5331
+ * Otherwise existing selection on a given task text prevents dragging the clue even if the clue has `user-select: none` styles.
5332
+ */
5333
+ var USER_SELECT_NONE_CLASS = 'k-user-select-none';
5334
+ /**
5335
+ * When added to the .k-task-wrap, the containing .k-task-dot elements will be kept visible even when not hovered.
5336
+ * Used for the drag clue from which the dragging has started.
5337
+ */
5338
+ var TASK_WRAPPER_DRAG_CLASS = 'k-origin';
5339
+ /**
5340
+ * Use 20px margin between the pointer and the popup.
5341
+ * Could be made user-configurable if there's demand.
5342
+ */
5343
+ var DEFAULT_POPUP_VERTICAL_MARGIN = 20;
5344
+ /**
5345
+ * A directive which enables the creation of new dependencies via dragging.
5346
+ */
5347
+ var DependencyDragCreateDirective = /** @class */ (function () {
5348
+ function DependencyDragCreateDirective(gantt, zone, renderer, mapper, popupService, timelineScrollService) {
5349
+ this.gantt = gantt;
5350
+ this.zone = zone;
5351
+ this.renderer = renderer;
5352
+ this.mapper = mapper;
5353
+ this.popupService = popupService;
5354
+ this.timelineScrollService = timelineScrollService;
5355
+ /**
5356
+ * Specifies whether the validation tooltip will be displayed during drag operations.
5357
+ *
5358
+ * @default true
5359
+ */
5360
+ this.displayValidationTooltip = true;
5361
+ this.gantt.renderDependencyDragClues = true;
5362
+ }
5363
+ Object.defineProperty(DependencyDragCreateDirective.prototype, "container", {
5364
+ get: function () {
5365
+ if (!isPresent(this.gantt.timeline) || !isPresent(this.gantt.timeline.timelineContent)) {
5366
+ return null;
5367
+ }
5368
+ return this.gantt.timeline.timelineContent.nativeElement;
5369
+ },
5370
+ enumerable: true,
5371
+ configurable: true
5372
+ });
5373
+ Object.defineProperty(DependencyDragCreateDirective.prototype, "polyline", {
5374
+ get: function () {
5375
+ if (!isPresent(this.gantt.timeline) || !isPresent(this.gantt.timeline.dependencyDragCreatePolyline)) {
5376
+ return null;
5377
+ }
5378
+ return this.gantt.timeline.dependencyDragCreatePolyline.nativeElement;
5379
+ },
5380
+ enumerable: true,
5381
+ configurable: true
5382
+ });
5383
+ Object.defineProperty(DependencyDragCreateDirective.prototype, "popupContainer", {
5384
+ get: function () {
5385
+ if (!isPresent(this.gantt.timeline) || !isPresent(this.gantt.timeline.dragPopupContainer)) {
5386
+ return null;
5387
+ }
5388
+ return this.gantt.timeline.dragPopupContainer;
5389
+ },
5390
+ enumerable: true,
5391
+ configurable: true
5392
+ });
5393
+ DependencyDragCreateDirective.prototype.ngAfterViewInit = function () {
5394
+ this.subscribeDraggable();
5395
+ this.addScrollListener();
5396
+ };
5397
+ DependencyDragCreateDirective.prototype.ngOnDestroy = function () {
5398
+ this.unsubscribeDraggable();
5399
+ this.removeScrollListener();
5400
+ this.fromTaskClue = null;
5401
+ this.cancelScroll();
5402
+ this.closeDragPopup();
5403
+ };
5404
+ DependencyDragCreateDirective.prototype.subscribeDraggable = function () {
5405
+ this.dragSubscriptions = this.gantt.timeline.timelineContainerPress
5406
+ .subscribe(this.handlePress.bind(this));
5407
+ this.dragSubscriptions.add(this.gantt.timeline.timelineContainerDrag
5408
+ .subscribe(this.handleDrag.bind(this)));
5409
+ this.dragSubscriptions.add(this.gantt.timeline.timelineContainerRelease
5410
+ .subscribe(this.handleRelease.bind(this)));
5411
+ };
5412
+ DependencyDragCreateDirective.prototype.unsubscribeDraggable = function () {
5413
+ if (isPresent(this.dragSubscriptions)) {
5414
+ this.dragSubscriptions.unsubscribe();
5415
+ this.dragSubscriptions = null;
5416
+ }
5417
+ };
5418
+ DependencyDragCreateDirective.prototype.handlePress = function (_a) {
5419
+ var clientX = _a.clientX, clientY = _a.clientY;
5420
+ // using `originalEvent.target` is not reliable under mobile devices with the current implementation of the draggable, so use this instead
5421
+ var target = elementFromPoint(clientX, clientY);
5422
+ if (isDependencyDragClue(target)) {
5423
+ this.fromTaskClue = target;
5424
+ this.assignDragStartClasses(this.fromTaskClue);
5425
+ // use the center of the target clue as polyline starting point
5426
+ var dragClueCenterCoords = getElementClientCenterCoords(this.fromTaskClue);
5427
+ // the polyline uses `position: aboslute`, so translate the client coordinates to offset coordinates (`left` and `top` relative to the timeline container)
5428
+ this.polylineStartCoords = clientToOffsetCoords(dragClueCenterCoords.left, dragClueCenterCoords.top, this.container);
5429
+ }
5430
+ };
5431
+ DependencyDragCreateDirective.prototype.handleDrag = function (_a) {
5432
+ var clientX = _a.clientX, clientY = _a.clientY;
5433
+ if (isPresent(this.fromTaskClue)) {
5434
+ // the polyline uses `position: aboslute`, so translate the client coordinates to offset coordinates (`left` and `top` relative to the timeline container)
5435
+ var pointerOffsetCoords = clientToOffsetCoords(clientX, clientY, this.container);
5436
+ // the start coords are calculated just once per drag session in handlePress
5437
+ // use the current drag coords as polyline end coords
5438
+ this.updatePolyline(this.polylineStartCoords, pointerOffsetCoords);
5439
+ this.currentPointerClientCoords = { left: clientX, top: clientY };
5440
+ if (this.gantt.dragScrollSettings.enabled) {
5441
+ // use client coordinates for scroll trigger
5442
+ this.scrollPointIntoView(this.currentPointerClientCoords);
5443
+ }
5444
+ if (this.displayValidationTooltip) {
5445
+ this.updateDragPopup(pointerOffsetCoords);
5446
+ }
5447
+ }
5448
+ };
5449
+ DependencyDragCreateDirective.prototype.handleRelease = function (_a) {
5450
+ var _this = this;
5451
+ var clientX = _a.clientX, clientY = _a.clientY;
5452
+ if (!isPresent(this.fromTaskClue)) {
5453
+ return;
5454
+ }
5455
+ // using `originalEvent.target` is not reliable under mobile devices with the current implementation of the draggable, so use this instead
5456
+ var target = elementFromPoint(clientX, clientY);
5457
+ if (isDependencyDragClue(target) && !sameTaskClues(this.fromTaskClue, target, this.container)) {
5458
+ this.zone.run(function () {
5459
+ var _a;
5460
+ var fromTaskClue = _this.fromTaskClue;
5461
+ var toTaskClue = target;
5462
+ var fromTask = _this.gantt.renderedTreeListItems[getClosestTaskIndex(fromTaskClue, _this.container)];
5463
+ var toTask = _this.gantt.renderedTreeListItems[getClosestTaskIndex(toTaskClue, _this.container)];
5464
+ var dependencyType = getDependencyTypeFromTargetTasks(fromTaskClue, toTaskClue);
5465
+ var _b = _this.mapper.dependencyFields, fromId = _b.fromId, toId = _b.toId, type = _b.type;
5466
+ _this.gantt.dependencyAdd.emit({
5467
+ fromTask: fromTask,
5468
+ toTask: toTask,
5469
+ type: dependencyType,
5470
+ isValid: _this.gantt.validateNewDependency((_a = {},
5471
+ _a[fromId] = _this.mapper.extractFromTask(fromTask, 'id'),
5472
+ _a[toId] = _this.mapper.extractFromTask(toTask, 'id'),
5473
+ _a[type] = dependencyType,
5474
+ _a))
5475
+ });
5476
+ });
5477
+ }
5478
+ this.clearPolyline();
5479
+ this.removeDragStartClasses(this.fromTaskClue);
5480
+ this.fromTaskClue = null;
5481
+ this.cancelScroll();
5482
+ this.closeDragPopup();
5483
+ };
5484
+ DependencyDragCreateDirective.prototype.updatePolyline = function (start, end) {
5485
+ var points = start.left + "," + start.top + " " + end.left + "," + end.top;
5486
+ this.renderer.setAttribute(this.polyline, 'points', points);
5487
+ };
5488
+ DependencyDragCreateDirective.prototype.clearPolyline = function () {
5489
+ this.renderer.removeAttribute(this.polyline, 'points');
5490
+ };
5491
+ DependencyDragCreateDirective.prototype.assignDragStartClasses = function (dragClue) {
5492
+ if (!isPresent(dragClue)) {
5493
+ return;
5494
+ }
5495
+ this.renderer.addClass(this.container, USER_SELECT_NONE_CLASS);
5496
+ this.renderer.addClass(dragClue, DRAG_CLUE_HOVER_CLASS);
5497
+ var taskWrapper = getClosestTaskWrapper(dragClue, this.container);
5498
+ if (isPresent(taskWrapper)) {
5499
+ this.renderer.addClass(taskWrapper, TASK_WRAPPER_DRAG_CLASS);
5500
+ }
5501
+ };
5502
+ DependencyDragCreateDirective.prototype.removeDragStartClasses = function (dragClue) {
5503
+ if (!isPresent(dragClue)) {
5504
+ return;
5505
+ }
5506
+ this.renderer.removeClass(this.container, USER_SELECT_NONE_CLASS);
5507
+ this.renderer.removeClass(dragClue, DRAG_CLUE_HOVER_CLASS);
5508
+ var taskWrapper = getClosestTaskWrapper(dragClue, this.container);
5509
+ if (isPresent(taskWrapper)) {
5510
+ this.renderer.removeClass(taskWrapper, TASK_WRAPPER_DRAG_CLASS);
5511
+ }
5512
+ };
5513
+ DependencyDragCreateDirective.prototype.scrollPointIntoView = function (_a) {
5514
+ var left = _a.left, top = _a.top;
5515
+ this.timelineScrollService.requestScrollCancel();
5516
+ this.timelineScrollService.requestHorizontalScroll(left);
5517
+ this.timelineScrollService.requestVerticalScroll(top);
5518
+ };
5519
+ DependencyDragCreateDirective.prototype.cancelScroll = function () {
5520
+ this.timelineScrollService.requestScrollCancel();
5521
+ };
5522
+ DependencyDragCreateDirective.prototype.addScrollListener = function () {
5523
+ var _this = this;
5524
+ if (!isDocumentAvailable()) {
5525
+ return;
5526
+ }
5527
+ this.zone.runOutsideAngular(function () {
5528
+ return _this.scrollListenerDisposer = _this.renderer.listen(_this.container, 'scroll', function () {
5529
+ // update the polyline only if we're currently dragging
5530
+ if (isPresent(_this.fromTaskClue) && isPresent(_this.currentPointerClientCoords)) {
5531
+ var _a = _this.currentPointerClientCoords, left = _a.left, top_1 = _a.top;
5532
+ var pointerOffsetCoords = clientToOffsetCoords(left, top_1, _this.container);
5533
+ _this.updatePolyline(_this.polylineStartCoords, pointerOffsetCoords);
5534
+ if (_this.displayValidationTooltip) {
5535
+ _this.updateDragPopup(pointerOffsetCoords);
5536
+ }
5537
+ }
5538
+ });
5539
+ });
5540
+ };
5541
+ DependencyDragCreateDirective.prototype.removeScrollListener = function () {
5542
+ if (isPresent(this.scrollListenerDisposer)) {
5543
+ this.scrollListenerDisposer();
5544
+ this.scrollListenerDisposer = null;
5545
+ }
5546
+ };
5547
+ DependencyDragCreateDirective.prototype.openDragPopup = function () {
5548
+ if (isPresent(this.dragPopup)) {
5549
+ this.closeDragPopup();
5550
+ }
5551
+ this.dragPopup = this.popupService.open({
5552
+ animate: false,
5553
+ content: DragValidationTooltipComponent,
5554
+ appendTo: this.popupContainer,
5555
+ positionMode: 'absolute',
5556
+ popupClass: 'k-popup-transparent'
5557
+ });
5558
+ };
5559
+ DependencyDragCreateDirective.prototype.updateDragPopup = function (pointerOffsetPosition) {
5560
+ if (!isPresent(this.dragPopup)) {
5561
+ this.openDragPopup();
5562
+ }
5563
+ var tooltip = this.dragPopup.content.instance;
5564
+ var _a = this.getTooltipContext(), fromTaskName = _a.fromTaskName, toTaskName = _a.toTaskName, isValid = _a.isValid, showValidityStatus = _a.showValidityStatus;
5565
+ if (tooltip.fromTaskName !== fromTaskName ||
5566
+ tooltip.toTaskName !== toTaskName ||
5567
+ tooltip.isValid !== isValid ||
5568
+ tooltip.showValidityStatus !== showValidityStatus) {
5569
+ tooltip.fromTaskName = fromTaskName;
5570
+ tooltip.toTaskName = toTaskName;
5571
+ tooltip.isValid = isValid;
5572
+ tooltip.showValidityStatus = showValidityStatus;
5573
+ this.dragPopup.content.changeDetectorRef.detectChanges();
5574
+ }
5575
+ this.dragPopup.popup.instance.offset = this.normalizePopupPosition(pointerOffsetPosition);
5576
+ this.dragPopup.popup.changeDetectorRef.detectChanges();
5577
+ };
5578
+ DependencyDragCreateDirective.prototype.closeDragPopup = function () {
5579
+ if (isPresent(this.dragPopup)) {
5580
+ this.dragPopup.close();
5581
+ this.dragPopup = null;
5582
+ }
5583
+ };
5584
+ DependencyDragCreateDirective.prototype.extractTaskName = function (target) {
5585
+ if (!isTaskWrapper(target, this.container)) {
5586
+ return null;
5587
+ }
5588
+ var taskIndex = getClosestTaskIndex(target, this.container);
5589
+ var task = this.gantt.renderedTreeListItems[taskIndex];
5590
+ var taskName = this.mapper.extractFromTask(task, 'title');
5591
+ return taskName;
5592
+ };
5593
+ DependencyDragCreateDirective.prototype.getTooltipContext = function () {
5594
+ var _a;
5595
+ var fromTaskName = this.extractTaskName(this.fromTaskClue);
5596
+ var currentPointerTarget = elementFromPoint(this.currentPointerClientCoords.left, this.currentPointerClientCoords.top);
5597
+ var toTaskName = isTaskWrapper(currentPointerTarget, this.container) && !sameTaskClues(this.fromTaskClue, currentPointerTarget, this.container) ?
5598
+ this.extractTaskName(currentPointerTarget) :
5599
+ '';
5600
+ var showValidityStatus = isDependencyDragClue(currentPointerTarget) && !sameTaskClues(this.fromTaskClue, currentPointerTarget, this.container);
5601
+ var _b = this.mapper.dependencyFields, fromId = _b.fromId, toId = _b.toId, type = _b.type;
5602
+ return {
5603
+ fromTaskName: fromTaskName,
5604
+ toTaskName: toTaskName,
5605
+ showValidityStatus: showValidityStatus,
5606
+ isValid: showValidityStatus && this.gantt.validateNewDependency((_a = {},
5607
+ _a[fromId] = this.mapper.extractFromTask(this.gantt.renderedTreeListItems[getClosestTaskIndex(this.fromTaskClue, this.container)], 'id'),
5608
+ _a[toId] = this.mapper.extractFromTask(this.gantt.renderedTreeListItems[getClosestTaskIndex(currentPointerTarget, this.container)], 'id'),
5609
+ _a[type] = getDependencyTypeFromTargetTasks(this.fromTaskClue, currentPointerTarget),
5610
+ _a))
5611
+ };
5612
+ };
5613
+ /**
5614
+ * Restricts the popup position to not go below the scroll height or width of the container.
5615
+ * Flips the position of the popup when there's not enough vertical space in the visible part of the container to render the popup.
5616
+ */
5617
+ DependencyDragCreateDirective.prototype.normalizePopupPosition = function (pointerOffsetPosition) {
5618
+ var top = pointerOffsetPosition.top + DEFAULT_POPUP_VERTICAL_MARGIN;
5619
+ var containerClientBottom = this.container.clientHeight + this.container.scrollTop;
5620
+ var popupHeight = this.dragPopup.popupElement.querySelector('.k-tooltip').clientHeight;
5621
+ var enoughSpaceToRender = top < containerClientBottom - popupHeight;
5622
+ // flip the popup above the pointer if there's not enough space in the bottom of the container
5623
+ if (!enoughSpaceToRender) {
5624
+ // margin * 2 to account for the already applied margin
5625
+ top -= popupHeight + (DEFAULT_POPUP_VERTICAL_MARGIN * 2);
5626
+ }
5627
+ // center the popup horizontally according to the pointer position
5628
+ var popupWidth = this.dragPopup.popupElement.querySelector('.k-tooltip').clientWidth;
5629
+ var left = pointerOffsetPosition.left - popupWidth / 2;
5630
+ // don't allow the popup to be cut out of the viewport
5631
+ var minLeftTop = 0;
5632
+ // restrict the popup from being positioned beyond or before the available scrollable space
5633
+ return {
5634
+ left: fitToRange(left, minLeftTop, this.container.scrollWidth - popupWidth),
5635
+ top: fitToRange(top, minLeftTop, this.container.scrollHeight - popupHeight)
5636
+ };
5637
+ };
5638
+ __decorate([
5639
+ Input(),
5640
+ __metadata("design:type", Boolean)
5641
+ ], DependencyDragCreateDirective.prototype, "displayValidationTooltip", void 0);
5642
+ DependencyDragCreateDirective = __decorate([
5643
+ Directive({
5644
+ selector: '[kendoGanttDependencyDragCreate]'
5645
+ }),
5646
+ __metadata("design:paramtypes", [GanttComponent,
5647
+ NgZone,
5648
+ Renderer2,
5649
+ MappingService,
5650
+ PopupService,
5651
+ TimelineScrollService])
5652
+ ], DependencyDragCreateDirective);
5653
+ return DependencyDragCreateDirective;
5654
+ }());
3954
5655
 
3955
5656
  /**
3956
- * Defines the size of the arrow that will be drawn at the end of each Gantt dependency.
5657
+ * @hidden
3957
5658
  */
3958
- var ARROW_SIZE = 4;
5659
+ var ScrollDirection;
5660
+ (function (ScrollDirection) {
5661
+ ScrollDirection[ScrollDirection["Backwards"] = -1] = "Backwards";
5662
+ ScrollDirection[ScrollDirection["Forward"] = 1] = "Forward";
5663
+ })(ScrollDirection || (ScrollDirection = {}));
3959
5664
  /**
3960
- * Defines the distance the polyline will cover from the task element before making a turn.
5665
+ * @hidden
3961
5666
  */
3962
- var MIN_DISTANCE_BEFORE_TURN = 10;
5667
+ var ScrollAxis;
5668
+ (function (ScrollAxis) {
5669
+ ScrollAxis["Vertical"] = "scrollTop";
5670
+ ScrollAxis["Horizontal"] = "scrollLeft";
5671
+ })(ScrollAxis || (ScrollAxis = {}));
5672
+
3963
5673
  /**
3964
5674
  * @hidden
5675
+ *
5676
+ * Checks if the beginning of the scrollable element is reached (top/left).
5677
+ * Floors the top value.
3965
5678
  */
3966
- var GanttDependencyDirective = /** @class */ (function () {
3967
- function GanttDependencyDirective(polyline, zone, renderer, mapper, dependencyDomService) {
3968
- var _this = this;
3969
- this.polyline = polyline;
5679
+ var isUpperLimitReached = function (element, axis) { return Math.floor(element[axis]) <= 0; };
5680
+ /**
5681
+ * @hidden
5682
+ *
5683
+ * Checks if the end of the scrollable element is reached (bottom/right).
5684
+ * Ceils the top value.
5685
+ */
5686
+ var isBottomLimitReached = function (element, axis) {
5687
+ var elementSize = axis === ScrollAxis.Horizontal ?
5688
+ element.scrollWidth - element.clientWidth :
5689
+ element.scrollHeight - element.clientHeight;
5690
+ return Math.ceil(element[axis]) >= elementSize;
5691
+ };
5692
+ /**
5693
+ * @hidden
5694
+ *
5695
+ * Scrolls the element in the given direction by the provided step in the provided scroll axis.
5696
+ *
5697
+ * If the targeted scroll incrementation doesn't yield any result due to device pixel ratio issues (https://github.com/dimitar-pechev/RenderingIndependentScrollOffsets#readme),
5698
+ * increments the step with 1px and again attempts to change the scrollTop of the element, until the content is actually scrolled.
5699
+ *
5700
+ * Cuts the operation short after 20 unsuccessful attempts to prevent infinite loops in possible corner-case scenarios.
5701
+ */
5702
+ var scrollElement = function (element, step, direction, scrollAxis) {
5703
+ if (!(isPresent(element) && isDocumentAvailable())) {
5704
+ return;
5705
+ }
5706
+ var initialScrollPosition = element[scrollAxis];
5707
+ var currentStep = step;
5708
+ var iterations = 0;
5709
+ while (initialScrollPosition === element[scrollAxis] &&
5710
+ !(direction === ScrollDirection.Backwards && isUpperLimitReached(element, scrollAxis)) &&
5711
+ !(direction === ScrollDirection.Forward && isBottomLimitReached(element, scrollAxis)) &&
5712
+ iterations < 20 // cut the operation short in 20 attempts - in case of a wild corner case
5713
+ ) {
5714
+ element[scrollAxis] += (currentStep * direction);
5715
+ // try with a larger step if the current one doesn't update the scroll position successfully
5716
+ currentStep += 1;
5717
+ iterations += 1;
5718
+ }
5719
+ };
5720
+ /**
5721
+ * @hidden
5722
+ *
5723
+ * As client coordinates are not restricted to the range 0px - {viewportSize}px, but can have negative starting values or ending values greater than the viewport size,
5724
+ * this function extracts the visible boundaries of the provided element - fall-backing to 0 when the top/left are below 0,
5725
+ * and fall-backing to the actual visible size of the container for bottom/right.
5726
+ */
5727
+ var getViewportBoundaries = function (element) {
5728
+ var elementRect = element.getBoundingClientRect();
5729
+ // if the beginning of the scrollable container is above/before the current viewport, fall-back to 0
5730
+ var topLimit = Math.max(elementRect.top, 0);
5731
+ var leftLimit = Math.max(elementRect.left, 0);
5732
+ // if the end of the scrollable container is beneath/after the current viewport, fall-back to its client height
5733
+ // add the distance from the start of the viewport to the beginning of the container to ensure scrolling bottom begins when the actual end of the container is reached
5734
+ var bottomLimit = topLimit + Math.min(elementRect.bottom, element.clientHeight);
5735
+ var rightLimit = leftLimit + Math.min(elementRect.right, element.clientWidth);
5736
+ return {
5737
+ top: topLimit,
5738
+ bottom: bottomLimit,
5739
+ left: leftLimit,
5740
+ right: rightLimit
5741
+ };
5742
+ };
5743
+
5744
+ /**
5745
+ * @hidden
5746
+ */
5747
+ var TimelineScrollableDirective = /** @class */ (function () {
5748
+ function TimelineScrollableDirective(timelineScrollableContainer, scrollService, zone) {
5749
+ this.timelineScrollableContainer = timelineScrollableContainer;
5750
+ this.scrollService = scrollService;
3970
5751
  this.zone = zone;
3971
- this.renderer = renderer;
3972
- this.mapper = mapper;
3973
- this.dependencyDomService = dependencyDomService;
3974
5752
  this.subscriptions = new Subscription();
3975
- this.subscriptions.add(dependencyDomService.taskChanges
3976
- .pipe(switchMap(function (changes) {
3977
- // reacts only on the very last event emission,
3978
- // ensures that the tasks are drawn in the DOM
3979
- return _this.zone.onStable.pipe(take(1), map(function () { return changes; }));
3980
- }))
3981
- .subscribe(function (changes) { return _this.updatePoints(changes); }));
5753
+ this.subscriptions.add(this.scrollService.horizontalScroll
5754
+ .subscribe(this.scrollHorizontallyTo.bind(this)));
5755
+ this.subscriptions.add(this.scrollService.verticalScroll
5756
+ .subscribe(this.scrollVerticallyTo.bind(this)));
5757
+ this.subscriptions.add(this.scrollService.scrollCancel
5758
+ .subscribe(this.cancelScroll.bind(this)));
3982
5759
  }
3983
- GanttDependencyDirective.prototype.ngOnDestroy = function () {
5760
+ TimelineScrollableDirective.prototype.ngOnDestroy = function () {
3984
5761
  this.subscriptions.unsubscribe();
3985
5762
  };
3986
- GanttDependencyDirective.prototype.ngOnChanges = function (changes) {
3987
- if (isPresent(changes.dependency)) {
3988
- this.updatePoints(this.dependencyDomService.dependencyDomArgs);
3989
- }
3990
- };
3991
- GanttDependencyDirective.prototype.updatePoints = function (_a) {
3992
- var timelineRow = _a.timelineRow, contentContainer = _a.contentContainer, tasks = _a.tasks;
3993
- if (!isPresent(timelineRow) || !isPresent(contentContainer) ||
3994
- !isPresent(tasks) || tasks.size === 0 ||
3995
- !tasks.has(this.mapper.extractFromDependency(this.dependency, 'fromId')) || !tasks.has(this.mapper.extractFromDependency(this.dependency, 'toId'))) {
3996
- this.clearPoints();
3997
- return;
3998
- }
3999
- var fromCoordinates = getElementRect(tasks.get(this.mapper.extractFromDependency(this.dependency, 'fromId')), contentContainer);
4000
- var toCoordinates = getElementRect(tasks.get(this.mapper.extractFromDependency(this.dependency, 'toId')), contentContainer);
4001
- var timelineRowHeight = isDocumentAvailable() ? timelineRow.getBoundingClientRect().height : 0;
4002
- var points = dependencyCoordinates(fromCoordinates, toCoordinates, timelineRowHeight, this.dependency.type, MIN_DISTANCE_BEFORE_TURN, ARROW_SIZE);
4003
- this.drawPoints(points);
5763
+ TimelineScrollableDirective.prototype.scrollHorizontallyTo = function (left) {
5764
+ var _this = this;
5765
+ this.zone.runOutsideAngular(function () {
5766
+ var container = _this.timelineScrollableContainer.nativeElement;
5767
+ var visibleBoundaries = getViewportBoundaries(container);
5768
+ if (left < visibleBoundaries.left + _this.scrollSettings.threshold) {
5769
+ _this.horizontalScrollInterval = setInterval(function () {
5770
+ return scrollElement(container, _this.scrollSettings.step, ScrollDirection.Backwards, ScrollAxis.Horizontal);
5771
+ }, _this.scrollSettings.interval);
5772
+ }
5773
+ else if (left > visibleBoundaries.right - _this.scrollSettings.threshold) {
5774
+ _this.horizontalScrollInterval = setInterval(function () {
5775
+ return scrollElement(container, _this.scrollSettings.step, ScrollDirection.Forward, ScrollAxis.Horizontal);
5776
+ }, _this.scrollSettings.interval);
5777
+ }
5778
+ });
4004
5779
  };
4005
- GanttDependencyDirective.prototype.clearPoints = function () {
4006
- this.renderer.setAttribute(this.polyline.nativeElement, 'points', '');
5780
+ TimelineScrollableDirective.prototype.scrollVerticallyTo = function (top) {
5781
+ var _this = this;
5782
+ this.zone.runOutsideAngular(function () {
5783
+ var container = _this.timelineScrollableContainer.nativeElement;
5784
+ var visibleBoundaries = getViewportBoundaries(container);
5785
+ if (top < visibleBoundaries.top + _this.scrollSettings.threshold) {
5786
+ _this.verticalScrollInterval = setInterval(function () {
5787
+ return scrollElement(container, _this.scrollSettings.step, ScrollDirection.Backwards, ScrollAxis.Vertical);
5788
+ }, _this.scrollSettings.interval);
5789
+ }
5790
+ else if (top > visibleBoundaries.bottom - _this.scrollSettings.threshold) {
5791
+ _this.verticalScrollInterval = setInterval(function () {
5792
+ return scrollElement(container, _this.scrollSettings.step, ScrollDirection.Forward, ScrollAxis.Vertical);
5793
+ }, _this.scrollSettings.interval);
5794
+ }
5795
+ });
4007
5796
  };
4008
- GanttDependencyDirective.prototype.drawPoints = function (points) {
4009
- if (!isPresent(points) || points.length === 0) {
4010
- this.clearPoints();
4011
- return;
5797
+ TimelineScrollableDirective.prototype.cancelScroll = function () {
5798
+ if (isPresent(this.verticalScrollInterval)) {
5799
+ clearInterval(this.verticalScrollInterval);
5800
+ this.verticalScrollInterval = null;
5801
+ }
5802
+ if (isPresent(this.horizontalScrollInterval)) {
5803
+ clearInterval(this.horizontalScrollInterval);
5804
+ this.horizontalScrollInterval = null;
4012
5805
  }
4013
- var parsedCoords = points.map(function (_a) {
4014
- var left = _a.left, top = _a.top;
4015
- return left + "," + top;
4016
- }).join(' ');
4017
- this.renderer.setAttribute(this.polyline.nativeElement, 'points', parsedCoords);
4018
5806
  };
4019
5807
  __decorate([
4020
5808
  Input(),
4021
5809
  __metadata("design:type", Object)
4022
- ], GanttDependencyDirective.prototype, "dependency", void 0);
4023
- GanttDependencyDirective = __decorate([
5810
+ ], TimelineScrollableDirective.prototype, "scrollSettings", void 0);
5811
+ TimelineScrollableDirective = __decorate([
4024
5812
  Directive({
4025
- selector: '[kendoGanttDependency]'
5813
+ selector: '[kendoGanttTimelineScrollable]'
4026
5814
  }),
4027
5815
  __metadata("design:paramtypes", [ElementRef,
4028
- NgZone,
4029
- Renderer2,
4030
- MappingService,
4031
- DependencyDomService])
4032
- ], GanttDependencyDirective);
4033
- return GanttDependencyDirective;
5816
+ TimelineScrollService,
5817
+ NgZone])
5818
+ ], TimelineScrollableDirective);
5819
+ return TimelineScrollableDirective;
4034
5820
  }());
4035
5821
 
4036
5822
  var TimelineDayViewComponent = /** @class */ (function (_super) {
@@ -4121,31 +5907,62 @@ var TimelineMonthViewComponent = /** @class */ (function (_super) {
4121
5907
  * @hidden
4122
5908
  */
4123
5909
  var EditDialogComponent = /** @class */ (function () {
4124
- function EditDialogComponent(mapper, editService, localizationService) {
5910
+ function EditDialogComponent(mapper, editService, cdr, localizationService) {
4125
5911
  this.mapper = mapper;
4126
5912
  this.editService = editService;
5913
+ this.cdr = cdr;
4127
5914
  this.localizationService = localizationService;
4128
5915
  }
5916
+ EditDialogComponent.prototype.ngOnInit = function () {
5917
+ var _this = this;
5918
+ this.editService.loadTasks(this.data).subscribe(function (value) {
5919
+ _this.loadedTasks = value;
5920
+ });
5921
+ };
5922
+ Object.defineProperty(EditDialogComponent.prototype, "predecessors", {
5923
+ get: function () {
5924
+ return this.editService.predecessors;
5925
+ },
5926
+ set: function (items) {
5927
+ this.editService.predecessors = items;
5928
+ },
5929
+ enumerable: true,
5930
+ configurable: true
5931
+ });
5932
+ Object.defineProperty(EditDialogComponent.prototype, "successors", {
5933
+ get: function () {
5934
+ return this.editService.successors;
5935
+ },
5936
+ set: function (items) {
5937
+ this.editService.successors = items;
5938
+ },
5939
+ enumerable: true,
5940
+ configurable: true
5941
+ });
4129
5942
  EditDialogComponent.prototype.getText = function (token) {
4130
5943
  return this.localizationService.get(token);
4131
5944
  };
5945
+ EditDialogComponent.prototype.getDependencyType = function (typeId) {
5946
+ return DependencyType[typeId];
5947
+ };
4132
5948
  EditDialogComponent.prototype.handleEditingResult = function (editResultType) {
4133
5949
  this.editService.triggerEditEvent(editResultType);
4134
5950
  };
4135
- EditDialogComponent.prototype.onTaskDelete = function () {
4136
- this.editService.showConfirmationDialog.next();
5951
+ EditDialogComponent.prototype.handleTaskDelete = function () {
5952
+ this.editService.taskDelete.next(this.editService.dataItem);
4137
5953
  };
4138
5954
  __decorate([
4139
5955
  Input(),
4140
- __metadata("design:type", FormGroup)
4141
- ], EditDialogComponent.prototype, "formGroup", void 0);
5956
+ __metadata("design:type", Array)
5957
+ ], EditDialogComponent.prototype, "data", void 0);
4142
5958
  EditDialogComponent = __decorate([
4143
5959
  Component({
4144
5960
  selector: 'kendo-gantt-edit-dialog',
4145
- template: "\n <kendo-dialog\n [title]=\"getText('taskEditingDialogTitle')\"\n [width]=\"575\"\n [height]=\"470\"\n (close)=\"handleEditingResult('cancel')\">\n <kendo-dialog-messages\n [closeTitle]=\"getText('taskEditingDialogCloseTitle')\"></kendo-dialog-messages>\n <form class=\"k-form\" [formGroup]=\"formGroup\">\n <kendo-formfield *ngIf=\"formGroup.contains(mapper.taskFields.title)\">\n <kendo-label [for]=\"mapper.taskFields.title\" [text]=\"getText('titleFieldInputLabel')\"></kendo-label>\n <input class=\"k-textbox\" [formControlName]=\"mapper.taskFields.title\" />\n </kendo-formfield>\n <div class=\"k-hstack\">\n <kendo-formfield [style.width.%]=\"49\" *ngIf=\"formGroup.contains(mapper.taskFields.start)\">\n <kendo-label [for]=\"mapper.taskFields.start\" [text]=\"getText('startFieldInputLabel')\"></kendo-label>\n <kendo-datetimepicker [formControlName]=\"mapper.taskFields.start\"></kendo-datetimepicker>\n </kendo-formfield>\n <kendo-treelist-spacer></kendo-treelist-spacer>\n <kendo-formfield [style.width.%]=\"49\" *ngIf=\"formGroup.contains(mapper.taskFields.end)\">\n <kendo-label [for]=\"mapper.taskFields.end\" [text]=\"getText('endFieldInputLabel')\"></kendo-label>\n <kendo-datetimepicker [formControlName]=\"mapper.taskFields.end\"></kendo-datetimepicker>\n </kendo-formfield>\n </div>\n <kendo-formfield [style.width.%]=\"49\" *ngIf=\"formGroup.contains(mapper.taskFields.completionRatio)\">\n <kendo-label [for]=\"mapper.taskFields.completionRatio\" [text]=\"getText('completionRatioFieldInputLabel')\"></kendo-label>\n <kendo-numerictextbox\n [formControlName]=\"mapper.taskFields.completionRatio\"\n [min]=\"0\"\n [max]=\"1\"\n [decimals]=\"2\"\n format=\"p2\"\n [step]=\"0.01\"\n ></kendo-numerictextbox>\n </kendo-formfield>\n </form>\n <kendo-dialog-actions layout=\"normal\">\n <button kendoButton (click)=\"onTaskDelete()\">{{ getText('deleteButtonText') }}</button>\n <kendo-treelist-spacer></kendo-treelist-spacer>\n <button kendoButton [primary]=\"true\" (click)=\"handleEditingResult('save')\">{{ getText('saveButtonText') }}</button>\n <button kendoButton (click)=\"handleEditingResult('cancel')\">{{ getText('cancelButtonText') }}</button>\n </kendo-dialog-actions>\n </kendo-dialog>\n "
5961
+ template: "\n <kendo-dialog\n [title]=\"getText('taskEditingDialogTitle')\"\n [width]=\"575\"\n [height]=\"470\"\n (close)=\"handleEditingResult('cancel')\">\n <kendo-dialog-messages\n [closeTitle]=\"getText('taskEditingDialogCloseTitle')\"></kendo-dialog-messages>\n\n <kendo-tabstrip [keepTabContent]=\"true\" style=\"height: 345px;\">\n <kendo-tabstrip-tab [title]=\"getText('taskEditingGeneralTabTitle')\" [selected]=\"true\">\n <ng-template kendoTabContent>\n <kendo-gantt-task-fields></kendo-gantt-task-fields>\n </ng-template>\n </kendo-tabstrip-tab>\n <kendo-tabstrip-tab [title]=\"getText('taskEditingPredecessorsTabTitle')\">\n <ng-template kendoTabContent>\n <kendo-gantt-dependencies-table\n [tasks]=\"loadedTasks\"\n [(dependencies)]=\"predecessors\"\n dependencyType=\"predecessor\"\n >\n </kendo-gantt-dependencies-table>\n </ng-template>\n </kendo-tabstrip-tab>\n <kendo-tabstrip-tab [title]=\"getText('taskEditingSuccessorsTabTitle')\">\n <ng-template kendoTabContent>\n <kendo-gantt-dependencies-table\n [tasks]=\"loadedTasks\"\n [(dependencies)]=\"successors\"\n dependencyType=\"successor\">\n </kendo-gantt-dependencies-table>\n </ng-template>\n </kendo-tabstrip-tab>\n </kendo-tabstrip>\n\n <kendo-dialog-actions layout=\"normal\">\n <button\n kendoButton\n [kendoEventsOutsideAngular]=\"{\n click: handleTaskDelete\n }\"\n [scope]=\"this\"\n >\n {{ getText('deleteButtonText') }}\n </button>\n <kendo-treelist-spacer></kendo-treelist-spacer>\n <button kendoButton [primary]=\"true\" (click)=\"handleEditingResult('save')\">{{ getText('saveButtonText') }}</button>\n <button kendoButton (click)=\"handleEditingResult('cancel')\">{{ getText('cancelButtonText') }}</button>\n </kendo-dialog-actions>\n </kendo-dialog>\n "
4146
5962
  }),
4147
5963
  __metadata("design:paramtypes", [MappingService,
4148
5964
  EditService,
5965
+ ChangeDetectorRef,
4149
5966
  LocalizationService])
4150
5967
  ], EditDialogComponent);
4151
5968
  return EditDialogComponent;
@@ -4583,6 +6400,160 @@ var GanttAddTaskComponent = /** @class */ (function () {
4583
6400
  return GanttAddTaskComponent;
4584
6401
  }());
4585
6402
 
6403
+ /**
6404
+ * @hidden
6405
+ */
6406
+ var DependenciesTableComponent = /** @class */ (function () {
6407
+ function DependenciesTableComponent(mapper, editService, localizationService) {
6408
+ this.mapper = mapper;
6409
+ this.editService = editService;
6410
+ this.localizationService = localizationService;
6411
+ this.dependenciesChange = new EventEmitter();
6412
+ this.selectedKeys = [];
6413
+ this.formGroups = new FormArray([]);
6414
+ this.dependencyTypes = this.getDependencyTypes();
6415
+ }
6416
+ Object.defineProperty(DependenciesTableComponent.prototype, "taskId", {
6417
+ get: function () {
6418
+ return this.editService.dataItem.id;
6419
+ },
6420
+ enumerable: true,
6421
+ configurable: true
6422
+ });
6423
+ Object.defineProperty(DependenciesTableComponent.prototype, "dependencyIdField", {
6424
+ // The target dependency id field
6425
+ // e.g. if Predecessors, we have the `fromId` which is the currently edited task,
6426
+ // while the `toId` is missing (needs to be selected by the user)
6427
+ get: function () {
6428
+ return this.dependencyType === 'predecessor' ? 'fromId' : 'toId';
6429
+ },
6430
+ enumerable: true,
6431
+ configurable: true
6432
+ });
6433
+ DependenciesTableComponent.prototype.ngOnInit = function () {
6434
+ var _this = this;
6435
+ // generate the FormGroups per each Grid row
6436
+ if (this.formGroups.controls.length === 0) {
6437
+ var fields_1 = this.mapper.dependencyFields;
6438
+ this.dependencies.forEach(function (item) {
6439
+ var _a;
6440
+ var formGroup = new FormGroup((_a = {},
6441
+ _a[fields_1.id] = new FormControl(_this.mapper.extractFromDependency(item, 'id')),
6442
+ _a[fields_1.fromId] = new FormControl(_this.mapper.extractFromDependency(item, 'fromId'), Validators.required),
6443
+ _a[fields_1.toId] = new FormControl(_this.mapper.extractFromDependency(item, 'toId'), Validators.required),
6444
+ _a[fields_1.type] = new FormControl(_this.mapper.extractFromDependency(item, 'type'), Validators.required),
6445
+ _a));
6446
+ _this.formGroups.push(formGroup);
6447
+ });
6448
+ }
6449
+ this.formGroups.valueChanges.subscribe(function (val) {
6450
+ _this.formGroups.controls.forEach(function (control) {
6451
+ if (control.dirty) {
6452
+ _this.editService.updateDependencies(control.value);
6453
+ }
6454
+ });
6455
+ _this.dependenciesChange.emit(val);
6456
+ });
6457
+ };
6458
+ DependenciesTableComponent.prototype.getFormControl = function (dataItemIndex, field) {
6459
+ // return the FormControl for the respective column editor
6460
+ return this.formGroups.controls
6461
+ .find(function (_control, index) { return index === dataItemIndex; })
6462
+ .get(this.mapper.dependencyFields[field]);
6463
+ };
6464
+ DependenciesTableComponent.prototype.getText = function (token) {
6465
+ return this.localizationService.get(token);
6466
+ };
6467
+ DependenciesTableComponent.prototype.getDependencyTypes = function () {
6468
+ var types = Object.keys(DependencyType)
6469
+ .filter(function (value) { return typeof DependencyType[value] === 'number'; })
6470
+ .map(function (type) {
6471
+ return {
6472
+ type: type,
6473
+ id: DependencyType[type]
6474
+ };
6475
+ });
6476
+ return types;
6477
+ };
6478
+ DependenciesTableComponent.prototype.addHandler = function () {
6479
+ var _a;
6480
+ var fields = this.mapper.dependencyFields;
6481
+ var formGroup = new FormGroup((_a = {},
6482
+ _a[fields.id] = new FormControl(),
6483
+ _a[fields.fromId] = new FormControl(this.dependencyIdField === 'toId' ? this.taskId : null, Validators.required),
6484
+ _a[fields.toId] = new FormControl(this.dependencyIdField === 'fromId' ? this.taskId : null, Validators.required),
6485
+ _a[fields.type] = new FormControl(null, Validators.required),
6486
+ _a));
6487
+ this.formGroups.push(formGroup);
6488
+ };
6489
+ DependenciesTableComponent.prototype.removeHandler = function () {
6490
+ var selectedIndex = this.selectedKeys[0];
6491
+ var item = this.formGroups.at(selectedIndex).value;
6492
+ this.editService.deleteDependency(item);
6493
+ this.formGroups.removeAt(selectedIndex);
6494
+ };
6495
+ __decorate([
6496
+ Input(),
6497
+ __metadata("design:type", Array)
6498
+ ], DependenciesTableComponent.prototype, "tasks", void 0);
6499
+ __decorate([
6500
+ Input(),
6501
+ __metadata("design:type", Array)
6502
+ ], DependenciesTableComponent.prototype, "dependencies", void 0);
6503
+ __decorate([
6504
+ Input(),
6505
+ __metadata("design:type", String)
6506
+ ], DependenciesTableComponent.prototype, "dependencyType", void 0);
6507
+ __decorate([
6508
+ Output(),
6509
+ __metadata("design:type", EventEmitter)
6510
+ ], DependenciesTableComponent.prototype, "dependenciesChange", void 0);
6511
+ DependenciesTableComponent = __decorate([
6512
+ Component({
6513
+ selector: 'kendo-gantt-dependencies-table',
6514
+ template: "\n <kendo-grid\n [data]=\"dependencies\"\n [selectable]=\"{ mode: 'single' }\"\n [(selectedKeys)]=\"selectedKeys\"\n kendoGridSelectBy\n [height]=\"275\"\n >\n <ng-template kendoGridToolbarTemplate>\n <button kendoButton (click)=\"addHandler()\">\n {{ getText('taskEditingDependenciesAddButtonText') }}\n </button>\n <button kendoButton (click)=\"removeHandler()\" [disabled]=\"selectedKeys.length === 0\">\n {{ getText('taskEditingDependenciesRemoveButtonText') }}\n </button>\n </ng-template>\n <kendo-grid-column [title]=\"getText('taskEditingDependenciesGridNameColumnTitle')\" [field]=\"dependencyIdField\">\n <ng-template kendoGridCellTemplate let-dataItem=\"dataItem\" let-column=\"column\" let-rowIndex=\"rowIndex\">\n <kendo-dropdownlist\n [data]=\"tasks\"\n textField=\"title\"\n valueField=\"id\"\n [valuePrimitive]=\"true\"\n [formControl]=\"getFormControl(rowIndex, column.field)\"\n >\n </kendo-dropdownlist>\n </ng-template>\n </kendo-grid-column>\n <kendo-grid-column [title]=\"getText('taskEditingDependenciesGridTypeColumnTitle')\" field=\"type\">\n <ng-template kendoGridCellTemplate let-dataItem=\"dataItem\" let-column=\"column\" let-rowIndex=\"rowIndex\">\n <kendo-dropdownlist\n [data]=\"dependencyTypes\"\n textField=\"type\"\n valueField=\"id\"\n [valuePrimitive]=\"true\"\n [formControl]=\"getFormControl(rowIndex, column.field)\"\n >\n </kendo-dropdownlist>\n </ng-template>\n </kendo-grid-column>\n </kendo-grid>\n "
6515
+ }),
6516
+ __metadata("design:paramtypes", [MappingService,
6517
+ EditService,
6518
+ GanttLocalizationService])
6519
+ ], DependenciesTableComponent);
6520
+ return DependenciesTableComponent;
6521
+ }());
6522
+
6523
+ /**
6524
+ * @hidden
6525
+ */
6526
+ var TaskFieldsComponent = /** @class */ (function () {
6527
+ function TaskFieldsComponent(mapper, editService, localizationService) {
6528
+ this.mapper = mapper;
6529
+ this.editService = editService;
6530
+ this.localizationService = localizationService;
6531
+ }
6532
+ Object.defineProperty(TaskFieldsComponent.prototype, "formGroup", {
6533
+ /**
6534
+ * @hidden
6535
+ */
6536
+ get: function () {
6537
+ return this.editService.taskFormGroup;
6538
+ },
6539
+ enumerable: true,
6540
+ configurable: true
6541
+ });
6542
+ TaskFieldsComponent.prototype.getText = function (token) {
6543
+ return this.localizationService.get(token);
6544
+ };
6545
+ TaskFieldsComponent = __decorate([
6546
+ Component({
6547
+ selector: 'kendo-gantt-task-fields',
6548
+ template: "\n <form class=\"k-form\" [formGroup]=\"formGroup\">\n <kendo-formfield *ngIf=\"formGroup.contains(mapper.taskFields.title)\">\n <kendo-label [for]=\"mapper.taskFields.title\" [text]=\"getText('titleFieldInputLabel')\"></kendo-label>\n <input kendoTextBox [formControlName]=\"mapper.taskFields.title\" />\n </kendo-formfield>\n <div class=\"k-hstack\">\n <kendo-formfield [style.width.%]=\"49\" *ngIf=\"formGroup.contains(mapper.taskFields.start)\">\n <kendo-label [for]=\"mapper.taskFields.start\" [text]=\"getText('startFieldInputLabel')\"></kendo-label>\n <kendo-datetimepicker [formControlName]=\"mapper.taskFields.start\"></kendo-datetimepicker>\n </kendo-formfield>\n <kendo-treelist-spacer></kendo-treelist-spacer>\n <kendo-formfield [style.width.%]=\"49\" *ngIf=\"formGroup.contains(mapper.taskFields.end)\">\n <kendo-label [for]=\"mapper.taskFields.end\" [text]=\"getText('endFieldInputLabel')\"></kendo-label>\n <kendo-datetimepicker [formControlName]=\"mapper.taskFields.end\"></kendo-datetimepicker>\n </kendo-formfield>\n </div>\n <kendo-formfield [style.width.%]=\"49\" *ngIf=\"formGroup.contains(mapper.taskFields.completionRatio)\">\n <kendo-label [for]=\"mapper.taskFields.completionRatio\" [text]=\"getText('completionRatioFieldInputLabel')\"></kendo-label>\n <kendo-numerictextbox\n [formControlName]=\"mapper.taskFields.completionRatio\"\n [min]=\"0\"\n [max]=\"1\"\n [decimals]=\"2\"\n format=\"p2\"\n [step]=\"0.01\"\n ></kendo-numerictextbox>\n </kendo-formfield>\n </form>\n "
6549
+ }),
6550
+ __metadata("design:paramtypes", [MappingService,
6551
+ EditService,
6552
+ GanttLocalizationService])
6553
+ ], TaskFieldsComponent);
6554
+ return TaskFieldsComponent;
6555
+ }());
6556
+
4586
6557
  var IMPORTED_MODULES = [
4587
6558
  CommonModule,
4588
6559
  ReactiveFormsModule,
@@ -4594,7 +6565,12 @@ var IMPORTED_MODULES = [
4594
6565
  TreeListModule,
4595
6566
  ButtonsModule,
4596
6567
  DialogModule,
4597
- EventsModule
6568
+ EventsModule,
6569
+ PopupModule,
6570
+ DraggableModule,
6571
+ TabStripModule,
6572
+ GridModule,
6573
+ DropDownsModule
4598
6574
  ];
4599
6575
  var DECLARATIONS = [
4600
6576
  GanttComponent,
@@ -4624,6 +6600,7 @@ var DECLARATIONS = [
4624
6600
  FooterTemplateDirective,
4625
6601
  GanttExpandableDirective,
4626
6602
  GanttDependencyDirective,
6603
+ DependencyDragCreateDirective,
4627
6604
  TimelineDayViewComponent,
4628
6605
  TimelineWeekViewComponent,
4629
6606
  TimelineMonthViewComponent,
@@ -4631,8 +6608,13 @@ var DECLARATIONS = [
4631
6608
  EditDialogComponent,
4632
6609
  CustomMessagesComponent,
4633
6610
  LocalizedMessagesDirective,
4634
- GanttAddTaskComponent
6611
+ GanttAddTaskComponent,
6612
+ DragValidationTooltipComponent,
6613
+ TimelineScrollableDirective,
6614
+ DependenciesTableComponent,
6615
+ TaskFieldsComponent
4635
6616
  ];
6617
+ var ɵ0$3 = touchEnabled;
4636
6618
  /**
4637
6619
  * Represents the [NgModule]({{ site.data.urls.angular['ngmoduleapi'] }})
4638
6620
  * definition for the Gantt component.
@@ -4672,58 +6654,21 @@ var GanttModule = /** @class */ (function () {
4672
6654
  imports: IMPORTED_MODULES.slice(),
4673
6655
  declarations: DECLARATIONS.slice(),
4674
6656
  exports: DECLARATIONS.slice(),
6657
+ entryComponents: [DragValidationTooltipComponent],
4675
6658
  providers: [{
4676
6659
  provide: L10N_PREFIX,
4677
6660
  useValue: 'kendo.gantt'
6661
+ }, {
6662
+ provide: TOUCH_ENABLED,
6663
+ useValue: ɵ0$3
4678
6664
  }]
4679
6665
  })
4680
6666
  ], GanttModule);
4681
6667
  return GanttModule;
4682
6668
  }());
4683
6669
 
4684
- /**
4685
- * @hidden
4686
- */
4687
- var PreventableEvent = /** @class */ (function () {
4688
- function PreventableEvent() {
4689
- this.prevented = false;
4690
- }
4691
- /**
4692
- * Prevents the default action for a specified event.
4693
- * In this way, the source component suppresses
4694
- * the built-in behavior that follows the event.
4695
- */
4696
- PreventableEvent.prototype.preventDefault = function () {
4697
- this.prevented = true;
4698
- };
4699
- /**
4700
- * Returns `true` if the event was prevented
4701
- * by any of its subscribers.
4702
- *
4703
- * @returns `true` if the default action was prevented.
4704
- * Otherwise, returns `false`.
4705
- */
4706
- PreventableEvent.prototype.isDefaultPrevented = function () {
4707
- return this.prevented;
4708
- };
4709
- return PreventableEvent;
4710
- }());
4711
-
4712
- /**
4713
- * Called every time a user leaves an edited cell.
4714
- */
4715
- var CellCloseEvent = /** @class */ (function (_super) {
4716
- __extends(CellCloseEvent, _super);
4717
- function CellCloseEvent(options) {
4718
- var _this = _super.call(this) || this;
4719
- Object.assign(_this, options);
4720
- return _this;
4721
- }
4722
- return CellCloseEvent;
4723
- }(PreventableEvent));
4724
-
4725
6670
  /**
4726
6671
  * Generated bundle index. Do not edit.
4727
6672
  */
4728
6673
 
4729
- export { MappingService, OptionChangesService, DependencyDomService, GanttDependencyDirective, GanttAddTaskComponent, EditDialogComponent, EditService, CustomMessagesComponent, LocalizedMessagesDirective, Messages, PreventableEvent, GanttHeaderTableBodyComponent, GanttMilestoneTaskComponent, GanttSummaryTaskComponent, GanttTaskBase, GanttTaskComponent, GanttTasksTableBodyComponent, ScrollSyncService, GanttTimelineComponent, TimelineBaseViewService, TimelineDayViewComponent, TimelineDayViewService, TimelineMonthViewComponent, TimelineMonthViewService, TimelineViewService, TimelineWeekViewComponent, TimelineWeekViewService, ViewBase, ToolbarComponent, ViewSelectorComponent, GanttComponent, GanttModule, GanttHierarchyBindingDirective, GanttFlatBindingDirective, GanttExpandableDirective, GanttTaskTemplateDirective, GanttTaskContentTemplateDirective, GanttSummaryTaskTemplateDirective, ToolbarTemplateDirective, SelectableDirective, CellCloseEvent, GanttColumnBase, GanttColumnComponent, GanttColumnGroupComponent, GanttSpanColumnComponent, CellTemplateDirective, HeaderTemplateDirective, FooterTemplateDirective, ColumnMenuTemplateDirective, FilterCellTemplateDirective, FilterMenuTemplateDirective, EditTemplateDirective };
6674
+ export { MappingService, OptionChangesService, TOUCH_ENABLED, DependencyDomService, GanttDependencyDirective, DragValidationTooltipComponent, GanttAddTaskComponent, DependenciesTableComponent, EditDialogComponent, EditService, TaskFieldsComponent, CustomMessagesComponent, GanttLocalizationService, LocalizedMessagesDirective, Messages, PreventableEvent, NavigationService, GanttHeaderTableBodyComponent, GanttMilestoneTaskComponent, GanttSummaryTaskComponent, GanttTaskBase, GanttTaskComponent, GanttTasksTableBodyComponent, ScrollSyncService, TimelineScrollableDirective, TimelineScrollService, GanttTimelineComponent, TimelineBaseViewService, TimelineDayViewComponent, TimelineDayViewService, TimelineMonthViewComponent, TimelineMonthViewService, TimelineViewService, TimelineWeekViewComponent, TimelineWeekViewService, ViewBase, ToolbarComponent, ViewSelectorComponent, GanttComponent, GanttModule, GanttHierarchyBindingDirective, GanttFlatBindingDirective, GanttExpandableDirective, DependencyDragCreateDirective, GanttTaskTemplateDirective, GanttTaskContentTemplateDirective, GanttSummaryTaskTemplateDirective, ToolbarTemplateDirective, SelectableDirective, DependencyType, CellCloseEvent, GanttColumnBase, GanttColumnComponent, GanttColumnGroupComponent, GanttSpanColumnComponent, CellTemplateDirective, HeaderTemplateDirective, FooterTemplateDirective, ColumnMenuTemplateDirective, FilterCellTemplateDirective, FilterMenuTemplateDirective, EditTemplateDirective };