After extensively using the Angular Calendar library, I encountered an issue that I believe might be a bug. However, it could also be an intended feature, and I couldn't find a definitive answer in the available examples or documentation.
To investigate further, I created an isolated project using the Angular Calendar library to reproduce the issue I faced in my main project.
Please let me know if this is indeed a bug or expected behavior, and if there’s a workaround. Thank you for your time and assistance!
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ViewEncapsulation } from '@angular/core';
import {
CalendarEvent,
CalendarEventTimesChangedEvent,
CalendarModule,
CalendarView,
CalendarWeekViewBeforeRenderEvent,
} from 'angular-calendar';
import { addHours, isBefore, isSameDay, setDay, setHours, setMinutes, startOfDay, subSeconds } from 'date-fns';
import { Subject } from 'rxjs';
export const colors: any = {
red: {
primary: '#ad2121',
secondary: '#FAE3E3',
},
blue: {
primary: '#1e90ff',
secondary: '#D1E8FF',
},
yellow: {
primary: '#e3bc08',
secondary: '#FDF1BA',
},
};
@Component({
selector: 'app-preview',
templateUrl: './preview.component.html',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
styles: [
`
.invalid-position .cal-event {
background-color: #ad2121 !important;
color: #fff;
}
.cal-disabled {
background-color: #eee;
pointer-events: none;
}
`,
],
imports: [CalendarModule],
})
export class PreviewComponent {
dayStartHour = 9;
dayEndHour = 16;
todayDate = new Date();
view: CalendarView = CalendarView.Week;
viewDate = new Date();
events: CalendarEvent[] = [
{
start: addHours(startOfDay(setDay(new Date(), 3)), 2),
end: subSeconds(addHours(startOfDay(setDay(new Date(), 3)), 3), 1),
title: 'An short event',
color: colors.yellow,
resizable: {
beforeStart: true,
afterEnd: true,
},
draggable: true,
},
{
start: addHours(startOfDay(setDay(new Date(), 3)), 5),
end: subSeconds(addHours(startOfDay(setDay(new Date(), 3)), 10), 1),
title: 'A draggable and resizable event',
color: colors.yellow,
resizable: {
beforeStart: true,
afterEnd: true,
},
draggable: true,
},
];
refresh = new Subject<void>();
constructor(private cdr: ChangeDetectorRef) {}
ngOnInit() {
var event: CalendarEvent = {
start: setHours(setMinutes(new Date(), 20), 16),
end: setHours(setMinutes(new Date(), 40), 18),
cssClass: 'invalid-position',
title: 'After limit and red event',
resizable: {
beforeStart: false,
afterEnd: false,
},
draggable: false,
};
/**just for testing */
setTimeout(() => {
this.events = [...this.events, event];
this.cdr.detectChanges();
}, 5000);
}
validateEventTimesChanged = (
{ event, newStart, newEnd, allDay }: CalendarEventTimesChangedEvent,
addCssClass = true
) => {
if (event.allDay) {
return true;
}
if (newEnd == undefined) {
newEnd = setHours(newStart, 1);
}
delete event.cssClass;
// don't allow dragging or resizing events to different days
const sameDay = isSameDay(newStart, newEnd);
if (!sameDay) {
return false;
}
// don't allow dragging events to the same times as other events
const overlappingEvent = this.events.find((otherEvent) => {
return (
otherEvent !== event &&
!otherEvent.allDay &&
((otherEvent.start < newStart && newStart < (otherEvent.end ?? new Date())) ||
(otherEvent.start < newEnd && newStart < (otherEvent.end ?? new Date())))
);
});
if (overlappingEvent) {
if (addCssClass) {
event.cssClass = 'invalid-position';
} else {
return false;
}
}
return true;
};
eventTimesChanged(eventTimesChangedEvent: CalendarEventTimesChangedEvent): void {
delete eventTimesChangedEvent.event.cssClass;
if (this.validateEventTimesChanged(eventTimesChangedEvent, false)) {
const { event, newStart, newEnd } = eventTimesChangedEvent;
event.start = newStart;
event.end = newEnd;
this.refresh.next();
}
}
beforeWeekViewRender(renderEvent: CalendarWeekViewBeforeRenderEvent) {
renderEvent.hourColumns.forEach((hourColumn) => {
const date = addHours(this.todayDate, 48);
hourColumn.hours.forEach((hour) => {
hour.segments.forEach((segment) => {
delete segment.cssClass;
debugger;
if (isBefore(segment.date, date)) {
segment.cssClass = 'cal-disabled';
}
});
});
});
}
}
<mwl-calendar-week-view
[viewDate]="viewDate"
[events]="events"
[refresh]="refresh"
[dayStartHour]="dayStartHour"
[dayEndHour]="dayEndHour"
(beforeViewRender)="beforeWeekViewRender($event)"
[validateEventTimesChanged]="validateEventTimesChanged"
(eventTimesChanged)="eventTimesChanged($event)"
>
</mwl-calendar-week-view>
"dependencies": {
"@angular/animations": "^18.2.0",
"@angular/common": "^18.2.0",
"@angular/compiler": "^18.2.0",
"@angular/core": "^18.2.0",
"@angular/forms": "^18.2.0",
"@angular/platform-browser": "^18.2.0",
"@angular/platform-browser-dynamic": "^18.2.0",
"@angular/router": "^18.2.0",
"angular-calendar": "^0.31.1",
"date-fns": "^4.1.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.10"
},
Hello mattlewis92,
Frist of all thank you for the angular-calendar library which is awesome work that you have done!
Describe the bug
After extensively using the Angular Calendar library, I encountered an issue that I believe might be a bug. However, it could also be an intended feature, and I couldn't find a definitive answer in the available examples or documentation.
To investigate further, I created an isolated project using the Angular Calendar library to reproduce the issue I faced in my main project.
Background:
Issue:
When a user resizes an event to the end limit of the day, the
mwlResizeHandledisappears. This behavior makes it impossible to resize the event back to a shorter duration (e.g., reducing from 6 hours to 4 hours) by dragging from bottom to top, as the resize handle is no longer visible.Supporting Information:
Please let me know if this is indeed a bug or expected behavior, and if there’s a workaround. Thank you for your time and assistance!
Minimal reproduction of the problem with instructions
ts file
HTML file
Screenshots
Versions
Chrome 131.0.6778.86 (Official Build) (64-bit)