Skip to content

Commit 86e5d06

Browse files
author
Matt Lewis
committed
fix(dayView): allow dropping of external events
Partially fixes #150
1 parent fca80a5 commit 86e5d06

File tree

5 files changed

+115
-11
lines changed

5 files changed

+115
-11
lines changed

demos/demo-modules/draggable-external-events/component.ts

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { colors } from '../demo-utils/colors';
99
})
1010
export class DemoComponent {
1111

12+
view: string = 'month';
13+
1214
viewDate: Date = new Date();
1315

1416
externalEvents: CalendarEvent[] = [{

demos/demo-modules/draggable-external-events/template.html

+26-6
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,32 @@
2121
</div>
2222

2323
<div class="col-md-9">
24-
<mwl-calendar-month-view
25-
[viewDate]="viewDate"
26-
[events]="events"
27-
[activeDayIsOpen]="activeDayIsOpen"
28-
(eventTimesChanged)="eventDropped($event)">
29-
</mwl-calendar-month-view>
24+
<mwl-calendar-header
25+
[(view)]="view"
26+
[(viewDate)]="viewDate">
27+
</mwl-calendar-header>
28+
29+
<div [ngSwitch]="view">
30+
<mwl-calendar-month-view
31+
*ngSwitchCase="'month'"
32+
[viewDate]="viewDate"
33+
[events]="events"
34+
[activeDayIsOpen]="activeDayIsOpen"
35+
(eventTimesChanged)="eventDropped($event)">
36+
</mwl-calendar-month-view>
37+
<mwl-calendar-week-view
38+
*ngSwitchCase="'week'"
39+
[viewDate]="viewDate"
40+
[events]="events"
41+
(eventTimesChanged)="eventDropped($event)">
42+
</mwl-calendar-week-view>
43+
<mwl-calendar-day-view
44+
*ngSwitchCase="'day'"
45+
[viewDate]="viewDate"
46+
[events]="events"
47+
(eventTimesChanged)="eventDropped($event)">
48+
</mwl-calendar-day-view>
49+
</div>
3050
</div>
3151

3252
</div>

scss/day-view.scss

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
text-align: center;
2727
}
2828

29-
.cal-hour-segment:hover {
29+
.cal-hour-segment:hover,
30+
.cal-drag-over .cal-hour-segment {
3031
background-color: #ededed;
3132
}
3233

src/components/day/calendarDayView.component.ts

+13-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
OnInit,
1111
OnDestroy
1212
} from '@angular/core';
13-
import { getDayView, getDayViewHourGrid, CalendarEvent, DayView, DayViewHour } from 'calendar-utils';
13+
import { getDayView, getDayViewHourGrid, CalendarEvent, DayView, DayViewHour, DayViewHourSegment } from 'calendar-utils';
1414
import { Subject } from 'rxjs/Subject';
1515
import { Subscription } from 'rxjs/Subscription';
1616
import { CalendarEventTimesChangedEvent } from '../../interfaces/calendarEventTimesChangedEvent.interface';
@@ -57,7 +57,12 @@ const SEGMENT_HEIGHT: number = 30;
5757
*ngFor="let segment of hour.segments"
5858
[segment]="segment"
5959
[locale]="locale"
60-
(click)="hourSegmentClicked.emit({date: segment.date})">
60+
(click)="hourSegmentClicked.emit({date: segment.date})"
61+
[class.cal-drag-over]="segment.dragOver"
62+
mwlDroppable
63+
(dragEnter)="segment.dragOver = true"
64+
(dragLeave)="segment.dragOver = false"
65+
(drop)="segment.dragOver = false; eventDropped($event, segment)">
6166
</mwl-calendar-day-view-hour-segment>
6267
</div>
6368
</div>
@@ -224,6 +229,12 @@ export class CalendarDayViewComponent implements OnChanges, OnInit, OnDestroy {
224229

225230
}
226231

232+
eventDropped(dropEvent: {dropData?: {event?: CalendarEvent}}, segment: DayViewHourSegment): void {
233+
if (dropEvent.dropData && dropEvent.dropData.event) {
234+
this.eventTimesChanged.emit({event: dropEvent.dropData.event, newStart: segment.date});
235+
}
236+
}
237+
227238
private refreshHourGrid(): void {
228239
this.hours = getDayViewHourGrid({
229240
viewDate: this.viewDate,

test/calendarDayView.component.spec.ts

+72-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Component } from '@angular/core';
12
import {
23
inject,
34
ComponentFixture,
@@ -6,7 +7,8 @@ import {
67
} from '@angular/core/testing';
78
import * as moment from 'moment';
89
import { expect } from 'chai';
9-
import { DraggableHelper } from 'angular-draggable-droppable';
10+
import * as sinon from 'sinon';
11+
import { DraggableHelper, DragAndDropModule } from 'angular-draggable-droppable';
1012
import {
1113
CalendarEventTitleFormatter,
1214
CalendarEvent,
@@ -23,8 +25,40 @@ import { triggerDomEvent } from './util';
2325

2426
describe('CalendarDayViewComponent component', () => {
2527

28+
@Component({
29+
template: '<div class="external-event" mwlDraggable [dropData]="{event: event}">{{ event.title }}</div>',
30+
styles: [`
31+
.external-event {
32+
position: fixed;
33+
top: 0;
34+
left: 0;
35+
width: 10px;
36+
height: 10px;
37+
}
38+
`]
39+
})
40+
class ExternalEventComponent {
41+
event: CalendarEvent = {
42+
title: 'foo',
43+
start: new Date(),
44+
draggable: true,
45+
color: {
46+
primary: 'blue',
47+
secondary: 'lightblue'
48+
}
49+
};
50+
}
51+
2652
beforeEach(() => {
27-
TestBed.configureTestingModule({imports: [CalendarModule]});
53+
TestBed.configureTestingModule({
54+
imports: [
55+
CalendarModule,
56+
DragAndDropModule
57+
],
58+
declarations: [
59+
ExternalEventComponent
60+
]
61+
});
2862
TestBed.configureCompiler({
2963
providers: [
3064
DraggableHelper,
@@ -480,4 +514,40 @@ describe('CalendarDayViewComponent component', () => {
480514
fixture.destroy();
481515
});
482516

517+
it('should allow external events to be dropped on the day view', () => {
518+
const fixture: ComponentFixture<CalendarDayViewComponent> = TestBed.createComponent(CalendarDayViewComponent);
519+
fixture.componentInstance.viewDate = new Date('2016-06-27');
520+
fixture.componentInstance.events = [];
521+
fixture.componentInstance.ngOnChanges({viewDate: {}, events: {}});
522+
fixture.detectChanges();
523+
document.body.appendChild(fixture.nativeElement);
524+
525+
const externalEventFixture: ComponentFixture<ExternalEventComponent> = TestBed.createComponent(ExternalEventComponent);
526+
externalEventFixture.detectChanges();
527+
document.body.appendChild(externalEventFixture.nativeElement);
528+
529+
const event: HTMLElement = externalEventFixture.nativeElement.querySelector('.external-event');
530+
const eventPosition: ClientRect = event.getBoundingClientRect();
531+
532+
const segments: any[] = Array.from(fixture.nativeElement.querySelectorAll('.cal-hour-segment'));
533+
const segment: HTMLElement = segments[2].parentNode;
534+
const segmentPosition: ClientRect = segment.getBoundingClientRect();
535+
536+
const eventDropped: sinon.SinonSpy = sinon.spy();
537+
fixture.componentInstance.eventTimesChanged.subscribe(eventDropped);
538+
triggerDomEvent('mousedown', event, {clientY: eventPosition.top, clientX: eventPosition.left});
539+
fixture.detectChanges();
540+
triggerDomEvent('mousemove', document.body, {clientY: segmentPosition.top, clientX: segmentPosition.left});
541+
fixture.detectChanges();
542+
expect(segment.classList.contains('cal-drag-over')).to.be.true;
543+
triggerDomEvent('mouseup', document.body, {clientY: segmentPosition.top, clientX: eventPosition.left});
544+
fixture.detectChanges();
545+
fixture.destroy();
546+
externalEventFixture.destroy();
547+
expect(eventDropped).to.have.been.calledWith({
548+
event: externalEventFixture.componentInstance.event,
549+
newStart: moment('2016-06-27').startOf('day').add(1, 'hours').toDate()
550+
});
551+
});
552+
483553
});

0 commit comments

Comments
 (0)