@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
@@ -11,8 +11,11 @@ import { Subscription } from 'rxjs';
11
11
  import { validatePackage } from '@progress/kendo-licensing';
12
12
  import { packageMetadata } from './package-metadata';
13
13
  import { anyChanged, hasObservers } from '@progress/kendo-angular-common';
14
+ import { GanttTimelineComponent } from './timeline/gantt-timeline.component';
14
15
  import { GanttColumnBase } from './columns/columns';
15
16
  import { fetchChildren, hasChildren, isSelected, rowClassCallback, taskClassCallback } from './common/default-callbacks';
17
+ import { DependencyType } from './models/models';
18
+ import { LocalizationService } from '@progress/kendo-angular-l10n';
16
19
  import { TimelineViewService } from './timeline/timeline-view.service';
17
20
  import { TimelineDayViewService } from './timeline/timeline-day-view.service';
18
21
  import { TimelineWeekViewService } from './timeline/timeline-week-view.service';
@@ -22,17 +25,25 @@ import { DependencyDomService } from './dependencies/dependency-dom.service';
22
25
  import { MappingService } from './common/mapping.service';
23
26
  import { OptionChangesService } from './common/option-changes.service';
24
27
  import { EditService } from './editing/edit.service';
25
- import { LocalizationService } from '@progress/kendo-angular-l10n';
26
- import { getClosestTaskIndex, isClearButton, isColumnGroup, isPresent, isTask, normalizeGanttData, scrollbarWidth } from './utils';
28
+ import { TimelineScrollService } from './scrolling/timeline-scroll.service';
29
+ import { GanttLocalizationService } from './localization/gantt-localization.service';
30
+ import { NavigationService } from './navigation/navigation.service';
31
+ import { areParentChild, getClosestTaskIndex, isClearButton, isColumnGroup, isPresent, isTask, normalizeGanttData, scrollbarWidth } from './utils';
27
32
  import { DEFAULT_TIMELINE_PANE_SETTINGS, DEFAULT_TREELIST_PANE_SETTINGS } from './models/splitter-pane-options.interface';
28
33
  import { GanttTaskTemplateDirective } from './template-directives/task-template.directive';
29
34
  import { GanttSummaryTaskTemplateDirective } from './template-directives/summary-task-template.directive';
30
35
  import { GanttTaskContentTemplateDirective } from './template-directives/task-content-template.directive';
31
36
  import { ToolbarTemplateDirective } from './toolbar/toolbar-template.directive';
32
37
  import { ViewBase } from './timeline/view-base';
33
- import { getEditItem } from './editing/util';
38
+ import { getEditItem } from './editing/utils';
34
39
  const TREELIST_GROUP_COLUMNS_CLASS = 'k-gantt-treelist-nested-columns';
35
40
  const DEFAULT_VIEW = 'week';
41
+ const DEFAULT_DRAG_SCROLL_SETTINGS = {
42
+ enabled: true,
43
+ step: 3,
44
+ interval: 1,
45
+ threshold: 10
46
+ };
36
47
  /**
37
48
  * Represents the Kendo UI Gantt component for Angular.
38
49
  *
@@ -105,7 +116,7 @@ const DEFAULT_VIEW = 'week';
105
116
  * ```
106
117
  */
