@progress/kendo-angular-scheduler 2.2.0-dev.202111260859 → 2.2.0-dev.202112171600
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-scheduler.js +2 -2
- package/dist/cdn/main.js +1 -1
- package/dist/es/events/slot-drag-end-event.js +17 -0
- package/dist/es/events/slot-drag-event.js +18 -0
- package/dist/es/events/slot-drag-start-event.js +24 -0
- package/dist/es/events.js +3 -0
- package/dist/es/index.js +1 -0
- package/dist/es/package-metadata.js +1 -1
- package/dist/es/scheduler.component.js +73 -1
- package/dist/es/scheduler.module.js +2 -0
- package/dist/es/types/slot-selection.js +23 -0
- package/dist/es/types.js +1 -0
- package/dist/es/views/common/base-view.js +102 -8
- package/dist/es/views/common/slot-selectable.directive.js +117 -0
- package/dist/es/views/day-time/day-time-view.component.js +1 -1
- package/dist/es/views/day-time/day-time.module.js +2 -1
- package/dist/es/views/month/month-view-renderer.component.js +9 -5
- package/dist/es/views/multi-day/multi-day-view-renderer.component.js +3 -3
- package/dist/es/views/timeline/timeline-multi-day-view.component.js +1 -1
- package/dist/es/views/utils.js +49 -0
- package/dist/es/views/view-state.service.js +18 -0
- package/dist/es2015/events/slot-drag-end-event.d.ts +10 -0
- package/dist/es2015/events/slot-drag-end-event.js +10 -0
- package/dist/es2015/events/slot-drag-event.d.ts +39 -0
- package/dist/es2015/events/slot-drag-event.js +16 -0
- package/dist/es2015/events/slot-drag-start-event.d.ts +41 -0
- package/dist/es2015/events/slot-drag-start-event.js +19 -0
- package/dist/es2015/events.d.ts +3 -0
- package/dist/es2015/events.js +3 -0
- package/dist/es2015/index.d.ts +2 -0
- package/dist/es2015/index.js +1 -0
- package/dist/es2015/index.metadata.json +1 -1
- package/dist/es2015/package-metadata.js +1 -1
- package/dist/es2015/scheduler.component.d.ts +27 -0
- package/dist/es2015/scheduler.component.js +73 -1
- package/dist/es2015/scheduler.module.js +2 -0
- package/dist/es2015/types/datepicker-options.interface.d.ts +5 -5
- package/dist/es2015/types/slot-selection.d.ts +71 -0
- package/dist/es2015/types/slot-selection.js +19 -0
- package/dist/es2015/types.d.ts +2 -0
- package/dist/es2015/types.js +1 -0
- package/dist/es2015/views/common/base-view.d.ts +26 -5
- package/dist/es2015/views/common/base-view.js +102 -8
- package/dist/es2015/views/common/slot-selectable.directive.d.ts +45 -0
- package/dist/es2015/views/common/slot-selectable.directive.js +112 -0
- package/dist/es2015/views/day-time/day-time-view.component.js +1 -1
- package/dist/es2015/views/day-time/day-time.module.js +2 -1
- package/dist/es2015/views/month/month-view-renderer.component.d.ts +3 -2
- package/dist/es2015/views/month/month-view-renderer.component.js +17 -7
- package/dist/es2015/views/multi-day/multi-day-view-renderer.component.d.ts +1 -1
- package/dist/es2015/views/multi-day/multi-day-view-renderer.component.js +22 -4
- package/dist/es2015/views/timeline/timeline-multi-day-view.component.js +8 -1
- package/dist/es2015/views/utils.d.ts +29 -0
- package/dist/es2015/views/utils.js +49 -0
- package/dist/es2015/views/view-state.service.d.ts +24 -1
- package/dist/es2015/views/view-state.service.js +18 -0
- package/dist/fesm2015/index.js +1636 -1221
- package/dist/fesm5/index.js +1785 -1384
- package/dist/npm/events/slot-drag-end-event.js +19 -0
- package/dist/npm/events/slot-drag-event.js +20 -0
- package/dist/npm/events/slot-drag-start-event.js +26 -0
- package/dist/npm/events.js +6 -0
- package/dist/npm/index.js +2 -0
- package/dist/npm/package-metadata.js +1 -1
- package/dist/npm/scheduler.component.js +73 -1
- package/dist/npm/scheduler.module.js +2 -0
- package/dist/npm/types/slot-selection.js +25 -0
- package/dist/npm/types.js +2 -0
- package/dist/npm/views/common/base-view.js +101 -7
- package/dist/npm/views/common/slot-selectable.directive.js +119 -0
- package/dist/npm/views/day-time/day-time-view.component.js +1 -1
- package/dist/npm/views/day-time/day-time.module.js +2 -1
- package/dist/npm/views/month/month-view-renderer.component.js +8 -4
- package/dist/npm/views/multi-day/multi-day-view-renderer.component.js +3 -3
- package/dist/npm/views/timeline/timeline-multi-day-view.component.js +1 -1
- package/dist/npm/views/utils.js +53 -0
- package/dist/npm/views/view-state.service.js +18 -0
- package/dist/systemjs/kendo-angular-scheduler.js +1 -1
- package/package.json +9 -7
|
@@ -10,17 +10,19 @@ import { Subscription, BehaviorSubject, combineLatest, fromEvent, merge } from '
|
|
|
10
10
|
import { switchMap, take, map, filter, tap } from 'rxjs/operators';
|
|
11
11
|
import { closestInScope, hasClasses, preventLockedScroll, scrollbarWidth, wheelDeltaY, hasScrollbar } from '../../common/dom-queries';
|
|
12
12
|
import { groupResources, getField, setField, fromClick, fromDoubleClick } from '../../common/util';
|
|
13
|
-
import { assignTasksResources, toPx, elementOffset, pointDistance, ignoreContentChild, resourceItemByValue, convertNgClassBindings } from '../utils';
|
|
13
|
+
import { assignTasksResources, toPx, elementOffset, pointDistance, ignoreContentChild, resourceItemByValue, convertNgClassBindings, toUTCDateTime, dateWithTime, normaliseRangeStartAndEnd } from '../utils';
|
|
14
14
|
import { BORDER_WIDTH } from '../constants';
|
|
15
15
|
import Draggable from '@telerik/kendo-draggable';
|
|
16
16
|
import { HintContainerComponent } from '../common/hint-container.component';
|
|
17
|
+
import { slotDragEventName } from '../../types/slot-selection';
|
|
18
|
+
import { SlotDragStartEvent } from '../../events/slot-drag-start-event';
|
|
17
19
|
const SCROLL_CHANGE = 15;
|
|
18
20
|
const MIN_DISTANCE = 60;
|
|
19
21
|
const SCROLL_INTERVAL = 50;
|
|
20
22
|
const MIN_MOVE_DISTANCE = 10;
|
|
21
23
|
/** @hidden */
|
|
22
24
|
export class BaseView {
|
|
23
|
-
constructor(viewContext, viewState, intl, slotService, zone, renderer, element, pdfService, localization) {
|
|
25
|
+
constructor(viewContext, viewState, intl, slotService, zone, renderer, element, pdfService, localization, cdr) {
|
|
24
26
|
this.viewContext = viewContext;
|
|
25
27
|
this.viewState = viewState;
|
|
26
28
|
this.intl = intl;
|
|
@@ -30,6 +32,7 @@ export class BaseView {
|
|
|
30
32
|
this.element = element;
|
|
31
33
|
this.pdfService = pdfService;
|
|
32
34
|
this.localization = localization;
|
|
35
|
+
this.cdr = cdr;
|
|
33
36
|
this.items = new BehaviorSubject(null);
|
|
34
37
|
this.horizontalResources = [];
|
|
35
38
|
this.verticalResources = [];
|
|
@@ -43,8 +46,17 @@ export class BaseView {
|
|
|
43
46
|
this.spans = [];
|
|
44
47
|
this.domEvents = [];
|
|
45
48
|
this.resourcesCache = {};
|
|
49
|
+
/**
|
|
50
|
+
* The slot which is currently being dragged over while selecting a range of slots.
|
|
51
|
+
*/
|
|
52
|
+
this.dragSelecting = null;
|
|
53
|
+
/**
|
|
54
|
+
* The slot where the drag-selecting originated. Used for flipping the start and end of the emitted range.
|
|
55
|
+
*/
|
|
56
|
+
this.dragSelectOrigin = null;
|
|
46
57
|
this.autoHeight = false;
|
|
47
58
|
this.rtl = false;
|
|
59
|
+
this.isSlotSelected = () => false;
|
|
48
60
|
this.setSlotClass = this.setSlotClass.bind(this);
|
|
49
61
|
this.setHintClass = this.setHintClass.bind(this);
|
|
50
62
|
this.weekStart = intl.firstDay();
|
|
@@ -161,6 +173,20 @@ export class BaseView {
|
|
|
161
173
|
}
|
|
162
174
|
return result;
|
|
163
175
|
}
|
|
176
|
+
// Similar to https://tc39.es/proposal-temporal/docs/plaindate.html
|
|
177
|
+
// Stores a "plain date" in the UTC parts of a regular `Date`.
|
|
178
|
+
toPlainDate(date) {
|
|
179
|
+
const result = toUTCDateTime(this.convertDate(date));
|
|
180
|
+
return result;
|
|
181
|
+
}
|
|
182
|
+
// Similar to https://tc39.es/proposal-temporal/docs/plaindatetime.html
|
|
183
|
+
// Stores a "plain date-time" in the UTC parts of a regular `Date`.
|
|
184
|
+
toPlainDateTime(date, time) {
|
|
185
|
+
if (!date || !time) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
return this.toPlainDate(dateWithTime(date, time));
|
|
189
|
+
}
|
|
164
190
|
optionsChange(options) {
|
|
165
191
|
this.schedulerEventTemplate = options.eventTemplate;
|
|
166
192
|
this.schedulerGroupHeaderTemplate = options.groupHeaderTemplate;
|
|
@@ -168,6 +194,8 @@ export class BaseView {
|
|
|
168
194
|
this.max = options.max;
|
|
169
195
|
this.editable = options.editable;
|
|
170
196
|
this.timezone = options.timezone;
|
|
197
|
+
this.selectable = options.selectable;
|
|
198
|
+
this.isSlotSelected = options.isSlotSelected;
|
|
171
199
|
if (!options.changes || anyChanged(['group', 'resources'], options.changes, false) ||
|
|
172
200
|
options.group !== this.group || options.resources !== this.resources) {
|
|
173
201
|
this.group = options.group;
|
|
@@ -194,6 +222,7 @@ export class BaseView {
|
|
|
194
222
|
this.toggleElement(true);
|
|
195
223
|
this.reflow();
|
|
196
224
|
this.viewState.notifyLayoutEnd();
|
|
225
|
+
this.viewState.emitEvent(slotDragEventName.refreshSlotSelection);
|
|
197
226
|
}
|
|
198
227
|
assignResources() {
|
|
199
228
|
assignTasksResources(this.tasks, {
|
|
@@ -234,16 +263,16 @@ export class BaseView {
|
|
|
234
263
|
});
|
|
235
264
|
}
|
|
236
265
|
onPress(args) {
|
|
237
|
-
const
|
|
238
|
-
const
|
|
266
|
+
const editResizable = this.editable && this.editable.resize !== false;
|
|
267
|
+
const editDraggable = this.editable && this.editable.drag !== false;
|
|
239
268
|
const target = args.originalEvent.target;
|
|
240
269
|
if (hasClasses(target, 'k-resize-handle')) {
|
|
241
|
-
if (!
|
|
270
|
+
if (!editResizable) {
|
|
242
271
|
return;
|
|
243
272
|
}
|
|
244
273
|
this.initResize(args);
|
|
245
274
|
}
|
|
246
|
-
else if (
|
|
275
|
+
else if (editDraggable) {
|
|
247
276
|
const task = this.targetTask(target);
|
|
248
277
|
if (task) {
|
|
249
278
|
if (!args.isTouch) {
|
|
@@ -253,6 +282,9 @@ export class BaseView {
|
|
|
253
282
|
this.pressTarget = task;
|
|
254
283
|
}
|
|
255
284
|
}
|
|
285
|
+
if (this.selectable) {
|
|
286
|
+
this.initDragSelect(args);
|
|
287
|
+
}
|
|
256
288
|
this.dragArgs = args;
|
|
257
289
|
}
|
|
258
290
|
onDrag(args) {
|
|
@@ -267,12 +299,15 @@ export class BaseView {
|
|
|
267
299
|
args.originalEvent.preventDefault();
|
|
268
300
|
this.scrollContainer(this.drag, args);
|
|
269
301
|
}
|
|
302
|
+
if (this.dragSelecting) {
|
|
303
|
+
this.dragSelect(args);
|
|
304
|
+
}
|
|
270
305
|
}
|
|
271
306
|
this.dragArgs = args;
|
|
272
307
|
}
|
|
273
|
-
onRelease() {
|
|
308
|
+
onRelease(args) {
|
|
274
309
|
clearInterval(this.scrollInterval);
|
|
275
|
-
const { resizing, dragging } = this;
|
|
310
|
+
const { resizing, dragging, dragSelecting } = this;
|
|
276
311
|
if (resizing) {
|
|
277
312
|
this.emitEvent('resizeEnd', {
|
|
278
313
|
event: resizing.task.event,
|
|
@@ -299,6 +334,20 @@ export class BaseView {
|
|
|
299
334
|
this.resizing = null;
|
|
300
335
|
this.dragging = null;
|
|
301
336
|
}
|
|
337
|
+
if (dragSelecting) {
|
|
338
|
+
const { start, end } = normaliseRangeStartAndEnd(this.dragSelectOrigin, this.dragSelecting);
|
|
339
|
+
const range = {
|
|
340
|
+
start: this.convertDate(start),
|
|
341
|
+
end: this.convertDate(end),
|
|
342
|
+
isAllDay: this.dragSelecting.isDaySlot,
|
|
343
|
+
resources: this.resourcesByIndex(this.dragSelecting.id.resourceIndex),
|
|
344
|
+
originalEvent: args.originalEvent
|
|
345
|
+
};
|
|
346
|
+
this.viewState.notifySlotSelectionEnd(range);
|
|
347
|
+
this.dragSelectOrigin = null;
|
|
348
|
+
this.dragSelecting = null;
|
|
349
|
+
this.cdr.markForCheck();
|
|
350
|
+
}
|
|
302
351
|
this.container = null;
|
|
303
352
|
this.dragArgs = null;
|
|
304
353
|
this.pressLocation = null;
|
|
@@ -446,6 +495,51 @@ export class BaseView {
|
|
|
446
495
|
this.updateHintContainer();
|
|
447
496
|
}
|
|
448
497
|
}
|
|
498
|
+
initDragSelect(args) {
|
|
499
|
+
this.updateDragContainer(args);
|
|
500
|
+
if (!this.containerOffset) {
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
const { x, y } = this.coordinatesOffset(args.pageX, args.pageY);
|
|
504
|
+
const slot = this.slotByPosition(x, y, this.container);
|
|
505
|
+
if (!slot) {
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
const range = {
|
|
509
|
+
start: this.convertDate(slot.start),
|
|
510
|
+
end: this.convertDate(slot.end),
|
|
511
|
+
isAllDay: slot.isDaySlot,
|
|
512
|
+
resources: this.resourcesByIndex(slot.id.resourceIndex),
|
|
513
|
+
originalEvent: args.originalEvent
|
|
514
|
+
};
|
|
515
|
+
const slotDragStartEvent = new SlotDragStartEvent(null, range);
|
|
516
|
+
this.viewState.notifySlotSelectionStart(slotDragStartEvent);
|
|
517
|
+
if (!slotDragStartEvent.isDefaultPrevented()) {
|
|
518
|
+
this.dragSelecting = slot;
|
|
519
|
+
this.dragSelectOrigin = slot;
|
|
520
|
+
this.cdr.markForCheck();
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
dragSelect(args) {
|
|
524
|
+
const { x, y } = this.coordinatesOffset(args.pageX, args.pageY);
|
|
525
|
+
const slot = this.slotByPosition(x, y, this.container);
|
|
526
|
+
if (!slot) {
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
if (this.dragSelecting !== slot) {
|
|
530
|
+
this.dragSelecting = slot;
|
|
531
|
+
const { start, end } = normaliseRangeStartAndEnd(this.dragSelectOrigin, this.dragSelecting);
|
|
532
|
+
const range = {
|
|
533
|
+
start: this.convertDate(start),
|
|
534
|
+
end: this.convertDate(end),
|
|
535
|
+
isAllDay: slot.isDaySlot,
|
|
536
|
+
resources: this.resourcesByIndex(slot.id.resourceIndex),
|
|
537
|
+
originalEvent: args.originalEvent
|
|
538
|
+
};
|
|
539
|
+
this.viewState.notifySlotSelectionDrag(range);
|
|
540
|
+
this.cdr.markForCheck();
|
|
541
|
+
}
|
|
542
|
+
}
|
|
449
543
|
dragHintClasses() {
|
|
450
544
|
const hintClass = this.dragging.hintClass;
|
|
451
545
|
let result = [];
|
|
@@ -0,0 +1,45 @@
|
|
|
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 { OnChanges, OnDestroy, OnInit, SimpleChanges, EventEmitter, ChangeDetectorRef } from '@angular/core';
|
|
6
|
+
import { SchedulerComponent } from '../../scheduler.component';
|
|
7
|
+
import { SlotRange } from '../../types/slot-selection';
|
|
8
|
+
/**
|
|
9
|
+
* A directive which manages the in-memory selection state of the Scheduler slots
|
|
10
|
+
* ([see example]({% slug slotselection_scheduler %}#toc-built-in-directive)).
|
|
11
|
+
*/
|
|
12
|
+
export declare class SlotSelectableDirective implements OnInit, OnChanges, OnDestroy {
|
|
13
|
+
private scheduler;
|
|
14
|
+
private cdr;
|
|
15
|
+
/**
|
|
16
|
+
* The currently selected slot range.
|
|
17
|
+
*/
|
|
18
|
+
slotSelection: SlotRange;
|
|
19
|
+
/**
|
|
20
|
+
* Fires when the currently selected slot range has changed through user interaction.
|
|
21
|
+
*/
|
|
22
|
+
slotSelectionChange: EventEmitter<SlotRange>;
|
|
23
|
+
/**
|
|
24
|
+
* @hidden
|
|
25
|
+
* The resources of the cell where the selection started.
|
|
26
|
+
* When dragging over the slots of a different resource in grouped mode, the ongoing selection will not be affected.
|
|
27
|
+
*/
|
|
28
|
+
private selectionOriginResources;
|
|
29
|
+
private selectedRange;
|
|
30
|
+
private slotSelectionChangeSource;
|
|
31
|
+
private subscriptions;
|
|
32
|
+
constructor(scheduler: SchedulerComponent, cdr: ChangeDetectorRef);
|
|
33
|
+
ngOnInit(): void;
|
|
34
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
35
|
+
ngOnDestroy(): void;
|
|
36
|
+
private isSlotSelected;
|
|
37
|
+
private initDragSelect;
|
|
38
|
+
private onDrag;
|
|
39
|
+
private onRelease;
|
|
40
|
+
/**
|
|
41
|
+
* @hidden
|
|
42
|
+
* Checks if the selected range contains a local date range.
|
|
43
|
+
*/
|
|
44
|
+
private isInRange;
|
|
45
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
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, Output, EventEmitter, ChangeDetectorRef } from '@angular/core';
|
|
7
|
+
import { Subscription } from 'rxjs';
|
|
8
|
+
import { intersects, isSameRange, resourcesMatch } from '../utils';
|
|
9
|
+
import { SchedulerComponent } from '../../scheduler.component';
|
|
10
|
+
import { distinctUntilChanged, filter } from 'rxjs/operators';
|
|
11
|
+
import { isChanged } from '@progress/kendo-angular-common';
|
|
12
|
+
/**
|
|
13
|
+
* A directive which manages the in-memory selection state of the Scheduler slots
|
|
14
|
+
* ([see example]({% slug slotselection_scheduler %}#toc-built-in-directive)).
|
|
15
|
+
*/
|
|
16
|
+
let SlotSelectableDirective = class SlotSelectableDirective {
|
|
17
|
+
constructor(scheduler, cdr) {
|
|
18
|
+
this.scheduler = scheduler;
|
|
19
|
+
this.cdr = cdr;
|
|
20
|
+
/**
|
|
21
|
+
* Fires when the currently selected slot range has changed through user interaction.
|
|
22
|
+
*/
|
|
23
|
+
this.slotSelectionChange = new EventEmitter();
|
|
24
|
+
this.selectedRange = null;
|
|
25
|
+
this.slotSelectionChangeSource = new EventEmitter();
|
|
26
|
+
this.subscriptions = new Subscription();
|
|
27
|
+
this.scheduler.selectable = true;
|
|
28
|
+
this.subscriptions.add(this.slotSelectionChangeSource
|
|
29
|
+
.pipe(distinctUntilChanged(isSameRange)).subscribe((v) => {
|
|
30
|
+
this.slotSelectionChange.emit(v);
|
|
31
|
+
}));
|
|
32
|
+
const start$ = this.scheduler.slotDragStart;
|
|
33
|
+
const drag$ = this.scheduler.slotDrag;
|
|
34
|
+
const end$ = this.scheduler.slotDragEnd;
|
|
35
|
+
const startSource = start$.pipe(filter(e => !e.isDefaultPrevented()));
|
|
36
|
+
this.subscriptions.add(startSource.subscribe(e => this.initDragSelect(e)));
|
|
37
|
+
this.subscriptions.add(drag$.subscribe(e => this.onDrag(e)));
|
|
38
|
+
this.subscriptions.add(end$.subscribe(() => this.onRelease()));
|
|
39
|
+
}
|
|
40
|
+
ngOnInit() {
|
|
41
|
+
this.scheduler.isSlotSelected = this.isSlotSelected.bind(this);
|
|
42
|
+
}
|
|
43
|
+
ngOnChanges(changes) {
|
|
44
|
+
if (isChanged("slotSelection", changes, false)) {
|
|
45
|
+
/**
|
|
46
|
+
* The default values for resources below are necessarry because this is not fixed yet: https://github.com/telerik/kendo-angular-scheduler/pull/338
|
|
47
|
+
*/
|
|
48
|
+
const resources = this.scheduler.resources ? [this.scheduler.resources[0].data[0]] : [undefined];
|
|
49
|
+
this.selectedRange = Object.assign({}, { isAllDay: false, resources }, changes.slotSelection.currentValue);
|
|
50
|
+
this.cdr.markForCheck();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
ngOnDestroy() {
|
|
54
|
+
this.subscriptions.unsubscribe();
|
|
55
|
+
}
|
|
56
|
+
isSlotSelected({ start, end, isAllDay, resources }) {
|
|
57
|
+
if (!start || !end || !this.selectedRange) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
const match = resourcesMatch(this.selectedRange.resources, resources, true);
|
|
61
|
+
if (!match) {
|
|
62
|
+
return false; // Limit selection to the grouped resource where the drag started.
|
|
63
|
+
}
|
|
64
|
+
return this.selectedRange && isAllDay === this.selectedRange.isAllDay && this.isInRange(start, end);
|
|
65
|
+
}
|
|
66
|
+
initDragSelect({ start, end, isAllDay, resources, originalEvent }) {
|
|
67
|
+
this.selectionOriginResources = resources.slice();
|
|
68
|
+
this.selectedRange = { start, end, isAllDay, resources: resources.slice(), originalEvent };
|
|
69
|
+
this.cdr.markForCheck();
|
|
70
|
+
}
|
|
71
|
+
onDrag({ start, end, resources }) {
|
|
72
|
+
const match = resourcesMatch(this.selectionOriginResources, resources, false); // Not strict - allow matching [ undefined ] and [ undefined ]
|
|
73
|
+
if (!match) {
|
|
74
|
+
return; // Don't change selection when dragging over a different grouped resource's cells.
|
|
75
|
+
}
|
|
76
|
+
this.selectedRange.start = start;
|
|
77
|
+
this.selectedRange.end = end;
|
|
78
|
+
this.cdr.markForCheck();
|
|
79
|
+
}
|
|
80
|
+
onRelease() {
|
|
81
|
+
this.selectionOriginResources = null;
|
|
82
|
+
if (this.selectedRange) {
|
|
83
|
+
this.slotSelectionChangeSource.emit(this.selectedRange);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* @hidden
|
|
88
|
+
* Checks if the selected range contains a local date range.
|
|
89
|
+
*/
|
|
90
|
+
isInRange(start, end) {
|
|
91
|
+
if (!this.selectedRange) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
return intersects(start, end, this.selectedRange.start, this.selectedRange.end);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
tslib_1.__decorate([
|
|
98
|
+
Input(),
|
|
99
|
+
tslib_1.__metadata("design:type", Object)
|
|
100
|
+
], SlotSelectableDirective.prototype, "slotSelection", void 0);
|
|
101
|
+
tslib_1.__decorate([
|
|
102
|
+
Output(),
|
|
103
|
+
tslib_1.__metadata("design:type", EventEmitter)
|
|
104
|
+
], SlotSelectableDirective.prototype, "slotSelectionChange", void 0);
|
|
105
|
+
SlotSelectableDirective = tslib_1.__decorate([
|
|
106
|
+
Directive({
|
|
107
|
+
selector: '[kendoSchedulerSlotSelectable]'
|
|
108
|
+
}),
|
|
109
|
+
tslib_1.__metadata("design:paramtypes", [SchedulerComponent,
|
|
110
|
+
ChangeDetectorRef])
|
|
111
|
+
], SlotSelectableDirective);
|
|
112
|
+
export { SlotSelectableDirective };
|
|
@@ -24,7 +24,7 @@ const ɵ2 = getNextDate;
|
|
|
24
24
|
*/
|
|
25
25
|
export class DayTimeViewComponent extends BaseView {
|
|
26
26
|
constructor(changeDetector, viewContext, viewState, intl, slotService, zone, renderer, element, pdfService, localization) {
|
|
27
|
-
super(viewContext, viewState, intl, slotService, zone, renderer, element, pdfService, localization);
|
|
27
|
+
super(viewContext, viewState, intl, slotService, zone, renderer, element, pdfService, localization, changeDetector);
|
|
28
28
|
this.changeDetector = changeDetector;
|
|
29
29
|
this.numberOfDays = 1;
|
|
30
30
|
this.startTime = '00:00';
|
|
@@ -8,6 +8,7 @@ import { CommonModule } from '@angular/common';
|
|
|
8
8
|
import { SharedModule } from '../../shared.module';
|
|
9
9
|
import { TimeSlotDirective, DaySlotDirective } from './event-slot.directive';
|
|
10
10
|
import { DayTimeViewItemComponent } from './day-time-view-item.component';
|
|
11
|
+
import { ViewsSharedModule } from '../common/views-shared.module';
|
|
11
12
|
const DIRECTIVES = [TimeSlotDirective, DaySlotDirective, DayTimeViewItemComponent];
|
|
12
13
|
/**
|
|
13
14
|
* @hidden
|
|
@@ -16,7 +17,7 @@ let DayTimeModule = class DayTimeModule {
|
|
|
16
17
|
};
|
|
17
18
|
DayTimeModule = tslib_1.__decorate([
|
|
18
19
|
NgModule({
|
|
19
|
-
imports: [CommonModule, SharedModule],
|
|
20
|
+
imports: [CommonModule, SharedModule, ViewsSharedModule],
|
|
20
21
|
exports: [
|
|
21
22
|
DIRECTIVES
|
|
22
23
|
],
|
|
@@ -2,7 +2,7 @@
|
|
|
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 { OnChanges, NgZone, ElementRef, Renderer2, TemplateRef } from '@angular/core';
|
|
5
|
+
import { OnChanges, NgZone, ElementRef, Renderer2, TemplateRef, ChangeDetectorRef } from '@angular/core';
|
|
6
6
|
import { IntlService } from '@progress/kendo-angular-intl';
|
|
7
7
|
import { DateRange, NavigationAction, ViewItem } from '../../types';
|
|
8
8
|
import { ViewContextService } from '../view-context.service';
|
|
@@ -20,13 +20,14 @@ export declare class MonthViewRendererComponent extends BaseView implements OnCh
|
|
|
20
20
|
weeks: any[];
|
|
21
21
|
readonly monthDaySlotTemplateRef: TemplateRef<any>;
|
|
22
22
|
private schedulerMonthDaySlotTemplate;
|
|
23
|
-
constructor(viewContext: ViewContextService, viewState: ViewStateService, intl: IntlService, slotService: MonthSlotService, zone: NgZone, element: ElementRef, renderer: Renderer2, pdfService: PDFService, localization: LocalizationService);
|
|
23
|
+
constructor(viewContext: ViewContextService, viewState: ViewStateService, intl: IntlService, slotService: MonthSlotService, zone: NgZone, element: ElementRef, renderer: Renderer2, pdfService: PDFService, localization: LocalizationService, changeDetector: ChangeDetectorRef);
|
|
24
24
|
ngOnChanges(changes: any): void;
|
|
25
25
|
horizontalColspan(resourceIndex: number): any;
|
|
26
26
|
verticalRowspan(resourceIndex: number): any;
|
|
27
27
|
verticalItem(leafIndex: number, resourceIndex: number): any;
|
|
28
28
|
daySlotClass(day: any, resourceIndex: any): string;
|
|
29
29
|
cellTitle(value: Date): string;
|
|
30
|
+
addDay(dayStart: Date): Date;
|
|
30
31
|
protected optionsChange(changes: any): void;
|
|
31
32
|
protected createTasks(items: ViewItem[], dateRange: DateRange): any[];
|
|
32
33
|
protected onTasksChange(): void;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
4
|
*-------------------------------------------------------------------------------------------*/
|
|
5
5
|
import * as tslib_1 from "tslib";
|
|
6
|
-
import { Component, Input, NgZone, ElementRef, Renderer2, TemplateRef } from '@angular/core';
|
|
6
|
+
import { Component, Input, NgZone, ElementRef, Renderer2, TemplateRef, ChangeDetectorRef } from '@angular/core';
|
|
7
7
|
import { IntlService } from '@progress/kendo-angular-intl';
|
|
8
8
|
import { isChanged } from '@progress/kendo-angular-common';
|
|
9
9
|
import { addDays, addMonths, firstDayInWeek, firstDayOfMonth, getDate, toLocalDate } from '@progress/kendo-date-math';
|
|
@@ -22,8 +22,8 @@ const WEEKS_COUNT = 6;
|
|
|
22
22
|
* @hidden
|
|
23
23
|
*/
|
|
24
24
|
let MonthViewRendererComponent = class MonthViewRendererComponent extends BaseView {
|
|
25
|
-
constructor(viewContext, viewState, intl, slotService, zone, element, renderer, pdfService, localization) {
|
|
26
|
-
super(viewContext, viewState, intl, slotService, zone, renderer, element, pdfService, localization);
|
|
25
|
+
constructor(viewContext, viewState, intl, slotService, zone, element, renderer, pdfService, localization, changeDetector) {
|
|
26
|
+
super(viewContext, viewState, intl, slotService, zone, renderer, element, pdfService, localization, changeDetector);
|
|
27
27
|
this.resizeHintFormat = { skeleton: 'Md' };
|
|
28
28
|
this.weeks = [];
|
|
29
29
|
}
|
|
@@ -74,6 +74,9 @@ let MonthViewRendererComponent = class MonthViewRendererComponent extends BaseVi
|
|
|
74
74
|
cellTitle(value) {
|
|
75
75
|
return this.intl.formatDate(value, 'D');
|
|
76
76
|
}
|
|
77
|
+
addDay(dayStart) {
|
|
78
|
+
return addDays(dayStart, 1);
|
|
79
|
+
}
|
|
77
80
|
optionsChange(changes) {
|
|
78
81
|
this.schedulerMonthDaySlotTemplate = changes.monthDaySlotTemplate;
|
|
79
82
|
super.optionsChange(changes);
|
|
@@ -238,7 +241,7 @@ MonthViewRendererComponent = tslib_1.__decorate([
|
|
|
238
241
|
</table>
|
|
239
242
|
</div>
|
|
240
243
|
<div class="k-scheduler-content" #content>
|
|
241
|
-
<table class="k-scheduler-table" #contentTable role="presentation">
|
|
244
|
+
<table class="k-scheduler-table k-user-select-none" #contentTable role="presentation">
|
|
242
245
|
<ng-container *ngFor="let resourceItem of verticalResources | resourceIterator; let verticalIndex = index; trackBy: itemIndex">
|
|
243
246
|
<tr *ngFor="let week of weeks; let rangeIndex = index; trackBy: itemIndex">
|
|
244
247
|
<ng-container *ngFor="let resource of horizontalResources | resourceIterator; let horizontalIndex = index; trackBy: itemIndex">
|
|
@@ -248,8 +251,14 @@ MonthViewRendererComponent = tslib_1.__decorate([
|
|
|
248
251
|
[start]="day"
|
|
249
252
|
[id]="{ resourceIndex: verticalResources.length ? verticalIndex : horizontalIndex, rangeIndex: rangeIndex, index: index }"
|
|
250
253
|
[title]="cellTitle(day)"
|
|
251
|
-
|
|
252
|
-
|
|
254
|
+
[class.k-state-selected]="isSlotSelected({
|
|
255
|
+
start: toPlainDate(day),
|
|
256
|
+
end: addDay(toPlainDate(day)),
|
|
257
|
+
isAllDay: true,
|
|
258
|
+
resources: resourcesByIndex(verticalResources.length ? verticalIndex : horizontalIndex)
|
|
259
|
+
})"
|
|
260
|
+
>
|
|
261
|
+
<span aria-hidden="true" class="k-link k-nav-day" *ngIf="!monthDaySlotTemplateRef">{{ day | kendoDate: 'dd' }}</span>
|
|
253
262
|
<ng-container *ngIf="monthDaySlotTemplateRef" [ngTemplateOutlet]="monthDaySlotTemplateRef"
|
|
254
263
|
[ngTemplateOutletContext]="{ date: day, resources: resourcesByIndex(verticalResources.length ? verticalIndex : horizontalIndex) }"></ng-container>
|
|
255
264
|
</td>
|
|
@@ -306,6 +315,7 @@ MonthViewRendererComponent = tslib_1.__decorate([
|
|
|
306
315
|
ElementRef,
|
|
307
316
|
Renderer2,
|
|
308
317
|
PDFService,
|
|
309
|
-
LocalizationService
|
|
318
|
+
LocalizationService,
|
|
319
|
+
ChangeDetectorRef])
|
|
310
320
|
], MonthViewRendererComponent);
|
|
311
321
|
export { MonthViewRendererComponent };
|
|
@@ -52,7 +52,7 @@ export declare class MultiDayViewRendererComponent extends DayTimeViewComponent
|
|
|
52
52
|
protected reflow(): void;
|
|
53
53
|
protected dragHorizontal(slot: any): boolean;
|
|
54
54
|
protected updateHintContainer(): void;
|
|
55
|
-
protected onRelease(): void;
|
|
55
|
+
protected onRelease(args: any): void;
|
|
56
56
|
protected updateDragContainer(args: any): void;
|
|
57
57
|
protected containerByPosition({ x, y }: any): any;
|
|
58
58
|
protected readonly containers: any[];
|
|
@@ -145,8 +145,8 @@ let MultiDayViewRendererComponent = class MultiDayViewRendererComponent extends
|
|
|
145
145
|
}
|
|
146
146
|
super.updateHintContainer();
|
|
147
147
|
}
|
|
148
|
-
onRelease() {
|
|
149
|
-
super.onRelease();
|
|
148
|
+
onRelease(args) {
|
|
149
|
+
super.onRelease(args);
|
|
150
150
|
this.dragContainers = null;
|
|
151
151
|
}
|
|
152
152
|
updateDragContainer(args) {
|
|
@@ -307,7 +307,7 @@ MultiDayViewRendererComponent = tslib_1.__decorate([
|
|
|
307
307
|
</tr>
|
|
308
308
|
</table>
|
|
309
309
|
<div style="position: relative;" *ngIf="!verticalResources.length">
|
|
310
|
-
<table class="k-scheduler-table k-scheduler-header-all-day" aria-hidden="true">
|
|
310
|
+
<table class="k-scheduler-table k-scheduler-header-all-day k-user-select-none" aria-hidden="true">
|
|
311
311
|
<tr>
|
|
312
312
|
<ng-container *ngFor="let resource of horizontalResources | resourceIterator; let resourceIndex = index; trackBy: itemIndex;">
|
|
313
313
|
<td *ngFor="let slot of daySlots; let index = index; trackBy: itemIndex"
|
|
@@ -315,6 +315,12 @@ MultiDayViewRendererComponent = tslib_1.__decorate([
|
|
|
315
315
|
[start]="slot.start"
|
|
316
316
|
[end]="slot.end"
|
|
317
317
|
[id]="{ resourceIndex: resourceIndex, rangeIndex: 0, index: index }"
|
|
318
|
+
[class.k-state-selected]="isSlotSelected({
|
|
319
|
+
start: toPlainDate(slot.start),
|
|
320
|
+
end: toPlainDate(slot.end),
|
|
321
|
+
isAllDay: true,
|
|
322
|
+
resources: resourcesByIndex(resourceIndex)
|
|
323
|
+
})"
|
|
318
324
|
[ngClass]="allDaySlotClass(slot, resourceIndex)">
|
|
319
325
|
<ng-container *ngIf="allDaySlotTemplateRef" [ngTemplateOutlet]="allDaySlotTemplateRef"
|
|
320
326
|
[ngTemplateOutletContext]="{ date: slot.start, resources: resourcesByIndex(resourceIndex) }"></ng-container>
|
|
@@ -396,7 +402,7 @@ MultiDayViewRendererComponent = tslib_1.__decorate([
|
|
|
396
402
|
</ng-container>
|
|
397
403
|
</table>
|
|
398
404
|
</div>
|
|
399
|
-
<div class="k-scheduler-content" #content>
|
|
405
|
+
<div class="k-scheduler-content k-user-select-none" #content>
|
|
400
406
|
<ng-container *ngIf="showCurrentTime">
|
|
401
407
|
<div *ngFor="let resource of verticalResources | resourceIterator; trackBy: itemIndex;"
|
|
402
408
|
#currentTimeMarker class="k-current-time">
|
|
@@ -409,6 +415,12 @@ MultiDayViewRendererComponent = tslib_1.__decorate([
|
|
|
409
415
|
daySlot
|
|
410
416
|
[start]="slot.start"
|
|
411
417
|
[end]="slot.end"
|
|
418
|
+
[class.k-state-selected]="isSlotSelected({
|
|
419
|
+
start: toPlainDate(slot.start),
|
|
420
|
+
end: toPlainDate(slot.end),
|
|
421
|
+
isAllDay: true,
|
|
422
|
+
resources: resourcesByIndex(verticalIndex)
|
|
423
|
+
})"
|
|
412
424
|
[id]="{ resourceIndex: verticalIndex, rangeIndex: 0, index: index }">
|
|
413
425
|
<ng-container *ngIf="allDaySlotTemplateRef" [ngTemplateOutlet]="allDaySlotTemplateRef"
|
|
414
426
|
[ngTemplateOutletContext]="{ date: slot.start, resources: resourcesByIndex(verticalIndex) }"></ng-container>
|
|
@@ -427,6 +439,12 @@ MultiDayViewRendererComponent = tslib_1.__decorate([
|
|
|
427
439
|
[workWeekStart]="workWeekStart"
|
|
428
440
|
[workWeekEnd]="workWeekEnd"
|
|
429
441
|
[id]="{ resourceIndex: verticalResources.length ? verticalIndex : horizontalIndex, rangeIndex: rangeIndex, index: index }"
|
|
442
|
+
[class.k-state-selected]="isSlotSelected({
|
|
443
|
+
start: toPlainDateTime(daySlot.start, slot.start),
|
|
444
|
+
end: toPlainDateTime(daySlot.start, slot.end),
|
|
445
|
+
isAllDay: false,
|
|
446
|
+
resources: resourcesByIndex(verticalResources.length ? verticalIndex : horizontalIndex)
|
|
447
|
+
})"
|
|
430
448
|
>
|
|
431
449
|
<ng-container *ngIf="timeSlotTemplateRef" [ngTemplateOutlet]="timeSlotTemplateRef"
|
|
432
450
|
[ngTemplateOutletContext]="{ date: timeSlot.startLocalTime, resources: resourcesByIndex(timeSlot.id.resourceIndex) }">
|
|
@@ -214,7 +214,7 @@ TimelineMultiDayViewComponent = tslib_1.__decorate([
|
|
|
214
214
|
class="k-current-time" #currentTimeMarker>
|
|
215
215
|
</div>
|
|
216
216
|
</ng-container>
|
|
217
|
-
<table class="k-scheduler-table" #contentTable role="presentation">
|
|
217
|
+
<table class="k-scheduler-table k-user-select-none" #contentTable role="presentation">
|
|
218
218
|
<colgroup>
|
|
219
219
|
<col *ngFor="let slotIndex of slotsCount | repeat; trackBy: itemIndex;" [ngStyle]="{ 'width.px': columnWidth }" />
|
|
220
220
|
</colgroup>
|
|
@@ -231,7 +231,14 @@ TimelineMultiDayViewComponent = tslib_1.__decorate([
|
|
|
231
231
|
[workDayEnd]="workDayEndTime"
|
|
232
232
|
[workWeekStart]="workWeekStart"
|
|
233
233
|
[workWeekEnd]="workWeekEnd"
|
|
234
|
+
selectableSlot
|
|
234
235
|
[id]="{ resourceIndex: verticalResources.length ? verticalIndex : horizontalIndex, rangeIndex: rangeIndex, index: index }"
|
|
236
|
+
[class.k-state-selected]="isSlotSelected({
|
|
237
|
+
start: toPlainDateTime(daySlot.start, slot.start),
|
|
238
|
+
end: toPlainDateTime(daySlot.start, slot.end),
|
|
239
|
+
isAllDay: false,
|
|
240
|
+
resources: resourcesByIndex(verticalResources.length ? verticalIndex : horizontalIndex)
|
|
241
|
+
})"
|
|
235
242
|
>
|
|
236
243
|
<ng-container *ngIf="timeSlotTemplateRef" [ngTemplateOutlet]="timeSlotTemplateRef"
|
|
237
244
|
[ngTemplateOutletContext]="{ date: timeSlot.start, resources: resourcesByIndex(timeSlot.id.resourceIndex ) }">
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
*-------------------------------------------------------------------------------------------*/
|
|
5
5
|
import { ZonedDate } from '@progress/kendo-date-math';
|
|
6
6
|
import { FormGroup } from '@angular/forms';
|
|
7
|
+
import { Resource } from '../types';
|
|
8
|
+
import { SlotRange } from '../types/slot-selection';
|
|
7
9
|
/** @hidden */
|
|
8
10
|
export declare const intersects: (startTime: Date, endTime: Date, periodStart: Date, periodEnd: Date) => boolean;
|
|
9
11
|
/** @hidden */
|
|
@@ -35,11 +37,34 @@ export declare function toUTCDateTime(localDate: Date): Date;
|
|
|
35
37
|
/** @hidden */
|
|
36
38
|
export declare function dateWithTime(target: Date, time: Date): Date;
|
|
37
39
|
/** @hidden */
|
|
40
|
+
export interface SimpleRange {
|
|
41
|
+
start: Date;
|
|
42
|
+
end: Date;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* @hidden
|
|
46
|
+
* Flips the start and end values of a slot selection based on whether
|
|
47
|
+
* the last dragged-over slot is before or after the slot where the selection began.
|
|
48
|
+
*/
|
|
49
|
+
export declare function normaliseRangeStartAndEnd(selectionOrigin: SimpleRange, currentSlot: SimpleRange): SimpleRange;
|
|
50
|
+
/** @hidden */
|
|
38
51
|
export declare function resourceItemByValue(event: any, resource: any): any;
|
|
39
52
|
/** @hidden */
|
|
40
53
|
export declare function eventResources(event: any, { taskResources, hasGroups, spans, allResources }: any): any[];
|
|
41
54
|
/** @hidden */
|
|
42
55
|
export declare function assignTasksResources(tasks: any[], options: any): void;
|
|
56
|
+
/**
|
|
57
|
+
* @hidden
|
|
58
|
+
*/
|
|
59
|
+
export declare function areValidResources(resources: Resource[]): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* @hidden
|
|
62
|
+
*/
|
|
63
|
+
export declare function resourcesMatch(res1: any[], res2: any[], strict: boolean): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* @hidden
|
|
66
|
+
*/
|
|
67
|
+
export declare function isSameRange(range1: SlotRange, range2: SlotRange): boolean;
|
|
43
68
|
/** @hidden */
|
|
44
69
|
export declare function findRowIndex(events: any[], data: any): number;
|
|
45
70
|
/** @hidden */
|
|
@@ -74,3 +99,7 @@ export declare function formValueOrDefault(group: FormGroup, field: string, defa
|
|
|
74
99
|
* @hidden
|
|
75
100
|
*/
|
|
76
101
|
export declare const isWorkWeekDay: (day: number, start: number, end: number) => boolean;
|
|
102
|
+
/**
|
|
103
|
+
* @hidden
|
|
104
|
+
*/
|
|
105
|
+
export declare const alwaysFalse: () => boolean;
|