Skip to content

Commit 01b776c

Browse files
author
Matt Lewis
committed
fix(weekView): allow events to be resized that are next to each other
1 parent bc16638 commit 01b776c

File tree

2 files changed

+84
-19
lines changed

2 files changed

+84
-19
lines changed

src/components/week/calendarWeekView.component.ts

+27-19
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ import { CalendarResizeHelper } from '../../providers/calendarResizeHelper.provi
2828
import { CalendarEventTimesChangedEvent } from '../../interfaces/calendarEventTimesChangedEvent.interface';
2929
import { CalendarUtils } from '../../providers/calendarUtils.provider';
3030

31+
interface CurrentResize {
32+
originalOffset: number;
33+
originalSpan: number;
34+
edge: string;
35+
}
36+
3137
/**
3238
* Shows all events on a given week. Example usage:
3339
*
@@ -68,7 +74,7 @@ import { CalendarUtils } from '../../providers/calendarUtils.provider';
6874
[dragSnapGrid]="{x: allowDragOutside ? 0 : getDayColumnWidth(eventRowContainer)}"
6975
[validateDrag]="validateDrag"
7076
(dragStart)="dragStart(weekViewContainer, event)"
71-
[dragAxis]="{x: weekEvent.event.draggable && !currentResize, y: allowDragOutside}"
77+
[dragAxis]="{x: weekEvent.event.draggable && currentResizes.size === 0, y: allowDragOutside}"
7278
(dragEnd)="eventDragged(weekEvent, $event.x, getDayColumnWidth(eventRowContainer))"
7379
[dropData]="{event: weekEvent.event}">
7480
<mwl-calendar-week-view-event
@@ -173,11 +179,7 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy {
173179
/**
174180
* @hidden
175181
*/
176-
currentResize: {
177-
originalOffset: number,
178-
originalSpan: number,
179-
edge: string
180-
};
182+
currentResizes: Map<WeekViewEvent, CurrentResize> = new Map();
181183

