@progress/kendo-angular-gantt 21.4.1-develop.1 → 22.0.0-develop.1

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 (127) hide show
  1. package/columns/column-base.component.d.ts +1 -1
  2. package/fesm2022/progress-kendo-angular-gantt.mjs +201 -201
  3. package/localization/messages.d.ts +1 -1
  4. package/package.json +22 -30
  5. package/rendering/gantt-task-base.d.ts +1 -1
  6. package/schematics/ngAdd/index.js +7 -7
  7. package/timeline/view-base.d.ts +1 -1
  8. package/esm2022/binding-directives/flat-binding.directive.mjs +0 -50
  9. package/esm2022/binding-directives/hierarchy-binding.directive.mjs +0 -49
  10. package/esm2022/columns/cell-template.directive.mjs +0 -47
  11. package/esm2022/columns/column-base.component.mjs +0 -22
  12. package/esm2022/columns/column-group.component.mjs +0 -80
  13. package/esm2022/columns/column-menu-template.directive.mjs +0 -40
  14. package/esm2022/columns/column.component.mjs +0 -122
  15. package/esm2022/columns/columns.mjs +0 -15
  16. package/esm2022/columns/edit-template.directive.mjs +0 -46
  17. package/esm2022/columns/filter-cell-template.directive.mjs +0 -32
  18. package/esm2022/columns/filter-menu-template.directive.mjs +0 -41
  19. package/esm2022/columns/footer-template.directive.mjs +0 -44
  20. package/esm2022/columns/header-template.directive.mjs +0 -43
  21. package/esm2022/columns/span-column.component.mjs +0 -82
  22. package/esm2022/common/default-callbacks.mjs +0 -25
  23. package/esm2022/common/mapping.service.mjs +0 -62
  24. package/esm2022/common/option-changes.service.mjs +0 -28
  25. package/esm2022/dependencies/dependency-dom.service.mjs +0 -80
  26. package/esm2022/dependencies/dom-dependency-args.mjs +0 -5
  27. package/esm2022/dependencies/gantt-dependency.directive.mjs +0 -91
  28. package/esm2022/dependencies/utils.mjs +0 -195
  29. package/esm2022/directives.mjs +0 -63
  30. package/esm2022/dragging/dependency-drag-create.directive.mjs +0 -337
  31. package/esm2022/dragging/drag-validation-tooltip.component.mjs +0 -70
  32. package/esm2022/dragging/task-drag.directive.mjs +0 -94
  33. package/esm2022/dragging/task-drag.service.mjs +0 -239
  34. package/esm2022/editing/add-task.component.mjs +0 -127
  35. package/esm2022/editing/dependencies-table.component.mjs +0 -233
  36. package/esm2022/editing/edit-dialog.component.mjs +0 -225
  37. package/esm2022/editing/edit.service.mjs +0 -118
  38. package/esm2022/editing/task-fields.component.mjs +0 -127
  39. package/esm2022/editing/utils.mjs +0 -15
  40. package/esm2022/expanded-state/expand-event.mjs +0 -18
  41. package/esm2022/expanded-state/expandable.directive.mjs +0 -39
  42. package/esm2022/gantt.component.mjs +0 -2415
  43. package/esm2022/gantt.module.mjs +0 -132
  44. package/esm2022/index.mjs +0 -42
  45. package/esm2022/localization/custom-messages.component.mjs +0 -52
  46. package/esm2022/localization/gantt-localization.service.mjs +0 -27
  47. package/esm2022/localization/localized-messages.directive.mjs +0 -39
  48. package/esm2022/localization/messages.mjs +0 -453
  49. package/esm2022/models/cell-content-type.interface.mjs +0 -5
  50. package/esm2022/models/class-callbacks.mjs +0 -5
  51. package/esm2022/models/column-menu-settings.interface.mjs +0 -5
  52. package/esm2022/models/column-reorder-config.mjs +0 -5
  53. package/esm2022/models/current-time-settings.interface.mjs +0 -5
  54. package/esm2022/models/date-range.interface.mjs +0 -5
  55. package/esm2022/models/dependency-type.enum.mjs +0 -32
  56. package/esm2022/models/events/cell-click-event.interface.mjs +0 -5
  57. package/esm2022/models/events/cell-close-event.interface.mjs +0 -44
  58. package/esm2022/models/events/click-event.interface.mjs +0 -5
  59. package/esm2022/models/events/column-locked-change-event.interface.mjs +0 -5
  60. package/esm2022/models/events/column-reorder-event.interface.mjs +0 -5
  61. package/esm2022/models/events/column-resize-event.interface.mjs +0 -5
  62. package/esm2022/models/events/column-visibility-change-event.interface.mjs +0 -5
  63. package/esm2022/models/events/data-state-change-event.interface.mjs +0 -5
  64. package/esm2022/models/events/dependency-add-event.interface.mjs +0 -5
  65. package/esm2022/models/events/index.mjs +0 -5
  66. package/esm2022/models/events/selected-view-change-event.interface.mjs +0 -5
  67. package/esm2022/models/events/task-add-event.interface.mjs +0 -5
  68. package/esm2022/models/events/task-click-event.interface.mjs +0 -5
  69. package/esm2022/models/events/task-delete-event.interface.mjs +0 -5
  70. package/esm2022/models/events/task-drag-event.interface.mjs +0 -5
  71. package/esm2022/models/events/task-edit-event.interface.mjs +0 -5
  72. package/esm2022/models/filterable-settings.mjs +0 -5
  73. package/esm2022/models/gantt-dependency-model-fields.interface.mjs +0 -13
  74. package/esm2022/models/gantt-dependency.interface.mjs +0 -5
  75. package/esm2022/models/gantt-task-model-fields.interface.mjs +0 -15
  76. package/esm2022/models/gantt-task.interface.mjs +0 -5
  77. package/esm2022/models/models.mjs +0 -8
  78. package/esm2022/models/slot.interface.mjs +0 -5
  79. package/esm2022/models/sort-settings.mjs +0 -17
  80. package/esm2022/models/splitter-pane-options.interface.mjs +0 -20
  81. package/esm2022/models/timeline-header-date-format.mjs +0 -5
  82. package/esm2022/models/timeline-options.interface.mjs +0 -5
  83. package/esm2022/models/timeline-view.mjs +0 -5
  84. package/esm2022/models/toolbar-settings.mjs +0 -5
  85. package/esm2022/models/tooltip-options.interface.mjs +0 -5
  86. package/esm2022/models/view-item.interface.mjs +0 -5
  87. package/esm2022/navigation/navigation-models.mjs +0 -5
  88. package/esm2022/navigation/navigation.service.mjs +0 -271
  89. package/esm2022/navigation/utils.mjs +0 -61
  90. package/esm2022/package-metadata.mjs +0 -16
  91. package/esm2022/progress-kendo-angular-gantt.mjs +0 -8
  92. package/esm2022/rendering/gantt-header-table-body.component.mjs +0 -61
  93. package/esm2022/rendering/gantt-milestone-task.component.mjs +0 -102
  94. package/esm2022/rendering/gantt-summary-task.component.mjs +0 -157
  95. package/esm2022/rendering/gantt-task-base.mjs +0 -230
  96. package/esm2022/rendering/gantt-task.component.mjs +0 -227
  97. package/esm2022/rendering/gantt-tasks-table-body.component.mjs +0 -206
  98. package/esm2022/scrolling/drag-scroll-settings.mjs +0 -20
  99. package/esm2022/scrolling/scroll-sync.service.mjs +0 -83
  100. package/esm2022/scrolling/timeline-scroll.directive.mjs +0 -83
  101. package/esm2022/scrolling/timeline-scroll.service.mjs +0 -37
  102. package/esm2022/scrolling/utils.mjs +0 -77
  103. package/esm2022/selection/selectable.directive.mjs +0 -126
  104. package/esm2022/selection/selection-change-event.mjs +0 -5
  105. package/esm2022/template-directives/summary-task-template.directive.mjs +0 -43
  106. package/esm2022/template-directives/task-content-template.directive.mjs +0 -46
  107. package/esm2022/template-directives/task-drag-tooltip-template.directive.mjs +0 -47
  108. package/esm2022/template-directives/task-template.directive.mjs +0 -41
  109. package/esm2022/template-directives/task-tooltip-template.directive.mjs +0 -48
  110. package/esm2022/timeline/current-time-marker.service.mjs +0 -90
  111. package/esm2022/timeline/gantt-timeline.component.mjs +0 -624
  112. package/esm2022/timeline/timeline-base-view.service.mjs +0 -201
  113. package/esm2022/timeline/timeline-day-view.component.mjs +0 -49
  114. package/esm2022/timeline/timeline-day-view.service.mjs +0 -68
  115. package/esm2022/timeline/timeline-month-view.component.mjs +0 -49
  116. package/esm2022/timeline/timeline-month-view.service.mjs +0 -66
  117. package/esm2022/timeline/timeline-view.service.mjs +0 -38
  118. package/esm2022/timeline/timeline-week-view.component.mjs +0 -49
  119. package/esm2022/timeline/timeline-week-view.service.mjs +0 -62
  120. package/esm2022/timeline/timeline-year-view.component.mjs +0 -49
  121. package/esm2022/timeline/timeline-year-view.service.mjs +0 -57
  122. package/esm2022/timeline/view-base.mjs +0 -73
  123. package/esm2022/toolbar/toolbar-navigation.service.mjs +0 -29
  124. package/esm2022/toolbar/toolbar-template.directive.mjs +0 -56
  125. package/esm2022/toolbar/toolbar.component.mjs +0 -181
  126. package/esm2022/toolbar/view-selector.component.mjs +0 -112
  127. package/esm2022/utils.mjs +0 -311