107
118
  let GanttComponent = GanttComponent_1 = class GanttComponent {
108
- constructor(timelineViewService, scrollSyncService, renderer, mapper, optionChangesService, dependencyDomService, editService, localizationService, hostElement, zone) {
119
+ constructor(timelineViewService, scrollSyncService, renderer, mapper, optionChangesService, dependencyDomService, editService, localizationService, hostElement, zone, navigationService) {
109
120
  this.timelineViewService = timelineViewService;
110
121
  this.scrollSyncService = scrollSyncService;
111
122
  this.renderer = renderer;
@@ -116,13 +127,33 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
116
127
  this.localizationService = localizationService;
117
128
  this.hostElement = hostElement;
118
129
  this.zone = zone;
130
+ this.navigationService = navigationService;
131
+ /**
132
+ * @hidden
133
+ */
134
+ this.roleDescription = 'Gantt Chart';
135
+ /**
136
+ * @hidden
137
+ */
138
+ this.role = 'application';
119
139
  this.hostClasses = true;
120
140
  /**
121
- * Provides a callback that determines if the given task is selected ([see example]({% slug selection_gantt %}#toc-custom-selection))
141
+ * Specifies a callback that determines if the given task is selected ([see example]({% slug selection_gantt %}#toc-custom-selection)).
122
142
  *
123
143
  * > The [`selectable`]({% slug api_gantt_ganttcomponent %}#toc-selectable) prop has to be set to `true` in order for this callback to be executed.
124
144
  */
125
145
  this.isSelected = isSelected;
146
+ /**
147
+ * Specifies a callback that determines if a new dependency is valid.
148
+ * Used when evaluating if an attempt to create a new dependency will result in a valid link between the two tasks
149
+ * [see example]({% slug editing_drag_create_dependencies_gantt %}#toc-validation).
150
+ *
151
+ * By defalut, dependencies are deemed invalid when:
152
+ * - The two tasks are in a parent-child relationship.
153
+ * - The two tasks are already dependent on one another. Only one dependency is allowed per pair.
154
+ * - The start or end times of the two tasks are incompatible with the attempted dependency type.
155
+ */
156
+ this.validateNewDependency = this.defaultValidateNewDependencyCallback.bind(this);
126
157
  /**
127
158
  * Fires when the Gantt selection is changed through user interaction.
128
159
  *
@@ -138,14 +169,6 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
138
169
  * > When applied, the [`SelectableDirective`]({% slug api_gantt_selectabledirective %}) sets `selectable` to `true` internally.
139
170
  */
140
171
  this.selectable = false;
141
- /**
142
- * Gets or sets the callback function that retrieves the child items for a particular item.
143
- */
144
- this.fetchChildren = fetchChildren;
145
- /**
146
- * Gets or sets the callback function that indicates if a particular item has child items.
147
- */
148
- this.hasChildren = hasChildren;
149
172
  /**
150
173
  * Defines the dependencies that will be drawn between the rendered tasks.
151
174
  *
@@ -184,6 +207,12 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
184
207
  * The end of the work week (index based).
185
208
  */
186
209
  this.workWeekEnd = 5;
210
+ /**
211
+ * If set to `true`, the user can use dedicated shortcuts to interact with the Gantt.
212
+ * By default, navigation is disabled for the TreeList and Timeline parts of the component,
213
+ * ([see example]({% slug keyboard_navigation_gantt %})).
214
+ */
215
+ this.navigable = false;
187
216
  /**
188
217
  * Indicates whether the Gantt columns will be resized during initialization so that they fit their headers and row content.
189
218
  * Columns with autoSize set to false are excluded.
@@ -227,7 +256,8 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
227
256
  */
228
257
  this.cellClose = new EventEmitter();
229
258
  /**
230
- * Fires when the end user clicks the `Delete` button in the task editing dialog or the task delete icon.
259
+ * Fires when the end user clicks the `Delete` button in the task editing dialog,
260
+ * the task delete icon, or presses the `Delete` key on the keyboard when a task in the timeline is focused.
231
261
  * Use the event handler to open a confirmation dialog when necessary.
232
262
  */
233
263
  this.taskDelete = new EventEmitter();
@@ -251,6 +281,11 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
251
281
  * Fires when the user adds a task.
252
282
  */
253
283
  this.taskAdd = new EventEmitter();
284
+ /**
285
+ * Fires when the user adds a dependency via dragging
286
+ * [see example]({% slug editing_drag_create_dependencies_gantt %}#toc-basic-concepts).
287
+ */
288
+ this.dependencyAdd = new EventEmitter();
254
289
  /**
255
290
  * Fires when the sorting of the Gantt is changed.
256
291
  * You have to handle the event yourself and sort the data.
@@ -307,6 +342,15 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
307
342
  * Fires when a task is clicked.
308
343
  */
309
344
  this.taskClick = new EventEmitter();
345
+ /**
346
+ * @hidden
347
+ *
348
+ * Specifies whether the dependency drag clues will be rendered.
349
+ * Set internally by the dependency-drag-create directive.
350
+ *
351
+ * @default false
352
+ */
353
+ this.renderDependencyDragClues = false;
310
354
  /**
311
355
  * @hidden
312
356
  *
@@ -323,6 +367,7 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
323
367
  this.showConfirmationDialog = false;
324
368
  this._columns = new QueryList();
325
369
  this._data = [];
370
+ this._dragScrollSettings = Object.assign({}, DEFAULT_DRAG_SCROLL_SETTINGS);
326
371
  this._timelinePaneOptions = Object.assign({}, DEFAULT_TIMELINE_PANE_SETTINGS);
327
372
  this._treeListPaneOptions = Object.assign({}, DEFAULT_TREELIST_PANE_SETTINGS);
328
373
  this._rowClass = rowClassCallback;
@@ -333,6 +378,8 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
333
378
  addTaskTool: 'none',
334
379
  viewSelectorTool: 'top'
335
380
  };
381
+ this._fetchChildren = fetchChildren;
382
+ this._hasChildren = hasChildren;
336
383
  this.rtl = false;
337
384
  this.optionChangesSubscriptions = new Subscription();
338
385
  this.editServiceSubscription = new Subscription();
@@ -345,16 +392,24 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
345
392
  }));
346
393
  this.editService.getSelectedItem = this.getFirstSelectedItem.bind(this);
347
394
  this.editServiceSubscription.add(this.editService.showEditingDialog.subscribe(show => this.showEditingDialog = show));
348
- this.editServiceSubscription.add(this.editService.showConfirmationDialog.subscribe(() => this.taskDelete.emit()));
395
+ this.editServiceSubscription.add(this.editService.taskDelete.subscribe(task => {
396
+ if (hasObservers(this.taskDelete)) {
397
+ this.zone.run(() => this.notifyTaskDelete(task));
398
+ }
399
+ }));
349
400
  this.editServiceSubscription.add(this.editService.editEvent.subscribe(args => {
350
401
  this[args.editResultType].emit({
351
- formGroup: args.formGroup,
402
+ taskFormGroup: args.taskFormGroup,
352
403
  item: getEditItem(args.dataItem, this.treeList.view.data, this.mapper),
404
+ dependencies: args.dependencies,
353
405
  sender: this
354
406
  });
355
407
  this.showConfirmationDialog = this.showEditingDialog = false;
356
- this.editService.dataItem = this.editService.formGroup = null;
408
+ this.editService.dataItem = this.editService.taskFormGroup = null;
357
409
  this.updateView();
410
+ if (this.navigable) {
411
+ this.focus();
412
+ }
358
413
  }));
359
414
  this.editServiceSubscription.add(this.editService.addEvent.subscribe(args => {
360
415
  const selectedItem = this.getFirstSelectedItem();
@@ -378,6 +433,12 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
378
433
  set toolbarTemplate(customToolbarTemplate) {
379
434
  this._customToolbarTemplate = customToolbarTemplate;
380
435
  }
436
+ get hostRoleDescriptionAttr() {
437
+ return this.roleDescription;
438
+ }
439
+ get hostRoleAttr() {
440
+ return this.role;
441
+ }
381
442
  get dir() {
382
443
  return this.direction;
383
444
  }
@@ -460,6 +521,26 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
460
521
  get toolbarSettings() {
461
522
  return this._toolbarSettings;
462
523
  }
524
+ /**
525
+ * Gets or sets the callback function that retrieves the child items for a particular item.
526
+ */
527
+ set fetchChildren(fn) {
528
+ this._fetchChildren = fn;
529
+ this.editService.fetchChildren = fn;
530
+ }
531
+ get fetchChildren() {
532
+ return this._fetchChildren;
533
+ }
534
+ /**
535
+ * Gets or sets the callback function that indicates if a particular item has child items.
536
+ */
537
+ set hasChildren(fn) {
538
+ this._hasChildren = fn;
539
+ this.editService.hasChildren = fn;
540
+ }
541
+ get hasChildren() {
542
+ return this._hasChildren;
543
+ }
463
544
  /**
464
545
  * The options of the timeline splitter pane. By default the pane is `collapsible`,
465
546
  * `resizable`, not `collapsed`, and its `size` is `'50%'`.
@@ -515,6 +596,17 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
515
596
  get taskIdField() {
516
597
  return this.mapper.taskFields.id;
517
598
  }
599
+ /**
600
+ * Specifies the settings for auto-scrolling during dragging
601
+ * when the pointer moves outside of the container bounderies
602
+ * [see example]({% slug editing_drag_create_dependencies_gantt %}#toc-auto-scrolling).
603
+ */
604
+ set dragScrollSettings(settings) {
605
+ this._dragScrollSettings = Object.assign({}, DEFAULT_DRAG_SCROLL_SETTINGS, settings);
606
+ }
607
+ get dragScrollSettings() {
608
+ return this._dragScrollSettings;
609
+ }
518
610
  /**
519
611
  * @hidden
520
612
  */
@@ -524,6 +616,15 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
524
616
  }
525
617
  return this.treeList.view.data.map(item => item.data);
526
618
  }
619
+ /**
620
+ * @hidden
621
+ */
622
+ get viewItems() {
623
+ if (!isPresent(this.treeList)) {
624
+ return [];
625
+ }
626
+ return this.treeList.view.data;
627
+ }
527
628
  /**
528
629
  * @hidden
529
630
  */
@@ -570,8 +671,8 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
570
671
  /**
571
672
  * @hidden
572
673
  */
573
- get editDialogFormGroup() {
574
- return this.editService.formGroup;
674
+ get isInEditMode() {
675
+ return this.showEditingDialog || this.showConfirmationDialog || this.treeList.isEditing();
575
676
  }
576
677
  ngOnChanges(changes) {
577
678
  if (anyChanged(['data', 'activeView', 'workWeekStart', 'workWeekEnd', 'workDayStart', 'workDayEnd'], changes)) {
@@ -580,6 +681,14 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
580
681
  }
581
682
  ngAfterViewInit() {
582
683
  this.updateTreeListMargin();
684
+ if (this.navigable) {
685
+ this.navigationService.initialize({
686
+ gantt: this,
687
+ host: this.hostElement.nativeElement,
688
+ treeListElement: this.treeList.wrapper.nativeElement,
689
+ timelineElement: this.timeline.timelineContent.nativeElement
690
+ });
691
+ }
583
692
  const leftContainer = this.treeList.wrapper.nativeElement.querySelector('kendo-treelist-list > div');
584
693
  this.scrollSyncService.registerElement(leftContainer, 'treelist');
585
694
  }
@@ -597,6 +706,34 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
597
706
  this.localizationSubscription.unsubscribe();
598
707
  }
599
708
  }
709
+ /**
710
+ * Focuses the last active cell or task in the Gantt.
711
+ * If no item has previously been focused, the first cell of the TreeList part will receive focus,
712
+ * ([see example]({% slug keyboard_navigation_gantt %}#toc-controlling-the-focus)).
713
+ */
714
+ focus() {
715
+ if (this.navigable) {
716
+ this.navigationService.focusLastActiveItem();
717
+ }
718
+ }
719
+ /**
720
+ * Focuses the targeted cell in the TreeList part of the component,
721
+ * ([see example]({% slug keyboard_navigation_gantt %}#toc-controlling-the-focus)).
722
+ */
723
+ focusCell(rowIndex, colIndex) {
724
+ if (this.navigable) {
725
+ this.navigationService.focusCell(rowIndex, colIndex);
726
+ }
727
+ }
728
+ /**
729
+ * Focuses the targeted task in the Timeline part of the component,
730
+ * ([see example]({% slug keyboard_navigation_gantt %}#toc-controlling-the-focus)).
731
+ */
732
+ focusTask(taskIndex) {
733
+ if (this.navigable) {
734
+ this.navigationService.focusTask(taskIndex);
735
+ }
736
+ }
600
737
  /**
601
738
  * Applies the minimum possible width for the specified column,
602
739
  * so that the whole text fits without wrapping. This method expects the Gantt
@@ -661,7 +798,10 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
661
798
  */
662
799
  editTask(dataItem, formGroup) {
663
800
  if (!this.showEditingDialog) {
664
- this.editService.createEditDialog(dataItem, formGroup);
801
+ const taskId = this.mapper.extractFromTask(dataItem, 'id');
802
+ const dependencies = this.dependencies.filter(item => this.mapper.extractFromDependency(item, 'toId') === taskId
803
+ || this.mapper.extractFromDependency(item, 'fromId') === taskId);
804
+ this.editService.createEditDialog(dataItem, formGroup, dependencies);
665
805
  }
666
806
  }
667
807
  /**
@@ -678,6 +818,15 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
678
818
  openConfirmationDialog() {
679
819
  this.showConfirmationDialog = true;
680
820
  }
821
+ /**
822
+ * @hidden
823
+ */
824
+ handleConfirmationDialogClose() {
825
+ this.showConfirmationDialog = false;
826
+ if (this.navigable) {
827
+ this.focus();
828
+ }
829
+ }
681
830
  /**
682
831
  * Opens a cell for editing.
683
832
  */
@@ -762,7 +911,7 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
762
911
  if (hasObservers(this.taskClick)) {
763
912
  const taskIndex = getClosestTaskIndex(target, gantt);
764
913
  const task = this.renderedTreeListItems[taskIndex];
765
- this.zone.run(() => this.emitTaskClick(event, task, taskIndex));
914
+ this.zone.run(() => this.notifyTaskClick(event, task, taskIndex));
766
915
  }
767
916
  }
