Skip to content

Commit c9a2366

Browse files
author
Matt Lewis
committed
feat(monthView): introduce the beforeViewRender output
BREAKING CHANGE: the `dayModifier` input has been replaced with a more powerful `beforeViewRender` output
1 parent 0ed83dd commit c9a2366

File tree

17 files changed

+77
-74
lines changed

17 files changed

+77
-74
lines changed

demos/demo-app.module.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import * as clickableDays from './demo-modules/clickable-days';
2626
import * as dayViewStartEnd from './demo-modules/day-view-start-end';
2727
import * as dayViewHourSplit from './demo-modules/day-view-hour-split';
2828
import * as navigatingBetweenViews from './demo-modules/navigating-between-views';
29-
import * as dayModifier from './demo-modules/day-modifier';
29+
import * as beforeViewRender from './demo-modules/before-view-render';
3030
import * as i18n from './demo-modules/i18n';
3131
import * as draggableExternalEvents from './demo-modules/draggable-external-events';
3232
import * as allDayEvents from './demo-modules/all-day-events';
@@ -66,7 +66,7 @@ import * as extraMonthViewWeeks from './demo-modules/extra-month-view-weeks';
6666
dayViewStartEnd.DemoModule,
6767
dayViewHourSplit.DemoModule,
6868
navigatingBetweenViews.DemoModule,
69-
dayModifier.DemoModule,
69+
beforeViewRender.DemoModule,
7070
i18n.DemoModule,
7171
draggableExternalEvents.DemoModule,
7272
allDayEvents.DemoModule,
@@ -169,9 +169,9 @@ import * as extraMonthViewWeeks from './demo-modules/extra-month-view-weeks';
169169
}
170170
}, {
171171
path: 'day-modifier',
172-
component: dayModifier.DemoComponent,
172+
component: beforeViewRender.DemoComponent,
173173
data: {
174-
label: 'Day modifier'
174+
label: 'Before view render'
175175
}
176176
}, {
177177
path: 'exclude-days',

demos/demo-modules/day-modifier/component.ts demos/demo-modules/before-view-render/component.ts

+3-6
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,12 @@ export class DemoComponent {
2020

2121
events: CalendarEvent[] = [];
2222

23-
addCssClass: (day: CalendarMonthViewDay) => void;
24-
25-
constructor() {
26-
// an arrow function is used so that `this` is the component instance
27-
this.addCssClass = (day: CalendarMonthViewDay): void => {
23+
beforeMonthViewRender({body}: {body: CalendarMonthViewDay[]}): void {
24+
body.forEach((day) => {
2825
if (day.date.getDate() % 2 === 1 && day.inMonth) {
2926
day.cssClass = 'odd-cell';
3027
}
31-
};
28+
});
3229
}
3330

3431
}

demos/demo-modules/day-modifier/template.html demos/demo-modules/before-view-render/template.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*ngSwitchCase="'month'"
99
[viewDate]="viewDate"
1010
[events]="events"
11-
[dayModifier]="addCssClass">
11+
(beforeViewRender)="beforeMonthViewRender($event)">
1212
</mwl-calendar-month-view>
1313
<mwl-calendar-week-view
1414
*ngSwitchCase="'week'"

demos/demo-modules/group-month-view-events/component.ts

+8-6
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,15 @@ export class DemoComponent {
5959
}
6060
}];
6161

62-
groupEvents(cell: CalendarMonthViewDay): void {
63-
const groups: any = {};
64-
cell.events.forEach((event: CalendarEvent<{type: string}>) => {
65-
groups[event.meta.type] = groups[event.meta.type] || [];
66-
groups[event.meta.type].push(event);
62+
beforeMonthViewRender({body}: {body: CalendarMonthViewDay[]}): void {
63+
body.forEach((cell) => {
64+
const groups: any = {};
65+
cell.events.forEach((event: CalendarEvent<{type: string}>) => {
66+
groups[event.meta.type] = groups[event.meta.type] || [];
67+
groups[event.meta.type].push(event);
68+
});
69+
cell['eventGroups'] = Object.entries(groups);
6770
});
68-
cell['eventGroups'] = Object.entries(groups);
6971
}
7072

7173
}

demos/demo-modules/group-month-view-events/template.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
[viewDate]="viewDate"
2424
[events]="events"
2525
[cellTemplate]="customCellTemplate"
26-
[dayModifier]="groupEvents"
26+
(beforeViewRender)="beforeMonthViewRender($event)"
2727
[activeDayIsOpen]="true">
2828
</mwl-calendar-month-view>
2929
<mwl-calendar-week-view

demos/demo-modules/min-max-date/component.ts

+8-7
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,11 @@ export class DemoComponent {
6969

7070
maxDate: Date = addMonths(new Date(), 1);
7171

72-
dayModifier: Function;
73-
7472
prevBtnDisabled: boolean = false;
7573

7674
nextBtnDisabled: boolean = false;
7775

7876
constructor() {
79-
this.dayModifier = function(day: CalendarMonthViewDay): void {
80-
if (!this.dateIsValid(day.date)) {
81-
day.cssClass = 'cal-disabled';
82-
}
83-
}.bind(this);
8477
this.dateOrViewChanged();
8578
}
8679

@@ -120,5 +113,13 @@ export class DemoComponent {
120113
}
121114
}
122115

116+
beforeMonthViewRender({body}: {body: CalendarMonthViewDay[]}): void {
117+
body.forEach((day) => {
118+
if (!this.dateIsValid(day.date)) {
119+
day.cssClass = 'cal-disabled';
120+
}
121+
});
122+
}
123+
123124
}
124125

demos/demo-modules/min-max-date/template.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ <h3>{{ viewDate | calendarDate:(view + 'ViewTitle'):'en' }}</h3>
3030
*ngSwitchCase="'month'"
3131
[viewDate]="viewDate"
3232
[events]="events"
33-
[dayModifier]="dayModifier">
33+
(beforeViewRender)="beforeMonthViewRender($event)">
3434
</mwl-calendar-month-view>
3535
<mwl-calendar-week-view
3636
*ngSwitchCase="'week'"

demos/demo-modules/month-view-badge-total/component.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@ export class DemoComponent {
2727
}
2828
}];
2929

