diff --git a/projects/angular-calendar/src/modules/week/calendar-week-view-header.component.ts b/projects/angular-calendar/src/modules/week/calendar-week-view-header.component.ts index 8da1dd3ef..427fe3025 100644 --- a/projects/angular-calendar/src/modules/week/calendar-week-view-header.component.ts +++ b/projects/angular-calendar/src/modules/week/calendar-week-view-header.component.ts @@ -18,6 +18,7 @@ import { trackByWeekDayHeaderDate } from '../common/util'; let-dayHeaderClicked="dayHeaderClicked" let-eventDropped="eventDropped" let-trackByWeekDayHeaderDate="trackByWeekDayHeaderDate" + let-dragEnter="dragEnter" >
@@ -55,6 +57,7 @@ import { trackByWeekDayHeaderDate } from '../common/util'; locale: locale, dayHeaderClicked: dayHeaderClicked, eventDropped: eventDropped, + dragEnter: dragEnter, trackByWeekDayHeaderDate: trackByWeekDayHeaderDate }" > @@ -68,17 +71,17 @@ export class CalendarWeekViewHeaderComponent { @Input() customTemplate: TemplateRef; - @Output() - dayHeaderClicked = new EventEmitter<{ + @Output() dayHeaderClicked = new EventEmitter<{ day: WeekDay; sourceEvent: MouseEvent; }>(); - @Output() - eventDropped: EventEmitter<{ + @Output() eventDropped = new EventEmitter<{ event: CalendarEvent; newStart: Date; - }> = new EventEmitter<{ event: CalendarEvent; newStart: Date }>(); + }>(); + + @Output() dragEnter = new EventEmitter<{ date: Date }>(); trackByWeekDayHeaderDate = trackByWeekDayHeaderDate; } 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 f7a25f5fa..fec38b5d8 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 @@ -88,6 +88,7 @@ export interface CalendarWeekViewBeforeRenderEvent extends WeekView { (eventDropped)=" eventDropped({ dropData: $event }, $event.newStart, true) " + (dragEnter)="dateDragEnter($event.date)" >
@@ -644,6 +647,11 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy { */ trackByDayOrWeekEvent = trackByDayOrWeekEvent; + /** + * @hidden + */ + private lastDragEnterDate: Date; + /** * @hidden */ @@ -893,6 +901,13 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy { return Math.floor(eventRowContainer.offsetWidth / this.days.length); } + /** + * @hidden + */ + dateDragEnter(date: Date) { + this.lastDragEnterDate = date; + } + /** * @hidden */ @@ -901,7 +916,10 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy { date: Date, allDay: boolean ): void { - if (shouldFireDroppedEvent(dropEvent, date, allDay, this.calendarId)) { + if ( + shouldFireDroppedEvent(dropEvent, date, allDay, this.calendarId) && + this.lastDragEnterDate.getTime() === date.getTime() + ) { this.eventTimesChanged.emit({ type: CalendarEventTimesChangedEventType.Drop, event: dropEvent.dropData.event, 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 e8cae6966..33010de84 100644 --- a/projects/angular-calendar/test/calendar-week-view.component.spec.ts +++ b/projects/angular-calendar/test/calendar-week-view.component.spec.ts @@ -26,6 +26,24 @@ import * as sinon from 'sinon'; import { triggerDomEvent, ExternalEventComponent } from './util'; import { take } from 'rxjs/operators'; import { adapterFactory } from '../src/date-adapters/date-fns'; +import { Component } from '@angular/core'; +import { By } from '@angular/platform-browser'; + +@Component({ + template: ` + + + ` +}) +class TestComponent { + viewDate: Date; + events: CalendarEvent[]; + eventTimesChanged = sinon.spy(); +} describe('calendarWeekView component', () => { beforeEach(() => { @@ -45,7 +63,7 @@ describe('calendarWeekView component', () => { ), DragAndDropModule ], - declarations: [ExternalEventComponent], + declarations: [ExternalEventComponent, TestComponent], providers: [{ provide: MOMENT, useValue: moment }] }); }); @@ -912,20 +930,14 @@ describe('calendarWeekView component', () => { }); it('should allow external events to be dropped on the week view headers', () => { - const fixture: ComponentFixture< - CalendarWeekViewComponent - > = TestBed.createComponent(CalendarWeekViewComponent); + const fixture = TestBed.createComponent(TestComponent); fixture.componentInstance.viewDate = new Date('2016-06-27'); fixture.componentInstance.events = []; - fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} }); fixture.detectChanges(); document.body.appendChild(fixture.nativeElement); - - const externalEventFixture: ComponentFixture< - ExternalEventComponent - > = TestBed.createComponent(ExternalEventComponent); - externalEventFixture.detectChanges(); - document.body.appendChild(externalEventFixture.nativeElement); + const externalEventFixture = fixture.debugElement.query( + By.directive(ExternalEventComponent) + ); const event: HTMLElement = externalEventFixture.nativeElement.querySelector( '.external-event' @@ -938,8 +950,7 @@ describe('calendarWeekView component', () => { const header: HTMLElement = headers[2]; const headerPosition: ClientRect = header.getBoundingClientRect(); - const eventDropped: sinon.SinonSpy = sinon.spy(); - fixture.componentInstance.eventTimesChanged.subscribe(eventDropped); + const eventDropped = fixture.componentInstance.eventTimesChanged; triggerDomEvent('mousedown', event, { clientY: eventPosition.top, clientX: eventPosition.left @@ -955,8 +966,6 @@ describe('calendarWeekView component', () => { clientX: headerPosition.left }); fixture.detectChanges(); - fixture.destroy(); - externalEventFixture.destroy(); expect(eventDropped).to.have.been.calledWith({ type: 'drop', event: externalEventFixture.componentInstance.event, @@ -966,6 +975,7 @@ describe('calendarWeekView component', () => { .toDate(), allDay: true }); + expect(eventDropped).to.have.been.calledOnce; }); it('should allow the weekend days to be customised', () => { @@ -2336,4 +2346,56 @@ describe('calendarWeekView component', () => { ); document.head.appendChild(style); }); + + it('should allow external events to be dropped on the hour segments', () => { + const fixture = TestBed.createComponent(TestComponent); + fixture.componentInstance.viewDate = new Date('2016-06-27'); + fixture.componentInstance.events = []; + fixture.detectChanges(); + document.body.appendChild(fixture.nativeElement); + const externalEventFixture = fixture.debugElement.query( + By.directive(ExternalEventComponent) + ); + + const event: HTMLElement = externalEventFixture.nativeElement.querySelector( + '.external-event' + ); + const eventPosition: ClientRect = event.getBoundingClientRect(); + + const segments: HTMLElement[] = Array.from( + fixture.nativeElement.querySelectorAll( + '.cal-day-columns .cal-hour-segment' + ) + ); + const segment = segments[1]; + const segmentPosition: ClientRect = segment.getBoundingClientRect(); + + const eventDropped = fixture.componentInstance.eventTimesChanged; + + triggerDomEvent('mousedown', event, { + clientY: eventPosition.top, + clientX: eventPosition.left + }); + fixture.detectChanges(); + triggerDomEvent('mousemove', document.body, { + clientY: segmentPosition.top, + clientX: segmentPosition.left + }); + fixture.detectChanges(); + triggerDomEvent('mouseup', document.body, { + clientY: segmentPosition.top, + clientX: segmentPosition.left + }); + fixture.detectChanges(); + expect(eventDropped).to.have.been.calledWith({ + type: 'drop', + event: externalEventFixture.componentInstance.event, + newStart: moment('2016-06-27') + .startOf('week') + .add(30, 'minutes') + .toDate(), + allDay: false + }); + expect(eventDropped).to.have.been.calledOnce; + }); }); diff --git a/projects/angular-calendar/test/util.ts b/projects/angular-calendar/test/util.ts index 5fc9efa0f..a1eb00040 100644 --- a/projects/angular-calendar/test/util.ts +++ b/projects/angular-calendar/test/util.ts @@ -14,6 +14,7 @@ export function triggerDomEvent( } @Component({ + selector: 'mwl-external-event', template: '
{{ event.title }}
', styles: [