182184
/**
183185
* @hidden
@@ -236,11 +238,11 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy {
236238
* @hidden
237239
*/
238240
resizeStarted(weekViewContainer: HTMLElement, weekEvent: WeekViewEvent, resizeEvent: ResizeEvent): void {
239-
this.currentResize = {
241+
this.currentResizes.set(weekEvent, {
240242
originalOffset: weekEvent.offset,
241243
originalSpan: weekEvent.span,
242244
edge: typeof resizeEvent.edges.left !== 'undefined' ? 'left' : 'right'
243-
};
245+
});
244246
const resizeHelper: CalendarResizeHelper = new CalendarResizeHelper(weekViewContainer, this.getDayColumnWidth(weekViewContainer));
245247
this.validateResize = ({rectangle}) => resizeHelper.validateResize({rectangle});
246248
this.cdr.markForCheck();
@@ -250,41 +252,47 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy {
250252
* @hidden
251253
*/
252254
resizing(weekEvent: WeekViewEvent, resizeEvent: ResizeEvent, dayWidth: number): void {
255+
256+
const currentResize: CurrentResize = this.currentResizes.get(weekEvent);
257+
253258
if (resizeEvent.edges.left) {
254259
const diff: number = Math.round(+resizeEvent.edges.left / dayWidth);
255-
weekEvent.offset = this.currentResize.originalOffset + diff;
256-
weekEvent.span = this.currentResize.originalSpan - diff;
260+
weekEvent.offset = currentResize.originalOffset + diff;
261+
weekEvent.span = currentResize.originalSpan - diff;
257262
} else if (resizeEvent.edges.right) {
258263
const diff: number = Math.round(+resizeEvent.edges.right / dayWidth);
259-
weekEvent.span = this.currentResize.originalSpan + diff;
264+
weekEvent.span = currentResize.originalSpan + diff;
260265
}
266+
261267
}
262268

263269
/**
264270
* @hidden
265271
*/
266272
resizeEnded(weekEvent: WeekViewEvent): void {
267273

274+
const currentResize: CurrentResize = this.currentResizes.get(weekEvent);
275+
268276
let daysDiff: number;
269-
if (this.currentResize.edge === 'left') {
270-
daysDiff = weekEvent.offset - this.currentResize.originalOffset;
277+
if (currentResize.edge === 'left') {
278+
daysDiff = weekEvent.offset - currentResize.originalOffset;
271279
} else {
272-
daysDiff = weekEvent.span - this.currentResize.originalSpan;
280+
daysDiff = weekEvent.span - currentResize.originalSpan;
273281
}
274282

275-
weekEvent.offset = this.currentResize.originalOffset;
276-
weekEvent.span = this.currentResize.originalSpan;
283+
weekEvent.offset = currentResize.originalOffset;
284+
weekEvent.span = currentResize.originalSpan;
277285

278286
let newStart: Date = weekEvent.event.start;
279287
let newEnd: Date = weekEvent.event.end;
280-
if (this.currentResize.edge === 'left') {
288+
if (currentResize.edge === 'left') {
281289
newStart = addDays(newStart, daysDiff);
282290
} else if (newEnd) {
283291
newEnd = addDays(newEnd, daysDiff);
284292
}
285293

286294
this.eventTimesChanged.emit({newStart, newEnd, event: weekEvent.event});
287-
this.currentResize = null;
295+
this.currentResizes.delete(weekEvent);
288296

289297
}
290298

@@ -331,7 +339,7 @@ export class CalendarWeekViewComponent implements OnChanges, OnInit, OnDestroy {
331339
dragStart(weekViewContainer: HTMLElement, event: HTMLElement): void {
332340
if (!this.allowDragOutside) {
333341
const dragHelper: CalendarDragHelper = new CalendarDragHelper(weekViewContainer, event);
334-
this.validateDrag = ({x, y}) => !this.currentResize && dragHelper.validateDrag({x, y});
342+
this.validateDrag = ({x, y}) => this.currentResizes.size === 0 && dragHelper.validateDrag({x, y});
335343
this.cdr.markForCheck();
336344
}
337345
}

test/calendarWeekView.component.spec.ts

+57
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,63 @@ describe('calendarWeekView component', () => {
337337
});
338338
});
339339

340+
it('should allow 2 events next to each other to be resized at the same time', () => {
341+
const fixture: ComponentFixture<CalendarWeekViewComponent> = TestBed.createComponent(CalendarWeekViewComponent);
342+
fixture.componentInstance.viewDate = new Date('2016-06-27');
343+
fixture.componentInstance.events = [{
344+
title: 'event 1',
345+
color: {primary: '', secondary: ''},
346+
start: moment('2016-06-27').add(4, 'hours').toDate(),
347+
end: moment('2016-06-27').add(6, 'hours').toDate(),
348+
resizable: {
349+
beforeStart: true,
350+
afterEnd: true
351+
}
352+
}, {
353+
title: 'event 2',
354+
color: {primary: '', secondary: ''},
355+
start: moment('2016-06-28').add(4, 'hours').toDate(),
356+
end: moment('2016-06-29').add(6, 'hours').toDate(),
357+
resizable: {
358+
beforeStart: true,
359+
afterEnd: true
360+
}
361+
}];
362+
fixture.componentInstance.ngOnChanges({viewDate: {}, events: {}});
363+
fixture.detectChanges();
364+
document.body.appendChild(fixture.nativeElement);
365+
const event1: HTMLElement = fixture.nativeElement.querySelectorAll('.cal-event-container')[0];
366+
const event2: HTMLElement = fixture.nativeElement.querySelectorAll('.cal-event-container')[1];
367+
const dayWidth: number = event1.parentElement.offsetWidth / 7;
368+
const event1Rect: ClientRect = event1.getBoundingClientRect();
369+
const event2Rect: ClientRect = event2.getBoundingClientRect();
370+
const resizeEvents: CalendarEventTimesChangedEvent[] = [];
371+
fixture.componentInstance.eventTimesChanged.subscribe(event => {
372+
resizeEvents.push(event);
373+
});
374+
triggerDomEvent('mousedown', document.body, {clientX: event1Rect.right, clientY: event1Rect.top});
375+
fixture.detectChanges();
376+
triggerDomEvent('mousemove', document.body, {clientX: event1Rect.right + dayWidth, clientY: event1Rect.top});
377+
fixture.detectChanges();
378+
expect(Math.round(event1.getBoundingClientRect().left)).to.equal(Math.round(event1Rect.left));
379+
expect(Math.round(event1.getBoundingClientRect().width)).to.equal(Math.round(event1Rect.width + dayWidth));
380+
expect(Math.round(event2.getBoundingClientRect().left)).to.equal(Math.round(event2Rect.left + dayWidth));
381+
expect(Math.round(event2.getBoundingClientRect().width)).to.equal(Math.round(event2Rect.width - dayWidth));
382+
triggerDomEvent('mouseup', document.body, {clientX: event1Rect.right + dayWidth, clientY: event1Rect.top});
383+
fixture.detectChanges();
384+
fixture.destroy();
385+
expect(resizeEvents[0]).to.deep.equal({
386+
event: fixture.componentInstance.events[0],
387+
newStart: moment('2016-06-27').add(4, 'hours').toDate(),
388+
newEnd: moment('2016-06-27').add(6, 'hours').add(1, 'day').toDate()
389+
});
390+
expect(resizeEvents[1]).to.deep.equal({
391+
event: fixture.componentInstance.events[1],
392+
newStart: moment('2016-06-28').add(1, 'day').add(4, 'hours').toDate(),
393+
newEnd: moment('2016-06-29').add(6, 'hours').toDate(),
394+
});
395+
});
396+
340397
it('should allow the event to be dragged and dropped', () => {
341398
const fixture: ComponentFixture<CalendarWeekViewComponent> = TestBed.createComponent(CalendarWeekViewComponent);
342399
fixture.componentInstance.viewDate = new Date('2016-12-08');

0 commit comments

Comments
 (0)