Skip to content

Commit

Permalink
feat(day-view): allow dragging and dropping all day events
Browse files Browse the repository at this point in the history
Closes #665
  • Loading branch information
mattlewis92 committed Aug 5, 2018
1 parent e3d6652 commit 62c41b9
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 24 deletions.
15 changes: 15 additions & 0 deletions src/modules/common/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,18 @@ export function isDraggedWithinPeriod(
(period.start <= end && end <= period.end)
);
}

export function shouldFireDroppedEvent(
dropEvent: { dropData?: { event?: CalendarEvent } },
date: Date,
allDay: boolean,
events: CalendarEvent[]
) {
return (
dropEvent.dropData &&
dropEvent.dropData.event &&
(events.indexOf(dropEvent.dropData.event) === -1 ||
(dropEvent.dropData.event.allDay && !allDay) ||
(!dropEvent.dropData.event.allDay && allDay))
);
}
42 changes: 26 additions & 16 deletions src/modules/day/calendar-day-view.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ import {
getDefaultEventEnd,
getMinimumEventHeightInMinutes,
trackByDayOrWeekEvent,
isDraggedWithinPeriod
isDraggedWithinPeriod,
shouldFireDroppedEvent
} from '../common/util';
import { DateAdapter } from '../../date-adapters/date-adapter';
import { DragEndEvent } from 'angular-draggable-droppable';
Expand Down Expand Up @@ -75,13 +76,24 @@ export interface DayViewEventResize {
selector: 'mwl-calendar-day-view',
template: `
<div class="cal-day-view">
<mwl-calendar-all-day-event
*ngFor="let event of view.allDayEvents; trackBy:trackByEventId"
[event]="event"
[customTemplate]="allDayEventTemplate"
[eventTitleTemplate]="eventTitleTemplate"
(eventClicked)="eventClicked.emit({event: event})">
</mwl-calendar-all-day-event>
<div
class="cal-all-day-events"
mwlDroppable
dragOverClass="cal-drag-over"
dragActiveClass="cal-drag-active"
(drop)="eventDropped($event, view.period.start, true)">
<mwl-calendar-all-day-event
*ngFor="let event of view.allDayEvents; trackBy:trackByEventId"
[event]="event"
[customTemplate]="allDayEventTemplate"
[eventTitleTemplate]="eventTitleTemplate"
(eventClicked)="eventClicked.emit({event: event})"
mwlDraggable
dragActiveClass="cal-drag-active"
[dropData]="{event: event}"
[dragAxis]="{x: !snapDraggedEvents && event.draggable, y: !snapDraggedEvents && event.draggable}">
</mwl-calendar-all-day-event>
</div>
<div
class="cal-hour-rows"
#dayEventsContainer
Expand Down Expand Up @@ -139,7 +151,7 @@ export interface DayViewEventResize {
mwlDroppable
dragOverClass="cal-drag-over"
dragActiveClass="cal-drag-active"
(drop)="eventDropped($event, segment)">
(drop)="eventDropped($event, segment.date, false)">
</mwl-calendar-day-view-hour-segment>
</div>
</div>
Expand Down Expand Up @@ -424,17 +436,15 @@ export class CalendarDayViewComponent implements OnChanges, OnInit, OnDestroy {

eventDropped(
dropEvent: { dropData?: { event?: CalendarEvent } },
segment: DayViewHourSegment
date: Date,
allDay: boolean
): void {
if (
dropEvent.dropData &&
dropEvent.dropData.event &&
this.events.indexOf(dropEvent.dropData.event) === -1
) {
if (shouldFireDroppedEvent(dropEvent, date, allDay, this.events)) {
this.eventTimesChanged.emit({
type: CalendarEventTimesChangedEventType.Drop,
event: dropEvent.dropData.event,
newStart: segment.date
newStart: date,
allDay
});
}
}
Expand Down
11 changes: 3 additions & 8 deletions src/modules/week/calendar-week-view.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ import {
getMinimumEventHeightInMinutes,
addDaysWithExclusions,
trackByDayOrWeekEvent,
isDraggedWithinPeriod
isDraggedWithinPeriod,
shouldFireDroppedEvent
} from '../common/util';
import { DateAdapter } from '../../date-adapters/date-adapter';
import {
Expand Down Expand Up @@ -766,13 +767,7 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy {
date: Date,
allDay: boolean
): void {
if (
dropEvent.dropData &&
dropEvent.dropData.event &&
(this.events.indexOf(dropEvent.dropData.event) === -1 ||
(dropEvent.dropData.event.allDay && !allDay) ||
(!dropEvent.dropData.event.allDay && allDay))
) {
if (shouldFireDroppedEvent(dropEvent, date, allDay, this.events)) {
this.eventTimesChanged.emit({
type: CalendarEventTimesChangedEventType.Drop,
event: dropEvent.dropData.event,
Expand Down
128 changes: 128 additions & 0 deletions test/calendar-day-view.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1400,4 +1400,132 @@ describe('CalendarDayViewComponent component', () => {
expect(events).to.deep.equal([fixture.componentInstance.events[0]]);
expect(allDayEvents).to.deep.equal([fixture.componentInstance.events[1]]);
});

it('should drag an all day event onto the time grid', () => {
const fixture: ComponentFixture<
CalendarDayViewComponent
> = TestBed.createComponent(CalendarDayViewComponent);
fixture.componentInstance.viewDate = new Date('2018-07-29');
fixture.componentInstance.events = [
{
start: moment(new Date('2018-07-29'))
.startOf('day')
.add(3, 'hours')
.toDate(),
end: moment(new Date('2018-07-29'))
.startOf('day')
.add(18, 'hours')
.toDate(),
title: 'foo',
draggable: true,
allDay: true
}
];
fixture.componentInstance.snapDraggedEvents = false;
fixture.componentInstance.ngOnChanges({ viewDate: {}, events: {} });
fixture.detectChanges();
document.body.appendChild(fixture.nativeElement);
const event = fixture.nativeElement.querySelector(
'.cal-all-day-events mwl-calendar-all-day-event'
);
const rect: ClientRect = event.getBoundingClientRect();
let dragEvent: CalendarEventTimesChangedEvent;
fixture.componentInstance.eventTimesChanged.subscribe(e => {
dragEvent = e;
});
triggerDomEvent('mousedown', event, {
clientX: rect.left,
clientY: rect.top
});
fixture.detectChanges();
const hourSegment = fixture.nativeElement.querySelectorAll(
'mwl-calendar-day-view-hour-segment'
)[3];
const hourSegmentPosition = hourSegment.getBoundingClientRect();
triggerDomEvent('mousemove', hourSegment, {
clientX: hourSegmentPosition.left,
clientY: hourSegmentPosition.top
});
fixture.detectChanges();
triggerDomEvent('mouseup', hourSegment, {
clientX: hourSegmentPosition.left,
clientY: hourSegmentPosition.top
});
fixture.detectChanges();
fixture.destroy();
expect(dragEvent).to.deep.equal({
type: 'drop',
allDay: false,
event: fixture.componentInstance.events[0],
newStart: moment(new Date('2018-07-29'))
.startOf('day')
.add(90, 'minutes')
.toDate()
});
});

it('should drag a time event onto the all day events', () => {
const fixture: ComponentFixture<
CalendarDayViewComponent
> = TestBed.createComponent(CalendarDayViewComponent);
fixture.componentInstance.viewDate = new Date('2018-07-29');
fixture.componentInstance.events = [
{
start: moment(new Date('2018-07-29'))
.startOf('day')
.add(3, 'hours')
.toDate(),
end: moment(new Date('2018-07-29'))
.startOf('day')
.add(18, 'hours')
.toDate(),
title: 'foo',
draggable: true,
allDay: false
},
{
start: new Date('2018-07-29'),
allDay: true,
title: 'bar'
}
];
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
});
fixture.detectChanges();
const allDayEvents = fixture.nativeElement.querySelector(
'.cal-all-day-events'
);
const allDayEventsPosition = allDayEvents.getBoundingClientRect();
triggerDomEvent('mousemove', allDayEvents, {
clientX: allDayEventsPosition.left,
clientY: allDayEventsPosition.top
});
fixture.detectChanges();
triggerDomEvent('mouseup', allDayEvents, {
clientX: allDayEventsPosition.left,
clientY: allDayEventsPosition.top
});
fixture.detectChanges();
fixture.destroy();
expect(dragEvent).to.deep.equal({
type: 'drop',
allDay: true,
event: fixture.componentInstance.events[0],
newStart: moment(new Date('2018-07-29'))
.startOf('day')
.toDate()
});
});
});

0 comments on commit 62c41b9

Please sign in to comment.