768
917
  /**
@@ -780,8 +929,8 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
780
929
  if ((hasObservers(this.selectionChange) && !this.isSameSelection(selectionAction, task)) ||
781
930
  hasObservers(this.taskClick)) {
782
931
  this.zone.run(() => {
783
- this.emitSelectionChange(task, selectionAction);
784
- this.emitTaskClick(event, task, taskIndex);
932
+ this.notifySelectionChange(task, selectionAction);
933
+ this.notifyTaskClick(event, task, taskIndex);
785
934
  });
786
935
  }
787
936
  }
@@ -818,7 +967,7 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
818
967
  }
819
968
  const task = event.items.map(item => item.dataItem)[0]; // single selection only currently available
820
969
  const action = event.action;
821
- this.emitSelectionChange(task, action);
970
+ this.notifySelectionChange(task, action);
822
971
  }
823
972
  /**
824
973
  * @hidden
@@ -869,7 +1018,7 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
869
1018
  dataItem: task,
870
1019
  originalEvent: event,
871
1020
  sender: this,
872
- rowIndex: taskIndex,
1021
+ index: taskIndex,
873
1022
  type: 'dblclick'
874
1023
  }));
875
1024
  }
@@ -880,16 +1029,35 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
880
1029
  getText(token) {
881
1030
  return this.localizationService.get(token);
882
1031
  }
883
- emitTaskClick(event, dataItem, itemIndex) {
1032
+ /**
1033
+ * @hidden
1034
+ */
1035
+ changeActiveView(view) {
1036
+ if (view !== this.activeView) {
1037
+ this.activeView = view;
1038
+ this.loadTimelineData();
1039
+ this.scrollSyncService.resetTimelineScrollLeft();
1040
+ this.activeViewChange.emit(view);
1041
+ }
1042
+ }
1043
+ /**
1044
+ * @hidden
1045
+ */
1046
+ notifyTaskClick(event, dataItem, itemIndex) {
1047
+ // simulates the TreeList `cellClick` event triggered by enter press (type: 'click')
1048
+ const type = event instanceof KeyboardEvent ? 'click' : event.type;
884
1049
  this.taskClick.emit({
885
1050
  originalEvent: event,
886
1051
  dataItem: dataItem,
887
- rowIndex: itemIndex,
888
- type: event.type,
1052
+ index: itemIndex,
1053
+ type: type,
889
1054
  sender: this
890
1055
  });
891
1056
  }
