import {NgModule,Component,ElementRef,OnDestroy,DoCheck,OnChanges,Input,Output,EventEmitter,IterableDiffers,OnInit,AfterViewChecked,SimpleChanges} from '@angular/core';
import {CommonModule} from '@angular/common';
declare var jQuery: any;
@Component({
selector: 'p-schedule',
template: '
'
})
export class Schedule implements DoCheck,OnDestroy,OnInit,OnChanges,AfterViewChecked {
@Input() events: any[];
@Input() header: any;
@Input() style: any;
@Input() styleClass: string;
@Input() rtl: boolean;
@Input() weekends: boolean;
@Input() hiddenDays: number[];
@Input() fixedWeekCount: boolean;
@Input() weekNumbers: boolean;
@Input() businessHours: any;
@Input() height: any;
@Input() contentHeight: any;
@Input() aspectRatio: number = 1.35;
@Input() eventLimit: any;
@Input() defaultDate: any;
@Input() editable: boolean;
@Input() droppable: boolean;
@Input() eventStartEditable: boolean;
@Input() eventDurationEditable: boolean;
@Input() defaultView: string = 'month';
@Input() allDaySlot: boolean = true;
@Input() allDayText: string = 'all-day';
@Input() slotDuration: any = '00:30:00';
@Input() slotLabelInterval: any;
@Input() snapDuration: any;
@Input() scrollTime: any = '06:00:00';
@Input() minTime: any = '00:00:00';
@Input() maxTime: any = '24:00:00';
@Input() slotEventOverlap: boolean = true;
@Input() nowIndicator: boolean;
@Input() dragRevertDuration: number = 500;
@Input() dragOpacity: number = .75;
@Input() dragScroll: boolean = true;
@Input() eventOverlap: any;
@Input() eventConstraint: any;
@Input() locale: string;
@Input() timezone: boolean | string = false;
@Input() timeFormat:string | null = null;
@Input() eventRender: Function;
@Input() dayRender: Function;
@Input() navLinks: boolean;
@Input() options: any;
@Output() onDayClick: EventEmitter = new EventEmitter();
@Output() onDrop: EventEmitter = new EventEmitter();
@Output() onEventClick: EventEmitter = new EventEmitter();
@Output() onEventMouseover: EventEmitter = new EventEmitter();
@Output() onEventMouseout: EventEmitter = new EventEmitter();
@Output() onEventDragStart: EventEmitter = new EventEmitter();
@Output() onEventDragStop: EventEmitter = new EventEmitter();
@Output() onEventDrop: EventEmitter = new EventEmitter();
@Output() onEventResizeStart: EventEmitter = new EventEmitter();
@Output() onEventResizeStop: EventEmitter = new EventEmitter();
@Output() onEventResize: EventEmitter = new EventEmitter();
@Output() onViewRender: EventEmitter = new EventEmitter();
@Output() onViewDestroy: EventEmitter = new EventEmitter();
@Output() onNavLinkDayClick: EventEmitter = new EventEmitter();
@Output() onNavLinkWeekClick: EventEmitter = new EventEmitter();
initialized: boolean;
stopNgOnChangesPropagation: boolean;
differ: any;
schedule: any;
config: any;
constructor(public el: ElementRef, differs: IterableDiffers) {
this.differ = differs.find([]).create(null);
this.initialized = false;
}
ngOnInit() {
this.config = {
theme: true,
header: this.header,
isRTL: this.rtl,
weekends: this.weekends,
hiddenDays: this.hiddenDays,
fixedWeekCount: this.fixedWeekCount,
weekNumbers: this.weekNumbers,
businessHours: this.businessHours,
height: this.height,
contentHeight: this.contentHeight,
aspectRatio: this.aspectRatio,
eventLimit: this.eventLimit,
defaultDate: this.defaultDate,
locale: this.locale,
timezone: this.timezone,
timeFormat: this.timeFormat,
editable: this.editable,
droppable: this.droppable,
eventStartEditable: this.eventStartEditable,
eventDurationEditable: this.eventDurationEditable,
defaultView: this.defaultView,
allDaySlot: this.allDaySlot,
allDayText: this.allDayText,
slotDuration: this.slotDuration,
slotLabelInterval: this.slotLabelInterval,
snapDuration: this.snapDuration,
scrollTime: this.scrollTime,
minTime: this.minTime,
maxTime: this.maxTime,
slotEventOverlap: this.slotEventOverlap,
nowIndicator: this.nowIndicator,
dragRevertDuration: this.dragRevertDuration,
dragOpacity: this.dragOpacity,
dragScroll: this.dragScroll,
eventOverlap: this.eventOverlap,
eventConstraint: this.eventConstraint,
eventRender: this.eventRender,
dayRender: this.dayRender,
navLinks: this.navLinks,
dayClick: (date, jsEvent, view) => {
this.onDayClick.emit({
'date': date,
'jsEvent': jsEvent,
'view': view
});
},
drop: (date, jsEvent, ui, resourceId) => {
this.onDrop.emit({
'date': date,
'jsEvent': jsEvent,
'ui': ui,
'resourceId': resourceId
});
},
eventClick: (calEvent, jsEvent, view) => {
this.onEventClick.emit({
'calEvent': calEvent,
'jsEvent': jsEvent,
'view': view
});
},
eventMouseover: (calEvent, jsEvent, view) => {
this.onEventMouseover.emit({
'calEvent': calEvent,
'jsEvent': jsEvent,
'view': view
});
},
eventMouseout: (calEvent, jsEvent, view) => {
this.onEventMouseout.emit({
'calEvent': calEvent,
'jsEvent': jsEvent,
'view': view
});
},
eventDragStart: (event, jsEvent, ui, view) => {
this.onEventDragStart.emit({
'event': event,
'jsEvent': jsEvent,
'view': view
});
},
eventDragStop: (event, jsEvent, ui, view) => {
this.onEventDragStop.emit({
'event': event,
'jsEvent': jsEvent,
'view': view
});
},
eventDrop: (event, delta, revertFunc, jsEvent, ui, view) => {
this._updateEvent(event);
this.onEventDrop.emit({
'event': event,
'delta': delta,
'revertFunc': revertFunc,
'jsEvent': jsEvent,
'view': view
});
},
eventResizeStart: (event, jsEvent, ui, view) => {
this.onEventResizeStart.emit({
'event': event,
'jsEvent': jsEvent,
'view': view
});
},
eventResizeStop: (event, jsEvent, ui, view) => {
this.onEventResizeStop.emit({
'event': event,
'jsEvent': jsEvent,
'view': view
});
},
eventResize: (event, delta, revertFunc, jsEvent, ui, view) => {
this._updateEvent(event);
this.onEventResize.emit({
'event': event,
'delta': delta,
'revertFunc': revertFunc,
'jsEvent': jsEvent,
'view': view
});
},
viewRender: (view, element) => {
this.onViewRender.emit({
'view': view,
'element': element
});
},
viewDestroy: (view, element) => {
this.onViewDestroy.emit({
'view': view,
'element': element
});
},
navLinkDayClick: (weekStart, jsEvent) => {
this.onNavLinkDayClick.emit({
'weekStart': weekStart,
'event': jsEvent
});
},
navLinkWeekClick: (weekStart, jsEvent) => {
this.onNavLinkWeekClick.emit({
'weekStart': weekStart,
'event': jsEvent
});
}
};
if(this.options) {
for(let prop in this.options) {
this.config[prop] = this.options[prop];
}
}
}
ngAfterViewChecked() {
if(!this.initialized && this.el.nativeElement.offsetParent) {
this.initialize();
}
}
ngOnChanges(changes: SimpleChanges) {
if(this.schedule) {
let options = {};
for(let change in changes) {
if(change !== 'events') {
options[change] = changes[change].currentValue;
}
}
if(Object.keys(options).length) {
this.schedule.fullCalendar('option', options);
}
}
}
initialize() {
this.schedule = jQuery(this.el.nativeElement.children[0]);
this.schedule.fullCalendar(this.config);
if(this.events) {
this.schedule.fullCalendar('addEventSource', this.events);
}
this.initialized = true;
}
ngDoCheck() {
let changes = this.differ.diff(this.events);
if(this.schedule && changes) {
this.schedule.fullCalendar('removeEventSources');
if(this.events) {
this.schedule.fullCalendar('addEventSource', this.events);
}
}
}
ngOnDestroy() {
jQuery(this.el.nativeElement.children[0]).fullCalendar('destroy');
this.initialized = false;
this.schedule = null;
}
gotoDate(date: any) {
this.schedule.fullCalendar('gotoDate', date);
}
prev() {
this.schedule.fullCalendar('prev');
}
next() {
this.schedule.fullCalendar('next');
}
prevYear() {
this.schedule.fullCalendar('prevYear');
}
nextYear() {
this.schedule.fullCalendar('nextYear');
}
today() {
this.schedule.fullCalendar('today');
}
incrementDate(duration: any) {
this.schedule.fullCalendar('incrementDate', duration);
}
changeView(viewName: string) {
this.schedule.fullCalendar('changeView', viewName);
}
getDate() {
return this.schedule.fullCalendar('getDate');
}
updateEvent(event: any) {
this.schedule.fullCalendar('updateEvent', event);
}
_findEvent(id: string) {
let event;
if(this.events) {
for(let e of this.events) {
if(e.id === id) {
event = e;
break;
}
}
}
return event;
}
_updateEvent(event: any) {
let sourceEvent = this._findEvent(event.id);
if(sourceEvent) {
sourceEvent.start = event.start.format();
if(event.end) {
sourceEvent.end = event.end.format();
}
}
}
}
@NgModule({
imports: [CommonModule],
exports: [Schedule],
declarations: [Schedule]
})
export class ScheduleModule { }