@@ -1,195 +0,0 @@
1
- /**-----------------------------------------------------------------------------------------
2
- * Copyright © 2026 Progress Software Corporation. All rights reserved.
3
- * Licensed under commercial license. See LICENSE.md in the project root for more information
4
- *-------------------------------------------------------------------------------------------*/
5
- import { DependencyType } from '../models/dependency-type.enum';
6
- /**
7
- * @hidden
8
- *
9
- * Gets the offset (top and left values) relative to a target element.
10
- */
11
- export const getOffsetRelativeToParent = (element, targetParent) => {
12
- const offset = {
13
- top: 0,
14
- left: 0
15
- };
16
- if (!targetParent.contains(element)) {
17
- return offset;
18
- }
19
- let offsetParent = element;
20
- while (offsetParent && offsetParent !== targetParent) {
21
- offset.top += offsetParent.offsetTop;
22
- offset.left += offsetParent.offsetLeft;
23
- offsetParent = offsetParent.offsetParent;
24
- }
25
- return offset;
26
- };
27
- /**
28
- * @hidden
29
- */
30
- export const getElementRect = (element, relativeContainer) => {
31
- const { top, left } = getOffsetRelativeToParent(element, relativeContainer);
32
- return {
33
- top: top + element.offsetHeight / 2,
34
- left: left,
35
- right: left + element.offsetWidth
36
- };
37
- };
38
- /**
39
- * @hidden
40
- */
41
- export const dependencyCoordinates = (from, to, rowHeight, type, minDistanceBeforeTurn, arrowSize) => {
42
- const points = [];
43
- const minTurnHeight = Math.floor(rowHeight / 2);
44
- const drawingDown = from.top < to.top;
45
- let top, left;
46
- // FF and SS are composed of 4 connected polyline points (not counting the arrow)
47
- /*
48
- [[[]]]- -[[[]]]
49
- | |
50
- [[[]]]- -[[[]]]
51
- */
52
- if (type === DependencyType.FF || type === DependencyType.SS) {
53
- // polyline start from first task
54
- const dir = type === DependencyType.SS ? 'left' : 'right';
55
- top = from.top;
56
- left = from[dir];
57
- points.push({ top, left });
58
- // first turn point
59
- left = Math[dir === 'left' ? 'min' : 'max'](from[dir], to[dir]);
60
- left = dir === 'left' ? left - minDistanceBeforeTurn : left + minDistanceBeforeTurn;
61
- points.push({ top, left });
62
- // second turn point
63
- top = to.top;
64
- points.push({ top, left });
65
- // second task reached
66
- left = dir === 'left' ? to[dir] - arrowSize : to[dir] + arrowSize;
67
- points.push({ top, left });
68
- // arrow pointing to the second task
69
- points.push(...getArrow(top, left, dir !== 'left', arrowSize));
70
- }
71
- else {
72
- // FS and SF are composed of 4 or 6 connected polyline points (not counting the arrow), depending on the position of the tasks
73
- /*
74
- [[[]]]- [[[]]]-
75
- | |
76
- -[[[]]] -----
77
- |
78
- -[[[]]]
79
- */
80
- const startDir = type === DependencyType.SF ? 'left' : 'right';
81
- const endDir = type === DependencyType.SF ? 'right' : 'left';
82
- const additionalTurn = type === DependencyType.SF
83
- ? from[startDir] - minDistanceBeforeTurn * 2 < to[endDir]
84
- : from[startDir] + minDistanceBeforeTurn * 2 > to[endDir];
85
- // polyline start from first task
86
- top = from.top;
87
- left = from[startDir];
88
- points.push({ top, left });
89
- // first turn point
90
- left = startDir === 'left'
91
- ? left - minDistanceBeforeTurn
92
- : left + minDistanceBeforeTurn;
93
- points.push({ top, left });
94
- // if second task start is before the first task end in FS
95
- // if second task end is after the first task start in SF
96
- if (additionalTurn) {
97
- // additional turn start
98
- top = drawingDown
99
- ? top + minTurnHeight
100
- : top - minTurnHeight;
101
- points.push({ top, left });
102
- // additional turn end
103
- left = startDir === 'left'
104
- ? to[endDir] + minDistanceBeforeTurn
105
- : to[endDir] - minDistanceBeforeTurn;
106
- points.push({ top, left });
107
- }
108
- // second task level reached
109
- top = to.top;
110
- points.push({ top, left });
111
- // second task element reached
112
- left = endDir === 'left' ? to[endDir] - arrowSize : to[endDir] + arrowSize;
113
- points.push({ top, left });
114
- // arrow pointing to the second task
115
- points.push(...getArrow(top, left, endDir !== 'left', arrowSize));
116
- }
117
- return points;
118
- };
119
- const getArrow = (top, left, isArrowWest, arrowSize) => {
120
- const points = isArrowWest
121
- ? getArrowWest(top, left, arrowSize)
122
- : getArrowEast(top, left, arrowSize);
123
- return points;
124
- };
125
- const getArrowWest = (top, left, arrowSize) => {
126
- const points = [];
127
- points.push({
128
- top: top - arrowSize / 2,
129
- left
130
- });
131
- points.push({
132
- top,
133
- left: left - arrowSize + 1
134
- });
135
- points.push({
136
- top: top + arrowSize / 2,
137
- left
138
- });
139
- points.push({
140
- top,
141
- left
142
- });
143
- return points;
144
- };
145
- const getArrowEast = (top, left, arrowSize) => {
146
- const points = [];
147
- points.push({
148
- top: top + arrowSize / 2,
149
- left
150
- });
151
- points.push({
152
- top,
153
- left: left + arrowSize - 1
154
- });
155
- points.push({
156
- top: top - arrowSize / 2,
157
- left
158
- });
159
- points.push({
160
- top,
161
- left
162
- });
163
- return points;
164
- };
165
- /**
166
- * @hidden
167
- *
168
- * Translates the provided client `left` and `top` coords to coords relative to the provided container.
169
- * https://developer.mozilla.org/en-US/docs/Web/CSS/CSSOM_View/Coordinate_systems#standard_cssom_coordinate_systems
170
- */
171
- export const clientToOffsetCoords = (clientLeft, clientTop, offsetContainer) => {
172
- // client (viewport) coordinates of the target container
173
- // https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect#value
174
- const offsetContainerClientRect = offsetContainer.getBoundingClientRect();
175
- return {
176
- left: clientLeft - offsetContainerClientRect.left + offsetContainer.scrollLeft,
177
- top: clientTop - offsetContainerClientRect.top + offsetContainer.scrollTop
178
- };
179
- };
180
- /**
181
- * @hidden
182
- *
183
- * Retrieves the `left` and `top` values of the center of the provided element.
184
- * The retrieved values are relative to the current viewport (client values).
185
- * https://developer.mozilla.org/en-US/docs/Web/CSS/CSSOM_View/Coordinate_systems#standard_cssom_coordinate_systems
186
- */
187
- export const getElementClientCenterCoords = (element) => {
188
- // client (viewport) coordinates of the targeted element
189
- // https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect#value
190
- const { left, top, width, height } = element.getBoundingClientRect();
191
- return {
192
- left: left + (width / 2),
193
- top: top + (height / 2)
194
- };
195
- };
@@ -1,63 +0,0 @@
1
- /**-----------------------------------------------------------------------------------------
2
- * Copyright © 2026 Progress Software Corporation. All rights reserved.
3
- * Licensed under commercial license. See LICENSE.md in the project root for more information
4
- *-------------------------------------------------------------------------------------------*/
5
- import { GanttFlatBindingDirective } from "./binding-directives/flat-binding.directive";
6
- import { GanttHierarchyBindingDirective } from "./binding-directives/hierarchy-binding.directive";
7
- import { GanttComponent } from "./gantt.component";
8
- import { GanttSummaryTaskTemplateDirective } from "./template-directives/summary-task-template.directive";
9
- import { GanttTaskContentTemplateDirective } from "./template-directives/task-content-template.directive";
10
- import { GanttTaskTemplateDirective } from "./template-directives/task-template.directive";
11
- import { ViewSelectorComponent } from "./toolbar/view-selector.component";
12
- import { GanttColumnComponent } from "./columns/column.component";
13
- import { GanttColumnGroupComponent } from "./columns/column-group.component";
14
- import { GanttSpanColumnComponent } from "./columns/span-column.component";
15
- import { CellTemplateDirective, ColumnMenuTemplateDirective, EditTemplateDirective, FilterCellTemplateDirective, FilterMenuTemplateDirective, FooterTemplateDirective, HeaderTemplateDirective } from "./columns/columns";
16
- import { GanttExpandableDirective } from "./expanded-state/expandable.directive";
17
- import { DependencyDragCreateDirective } from "./dragging/dependency-drag-create.directive";
18
- import { TimelineDayViewComponent } from "./timeline/timeline-day-view.component";
19
- import { TimelineWeekViewComponent } from "./timeline/timeline-week-view.component";
20
- import { TimelineMonthViewComponent } from "./timeline/timeline-month-view.component";
21
- import { TimelineYearViewComponent } from "./timeline/timeline-year-view.component";
22
- import { SelectableDirective } from "./selection/selectable.directive";
23
- import { CustomMessagesComponent } from "./localization/custom-messages.component";
24
- import { GanttAddTaskComponent } from "./editing/add-task.component";
25
- import { ToolbarTemplateDirective } from "./toolbar/toolbar-template.directive";
26
- import { TaskDragDirective } from "./dragging/task-drag.directive";
27
- import { GanttTaskTooltipTemplateDirective } from "./template-directives/task-tooltip-template.directive";
28
- import { GanttTaskDragTooltipTemplateDirective } from "./template-directives/task-drag-tooltip-template.directive";
29
- /**
30
- * Use the `KENDO_GANTT` utility array to import all Kendo UI for Angular Gantt components and directives to a standalone Angular component.
31
- */
32
- export const KENDO_GANTT = [
33
- GanttComponent,
34
- GanttFlatBindingDirective,
35
- GanttHierarchyBindingDirective,
36
- GanttTaskContentTemplateDirective,
37
- GanttTaskTemplateDirective,
38
- GanttSummaryTaskTemplateDirective,
39
- GanttTaskDragTooltipTemplateDirective,
40
- ToolbarTemplateDirective,
41
- ViewSelectorComponent,
42
- GanttColumnComponent,
43
- GanttColumnGroupComponent,
44
- GanttSpanColumnComponent,
45
- FilterCellTemplateDirective,
46
- FilterMenuTemplateDirective,
47
- CellTemplateDirective,
48
- EditTemplateDirective,
49
- ColumnMenuTemplateDirective,
50
- HeaderTemplateDirective,
51
- FooterTemplateDirective,
52
- GanttExpandableDirective,
53
- DependencyDragCreateDirective,
54
- TimelineDayViewComponent,
55
- TimelineWeekViewComponent,
56
- TimelineMonthViewComponent,
57
- TimelineYearViewComponent,
58
- SelectableDirective,
59
- CustomMessagesComponent,
60
- GanttAddTaskComponent,
61
- TaskDragDirective,
62
- GanttTaskTooltipTemplateDirective
63
- ];
@@ -1,337 +0,0 @@
1
- /**-----------------------------------------------------------------------------------------
2
- * Copyright © 2026 Progress Software Corporation. All rights reserved.
3
- * Licensed under commercial license. See LICENSE.md in the project root for more information
4
- *-------------------------------------------------------------------------------------------*/
5
- import { Directive, Input, NgZone, Renderer2 } from '@angular/core';
6
- import { isDocumentAvailable } from '@progress/kendo-angular-common';
7
- import { PopupService } from '@progress/kendo-angular-popup';
8
- import { GanttComponent } from '../gantt.component';
9
- import { MappingService } from '../common/mapping.service';
10
- import { TimelineScrollService } from '../scrolling/timeline-scroll.service';
11
- import { DragValidationTooltipComponent } from './drag-validation-tooltip.component';
12
- import { clientToOffsetCoords, getElementClientCenterCoords } from '../dependencies/utils';
13
- import { isPresent, isDependencyDragClue, getClosestTaskWrapper, getDependencyTypeFromTargetTasks, getClosestTaskIndex, sameTaskClues, isTaskWrapper, fitToRange } from '../utils';
14
- import { elementFromPoint } from '../utils';
15
- import * as i0 from "@angular/core";
16
- import * as i1 from "../gantt.component";
17
- import * as i2 from "../common/mapping.service";
18
- import * as i3 from "@progress/kendo-angular-popup";
19
- import * as i4 from "../scrolling/timeline-scroll.service";
20
- const DRAG_CLUE_HOVER_CLASS = 'k-hover';
21
- const USER_SELECT_NONE_CLASS = 'k-user-select-none';
22
- const TASK_WRAPPER_DRAG_CLASS = 'k-origin';
23
- const DEFAULT_POPUP_VERTICAL_MARGIN = 20;
24
- /**
25
- * Enables creating new dependencies by dragging.
26
- *
27
- * ```html
28
- * <kendo-gantt kendoGanttDependencyDragCreate></kendo-gantt>
29
- * ```
30
- *
31
- * @remarks
32
- * Applied to: {@link GanttComponent}
33
- */
34
- export class DependencyDragCreateDirective {
35
- gantt;
36
- zone;
37
- renderer;
38
- mapper;
39
- popupService;
40
- timelineScrollService;
41
- /**
42
- * Shows the validation tooltip during drag operations.
43
- *
44
- * @default true
45
- */
46
- displayValidationTooltip = true;
47
- get container() {
48
- if (!isPresent(this.gantt.timeline) || !isPresent(this.gantt.timeline.timelineContent)) {
49
- return null;
50
- }
51
- return this.gantt.timeline.timelineContent.nativeElement;
52
- }
53
- get polyline() {
54
- if (!isPresent(this.gantt.timeline) || !isPresent(this.gantt.timeline.dependencyDragCreatePolyline)) {
55
- return null;
56
- }
57
- return this.gantt.timeline.dependencyDragCreatePolyline.nativeElement;
58
- }
59
- get popupContainer() {
60
- if (!isPresent(this.gantt.timeline) || !isPresent(this.gantt.timeline.dragPopupContainer)) {
61
- return null;
62
- }
63
- return this.gantt.timeline.dragPopupContainer;
64
- }
65
- /**
66
- * Points to the drag clue where the dragging started (the FROM task).
67
- * Used to attach/detach classes to the target element and its task wrapper parent element.
68
- */
69
- fromTaskClue;
70
- /**
71
- * The drag start element coords will be the same through the enitre dragging session, so compute them on press and cache them.
72
- */
73
- polylineStartCoords;
74
- /**
75
- * Stored during dragging to be consumed by the container scroll subscription.
76
- * The scroll event doesn't expose the current pointer position, so it has to be stored separately.
77
- */
78
- currentPointerClientCoords;
79
- scrollListenerDisposer;
80
- dragPopup;
81
- dragSubscriptions;
82
- constructor(gantt, zone, renderer, mapper, popupService, timelineScrollService) {
83
- this.gantt = gantt;
84
- this.zone = zone;
85
- this.renderer = renderer;
86
- this.mapper = mapper;
87
- this.popupService = popupService;
88
- this.timelineScrollService = timelineScrollService;
89
- this.gantt.renderDependencyDragClues = true;
90
- }
91
- ngAfterViewInit() {
92
- this.subscribeDraggable();
93
- this.addScrollListener();
94
- }
95
- ngOnDestroy() {
96
- this.unsubscribeDraggable();
97
- this.removeScrollListener();
98
- this.fromTaskClue = null;
99
- this.cancelScroll();
100
- this.closeDragPopup();
101
- }
102
- subscribeDraggable() {
103
- this.dragSubscriptions = this.gantt.timeline.timelineContainerPress
104
- .subscribe(this.handlePress.bind(this));
105
- this.dragSubscriptions.add(this.gantt.timeline.timelineContainerDrag
106
- .subscribe(this.handleDrag.bind(this)));
107
- this.dragSubscriptions.add(this.gantt.timeline.timelineContainerRelease
108
- .subscribe(this.handleRelease.bind(this)));
109
- }
110
- unsubscribeDraggable() {
111
- if (isPresent(this.dragSubscriptions)) {
112
- this.dragSubscriptions.unsubscribe();
113
- this.dragSubscriptions = null;
114
- }
115
- }
116
- handlePress({ clientX, clientY }) {
117
- // using `originalEvent.target` is not reliable under mobile devices with the current implementation of the draggable, so use this instead
118
- const target = elementFromPoint(clientX, clientY);
119
- if (isDependencyDragClue(target)) {
120
- this.fromTaskClue = target;
121
- this.assignDragStartClasses(this.fromTaskClue);
122
- // use the center of the target clue as polyline starting point
123
- const dragClueCenterCoords = getElementClientCenterCoords(this.fromTaskClue);
124
- // the polyline uses `position: aboslute`, so translate the client coordinates to offset coordinates (`left` and `top` relative to the timeline container)
125
- this.polylineStartCoords = clientToOffsetCoords(dragClueCenterCoords.left, dragClueCenterCoords.top, this.container);
126
- }
127
- }
128
- handleDrag({ clientX, clientY }) {
129
- if (isPresent(this.fromTaskClue)) {
130
- // the polyline uses `position: aboslute`, so translate the client coordinates to offset coordinates (`left` and `top` relative to the timeline container)
131
- const pointerOffsetCoords = clientToOffsetCoords(clientX, clientY, this.container);
132
- // the start coords are calculated just once per drag session in handlePress
133
- // use the current drag coords as polyline end coords
134
- this.updatePolyline(this.polylineStartCoords, pointerOffsetCoords);
135
- this.currentPointerClientCoords = { left: clientX, top: clientY };
136
- if (this.gantt.dragScrollSettings.enabled) {
137
- // use client coordinates for scroll trigger
138
- this.scrollPointIntoView(this.currentPointerClientCoords);
139
- }
140
- if (this.displayValidationTooltip) {
141
- this.updateDragPopup(pointerOffsetCoords);
142
- }
143
- }
144
- }
145
- handleRelease({ clientX, clientY }) {
146
- if (!isPresent(this.fromTaskClue)) {
147
- return;
148
- }
149
- // using `originalEvent.target` is not reliable under mobile devices with the current implementation of the draggable, so use this instead
150
- const target = elementFromPoint(clientX, clientY);
151
- if (isDependencyDragClue(target) && !sameTaskClues(this.fromTaskClue, target, this.container)) {
152
- this.zone.run(() => {
153
- const fromTaskClue = this.fromTaskClue;
154
- const toTaskClue = target;
155
- const fromTask = this.gantt.renderedTreeListItems[getClosestTaskIndex(fromTaskClue, this.container)];
156
- const toTask = this.gantt.renderedTreeListItems[getClosestTaskIndex(toTaskClue, this.container)];
157
- const dependencyType = getDependencyTypeFromTargetTasks(fromTaskClue, toTaskClue);
158
- const { fromId, toId, type } = this.mapper.dependencyFields;
159
- this.gantt.dependencyAdd.emit({
160
- fromTask: fromTask,
161
- toTask: toTask,
162
- type: dependencyType,
163
- isValid: this.gantt.validateNewDependency({
164
- [fromId]: this.mapper.extractFromTask(fromTask, 'id'),
165
- [toId]: this.mapper.extractFromTask(toTask, 'id'),
166
- [type]: dependencyType
167
- })
168
- });
169
- });
170
- }
171
- this.clearPolyline();
172
- this.removeDragStartClasses(this.fromTaskClue);
173
- this.fromTaskClue = null;
174
- this.cancelScroll();
175
- this.closeDragPopup();
176
- }
177
- updatePolyline(start, end) {
178
- const points = `${start.left},${start.top} ${end.left},${end.top}`;
179
- this.renderer.setAttribute(this.polyline, 'points', points);
180
- }
181
- clearPolyline() {
182
- this.renderer.removeAttribute(this.polyline, 'points');
183
- }
184
- assignDragStartClasses(dragClue) {
185
- if (!isPresent(dragClue)) {
186
- return;
187
- }
188
- this.renderer.addClass(this.container, USER_SELECT_NONE_CLASS);
189
- this.renderer.addClass(dragClue, DRAG_CLUE_HOVER_CLASS);
190
- const taskWrapper = getClosestTaskWrapper(dragClue, this.container);
191
- if (isPresent(taskWrapper)) {
192
- this.renderer.addClass(taskWrapper, TASK_WRAPPER_DRAG_CLASS);
193
- }
194
- }
195
- removeDragStartClasses(dragClue) {
196
- if (!isPresent(dragClue)) {
197
- return;
198
- }
199
- this.renderer.removeClass(this.container, USER_SELECT_NONE_CLASS);
200
- this.renderer.removeClass(dragClue, DRAG_CLUE_HOVER_CLASS);
201
- const taskWrapper = getClosestTaskWrapper(dragClue, this.container);
202
- if (isPresent(taskWrapper)) {
203
- this.renderer.removeClass(taskWrapper, TASK_WRAPPER_DRAG_CLASS);
204
- }
205
- }
206
- scrollPointIntoView({ left, top }) {
207
- this.timelineScrollService.requestScrollCancel();
208
- this.timelineScrollService.requestHorizontalScroll(left);
209
- this.timelineScrollService.requestVerticalScroll(top);
210
- }
211
- cancelScroll() {
212
- this.timelineScrollService.requestScrollCancel();
213
- }
214
- addScrollListener() {
215
- if (!isDocumentAvailable()) {
216
- return;
217
- }
218
- this.zone.runOutsideAngular(() => this.scrollListenerDisposer = this.renderer.listen(this.container, 'scroll', () => {
219
- // update the polyline only if we're currently dragging
220
- if (isPresent(this.fromTaskClue) && isPresent(this.currentPointerClientCoords)) {
221
- const { left, top } = this.currentPointerClientCoords;
222
- const pointerOffsetCoords = clientToOffsetCoords(left, top, this.container);
223
- this.updatePolyline(this.polylineStartCoords, pointerOffsetCoords);
224
- if (this.displayValidationTooltip) {
225
- this.updateDragPopup(pointerOffsetCoords);
226
- }
227
- }
228
- }));
229
- }
230
- removeScrollListener() {
231
- if (isPresent(this.scrollListenerDisposer)) {
232
- this.scrollListenerDisposer();
233
- this.scrollListenerDisposer = null;
234
- }
235
- }
236
- openDragPopup() {
237
- if (isPresent(this.dragPopup)) {
238
- this.closeDragPopup();
239
- }
240
- this.dragPopup = this.popupService.open({
241
- animate: false,
242
- content: DragValidationTooltipComponent,
243
- appendTo: this.popupContainer,
244
- positionMode: 'absolute',
245
- popupClass: 'k-popup-transparent'
246
- });
247
- }
248
- updateDragPopup(pointerOffsetPosition) {
249
- if (!isPresent(this.dragPopup)) {
250
- this.openDragPopup();
251
- }
252
- const tooltip = this.dragPopup.content.instance;
253
- const { fromTaskName, toTaskName, isValid, showValidityStatus } = this.getTooltipContext();
254
- if (tooltip.fromTaskName !== fromTaskName ||
255
- tooltip.toTaskName !== toTaskName ||
256
- tooltip.isValid !== isValid ||
257
- tooltip.showValidityStatus !== showValidityStatus) {
258
- tooltip.fromTaskName = fromTaskName;
259
- tooltip.toTaskName = toTaskName;
260
- tooltip.isValid = isValid;
261
- tooltip.showValidityStatus = showValidityStatus;
262
- this.dragPopup.content.changeDetectorRef.detectChanges();
263
- }
264
- this.dragPopup.popup.instance.offset = this.normalizePopupPosition(pointerOffsetPosition);
265
- this.dragPopup.popup.changeDetectorRef.detectChanges();
266
- }
267
- closeDragPopup() {
268
- if (isPresent(this.dragPopup)) {
269
- this.dragPopup.close();
270
- this.dragPopup = null;
271
- }
272
- }
273
- extractTaskName(target) {
274
- if (!isTaskWrapper(target, this.container)) {
275
- return null;
276
- }
277
- const taskIndex = getClosestTaskIndex(target, this.container);
278
- const task = this.gantt.renderedTreeListItems[taskIndex];
279
- const taskName = this.mapper.extractFromTask(task, 'title');
280
- return taskName;
281
- }
282
- getTooltipContext() {
283
- const fromTaskName = this.extractTaskName(this.fromTaskClue);
284
- const currentPointerTarget = elementFromPoint(this.currentPointerClientCoords.left, this.currentPointerClientCoords.top);
285
- const toTaskName = isTaskWrapper(currentPointerTarget, this.container) && !sameTaskClues(this.fromTaskClue, currentPointerTarget, this.container) ?
286
- this.extractTaskName(currentPointerTarget) :
287
- '';
288
- const showValidityStatus = isDependencyDragClue(currentPointerTarget) && !sameTaskClues(this.fromTaskClue, currentPointerTarget, this.container);
289
- const { fromId, toId, type } = this.mapper.dependencyFields;
290
- return {
291
- fromTaskName,
292
- toTaskName,
293
- showValidityStatus,
294
- isValid: showValidityStatus && this.gantt.validateNewDependency({
295
- [fromId]: this.mapper.extractFromTask(this.gantt.renderedTreeListItems[getClosestTaskIndex(this.fromTaskClue, this.container)], 'id'),
296
- [toId]: this.mapper.extractFromTask(this.gantt.renderedTreeListItems[getClosestTaskIndex(currentPointerTarget, this.container)], 'id'),
297
- [type]: getDependencyTypeFromTargetTasks(this.fromTaskClue, currentPointerTarget)
298
- })
299
- };
300
- }
301
- /**
302
- * Restricts the popup position to not go below the scroll height or width of the container.
303
- * Flips the position of the popup when there's not enough vertical space in the visible part of the container to render the popup.
304
- */
305
- normalizePopupPosition(pointerOffsetPosition) {
306
- let top = pointerOffsetPosition.top + DEFAULT_POPUP_VERTICAL_MARGIN;
307
- const containerClientBottom = this.container.clientHeight + this.container.scrollTop;
308
- const popupHeight = this.dragPopup.popupElement.querySelector('.k-tooltip').clientHeight;
309
- const enoughSpaceToRender = top < containerClientBottom - popupHeight;
310
- // flip the popup above the pointer if there's not enough space in the bottom of the container
311
- if (!enoughSpaceToRender) {
312
- // margin * 2 to account for the already applied margin
313
- top -= popupHeight + (DEFAULT_POPUP_VERTICAL_MARGIN * 2);
314
- }
315
- // center the popup horizontally according to the pointer position
316
- const popupWidth = this.dragPopup.popupElement.querySelector('.k-tooltip').clientWidth;
317
- const left = pointerOffsetPosition.left - popupWidth / 2;
318
- // don't allow the popup to be cut out of the viewport
319
- const minLeftTop = 0;
320
- // restrict the popup from being positioned beyond or before the available scrollable space
321
- return {
322
- left: fitToRange(left, minLeftTop, this.container.scrollWidth - popupWidth),
323
- top: fitToRange(top, minLeftTop, this.container.scrollHeight - popupHeight)
324
- };
325
- }
326
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DependencyDragCreateDirective, deps: [{ token: i1.GanttComponent }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i2.MappingService }, { token: i3.PopupService }, { token: i4.TimelineScrollService }], target: i0.ɵɵFactoryTarget.Directive });
327
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: DependencyDragCreateDirective, isStandalone: true, selector: "[kendoGanttDependencyDragCreate]", inputs: { displayValidationTooltip: "displayValidationTooltip" }, ngImport: i0 });
328
- }
329
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DependencyDragCreateDirective, decorators: [{
330
- type: Directive,
331
- args: [{
332
- selector: '[kendoGanttDependencyDragCreate]',
333
- standalone: true
334
- }]
335
- }], ctorParameters: () => [{ type: i1.GanttComponent }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i2.MappingService }, { type: i3.PopupService }, { type: i4.TimelineScrollService }], propDecorators: { displayValidationTooltip: [{
336
- type: Input
337
- }] } });
@@ -1,70 +0,0 @@
1
- /**-----------------------------------------------------------------------------------------
2
- * Copyright © 2026 Progress Software Corporation. All rights reserved.
3
- * Licensed under commercial license. See LICENSE.md in the project root for more information
4
- *-------------------------------------------------------------------------------------------*/
5
- import { Component } from '@angular/core';
6
- import * as i0 from "@angular/core";
7
- /**
8
- * @hidden
9
- */
10
- export class DragValidationTooltipComponent {
11
- /**
12
- * Sets the status class of the attempted operation.
13
- * Note that the status will be ignored and the `neutral` status class will be rendered,
14
- * if the any of the fromTaskName or toTaskName are not populated.
15
- */
16
- isValid = false;
17
- /**
18
- * The name of the task where the dragging has started.
19
- */
20
- fromTaskName;
21
- /**
22
- * The name of the task which is being currently hovered.
23
- */
24
- toTaskName;
25
- /**
26
- * Specifies whether the valid/invalid validity classes should be rendered or not.
27
- * Prevents the validity classes being rendered when e.g. the same task is hovered during drag,
28
- * or when a task body is hovered and not an actual drag clue.
29
- */
30
- showValidityStatus;
31
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DragValidationTooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
32
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: DragValidationTooltipComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: `
33
- <div
34
- class="k-tooltip k-gantt-tooltip-validation"
35
- [class.k-gantt-tooltip-valid]="showValidityStatus && isValid"
36
- [class.k-gantt-tooltip-invalid]="showValidityStatus && !isValid"
37
- >
38
- <div class="k-gantt-tooltip-validation-row">
39
- <span class="k-gantt-tooltip-validation-label">From:</span>
40
- <span class="k-gantt-tooltip-validation-value">{{ fromTaskName }}</span>
41
- </div>
42
- <div class="k-gantt-tooltip-validation-row">
43
- <span class="k-gantt-tooltip-validation-label">To:</span>
44
- <span class="k-gantt-tooltip-validation-value">{{ toTaskName }}</span>
45
- </div>
46
- </div>
47
- `, isInline: true });
48
- }
49
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DragValidationTooltipComponent, decorators: [{
50
- type: Component,
51
- args: [{
52
- template: `
53
- <div
54
- class="k-tooltip k-gantt-tooltip-validation"
55
- [class.k-gantt-tooltip-valid]="showValidityStatus && isValid"
56
- [class.k-gantt-tooltip-invalid]="showValidityStatus && !isValid"
57
- >
58
- <div class="k-gantt-tooltip-validation-row">
59
- <span class="k-gantt-tooltip-validation-label">From:</span>
60
- <span class="k-gantt-tooltip-validation-value">{{ fromTaskName }}</span>
61
- </div>
62
- <div class="k-gantt-tooltip-validation-row">
63
- <span class="k-gantt-tooltip-validation-label">To:</span>
64
- <span class="k-gantt-tooltip-validation-value">{{ toTaskName }}</span>
65
- </div>
66
- </div>
67
- `,
68
- standalone: true
69
- }]
70
- }] });