892
- emitSelectionChange(dataItem, action) {
1057
+ /**
1058
+ * @hidden
1059
+ */
1060
+ notifySelectionChange(dataItem, action) {
893
1061
  if (this.isSameSelection(action, dataItem)) {
894
1062
  return;
895
1063
  }
@@ -900,6 +1068,29 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
900
1068
  });
901
1069
  this.treeList.updateView();
902
1070
  }
1071
+ /**
1072
+ * @hidden
1073
+ */
1074
+ notifyTaskDelete(task) {
1075
+ this.editService.dataItem = task;
1076
+ this.taskDelete.emit({
1077
+ item: getEditItem(task, this.treeList.view.data, this.mapper),
1078
+ sender: this
1079
+ });
1080
+ }
1081
+ /**
1082
+ * @hidden
1083
+ */
1084
+ isSameSelection(action, dataItem) {
1085
+ return action === 'select' && this.isSelected(dataItem);
1086
+ }
1087
+ /**
1088
+ * @hidden
1089
+ */
1090
+ getSelectionAction({ ctrlKey, metaKey }, dataItem) {
1091
+ const shouldToggleSelection = ctrlKey || metaKey;
1092
+ return (shouldToggleSelection && this.isSelected(dataItem)) ? 'remove' : 'select';
1093
+ }
903
1094
  updateTreeListGroupClass(columns = this.columns) {
904
1095
  if (!isPresent(this.treeList)) {
905
1096
  return;
@@ -926,23 +1117,65 @@ let GanttComponent = GanttComponent_1 = class GanttComponent {
926
1117
  }
927
1118
  return this.views.find(view => view.type === this.activeView);
928
1119
  }
929
- isSameSelection(action, dataItem) {
930
- return action === 'select' && this.isSelected(dataItem);
931
- }
932
- getSelectionAction({ ctrlKey, metaKey }, dataItem) {
933
- const shouldToggleSelection = ctrlKey || metaKey;
934
- return (shouldToggleSelection && this.isSelected(dataItem)) ? 'remove' : 'select';
935
- }
936
1120
  getFirstSelectedItem() {
937
1121
  const isSelectedCallback = this.isSelected || isSelected;
938
1122
  const loadedItems = this.renderedTreeListItems || [];
939
1123
  return loadedItems.find(isSelectedCallback);
940
1124
  }
1125
+ defaultValidateNewDependencyCallback(dependency) {
1126
+ const fromTaskId = this.mapper.extractFromDependency(dependency, 'fromId');
1127
+ const toTaskId = this.mapper.extractFromDependency(dependency, 'toId');
1128
+ const fromTask = this.treeList.view.data.find(task => this.mapper.extractFromTask(task.data, 'id') === fromTaskId);
1129
+ const toTask = this.treeList.view.data.find(task => this.mapper.extractFromTask(task.data, 'id') === toTaskId);
1130
+ // mark as invalid if the attempted dependency is lacking valid from- and to-tasks
1131
+ // or when the from- and to-tasks are actually the same task
1132
+ if (!isPresent(fromTask) || !isPresent(fromTask.data) ||
1133
+ !isPresent(toTask) || !isPresent(toTask.data) ||
1134
+ fromTask.data === toTask.data) {
1135
+ return false;
1136
+ }
1137
+ const tasksDependentOnOneAnother = this.dependencies.some(current => {
1138
+ const currentFromId = this.mapper.extractFromDependency(current, 'fromId');
1139
+ const currentToId = this.mapper.extractFromDependency(current, 'toId');
1140
+ return (fromTaskId === currentFromId && toTaskId === currentToId) ||
1141
+ (toTaskId === currentFromId && fromTaskId === currentToId);
1142
+ });
1143
+ // mark as invalid if the attempted dependency is trying to connect already dependent tasks
1144
+ // mark as invalid if the two tasks are in parent-child relationship
1145
+ if (tasksDependentOnOneAnother || areParentChild(fromTask, toTask)) {
1146
+ return false;
1147
+ }
1148
+ const fromTaskStart = this.mapper.extractFromTask(fromTask.data, 'start');
1149
+ const fromTaskEnd = this.mapper.extractFromTask(fromTask.data, 'end');
1150
+ const toTaskStart = this.mapper.extractFromTask(toTask.data, 'start');
1151
+ const toTaskEnd = this.mapper.extractFromTask(toTask.data, 'end');
1152
+ // if the two tasks are available to be connected via a dependency,
1153
+ // check if their start and end time allow for the attempted dependency type
1154
+ switch (this.mapper.extractFromDependency(dependency, 'type')) {
1155
+ // finish to finish (FF) — the from-task ends before the to-task can end
1156
+ case DependencyType.FF:
1157
+ return fromTaskEnd <= toTaskEnd;
1158
+ // finish to start (FS) — the from-task ends before the to-task can begin
1159
+ case DependencyType.FS:
1160
+ return fromTaskEnd <= toTaskStart;
1161
+ // start to finish (SF) — the from-task begins before the to-task can end
1162
+ case DependencyType.SF:
1163
+ return fromTaskStart <= toTaskEnd;
1164
+ // start to start (SS) — the from-task begins before the to-task can begin
1165
+ case DependencyType.SS:
1166
+ return fromTaskStart <= toTaskStart;
1167
+ default: return false;
1168
+ }
1169
+ }
941
1170
  };