30-
addBadgeTotal(day: CalendarMonthViewDay): void {
31-
day.badgeTotal = day.events.filter(event => event.meta.incrementsBadgeTotal).length;
30+
beforeMonthViewRender({body}: {body: CalendarMonthViewDay[]}): void {
31+
body.forEach((day) => {
32+
day.badgeTotal = day.events.filter(event => event.meta.incrementsBadgeTotal).length;
33+
});
3234
}
3335

3436
}

demos/demo-modules/month-view-badge-total/template.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
[viewDate]="viewDate"
33
[events]="events"
44
[activeDayIsOpen]="true"
5-
[dayModifier]="addBadgeTotal">
5+
(beforeViewRender)="beforeMonthViewRender($event)">
66
</mwl-calendar-month-view>

demos/demo-modules/refreshing-the-view/component.ts

+8-10
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,20 @@ export class DemoComponent {
2929

3030
refresh: Subject<any> = new Subject();
3131

32-
addCssClass: (day: CalendarMonthViewDay) => void;
33-
3432
cssClass: string = RED_CELL;
3533

36-
constructor() {
37-
this.addCssClass = (day: CalendarMonthViewDay): void => {
38-
if (day.date.getDate() % 2 === 1) {
39-
day.cssClass = this.cssClass;
40-
}
41-
};
42-
}
43-
4434
refreshView(): void {
4535
this.cssClass = this.cssClass === RED_CELL ? BLUE_CELL : RED_CELL;
4636
this.refresh.next();
4737
}
4838

39+
beforeMonthViewRender({body}: {body: CalendarMonthViewDay[]}): void {
40+
body.forEach((day) => {
41+
if (day.date.getDate() % 2 === 1) {
42+
day.cssClass = this.cssClass;
43+
}
44+
});
45+
}
46+
4947
}
5048

demos/demo-modules/refreshing-the-view/template.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
[viewDate]="viewDate"
1414
[events]="events"
1515
[refresh]="refresh"
16-
[dayModifier]="addCssClass">
16+
(beforeViewRender)="beforeMonthViewRender($event)">
1717
</mwl-calendar-month-view>
1818
<mwl-calendar-week-view
1919
*ngSwitchCase="'week'"

demos/demo-modules/selectable-month-day/component.ts

+9-11
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,6 @@ export class DemoComponent {
2222

2323
events: CalendarEvent[] = [];
2424

25-
selectDay: (day: CalendarMonthViewDay) => void;
26-
27-
constructor() {
28-
// an arrow function is used so that `this` is the component instance
29-
this.selectDay = (day: CalendarMonthViewDay): void => {
30-
if (this.selectedDay && day.date.getTime() === this.selectedDay.date.getTime()) {
31-
day.cssClass = 'cal-day-selected';
32-
}
33-
};
34-
}
35-
3625
dayClicked(day: CalendarMonthViewDay): void {
3726
if (this.selectedDay) {
3827
delete this.selectedDay.cssClass;
@@ -41,4 +30,13 @@ export class DemoComponent {
4130
this.selectedDay = day;
4231
}
4332

33+
beforeMonthViewRender({body}: {body: CalendarMonthViewDay[]}): void {
34+
body.forEach((day) => {
35+
if (this.selectedDay && day.date.getTime() === this.selectedDay.date.getTime()) {
36+
day.cssClass = 'cal-day-selected';
37+
this.selectedDay = day;
38+
}
39+
});
40+
}
41+
4442
}

demos/demo-modules/selectable-month-day/template.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@ <h3>{{ viewDate | calendarDate:'monthViewTitle':'en' }}</h3>
3232
<mwl-calendar-month-view
3333
[viewDate]="viewDate"
3434
[events]="events"
35-
[dayModifier]="selectDay"
35+
(beforeViewRender)="beforeMonthViewRender($event)"
3636
(dayClicked)="dayClicked($event.day)">
3737
</mwl-calendar-month-view>

src/components/month/calendarMonthView.component.ts

+17-9
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,6 @@ export class CalendarMonthViewComponent implements OnChanges, OnInit, OnDestroy
107107
*/
108108
@Input() activeDayIsOpen: boolean = false;
109109

110-
/**
111-
* A function that will be called before each cell is rendered. The first argument will contain the calendar cell.
112-
* If you add the `cssClass` property to the cell it will add that class to the cell in the template
113-
*/
114-
@Input() dayModifier: Function;
115-
116110
/**
117111
* An observable that when emitted on will re-render the current view
118112
*/
@@ -158,6 +152,12 @@ export class CalendarMonthViewComponent implements OnChanges, OnInit, OnDestroy
158152
*/
159153
@Input() weekendDays: number[];
160154

155+
/**
156+
* An output that will be called before the view is rendered for the current month.
157+
* If you add the `cssClass` property to a day in the body it will add that class to the cell element in the template
158+
*/
159+
@Output() beforeViewRender: EventEmitter<{header: WeekDay[], body: MonthViewDay[]}> = new EventEmitter();
160+
161161
/**
162162
* Called when the day cell is clicked
163163
*/
@@ -280,6 +280,7 @@ export class CalendarMonthViewComponent implements OnChanges, OnInit, OnDestroy
280280
excluded: this.excludeDays,
281281
weekendDays: this.weekendDays
282282
});
283+
this.emitBeforeViewRender();
283284
}
284285

