From cb079240a22dd682b962a4165f258b9e6e6cec0d Mon Sep 17 00:00:00 2001 From: Hapcy Date: Sun, 3 Feb 2019 08:48:55 +0100 Subject: [PATCH] fix: allow events to be dragged back to their original location Closes #847 --- .../common/calendar-drag-helper.provider.ts | 8 +- .../day/calendar-day-view.component.ts | 17 ++- .../week/calendar-week-view.component.ts | 18 ++- .../test/calendar-week-view.component.spec.ts | 114 ++++++++++++++++++ .../day-view-scheduler.component.html | 1 + 5 files changed, 153 insertions(+), 5 deletions(-) diff --git a/projects/angular-calendar/src/modules/common/calendar-drag-helper.provider.ts b/projects/angular-calendar/src/modules/common/calendar-drag-helper.provider.ts index b0a4b5fe5..2d2fc8eaa 100644 --- a/projects/angular-calendar/src/modules/common/calendar-drag-helper.provider.ts +++ b/projects/angular-calendar/src/modules/common/calendar-drag-helper.provider.ts @@ -15,11 +15,13 @@ export class CalendarDragHelper { validateDrag({ x, y, - snapDraggedEvents + snapDraggedEvents, + dragAlreadyMoved }: { x: number; y: number; snapDraggedEvents: boolean; + dragAlreadyMoved: boolean; }): boolean { const isWithinThreshold = Math.abs(x) > DRAG_THRESHOLD || Math.abs(y) > DRAG_THRESHOLD; @@ -33,11 +35,11 @@ export class CalendarDragHelper { }); return ( - isWithinThreshold && + (isWithinThreshold || dragAlreadyMoved) && isInside(this.dragContainerElement.getBoundingClientRect(), newRect) ); } else { - return isWithinThreshold; + return isWithinThreshold || dragAlreadyMoved; } } } diff --git a/projects/angular-calendar/src/modules/day/calendar-day-view.component.ts b/projects/angular-calendar/src/modules/day/calendar-day-view.component.ts index 322f3676e..47645d215 100644 --- a/projects/angular-calendar/src/modules/day/calendar-day-view.component.ts +++ b/projects/angular-calendar/src/modules/day/calendar-day-view.component.ts @@ -145,6 +145,7 @@ export interface DayViewEventResize { " [validateDrag]="validateDrag" (dragPointerDown)="dragStarted(event, dayEventsContainer)" + (dragging)="dragMove()" (dragEnd)="dragEnded(dayEvent, $event)" [style.marginTop.px]="dayEvent.top" [style.height.px]="dayEvent.height" @@ -371,6 +372,11 @@ export class CalendarDayViewComponent implements OnChanges, OnInit, OnDestroy { */ calendarId = Symbol('angular calendar day view id'); + /** + * @hidden + */ + dragAlreadyMoved = false; + /** * @hidden */ @@ -561,12 +567,21 @@ export class CalendarDayViewComponent implements OnChanges, OnInit, OnDestroy { dragHelper.validateDrag({ x, y, - snapDraggedEvents: this.snapDraggedEvents + snapDraggedEvents: this.snapDraggedEvents, + dragAlreadyMoved: this.dragAlreadyMoved }); this.eventDragEnter = 0; + this.dragAlreadyMoved = false; this.cdr.markForCheck(); } + /** + * @hidden + */ + dragMove() { + this.dragAlreadyMoved = true; + } + dragEnded(dayEvent: DayViewEvent, dragEndEvent: DragEndEvent): void { if (this.eventDragEnter > 0) { let minutesMoved = getMinutesMoved( diff --git a/projects/angular-calendar/src/modules/week/calendar-week-view.component.ts b/projects/angular-calendar/src/modules/week/calendar-week-view.component.ts index a65074029..eee0a2735 100644 --- a/projects/angular-calendar/src/modules/week/calendar-week-view.component.ts +++ b/projects/angular-calendar/src/modules/week/calendar-week-view.component.ts @@ -153,6 +153,7 @@ export interface CalendarWeekViewBeforeRenderEvent extends WeekView { [dragSnapGrid]="snapDraggedEvents ? { x: dayColumnWidth } : {}" [validateDrag]="validateDrag" (dragPointerDown)="dragStarted(eventRowContainer, event)" + (dragging)="allDayEventDragMove()" (dragEnd)="dragEnded(allDayEvent, $event, dayColumnWidth)" >
{ @@ -909,6 +917,14 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy { new Map([[adjustedEvent, originalEvent]]) ); } + this.dragAlreadyMoved = true; + } + + /** + * @hidden + */ + allDayEventDragMove() { + this.dragAlreadyMoved = true; } /** diff --git a/projects/angular-calendar/test/calendar-week-view.component.spec.ts b/projects/angular-calendar/test/calendar-week-view.component.spec.ts index e88a09e24..6db810701 100644 --- a/projects/angular-calendar/test/calendar-week-view.component.spec.ts +++ b/projects/angular-calendar/test/calendar-week-view.component.spec.ts @@ -1600,6 +1600,66 @@ describe('calendarWeekView component', () => { }); }); + it('should drag time events back to their original position while snapping to a grid', () => { + const fixture: ComponentFixture< + CalendarWeekViewComponent + > = TestBed.createComponent(CalendarWeekViewComponent); + fixture.componentInstance.viewDate = new Date('2018-07-29'); + const originalEvent = { + start: moment(new Date('2018-07-29')) + .startOf('day') + .add(3, 'hours') + .toDate(), + end: moment(new Date('2018-07-29')) + .startOf('day') + .add(5, 'hours') + .toDate(), + title: 'foo', + draggable: true + }; + fixture.componentInstance.events = [originalEvent]; + fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); + document.body.appendChild(fixture.nativeElement); + const event = fixture.nativeElement.querySelector('.cal-event-container'); + const rect: ClientRect = event.getBoundingClientRect(); + let dragEvent: CalendarEventTimesChangedEvent; + fixture.componentInstance.eventTimesChanged.subscribe(e => { + dragEvent = e; + }); + triggerDomEvent('mousedown', event, { + clientX: rect.right, + clientY: rect.bottom + }); + fixture.detectChanges(); + triggerDomEvent('mousemove', event, { + clientX: rect.right, + clientY: rect.bottom + 95 + }); + fixture.detectChanges(); + const updatedEvent1 = fixture.nativeElement.querySelector( + '.cal-event-container' + ); + expect(updatedEvent1.getBoundingClientRect().top).to.equal(rect.top + 90); + triggerDomEvent('mousemove', event, { + clientX: rect.right, + clientY: rect.bottom + }); + fixture.detectChanges(); + const updatedEvent2 = fixture.nativeElement.querySelector( + '.cal-event-container' + ); + expect(updatedEvent2.getBoundingClientRect().top).to.equal(rect.top); + triggerDomEvent('mouseup', event, { + clientX: rect.right, + clientY: rect.bottom + }); + fixture.detectChanges(); + fixture.destroy(); + expect(dragEvent.newStart).to.deep.equal(originalEvent.start); + expect(dragEvent.newEnd).to.deep.equal(originalEvent.end); + }); + it('should drag time events without end dates', () => { const fixture: ComponentFixture< CalendarWeekViewComponent @@ -1733,6 +1793,60 @@ describe('calendarWeekView component', () => { }); }); + it('should drag time events back to their original position while not snapping to a grid', () => { + const fixture: ComponentFixture< + CalendarWeekViewComponent + > = TestBed.createComponent(CalendarWeekViewComponent); + fixture.componentInstance.viewDate = new Date('2018-07-29'); + const originalEvent = { + start: moment(new Date('2018-07-29')) + .startOf('day') + .add(3, 'hours') + .toDate(), + end: moment(new Date('2018-07-29')) + .startOf('day') + .add(5, 'hours') + .toDate(), + title: 'foo', + draggable: true + }; + fixture.componentInstance.events = [originalEvent]; + fixture.componentInstance.snapDraggedEvents = false; + fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); + fixture.detectChanges(); + document.body.appendChild(fixture.nativeElement); + const event = fixture.nativeElement.querySelector('.cal-event-container'); + const rect: ClientRect = event.getBoundingClientRect(); + let dragEvent: CalendarEventTimesChangedEvent; + fixture.componentInstance.eventTimesChanged.subscribe(e => { + dragEvent = e; + }); + triggerDomEvent('mousedown', event, { + clientX: rect.left, + clientY: rect.top + }); + const timeEvents = fixture.nativeElement.querySelector('.cal-time-events'); + fixture.detectChanges(); + triggerDomEvent('mousemove', timeEvents, { + clientX: rect.left, + clientY: rect.top + 95 + }); + fixture.detectChanges(); + triggerDomEvent('mousemove', timeEvents, { + clientX: rect.left, + clientY: rect.top + }); + fixture.detectChanges(); + triggerDomEvent('mouseup', timeEvents, { + clientX: rect.left, + clientY: rect.top + }); + fixture.detectChanges(); + fixture.destroy(); + expect(dragEvent.newStart).to.deep.equal(originalEvent.start); + expect(dragEvent.newEnd).to.deep.equal(originalEvent.end); + }); + it('should drag an all day event onto the time grid', () => { const fixture: ComponentFixture< CalendarWeekViewComponent diff --git a/projects/demos/app/demo-modules/day-view-scheduler/day-view-scheduler.component.html b/projects/demos/app/demo-modules/day-view-scheduler/day-view-scheduler.component.html index 3da5aac2b..90e0faf32 100644 --- a/projects/demos/app/demo-modules/day-view-scheduler/day-view-scheduler.component.html +++ b/projects/demos/app/demo-modules/day-view-scheduler/day-view-scheduler.component.html @@ -40,6 +40,7 @@ }" [validateDrag]="validateDrag" (dragStart)="dragStarted(event, dayViewContainer)" + (dragging)="dragMove()" (dragEnd)="eventDragged(dayEvent, $event.x, $event.y)" [style.marginTop.px]="dayEvent.top" [style.height.px]="dayEvent.height"