942
1171
  tslib_1.__decorate([
943
1172
  ViewChild(TreeListComponent, { static: true }),
944
1173
  tslib_1.__metadata("design:type", TreeListComponent)
945
1174
  ], GanttComponent.prototype, "treeList", void 0);
1175
+ tslib_1.__decorate([
1176
+ ViewChild(GanttTimelineComponent, { static: false }),
1177
+ tslib_1.__metadata("design:type", GanttTimelineComponent)
1178
+ ], GanttComponent.prototype, "timeline", void 0);
946
1179
  tslib_1.__decorate([
947
1180
  ContentChild(GanttTaskContentTemplateDirective, { static: true }),
948
1181
  tslib_1.__metadata("design:type", GanttTaskContentTemplateDirective)
@@ -959,6 +1192,24 @@ tslib_1.__decorate([
959
1192
  ContentChildren(ToolbarTemplateDirective),
960
1193
  tslib_1.__metadata("design:type", QueryList)
961
1194
  ], GanttComponent.prototype, "toolbarTemplateChildren", void 0);
1195
+ tslib_1.__decorate([
1196
+ Input('aria-roledescription'),
1197
+ tslib_1.__metadata("design:type", String)
1198
+ ], GanttComponent.prototype, "roleDescription", void 0);
1199
+ tslib_1.__decorate([
1200
+ HostBinding('attr.aria-roledescription'),
1201
+ tslib_1.__metadata("design:type", String),
1202
+ tslib_1.__metadata("design:paramtypes", [])
1203
+ ], GanttComponent.prototype, "hostRoleDescriptionAttr", null);
1204
+ tslib_1.__decorate([
1205
+ Input('role'),
1206
+ tslib_1.__metadata("design:type", String)
1207
+ ], GanttComponent.prototype, "role", void 0);
1208
+ tslib_1.__decorate([
1209
+ HostBinding('attr.role'),
1210
+ tslib_1.__metadata("design:type", String),
1211
+ tslib_1.__metadata("design:paramtypes", [])
1212
+ ], GanttComponent.prototype, "hostRoleAttr", null);
962
1213
  tslib_1.__decorate([
963
1214
  HostBinding('class.k-gantt'),
964
1215
  tslib_1.__metadata("design:type", Boolean)
@@ -1001,6 +1252,10 @@ tslib_1.__decorate([
1001
1252
  Input(),
1002
1253
  tslib_1.__metadata("design:type", Function)
1003
1254
  ], GanttComponent.prototype, "isSelected", void 0);
1255
+ tslib_1.__decorate([
1256
+ Input(),
1257
+ tslib_1.__metadata("design:type", Function)
1258
+ ], GanttComponent.prototype, "validateNewDependency", void 0);
1004
1259
  tslib_1.__decorate([
1005
1260
  Output(),
1006
1261
  tslib_1.__metadata("design:type", EventEmitter)
@@ -1016,12 +1271,14 @@ tslib_1.__decorate([
1016
1271
  ], GanttComponent.prototype, "toolbarSettings", null);
1017
1272
  tslib_1.__decorate([
1018
1273
  Input(),
1019
- tslib_1.__metadata("design:type", Function)
1020
- ], GanttComponent.prototype, "fetchChildren", void 0);
1274
+ tslib_1.__metadata("design:type", Function),
1275
+ tslib_1.__metadata("design:paramtypes", [Function])
1276
+ ], GanttComponent.prototype, "fetchChildren", null);
1021
1277
  tslib_1.__decorate([
1022
1278
  Input(),
1023
- tslib_1.__metadata("design:type", Function)
1024
- ], GanttComponent.prototype, "hasChildren", void 0);
1279
+ tslib_1.__metadata("design:type", Function),
1280
+ tslib_1.__metadata("design:paramtypes", [Function])
1281
+ ], GanttComponent.prototype, "hasChildren", null);
1025
1282
  tslib_1.__decorate([
1026
1283
  Input(),
1027
1284
  tslib_1.__metadata("design:type", Array)
@@ -1058,6 +1315,10 @@ tslib_1.__decorate([
1058
1315
  Input(),
1059
1316
  tslib_1.__metadata("design:type", Number)
1060
1317
  ], GanttComponent.prototype, "workWeekEnd", void 0);
1318
+ tslib_1.__decorate([
1319
+ Input(),
1320
+ tslib_1.__metadata("design:type", Boolean)
1321
+ ], GanttComponent.prototype, "navigable", void 0);
1061
1322
  tslib_1.__decorate([
1062
1323
  Input(),
1063
1324
  tslib_1.__metadata("design:type", Object),
@@ -1098,6 +1359,11 @@ tslib_1.__decorate([
1098
1359
  Input(),
1099
1360
  tslib_1.__metadata("design:type", Boolean)
1100
1361
  ], GanttComponent.prototype, "columnsResizable", void 0);
1362
+ tslib_1.__decorate([
1363
+ Input(),
1364
+ tslib_1.__metadata("design:type", Object),
1365
+ tslib_1.__metadata("design:paramtypes", [Object])
1366
+ ], GanttComponent.prototype, "dragScrollSettings", null);
1101
1367
  tslib_1.__decorate([
1102
1368
  Output(),
1103
1369
  tslib_1.__metadata("design:type", EventEmitter)
@@ -1138,6 +1404,10 @@ tslib_1.__decorate([
1138
1404
  Output(),
1139
1405
  tslib_1.__metadata("design:type", EventEmitter)
1140
1406
  ], GanttComponent.prototype, "taskAdd", void 0);
1407
+ tslib_1.__decorate([
1408
+ Output(),
1409
+ tslib_1.__metadata("design:type", EventEmitter)
1410
+ ], GanttComponent.prototype, "dependencyAdd", void 0);
1141
1411
  tslib_1.__decorate([
1142
1412
  Output(),
1143
1413
  tslib_1.__metadata("design:type", EventEmitter)
@@ -1195,6 +1465,7 @@ GanttComponent = GanttComponent_1 = tslib_1.__decorate([
1195
1465
  selector: 'kendo-gantt',
1196
1466
  exportAs: 'kendoGantt',
1197
1467
  providers: [
1468
+ GanttLocalizationService,
1198
1469
  LocalizationService,
1199
1470
  {
1200
1471
  provide: DataBoundTreeComponent,
@@ -1212,7 +1483,9 @@ GanttComponent = GanttComponent_1 = tslib_1.__decorate([
1212
1483
  DependencyDomService,
1213
1484
  MappingService,
1214
1485
  OptionChangesService,
1215
- EditService
1486
+ EditService,
1487
+ TimelineScrollService,
1488
+ NavigationService
1216
1489
  ],
1217
1490
  template: `
1218
1491
  <ng-container kendoGanttLocalizedMessages
@@ -1439,6 +1712,7 @@ GanttComponent = GanttComponent_1 = tslib_1.__decorate([
1439
1712
  [data]="data"
1440
1713
  [hasChildren]="hasChildren"
1441
1714
  [fetchChildren]="fetchChildren"
1715
+ [navigable]="navigable"
1442
1716
  [isExpanded]="isExpanded"
1443
1717
  [autoSize]="columnsAutoSize"
1444
1718
  [columnMenu]="columnMenu"
@@ -1527,7 +1801,9 @@ GanttComponent = GanttComponent_1 = tslib_1.__decorate([
1527
1801
  [scrollable]="false">
1528
1802
  <kendo-gantt-timeline
1529
1803
  *ngIf="views && views.length"
1530
- [rows]="renderedTreeListItems"
1804
+ [renderDependencyDragClues]="renderDependencyDragClues"
1805
+ [dragScrollSettings]="dragScrollSettings"
1806
+ [rows]="viewItems"
1531
1807
  [slots]="timelineSlots"
1532
1808
  [groupSlots]="timelineGroupSlots"
1533
1809
  [tableWidth]="tableWidth"
@@ -1537,7 +1813,8 @@ GanttComponent = GanttComponent_1 = tslib_1.__decorate([
1537
1813
  [summaryTaskTemplate]="summaryTaskTemplate?.templateRef"
1538
1814
  [taskClass]="taskClass"
1539
1815
  [dependencies]="dependencies"
1540
- [hasChildren]="hasChildren"
1816
+ [isExpanded]="isExpanded"
1817
+ [selectable]="selectable"
1541
1818
  [isTaskSelected]="isTaskSelected"
1542
1819
  [kendoEventsOutsideAngular]="{
1543
1820
  click: handleTimelineClick,
@@ -1556,18 +1833,21 @@ GanttComponent = GanttComponent_1 = tslib_1.__decorate([
1556
1833
  [showViewSelector]="toolbarSettings.viewSelectorTool === 'bottom' || toolbarSettings.viewSelectorTool === 'both'"
1557
1834
  class="k-gantt-footer k-toolbar k-gantt-toolbar"
1558
1835
  position="bottom"></kendo-gantt-toolbar>
1559
- <kendo-gantt-edit-dialog *ngIf="showEditingDialog" [formGroup]="editDialogFormGroup"></kendo-gantt-edit-dialog>
1836
+ <kendo-gantt-edit-dialog
1837
+ *ngIf="showEditingDialog"
1838
+ [data]="data">
1839
+ </kendo-gantt-edit-dialog>
1560
1840
  <kendo-dialog
1561
1841
  *ngIf="showConfirmationDialog"
1562
1842
  [width]="575"
1563
1843
  [height]="170"
1564
1844
  [title]="getText('confirmationDialogTitle')"
1565
- (close)="showConfirmationDialog = false;">
1566
- <span>{{getText('confirmationDialogContent')}}</span>
1845
+ (close)="handleConfirmationDialogClose()">
1846
+ <span>{{ getText('confirmationDialogContent') }}</span>
1567
1847
  <kendo-dialog-actions layout="normal">
1568
1848
  <kendo-treelist-spacer></kendo-treelist-spacer>
1569
1849
  <button kendoButton [primary]="true" (click)="handleDeleteConfirmation()">{{ getText('deleteButtonText') }}</button>
1570
- <button kendoButton (click)="showConfirmationDialog = false;">{{ getText('cancelButtonText') }}</button>
1850
+ <button kendoButton (click)="handleConfirmationDialogClose()">{{ getText('cancelButtonText') }}</button>
1571
1851
  </kendo-dialog-actions>
1572
1852
  </kendo-dialog>
1573
1853
  `
@@ -1581,6 +1861,7 @@ GanttComponent = GanttComponent_1 = tslib_1.__decorate([
1581
1861
  EditService,
1582
1862
  LocalizationService,
1583
1863
  ElementRef,
1584
- NgZone])
1864
+ NgZone,
1865
+ NavigationService])
1585
1866
  ], GanttComponent);
1586
1867
  export { GanttComponent };