285286
private refreshBody(): void {
@@ -290,9 +291,7 @@ export class CalendarMonthViewComponent implements OnChanges, OnInit, OnDestroy
290291
excluded: this.excludeDays,
291292
weekendDays: this.weekendDays
292293
});
293-
if (this.dayModifier) {
294-
this.view.days.forEach(day => this.dayModifier(day));
295-
}
294+
this.emitBeforeViewRender();
296295
}
297296

298297
private checkActiveDayIsOpen(): void {
@@ -312,4 +311,13 @@ export class CalendarMonthViewComponent implements OnChanges, OnInit, OnDestroy
312311
this.checkActiveDayIsOpen();
313312
}
314313

314+
private emitBeforeViewRender(): void {
315+
if (this.columnHeaders && this.view) {
316+
this.beforeViewRender.emit({
317+
header: this.columnHeaders,
318+
body: this.view.days
319+
});
320+
}
321+
}
322+
315323
}

test/calendarMonthView.component.spec.ts

+10-13
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,9 @@ describe('calendarMonthView component', () => {
122122
it('should add a custom CSS class to days via the day modifier', () => {
123123
const fixture: ComponentFixture<CalendarMonthViewComponent> = TestBed.createComponent(CalendarMonthViewComponent);
124124
fixture.componentInstance.viewDate = new Date('2016-06-27');
125-
fixture.componentInstance.dayModifier = day => {
126-
day.cssClass = 'foo';
127-
};
125+
fixture.componentInstance.beforeViewRender.take(1).subscribe(({body}) => {
126+
body[0].cssClass = 'foo';
127+
});
128128
fixture.componentInstance.ngOnChanges({viewDate: {}, events: {}});
129129
fixture.detectChanges();
130130
expect(fixture.nativeElement.querySelector('.cal-days .cal-cell').classList.contains('foo')).to.equal(true);
@@ -135,12 +135,10 @@ describe('calendarMonthView component', () => {
135135
const fixture: ComponentFixture<CalendarMonthViewComponent> = TestBed.createComponent(CalendarMonthViewComponent);
136136
fixture.componentInstance.viewDate = new Date('2016-06-27');
137137
let firstDay: CalendarMonthViewDay;
138-
fixture.componentInstance.dayModifier = (day) => {
139-
if (!firstDay) {
140-
firstDay = day;
141-
day.cssClass = 'foo';
142-
}
143-
};
138+
fixture.componentInstance.beforeViewRender.take(1).subscribe(({body}) => {
139+
body[0].cssClass = 'foo';
140+
firstDay = body[0];
141+
});
144142
fixture.componentInstance.ngOnChanges({viewDate: {}, events: {}});
145143
fixture.detectChanges();
146144
const cell: HTMLElement = fixture.nativeElement.querySelector('.cal-days .cal-cell');
@@ -288,10 +286,9 @@ describe('calendarMonthView component', () => {
288286
it('should allow the badge total to be customised', () => {
289287
const fixture: ComponentFixture<CalendarMonthViewComponent> = TestBed.createComponent(CalendarMonthViewComponent);
290288
fixture.componentInstance.viewDate = new Date('2016-06-27');
291-
fixture.componentInstance.dayModifier = day => {
292-
day.badgeTotal = 100;
293-
return day;
294-
};
289+
fixture.componentInstance.beforeViewRender.take(1).subscribe(({body}) => {
290+
body[0].badgeTotal = 100;
291+
});
295292
fixture.componentInstance.ngOnChanges({viewDate: {}, events: {}});
296293
fixture.detectChanges();
297294
expect(fixture.nativeElement.querySelector('.cal-day-badge').innerHTML).to.equal('100');

0 commit comments

Comments
 (0)