@progress/kendo-angular-gantt 0.3.0-dev.202201111723 → 1.0.0
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.
- package/dist/cdn/js/kendo-angular-gantt.js +2 -2
- package/dist/cdn/main.js +1 -29
- package/dist/es/common/touch-enabled.js +9 -0
- package/dist/es/dependencies/utils.js +34 -0
- package/dist/es/dragging/dependency-drag-create.directive.js +347 -0
- package/dist/es/dragging/drag-validation-tooltip.component.js +27 -0
- package/dist/es/editing/dependencies-table.component.js +1 -1
- package/dist/es/editing/edit-dialog.component.js +3 -3
- package/dist/es/editing/edit.service.js +4 -2
- package/dist/es/editing/task-fields.component.js +1 -1
- package/dist/es/editing/{util.js → utils.js} +0 -0
- package/dist/es/gantt.component.js +313 -28
- package/dist/es/gantt.module.js +23 -6
- package/dist/es/index.js +5 -0
- package/dist/es/main.js +1 -0
- package/dist/es/models/events/dependency-add-event.interface.js +4 -0
- package/dist/es/models/events/task-delete-event.interface.js +4 -0
- package/dist/es/models/view-item.interface.js +4 -0
- package/dist/es/navigation/navigation-models.js +4 -0
- package/dist/es/navigation/navigation.service.js +390 -0
- package/dist/es/navigation/utils.js +77 -0
- package/dist/es/package-metadata.js +1 -1
- package/dist/es/rendering/gantt-milestone-task.component.js +12 -6
- package/dist/es/rendering/gantt-summary-task.component.js +27 -6
- package/dist/es/rendering/gantt-task-base.js +84 -22
- package/dist/es/rendering/gantt-task.component.js +13 -8
- package/dist/es/rendering/gantt-tasks-table-body.component.js +13 -5
- package/dist/es/scrolling/drag-scroll-settings.js +20 -0
- package/dist/es/scrolling/timeline-scroll.directive.js +89 -0
- package/dist/es/scrolling/timeline-scroll.service.js +39 -0
- package/dist/es/scrolling/utils.js +80 -0
- package/dist/es/timeline/gantt-timeline.component.js +50 -4
- package/dist/es/toolbar/toolbar.component.js +12 -13
- package/dist/es/toolbar/view-selector.component.js +1 -1
- package/dist/es/utils.js +153 -12
- package/dist/es2015/common/touch-enabled.d.ts +9 -0
- package/dist/es2015/common/touch-enabled.js +9 -0
- package/dist/es2015/dependencies/utils.d.ts +15 -0
- package/dist/es2015/dependencies/utils.js +34 -0
- package/dist/es2015/dragging/dependency-drag-create.directive.d.ts +72 -0
- package/dist/es2015/dragging/dependency-drag-create.directive.js +324 -0
- package/dist/es2015/dragging/drag-validation-tooltip.component.d.ts +29 -0
- package/dist/es2015/dragging/drag-validation-tooltip.component.js +76 -0
- package/dist/es2015/editing/dependencies-table.component.js +1 -1
- package/dist/es2015/editing/edit-dialog.component.d.ts +1 -1
- package/dist/es2015/editing/edit-dialog.component.js +12 -4
- package/dist/es2015/editing/edit.service.d.ts +2 -3
- package/dist/es2015/editing/edit.service.js +4 -2
- package/dist/es2015/editing/task-fields.component.js +1 -1
- package/dist/es2015/editing/{util.d.ts → utils.d.ts} +2 -2
- package/dist/es2015/editing/{util.js → utils.js} +0 -0
- package/dist/es2015/gantt.component.d.ts +112 -17
- package/dist/es2015/gantt.component.js +292 -30
- package/dist/es2015/gantt.module.js +23 -6
- package/dist/es2015/index.d.ts +5 -0
- package/dist/es2015/index.js +5 -0
- package/dist/es2015/index.metadata.json +1 -1
- package/dist/es2015/main.d.ts +1 -0
- package/dist/es2015/main.js +1 -0
- package/dist/es2015/models/events/dependency-add-event.interface.d.ts +26 -0
- package/dist/es2015/models/events/dependency-add-event.interface.js +4 -0
- package/dist/es2015/models/events/task-click-event.interface.d.ts +3 -3
- package/dist/es2015/models/events/task-delete-event.interface.d.ts +21 -0
- package/dist/es2015/models/events/task-delete-event.interface.js +4 -0
- package/dist/es2015/models/events/task-edit-event.interface.d.ts +27 -10
- package/dist/es2015/models/models.d.ts +4 -0
- package/dist/es2015/models/view-item.interface.d.ts +35 -0
- package/dist/es2015/models/view-item.interface.js +4 -0
- package/dist/es2015/navigation/navigation-models.d.ts +34 -0
- package/dist/es2015/navigation/navigation-models.js +4 -0
- package/dist/es2015/navigation/navigation.service.d.ts +126 -0
- package/dist/es2015/navigation/navigation.service.js +355 -0
- package/dist/es2015/navigation/utils.d.ts +26 -0
- package/dist/es2015/navigation/utils.js +69 -0
- package/dist/es2015/package-metadata.js +1 -1
- package/dist/es2015/rendering/gantt-milestone-task.component.d.ts +3 -1
- package/dist/es2015/rendering/gantt-milestone-task.component.js +35 -8
- package/dist/es2015/rendering/gantt-summary-task.component.d.ts +5 -1
- package/dist/es2015/rendering/gantt-summary-task.component.js +47 -8
- package/dist/es2015/rendering/gantt-task-base.d.ts +20 -6
- package/dist/es2015/rendering/gantt-task-base.js +75 -22
- package/dist/es2015/rendering/gantt-task.component.d.ts +4 -2
- package/dist/es2015/rendering/gantt-task.component.js +47 -13
- package/dist/es2015/rendering/gantt-tasks-table-body.component.d.ts +6 -3
- package/dist/es2015/rendering/gantt-tasks-table-body.component.js +27 -9
- package/dist/es2015/scrolling/drag-scroll-settings.d.ts +47 -0
- package/dist/es2015/scrolling/drag-scroll-settings.js +20 -0
- package/dist/es2015/scrolling/scroll-sync.service.d.ts +1 -1
- package/dist/es2015/scrolling/timeline-scroll.directive.d.ts +24 -0
- package/dist/es2015/scrolling/timeline-scroll.directive.js +78 -0
- package/dist/es2015/scrolling/timeline-scroll.service.d.ts +20 -0
- package/dist/es2015/scrolling/timeline-scroll.service.js +44 -0
- package/dist/es2015/scrolling/utils.d.ts +29 -0
- package/dist/es2015/scrolling/utils.js +80 -0
- package/dist/es2015/timeline/gantt-timeline.component.d.ts +29 -4
- package/dist/es2015/timeline/gantt-timeline.component.js +67 -5
- package/dist/es2015/toolbar/toolbar.component.d.ts +4 -5
- package/dist/es2015/toolbar/toolbar.component.js +12 -13
- package/dist/es2015/toolbar/view-selector.component.js +3 -1
- package/dist/es2015/utils.d.ts +77 -8
- package/dist/es2015/utils.js +153 -12
- package/dist/fesm2015/index.js +3033 -1367
- package/dist/fesm5/index.js +2447 -830
- package/dist/npm/common/touch-enabled.js +11 -0
- package/dist/npm/dependencies/utils.js +34 -0
- package/dist/npm/dragging/dependency-drag-create.directive.js +349 -0
- package/dist/npm/dragging/drag-validation-tooltip.component.js +29 -0
- package/dist/npm/editing/dependencies-table.component.js +1 -1
- package/dist/npm/editing/edit-dialog.component.js +3 -3
- package/dist/npm/editing/edit.service.js +4 -2
- package/dist/npm/editing/task-fields.component.js +1 -1
- package/dist/npm/editing/{util.js → utils.js} +0 -0
- package/dist/npm/gantt.component.js +315 -30
- package/dist/npm/gantt.module.js +22 -5
- package/dist/npm/index.js +10 -0
- package/dist/npm/main.js +2 -0
- package/dist/npm/models/events/dependency-add-event.interface.js +6 -0
- package/dist/npm/models/events/task-delete-event.interface.js +6 -0
- package/dist/npm/models/view-item.interface.js +6 -0
- package/dist/npm/navigation/navigation-models.js +6 -0
- package/dist/npm/navigation/navigation.service.js +392 -0
- package/dist/npm/navigation/utils.js +79 -0
- package/dist/npm/package-metadata.js +1 -1
- package/dist/npm/rendering/gantt-milestone-task.component.js +11 -5
- package/dist/npm/rendering/gantt-summary-task.component.js +26 -5
- package/dist/npm/rendering/gantt-task-base.js +84 -22
- package/dist/npm/rendering/gantt-task.component.js +12 -7
- package/dist/npm/rendering/gantt-tasks-table-body.component.js +13 -5
- package/dist/npm/scrolling/drag-scroll-settings.js +22 -0
- package/dist/npm/scrolling/timeline-scroll.directive.js +91 -0
- package/dist/npm/scrolling/timeline-scroll.service.js +41 -0
- package/dist/npm/scrolling/utils.js +83 -0
- package/dist/npm/timeline/gantt-timeline.component.js +49 -3
- package/dist/npm/toolbar/toolbar.component.js +10 -11
- package/dist/npm/toolbar/view-selector.component.js +1 -1
- package/dist/npm/utils.js +153 -12
- package/dist/systemjs/kendo-angular-gantt.js +1 -1
- package/package.json +23 -21
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/**-----------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright © 2021 Progress Software Corporation. All rights reserved.
|
|
3
|
+
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
+
*-------------------------------------------------------------------------------------------*/
|
|
5
|
+
import * as tslib_1 from "tslib";
|
|
6
|
+
import { Directive, Input, NgZone, Renderer2 } from '@angular/core';
|
|
7
|
+
import { isDocumentAvailable } from '@progress/kendo-angular-common';
|
|
8
|
+
import { PopupService } from '@progress/kendo-angular-popup';
|
|
9
|
+
import { GanttComponent } from '../gantt.component';
|
|
10
|
+
import { MappingService } from '../common/mapping.service';
|
|
11
|
+
import { TimelineScrollService } from '../scrolling/timeline-scroll.service';
|
|
12
|
+
import { DragValidationTooltipComponent } from './drag-validation-tooltip.component';
|
|
13
|
+
import { clientToOffsetCoords, getElementClientCenterCoords } from '../dependencies/utils';
|
|
14
|
+
import { isPresent, isDependencyDragClue, getClosestTaskWrapper, getDependencyTypeFromTargetTasks, getClosestTaskIndex, sameTaskClues, isTaskWrapper, fitToRange } from '../utils';
|
|
15
|
+
import { elementFromPoint } from '../utils';
|
|
16
|
+
/**
|
|
17
|
+
* When added to the .k-task-dot, the element will be kept with hover styles.
|
|
18
|
+
* Used for the drag clue from which the dragging has started.
|
|
19
|
+
*/
|
|
20
|
+
const DRAG_CLUE_HOVER_CLASS = 'k-state-hover';
|
|
21
|
+
/**
|
|
22
|
+
* Add the selection disabling class to the enitre container.
|
|
23
|
+
* Otherwise existing selection on a given task text prevents dragging the clue even if the clue has `user-select: none` styles.
|
|
24
|
+
*/
|
|
25
|
+
const USER_SELECT_NONE_CLASS = 'k-user-select-none';
|
|
26
|
+
/**
|
|
27
|
+
* When added to the .k-task-wrap, the containing .k-task-dot elements will be kept visible even when not hovered.
|
|
28
|
+
* Used for the drag clue from which the dragging has started.
|
|
29
|
+
*/
|
|
30
|
+
const TASK_WRAPPER_DRAG_CLASS = 'k-origin';
|
|
31
|
+
/**
|
|
32
|
+
* Use 20px margin between the pointer and the popup.
|
|
33
|
+
* Could be made user-configurable if there's demand.
|
|
34
|
+
*/
|
|
35
|
+
const DEFAULT_POPUP_VERTICAL_MARGIN = 20;
|
|
36
|
+
/**
|
|
37
|
+
* A directive which enables the creation of new dependencies via dragging.
|
|
38
|
+
*/
|
|
39
|
+
let DependencyDragCreateDirective = class DependencyDragCreateDirective {
|
|
40
|
+
constructor(gantt, zone, renderer, mapper, popupService, timelineScrollService) {
|
|
41
|
+
this.gantt = gantt;
|
|
42
|
+
this.zone = zone;
|
|
43
|
+
this.renderer = renderer;
|
|
44
|
+
this.mapper = mapper;
|
|
45
|
+
this.popupService = popupService;
|
|
46
|
+
this.timelineScrollService = timelineScrollService;
|
|
47
|
+
/**
|
|
48
|
+
* Specifies whether the validation tooltip will be displayed during drag operations.
|
|
49
|
+
*
|
|
50
|
+
* @default true
|
|
51
|
+
*/
|
|
52
|
+
this.displayValidationTooltip = true;
|
|
53
|
+
this.gantt.renderDependencyDragClues = true;
|
|
54
|
+
}
|
|
55
|
+
get container() {
|
|
56
|
+
if (!isPresent(this.gantt.timeline) || !isPresent(this.gantt.timeline.timelineContent)) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
return this.gantt.timeline.timelineContent.nativeElement;
|
|
60
|
+
}
|
|
61
|
+
get polyline() {
|
|
62
|
+
if (!isPresent(this.gantt.timeline) || !isPresent(this.gantt.timeline.dependencyDragCreatePolyline)) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
return this.gantt.timeline.dependencyDragCreatePolyline.nativeElement;
|
|
66
|
+
}
|
|
67
|
+
get popupContainer() {
|
|
68
|
+
if (!isPresent(this.gantt.timeline) || !isPresent(this.gantt.timeline.dragPopupContainer)) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
return this.gantt.timeline.dragPopupContainer;
|
|
72
|
+
}
|
|
73
|
+
ngAfterViewInit() {
|
|
74
|
+
this.subscribeDraggable();
|
|
75
|
+
this.addScrollListener();
|
|
76
|
+
}
|
|
77
|
+
ngOnDestroy() {
|
|
78
|
+
this.unsubscribeDraggable();
|
|
79
|
+
this.removeScrollListener();
|
|
80
|
+
this.fromTaskClue = null;
|
|
81
|
+
this.cancelScroll();
|
|
82
|
+
this.closeDragPopup();
|
|
83
|
+
}
|
|
84
|
+
subscribeDraggable() {
|
|
85
|
+
this.dragSubscriptions = this.gantt.timeline.timelineContainerPress
|
|
86
|
+
.subscribe(this.handlePress.bind(this));
|
|
87
|
+
this.dragSubscriptions.add(this.gantt.timeline.timelineContainerDrag
|
|
88
|
+
.subscribe(this.handleDrag.bind(this)));
|
|
89
|
+
this.dragSubscriptions.add(this.gantt.timeline.timelineContainerRelease
|
|
90
|
+
.subscribe(this.handleRelease.bind(this)));
|
|
91
|
+
}
|
|
92
|
+
unsubscribeDraggable() {
|
|
93
|
+
if (isPresent(this.dragSubscriptions)) {
|
|
94
|
+
this.dragSubscriptions.unsubscribe();
|
|
95
|
+
this.dragSubscriptions = null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
handlePress({ clientX, clientY }) {
|
|
99
|
+
// using `originalEvent.target` is not reliable under mobile devices with the current implementation of the draggable, so use this instead
|
|
100
|
+
const target = elementFromPoint(clientX, clientY);
|
|
101
|
+
if (isDependencyDragClue(target)) {
|
|
102
|
+
this.fromTaskClue = target;
|
|
103
|
+
this.assignDragStartClasses(this.fromTaskClue);
|
|
104
|
+
// use the center of the target clue as polyline starting point
|
|
105
|
+
const dragClueCenterCoords = getElementClientCenterCoords(this.fromTaskClue);
|
|
106
|
+
// the polyline uses `position: aboslute`, so translate the client coordinates to offset coordinates (`left` and `top` relative to the timeline container)
|
|
107
|
+
this.polylineStartCoords = clientToOffsetCoords(dragClueCenterCoords.left, dragClueCenterCoords.top, this.container);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
handleDrag({ clientX, clientY }) {
|
|
111
|
+
if (isPresent(this.fromTaskClue)) {
|
|
112
|
+
// the polyline uses `position: aboslute`, so translate the client coordinates to offset coordinates (`left` and `top` relative to the timeline container)
|
|
113
|
+
const pointerOffsetCoords = clientToOffsetCoords(clientX, clientY, this.container);
|
|
114
|
+
// the start coords are calculated just once per drag session in handlePress
|
|
115
|
+
// use the current drag coords as polyline end coords
|
|
116
|
+
this.updatePolyline(this.polylineStartCoords, pointerOffsetCoords);
|
|
117
|
+
this.currentPointerClientCoords = { left: clientX, top: clientY };
|
|
118
|
+
if (this.gantt.dragScrollSettings.enabled) {
|
|
119
|
+
// use client coordinates for scroll trigger
|
|
120
|
+
this.scrollPointIntoView(this.currentPointerClientCoords);
|
|
121
|
+
}
|
|
122
|
+
if (this.displayValidationTooltip) {
|
|
123
|
+
this.updateDragPopup(pointerOffsetCoords);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
handleRelease({ clientX, clientY }) {
|
|
128
|
+
if (!isPresent(this.fromTaskClue)) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
// using `originalEvent.target` is not reliable under mobile devices with the current implementation of the draggable, so use this instead
|
|
132
|
+
const target = elementFromPoint(clientX, clientY);
|
|
133
|
+
if (isDependencyDragClue(target) && !sameTaskClues(this.fromTaskClue, target, this.container)) {
|
|
134
|
+
this.zone.run(() => {
|
|
135
|
+
const fromTaskClue = this.fromTaskClue;
|
|
136
|
+
const toTaskClue = target;
|
|
137
|
+
const fromTask = this.gantt.renderedTreeListItems[getClosestTaskIndex(fromTaskClue, this.container)];
|
|
138
|
+
const toTask = this.gantt.renderedTreeListItems[getClosestTaskIndex(toTaskClue, this.container)];
|
|
139
|
+
const dependencyType = getDependencyTypeFromTargetTasks(fromTaskClue, toTaskClue);
|
|
140
|
+
const { fromId, toId, type } = this.mapper.dependencyFields;
|
|
141
|
+
this.gantt.dependencyAdd.emit({
|
|
142
|
+
fromTask: fromTask,
|
|
143
|
+
toTask: toTask,
|
|
144
|
+
type: dependencyType,
|
|
145
|
+
isValid: this.gantt.validateNewDependency({
|
|
146
|
+
[fromId]: this.mapper.extractFromTask(fromTask, 'id'),
|
|
147
|
+
[toId]: this.mapper.extractFromTask(toTask, 'id'),
|
|
148
|
+
[type]: dependencyType
|
|
149
|
+
})
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
this.clearPolyline();
|
|
154
|
+
this.removeDragStartClasses(this.fromTaskClue);
|
|
155
|
+
this.fromTaskClue = null;
|
|
156
|
+
this.cancelScroll();
|
|
157
|
+
this.closeDragPopup();
|
|
158
|
+
}
|
|
159
|
+
updatePolyline(start, end) {
|
|
160
|
+
const points = `${start.left},${start.top} ${end.left},${end.top}`;
|
|
161
|
+
this.renderer.setAttribute(this.polyline, 'points', points);
|
|
162
|
+
}
|
|
163
|
+
clearPolyline() {
|
|
164
|
+
this.renderer.removeAttribute(this.polyline, 'points');
|
|
165
|
+
}
|
|
166
|
+
assignDragStartClasses(dragClue) {
|
|
167
|
+
if (!isPresent(dragClue)) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
this.renderer.addClass(this.container, USER_SELECT_NONE_CLASS);
|
|
171
|
+
this.renderer.addClass(dragClue, DRAG_CLUE_HOVER_CLASS);
|
|
172
|
+
const taskWrapper = getClosestTaskWrapper(dragClue, this.container);
|
|
173
|
+
if (isPresent(taskWrapper)) {
|
|
174
|
+
this.renderer.addClass(taskWrapper, TASK_WRAPPER_DRAG_CLASS);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
removeDragStartClasses(dragClue) {
|
|
178
|
+
if (!isPresent(dragClue)) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
this.renderer.removeClass(this.container, USER_SELECT_NONE_CLASS);
|
|
182
|
+
this.renderer.removeClass(dragClue, DRAG_CLUE_HOVER_CLASS);
|
|
183
|
+
const taskWrapper = getClosestTaskWrapper(dragClue, this.container);
|
|
184
|
+
if (isPresent(taskWrapper)) {
|
|
185
|
+
this.renderer.removeClass(taskWrapper, TASK_WRAPPER_DRAG_CLASS);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
scrollPointIntoView({ left, top }) {
|
|
189
|
+
this.timelineScrollService.requestScrollCancel();
|
|
190
|
+
this.timelineScrollService.requestHorizontalScroll(left);
|
|
191
|
+
this.timelineScrollService.requestVerticalScroll(top);
|
|
192
|
+
}
|
|
193
|
+
cancelScroll() {
|
|
194
|
+
this.timelineScrollService.requestScrollCancel();
|
|
195
|
+
}
|
|
196
|
+
addScrollListener() {
|
|
197
|
+
if (!isDocumentAvailable()) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
this.zone.runOutsideAngular(() => this.scrollListenerDisposer = this.renderer.listen(this.container, 'scroll', () => {
|
|
201
|
+
// update the polyline only if we're currently dragging
|
|
202
|
+
if (isPresent(this.fromTaskClue) && isPresent(this.currentPointerClientCoords)) {
|
|
203
|
+
const { left, top } = this.currentPointerClientCoords;
|
|
204
|
+
const pointerOffsetCoords = clientToOffsetCoords(left, top, this.container);
|
|
205
|
+
this.updatePolyline(this.polylineStartCoords, pointerOffsetCoords);
|
|
206
|
+
if (this.displayValidationTooltip) {
|
|
207
|
+
this.updateDragPopup(pointerOffsetCoords);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}));
|
|
211
|
+
}
|
|
212
|
+
removeScrollListener() {
|
|
213
|
+
if (isPresent(this.scrollListenerDisposer)) {
|
|
214
|
+
this.scrollListenerDisposer();
|
|
215
|
+
this.scrollListenerDisposer = null;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
openDragPopup() {
|
|
219
|
+
if (isPresent(this.dragPopup)) {
|
|
220
|
+
this.closeDragPopup();
|
|
221
|
+
}
|
|
222
|
+
this.dragPopup = this.popupService.open({
|
|
223
|
+
animate: false,
|
|
224
|
+
content: DragValidationTooltipComponent,
|
|
225
|
+
appendTo: this.popupContainer,
|
|
226
|
+
positionMode: 'absolute',
|
|
227
|
+
popupClass: 'k-popup-transparent'
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
updateDragPopup(pointerOffsetPosition) {
|
|
231
|
+
if (!isPresent(this.dragPopup)) {
|
|
232
|
+
this.openDragPopup();
|
|
233
|
+
}
|
|
234
|
+
const tooltip = this.dragPopup.content.instance;
|
|
235
|
+
const { fromTaskName, toTaskName, isValid, showValidityStatus } = this.getTooltipContext();
|
|
236
|
+
if (tooltip.fromTaskName !== fromTaskName ||
|
|
237
|
+
tooltip.toTaskName !== toTaskName ||
|
|
238
|
+
tooltip.isValid !== isValid ||
|
|
239
|
+
tooltip.showValidityStatus !== showValidityStatus) {
|
|
240
|
+
tooltip.fromTaskName = fromTaskName;
|
|
241
|
+
tooltip.toTaskName = toTaskName;
|
|
242
|
+
tooltip.isValid = isValid;
|
|
243
|
+
tooltip.showValidityStatus = showValidityStatus;
|
|
244
|
+
this.dragPopup.content.changeDetectorRef.detectChanges();
|
|
245
|
+
}
|
|
246
|
+
this.dragPopup.popup.instance.offset = this.normalizePopupPosition(pointerOffsetPosition);
|
|
247
|
+
this.dragPopup.popup.changeDetectorRef.detectChanges();
|
|
248
|
+
}
|
|
249
|
+
closeDragPopup() {
|
|
250
|
+
if (isPresent(this.dragPopup)) {
|
|
251
|
+
this.dragPopup.close();
|
|
252
|
+
this.dragPopup = null;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
extractTaskName(target) {
|
|
256
|
+
if (!isTaskWrapper(target, this.container)) {
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
const taskIndex = getClosestTaskIndex(target, this.container);
|
|
260
|
+
const task = this.gantt.renderedTreeListItems[taskIndex];
|
|
261
|
+
const taskName = this.mapper.extractFromTask(task, 'title');
|
|
262
|
+
return taskName;
|
|
263
|
+
}
|
|
264
|
+
getTooltipContext() {
|
|
265
|
+
const fromTaskName = this.extractTaskName(this.fromTaskClue);
|
|
266
|
+
const currentPointerTarget = elementFromPoint(this.currentPointerClientCoords.left, this.currentPointerClientCoords.top);
|
|
267
|
+
const toTaskName = isTaskWrapper(currentPointerTarget, this.container) && !sameTaskClues(this.fromTaskClue, currentPointerTarget, this.container) ?
|
|
268
|
+
this.extractTaskName(currentPointerTarget) :
|
|
269
|
+
'';
|
|
270
|
+
const showValidityStatus = isDependencyDragClue(currentPointerTarget) && !sameTaskClues(this.fromTaskClue, currentPointerTarget, this.container);
|
|
271
|
+
const { fromId, toId, type } = this.mapper.dependencyFields;
|
|
272
|
+
return {
|
|
273
|
+
fromTaskName,
|
|
274
|
+
toTaskName,
|
|
275
|
+
showValidityStatus,
|
|
276
|
+
isValid: showValidityStatus && this.gantt.validateNewDependency({
|
|
277
|
+
[fromId]: this.mapper.extractFromTask(this.gantt.renderedTreeListItems[getClosestTaskIndex(this.fromTaskClue, this.container)], 'id'),
|
|
278
|
+
[toId]: this.mapper.extractFromTask(this.gantt.renderedTreeListItems[getClosestTaskIndex(currentPointerTarget, this.container)], 'id'),
|
|
279
|
+
[type]: getDependencyTypeFromTargetTasks(this.fromTaskClue, currentPointerTarget)
|
|
280
|
+
})
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Restricts the popup position to not go below the scroll height or width of the container.
|
|
285
|
+
* Flips the position of the popup when there's not enough vertical space in the visible part of the container to render the popup.
|
|
286
|
+
*/
|
|
287
|
+
normalizePopupPosition(pointerOffsetPosition) {
|
|
288
|
+
let top = pointerOffsetPosition.top + DEFAULT_POPUP_VERTICAL_MARGIN;
|
|
289
|
+
const containerClientBottom = this.container.clientHeight + this.container.scrollTop;
|
|
290
|
+
const popupHeight = this.dragPopup.popupElement.querySelector('.k-tooltip').clientHeight;
|
|
291
|
+
const enoughSpaceToRender = top < containerClientBottom - popupHeight;
|
|
292
|
+
// flip the popup above the pointer if there's not enough space in the bottom of the container
|
|
293
|
+
if (!enoughSpaceToRender) {
|
|
294
|
+
// margin * 2 to account for the already applied margin
|
|
295
|
+
top -= popupHeight + (DEFAULT_POPUP_VERTICAL_MARGIN * 2);
|
|
296
|
+
}
|
|
297
|
+
// center the popup horizontally according to the pointer position
|
|
298
|
+
const popupWidth = this.dragPopup.popupElement.querySelector('.k-tooltip').clientWidth;
|
|
299
|
+
const left = pointerOffsetPosition.left - popupWidth / 2;
|
|
300
|
+
// don't allow the popup to be cut out of the viewport
|
|
301
|
+
const minLeftTop = 0;
|
|
302
|
+
// restrict the popup from being positioned beyond or before the available scrollable space
|
|
303
|
+
return {
|
|
304
|
+
left: fitToRange(left, minLeftTop, this.container.scrollWidth - popupWidth),
|
|
305
|
+
top: fitToRange(top, minLeftTop, this.container.scrollHeight - popupHeight)
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
tslib_1.__decorate([
|
|
310
|
+
Input(),
|
|
311
|
+
tslib_1.__metadata("design:type", Boolean)
|
|
312
|
+
], DependencyDragCreateDirective.prototype, "displayValidationTooltip", void 0);
|
|
313
|
+
DependencyDragCreateDirective = tslib_1.__decorate([
|
|
314
|
+
Directive({
|
|
315
|
+
selector: '[kendoGanttDependencyDragCreate]'
|
|
316
|
+
}),
|
|
317
|
+
tslib_1.__metadata("design:paramtypes", [GanttComponent,
|
|
318
|
+
NgZone,
|
|
319
|
+
Renderer2,
|
|
320
|
+
MappingService,
|
|
321
|
+
PopupService,
|
|
322
|
+
TimelineScrollService])
|
|
323
|
+
], DependencyDragCreateDirective);
|
|
324
|
+
export { DependencyDragCreateDirective };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**-----------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright © 2021 Progress Software Corporation. All rights reserved.
|
|
3
|
+
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
+
*-------------------------------------------------------------------------------------------*/
|
|
5
|
+
/**
|
|
6
|
+
* @hidden
|
|
7
|
+
*/
|
|
8
|
+
export declare class DragValidationTooltipComponent {
|
|
9
|
+
/**
|
|
10
|
+
* Sets the status class of the attempted operation.
|
|
11
|
+
* Note that the status will be ignored and the `neutral` status class will be rendered,
|
|
12
|
+
* if the any of the fromTaskName or toTaskName are not populated.
|
|
13
|
+
*/
|
|
14
|
+
isValid: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* The name of the task where the dragging has started.
|
|
17
|
+
*/
|
|
18
|
+
fromTaskName: string;
|
|
19
|
+
/**
|
|
20
|
+
* The name of the task which is being currently hovered.
|
|
21
|
+
*/
|
|
22
|
+
toTaskName: string;
|
|
23
|
+
/**
|
|
24
|
+
* Specifies whether the valid/invalid validity classes should be rendered or not.
|
|
25
|
+
* Prevents the validity classes being rendered when e.g. the same task is hovered during drag,
|
|
26
|
+
* or when a task body is hovered and not an actual drag clue.
|
|
27
|
+
*/
|
|
28
|
+
showValidityStatus: boolean;
|
|
29
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**-----------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright © 2021 Progress Software Corporation. All rights reserved.
|
|
3
|
+
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
+
*-------------------------------------------------------------------------------------------*/
|
|
5
|
+
import * as tslib_1 from "tslib";
|
|
6
|
+
import { Component } from '@angular/core';
|
|
7
|
+
/**
|
|
8
|
+
* @hidden
|
|
9
|
+
*/
|
|
10
|
+
let DragValidationTooltipComponent = class DragValidationTooltipComponent {
|
|
11
|
+
/**
|
|
12
|
+
* @hidden
|
|
13
|
+
*/
|
|
14
|
+
constructor() {
|
|
15
|
+
/**
|
|
16
|
+
* Sets the status class of the attempted operation.
|
|
17
|
+
* Note that the status will be ignored and the `neutral` status class will be rendered,
|
|
18
|
+
* if the any of the fromTaskName or toTaskName are not populated.
|
|
19
|
+
*/
|
|
20
|
+
this.isValid = false;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
DragValidationTooltipComponent = tslib_1.__decorate([
|
|
24
|
+
Component({
|
|
25
|
+
template: `
|
|
26
|
+
<div
|
|
27
|
+
class="k-tooltip k-gantt-tooltip-validation"
|
|
28
|
+
[class.k-gantt-tooltip-valid]="showValidityStatus && isValid"
|
|
29
|
+
[class.k-gantt-tooltip-invalid]="showValidityStatus && !isValid"
|
|
30
|
+
>
|
|
31
|
+
<div class="k-gantt-tooltip-validation-row">
|
|
32
|
+
<span class="k-gantt-tooltip-validation-label">From:</span>
|
|
33
|
+
<span class="k-gantt-tooltip-validation-value">{{ fromTaskName }}</span>
|
|
34
|
+
</div>
|
|
35
|
+
<div class="k-gantt-tooltip-validation-row">
|
|
36
|
+
<span class="k-gantt-tooltip-validation-label">To:</span>
|
|
37
|
+
<span class="k-gantt-tooltip-validation-value">{{ toTaskName }}</span>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
`,
|
|
41
|
+
styles: [`
|
|
42
|
+
.k-gantt-tooltip-validation {
|
|
43
|
+
max-width: 200px;
|
|
44
|
+
display: block;
|
|
45
|
+
}
|
|
46
|
+
.k-gantt-tooltip-validation::before {
|
|
47
|
+
content: '';
|
|
48
|
+
position: absolute;
|
|
49
|
+
left: 0;
|
|
50
|
+
top: 0;
|
|
51
|
+
width: 4px;
|
|
52
|
+
height: 100%;
|
|
53
|
+
background: #656565;
|
|
54
|
+
}
|
|
55
|
+
.k-gantt-tooltip-validation.k-gantt-tooltip-valid::before {
|
|
56
|
+
background: #37B400;
|
|
57
|
+
}
|
|
58
|
+
.k-gantt-tooltip-validation.k-gantt-tooltip-invalid::before {
|
|
59
|
+
background: #F31700;
|
|
60
|
+
}
|
|
61
|
+
.k-gantt-tooltip-validation-row {
|
|
62
|
+
white-space: nowrap;
|
|
63
|
+
overflow: hidden;
|
|
64
|
+
text-overflow: ellipsis;
|
|
65
|
+
}
|
|
66
|
+
.k-gantt-tooltip-validation-label {
|
|
67
|
+
display: inline-flex;
|
|
68
|
+
width: 50px;
|
|
69
|
+
}
|
|
70
|
+
.k-gantt-tooltip-validation-value {
|
|
71
|
+
font-weight: bold;
|
|
72
|
+
}
|
|
73
|
+
`]
|
|
74
|
+
})
|
|
75
|
+
], DragValidationTooltipComponent);
|
|
76
|
+
export { DragValidationTooltipComponent };
|
|
@@ -116,7 +116,7 @@ DependenciesTableComponent = tslib_1.__decorate([
|
|
|
116
116
|
[selectable]="{ mode: 'single' }"
|
|
117
117
|
[(selectedKeys)]="selectedKeys"
|
|
118
118
|
kendoGridSelectBy
|
|
119
|
-
[height]="
|
|
119
|
+
[height]="275"
|
|
120
120
|
>
|
|
121
121
|
<ng-template kendoGridToolbarTemplate>
|
|
122
122
|
<button kendoButton (click)="addHandler()">
|
|
@@ -44,8 +44,8 @@ let EditDialogComponent = class EditDialogComponent {
|
|
|
44
44
|
handleEditingResult(editResultType) {
|
|
45
45
|
this.editService.triggerEditEvent(editResultType);
|
|
46
46
|
}
|
|
47
|
-
|
|
48
|
-
this.editService.
|
|
47
|
+
handleTaskDelete() {
|
|
48
|
+
this.editService.taskDelete.next(this.editService.dataItem);
|
|
49
49
|
}
|
|
50
50
|
};
|
|
51
51
|
tslib_1.__decorate([
|
|
@@ -64,7 +64,7 @@ EditDialogComponent = tslib_1.__decorate([
|
|
|
64
64
|
<kendo-dialog-messages
|
|
65
65
|
[closeTitle]="getText('taskEditingDialogCloseTitle')"></kendo-dialog-messages>
|
|
66
66
|
|
|
67
|
-
<kendo-tabstrip [keepTabContent]="true">
|
|
67
|
+
<kendo-tabstrip [keepTabContent]="true" style="height: 345px;">
|
|
68
68
|
<kendo-tabstrip-tab [title]="getText('taskEditingGeneralTabTitle')" [selected]="true">
|
|
69
69
|
<ng-template kendoTabContent>
|
|
70
70
|
<kendo-gantt-task-fields></kendo-gantt-task-fields>
|
|
@@ -92,7 +92,15 @@ EditDialogComponent = tslib_1.__decorate([
|
|
|
92
92
|
</kendo-tabstrip>
|
|
93
93
|
|
|
94
94
|
<kendo-dialog-actions layout="normal">
|
|
95
|
-
<button
|
|
95
|
+
<button
|
|
96
|
+
kendoButton
|
|
97
|
+
[kendoEventsOutsideAngular]="{
|
|
98
|
+
click: handleTaskDelete
|
|
99
|
+
}"
|
|
100
|
+
[scope]="this"
|
|
101
|
+
>
|
|
102
|
+
{{ getText('deleteButtonText') }}
|
|
103
|
+
</button>
|
|
96
104
|
<kendo-treelist-spacer></kendo-treelist-spacer>
|
|
97
105
|
<button kendoButton [primary]="true" (click)="handleEditingResult('save')">{{ getText('saveButtonText') }}</button>
|
|
98
106
|
<button kendoButton (click)="handleEditingResult('cancel')">{{ getText('cancelButtonText') }}</button>
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
*-------------------------------------------------------------------------------------------*/
|
|
5
5
|
import { FormGroup } from '@angular/forms';
|
|
6
6
|
import { Observable, Subject } from 'rxjs';
|
|
7
|
-
import { TaskAddEvent } from '../models/
|
|
8
|
-
import { GanttDependency } from '../main';
|
|
7
|
+
import { GanttDependency, TaskAddEvent } from '../models/models';
|
|
9
8
|
import { EditEvent, EditResultType } from '../models/events/task-edit-event.interface';
|
|
10
9
|
import { MappingService } from '../common/mapping.service';
|
|
11
10
|
/**
|
|
@@ -14,7 +13,7 @@ import { MappingService } from '../common/mapping.service';
|
|
|
14
13
|
export declare class EditService {
|
|
15
14
|
private mapper;
|
|
16
15
|
showEditingDialog: Subject<boolean>;
|
|
17
|
-
|
|
16
|
+
taskDelete: Subject<object>;
|
|
18
17
|
editEvent: Subject<EditEvent>;
|
|
19
18
|
addEvent: Subject<TaskAddEvent>;
|
|
20
19
|
taskFormGroup: FormGroup;
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
import * as tslib_1 from "tslib";
|
|
6
6
|
import { Injectable } from '@angular/core';
|
|
7
7
|
import { EMPTY, forkJoin, isObservable, of, Subject } from 'rxjs';
|
|
8
|
-
import { MappingService } from '../common/mapping.service';
|
|
9
8
|
import { map, expand, reduce } from 'rxjs/operators';
|
|
9
|
+
import { MappingService } from '../common/mapping.service';
|
|
10
10
|
import { isPresent, normalizeGanttData } from '../utils';
|
|
11
11
|
/**
|
|
12
12
|
* @hidden
|
|
@@ -15,9 +15,11 @@ let EditService = class EditService {
|
|
|
15
15
|
constructor(mapper) {
|
|
16
16
|
this.mapper = mapper;
|
|
17
17
|
this.showEditingDialog = new Subject();
|
|
18
|
-
this.
|
|
18
|
+
this.taskDelete = new Subject();
|
|
19
19
|
this.editEvent = new Subject();
|
|
20
20
|
this.addEvent = new Subject();
|
|
21
|
+
this.predecessors = [];
|
|
22
|
+
this.successors = [];
|
|
21
23
|
this.updatedItems = [];
|
|
22
24
|
this.deletedItems = [];
|
|
23
25
|
this.itemIndex = (item, data) => {
|
|
@@ -33,7 +33,7 @@ TaskFieldsComponent = tslib_1.__decorate([
|
|
|
33
33
|
<form class="k-form" [formGroup]="formGroup">
|
|
34
34
|
<kendo-formfield *ngIf="formGroup.contains(mapper.taskFields.title)">
|
|
35
35
|
<kendo-label [for]="mapper.taskFields.title" [text]="getText('titleFieldInputLabel')"></kendo-label>
|
|
36
|
-
<input
|
|
36
|
+
<input kendoTextBox [formControlName]="mapper.taskFields.title" />
|
|
37
37
|
</kendo-formfield>
|
|
38
38
|
<div class="k-hstack">
|
|
39
39
|
<kendo-formfield [style.width.%]="49" *ngIf="formGroup.contains(mapper.taskFields.start)">
|
|
@@ -2,8 +2,8 @@
|
|
|
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 { MappingService } from
|
|
6
|
-
import { TaskEditItem } from
|
|
5
|
+
import { MappingService } from '../common/mapping.service';
|
|
6
|
+
import { TaskEditItem } from '../models/events/task-edit-event.interface';
|
|
7
7
|
/**
|
|
8
8
|
* @hidden
|
|
9
9
|
*/
|
|
File without changes
|