@@ -24,8 +24,9 @@ import { CalendarDragHelper } from '../common/calendar-drag-helper.provider';
24
24
import { CalendarResizeHelper } from '../common/calendar-resize-helper.provider' ;
25
25
import { CalendarEventTimesChangedEvent } from '../common/calendar-event-times-changed-event.interface' ;
26
26
import { CalendarUtils } from '../common/calendar-utils.provider' ;
27
- import { validateEvents , trackByIndex } from '../common/util' ;
27
+ import { validateEvents , trackByIndex , roundToNearest } from '../common/util' ;
28
28
import { DateAdapter } from '../../date-adapters/date-adapter' ;
29
+ import { DragEnd } from 'angular-draggable-droppable/draggable.directive' ;
29
30
30
31
export interface WeekViewEventResize {
31
32
originalOffset : number ;
@@ -51,48 +52,54 @@ export interface CalendarWeekViewBeforeRenderEvent {
51
52
@Component ( {
52
53
selector : 'mwl-calendar-week-view' ,
53
54
template : `
54
- <div class="cal-week-view" #weekViewContainer >
55
+ <div class="cal-week-view">
55
56
<mwl-calendar-week-view-header
56
57
[days]="days"
57
58
[locale]="locale"
58
59
[customTemplate]="headerTemplate"
59
60
(dayHeaderClicked)="dayHeaderClicked.emit($event)"
60
61
(eventDropped)="eventTimesChanged.emit($event)">
61
62
</mwl-calendar-week-view-header>
62
- <div *ngFor="let eventRow of view.eventRows; trackBy:trackByIndex" #eventRowContainer class="cal-events-row">
63
- <div
64
- *ngFor="let weekEvent of eventRow.row; trackBy:trackByEventId"
65
- #event
66
- class="cal-event-container"
67
- [class.cal-draggable]="weekEvent.event.draggable"
68
- [class.cal-starts-within-week]="!weekEvent.startsBeforeWeek"
69
- [class.cal-ends-within-week]="!weekEvent.endsAfterWeek"
70
- [ngClass]="weekEvent.event?.cssClass"
71
- [style.width]="((100 / days.length) * weekEvent.span) + '%'"
72
- [style.marginLeft]="((100 / days.length) * weekEvent.offset) + '%'"
73
- mwlResizable
74
- [resizeEdges]="{left: weekEvent.event?.resizable?.beforeStart, right: weekEvent.event?.resizable?.afterEnd}"
75
- [resizeSnapGrid]="{left: dayColumnWidth, right: dayColumnWidth}"
76
- [validateResize]="validateResize"
77
- (resizeStart)="resizeStarted(weekViewContainer, weekEvent, $event)"
78
- (resizing)="resizing(weekEvent, $event, dayColumnWidth)"
79
- (resizeEnd)="resizeEnded(weekEvent)"
80
- mwlDraggable
81
- dragActiveClass="cal-drag-active"
82
- [dragAxis]="{x: weekEvent.event.draggable && currentResizes.size === 0, y: false}"
83
- [dragSnapGrid]="{x: dayColumnWidth}"
84
- [validateDrag]="validateDrag"
85
- (dragPointerDown)="dragStart(weekViewContainer, event)"
86
- (dragEnd)="eventDragged(weekEvent, $event.x, dayColumnWidth)">
87
- <mwl-calendar-week-view-event
88
- [weekEvent]="weekEvent"
89
- [tooltipPlacement]="tooltipPlacement"
90
- [tooltipTemplate]="tooltipTemplate"
91
- [tooltipAppendToBody]="tooltipAppendToBody"
92
- [customTemplate]="eventTemplate"
93
- [eventTitleTemplate]="eventTitleTemplate"
94
- (eventClicked)="eventClicked.emit({event: weekEvent.event})">
95
- </mwl-calendar-week-view-event>
63
+ <div
64
+ #weekEventsContainer
65
+ mwlDroppable
66
+ (drop)="eventDroppedWithinContainer = true">
67
+ <div *ngFor="let eventRow of view.eventRows; trackBy:trackByIndex" #eventRowContainer class="cal-events-row">
68
+ <div
69
+ *ngFor="let weekEvent of eventRow.row; trackBy:trackByEventId"
70
+ #event
71
+ class="cal-event-container"
72
+ [class.cal-draggable]="weekEvent.event.draggable"
73
+ [class.cal-starts-within-week]="!weekEvent.startsBeforeWeek"
74
+ [class.cal-ends-within-week]="!weekEvent.endsAfterWeek"
75
+ [ngClass]="weekEvent.event?.cssClass"
76
+ [style.width]="((100 / days.length) * weekEvent.span) + '%'"
77
+ [style.marginLeft]="((100 / days.length) * weekEvent.offset) + '%'"
78
+ mwlResizable
79
+ [resizeEdges]="{left: weekEvent.event?.resizable?.beforeStart, right: weekEvent.event?.resizable?.afterEnd}"
80
+ [resizeSnapGrid]="{left: dayColumnWidth, right: dayColumnWidth}"
81
+ [validateResize]="validateResize"
82
+ (resizeStart)="resizeStarted(weekEventsContainer, weekEvent, $event)"
83
+ (resizing)="resizing(weekEvent, $event, dayColumnWidth)"
84
+ (resizeEnd)="resizeEnded(weekEvent)"
85
+ mwlDraggable
86
+ dragActiveClass="cal-drag-active"
87
+ [dropData]="{event: weekEvent.event}"
88
+ [dragAxis]="{x: weekEvent.event.draggable && currentResizes.size === 0, y: !snapDraggedEvents && weekEvent.event.draggable && currentResizes.size === 0}"
89
+ [dragSnapGrid]="snapDraggedEvents ? {x: dayColumnWidth} : {}"
90
+ [validateDrag]="snapDraggedEvents ? validateDrag : false"
91
+ (dragPointerDown)="dragStarted(weekEventsContainer, event)"
92
+ (dragEnd)="dragEnded(weekEvent, $event, dayColumnWidth)">
93
+ <mwl-calendar-week-view-event
94
+ [weekEvent]="weekEvent"
95
+ [tooltipPlacement]="tooltipPlacement"
96
+ [tooltipTemplate]="tooltipTemplate"
97
+ [tooltipAppendToBody]="tooltipAppendToBody"
98
+ [customTemplate]="eventTemplate"
99
+ [eventTitleTemplate]="eventTitleTemplate"
100
+ (eventClicked)="eventClicked.emit({event: weekEvent.event})">
101
+ </mwl-calendar-week-view-event>
102
+ </div>
96
103
</div>
97
104
</div>
98
105
</div>
@@ -171,6 +178,11 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy {
171
178
*/
172
179
@Input ( ) weekendDays : number [ ] ;
173
180
181
+ /**
182
+ * Whether to snap events to a grid when dragging
183
+ */
184
+ @Input ( ) snapDraggedEvents : boolean = true ;
185
+
174
186
/**
175
187
* Called when a header week day is clicked. Adding a `cssClass` property on `$event.day` will add that class to the header element
176
188
*/
@@ -222,6 +234,11 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy {
222
234
*/
223
235
currentResizes : Map < WeekViewEvent , WeekViewEventResize > = new Map ( ) ;
224
236
237
+ /**
238
+ * @hidden
239
+ */
240
+ eventDroppedWithinContainer = false ;
241
+
225
242
/**
226
243
* @hidden
227
244
*/
@@ -302,7 +319,7 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy {
302
319
* @hidden
303
320
*/
304
321
resizeStarted (
305
- weekViewContainer : HTMLElement ,
322
+ weekEventsContainer : HTMLElement ,
306
323
weekEvent : WeekViewEvent ,
307
324
resizeEvent : ResizeEvent
308
325
) : void {
@@ -311,9 +328,9 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy {
311
328
originalSpan : weekEvent . span ,
312
329
edge : typeof resizeEvent . edges . left !== 'undefined' ? 'left' : 'right'
313
330
} ) ;
314
- this . dayColumnWidth = this . getDayColumnWidth ( weekViewContainer ) ;
331
+ this . dayColumnWidth = this . getDayColumnWidth ( weekEventsContainer ) ;
315
332
const resizeHelper : CalendarResizeHelper = new CalendarResizeHelper (
316
- weekViewContainer ,
333
+ weekEventsContainer ,
317
334
this . dayColumnWidth
318
335
) ;
319
336
this . validateResize = ( { rectangle } ) =>
@@ -373,27 +390,6 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy {
373
390
this . currentResizes . delete ( weekEvent ) ;
374
391
}
375
392
376
- /**
377
- * @hidden
378
- */
379
- eventDragged (
380
- weekEvent : WeekViewEvent ,
381
- draggedByPx : number ,
382
- dayWidth : number
383
- ) : void {
384
- const daysDragged : number = draggedByPx / dayWidth ;
385
- const newStart : Date = this . dateAdapter . addDays (
386
- weekEvent . event . start ,
387
- daysDragged
388
- ) ;
389
- let newEnd : Date ;
390
- if ( weekEvent . event . end ) {
391
- newEnd = this . dateAdapter . addDays ( weekEvent . event . end , daysDragged ) ;
392
- }
393
-
394
- this . eventTimesChanged . emit ( { newStart, newEnd, event : weekEvent . event } ) ;
395
- }
396
-
397
393
/**
398
394
* @hidden
399
395
*/
@@ -404,17 +400,41 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy {
404
400
/**
405
401
* @hidden
406
402
*/
407
- dragStart ( weekViewContainer : HTMLElement , event : HTMLElement ) : void {
408
- this . dayColumnWidth = this . getDayColumnWidth ( weekViewContainer ) ;
403
+ dragStarted ( weekEventsContainer : HTMLElement , event : HTMLElement ) : void {
404
+ this . dayColumnWidth = this . getDayColumnWidth ( weekEventsContainer ) ;
409
405
const dragHelper : CalendarDragHelper = new CalendarDragHelper (
410
- weekViewContainer ,
406
+ weekEventsContainer ,
411
407
event
412
408
) ;
413
409
this . validateDrag = ( { x, y } ) =>
414
410
this . currentResizes . size === 0 && dragHelper . validateDrag ( { x, y } ) ;
411
+ this . eventDroppedWithinContainer = false ;
415
412
this . cdr . markForCheck ( ) ;
416
413
}
417
414
415
+ /**
416
+ * @hidden
417
+ */
418
+ dragEnded (
419
+ weekEvent : WeekViewEvent ,
420
+ dragEndEvent : DragEnd ,
421
+ dayWidth : number
422
+ ) : void {
423
+ if ( this . eventDroppedWithinContainer ) {
424
+ const daysDragged = roundToNearest ( dragEndEvent . x , dayWidth ) / dayWidth ;
425
+ const newStart = this . dateAdapter . addDays (
426
+ weekEvent . event . start ,
427
+ daysDragged
428
+ ) ;
429
+ let newEnd : Date ;
430
+ if ( weekEvent . event . end ) {
431
+ newEnd = this . dateAdapter . addDays ( weekEvent . event . end , daysDragged ) ;
432
+ }
433
+
434
+ this . eventTimesChanged . emit ( { newStart, newEnd, event : weekEvent . event } ) ;
435
+ }
436
+ }
437
+
418
438
private refreshHeader ( ) : void {
419
439
this . days = this . utils . getWeekViewHeader ( {
420
440
viewDate : this . viewDate ,
0 commit comments