Skip to content

Commit aa7edd9

Browse files
committed
feat(week-view): make the week view title work with no config with i18n
BREAKING CHANGE: the format of the week view title has changed from `Week d of yyyy` to `MMM d - MMM d, yyyy`. You can override this by using a custom date formatter. Closes #670
1 parent 4bfac45 commit aa7edd9

17 files changed

+230
-113
lines changed

demos/demo-modules/exclude-days/component.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {
33
ChangeDetectionStrategy,
44
ViewEncapsulation
55
} from '@angular/core';
6-
import { CalendarEvent } from 'angular-calendar';
6+
import { CalendarEvent, DAYS_OF_WEEK } from 'angular-calendar';
77
import { colors } from '../demo-utils/colors';
88

99
@Component({
@@ -22,15 +22,19 @@ export class DemoComponent {
2222
start: new Date('2016-01-08'),
2323
end: new Date('2016-01-10'),
2424
title: 'One day excluded event',
25-
color: colors.red
25+
color: colors.red,
26+
allDay: true
2627
},
2728
{
2829
start: new Date('2016-01-01'),
2930
end: new Date('2016-01-09'),
30-
title: 'Multiple weeks event'
31+
title: 'Multiple weeks event',
32+
allDay: true
3133
}
3234
];
3335

3436
// exclude weekends
3537
excludeDays: number[] = [0, 6];
38+
39+
weekStartsOn = DAYS_OF_WEEK.SUNDAY;
3640
}

demos/demo-modules/exclude-days/template.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
</div>
2727
</div>
2828
<div class="col-md-4">
29-
<h3>{{ viewDate | calendarDate:(view + 'ViewTitle'):'en' }}</h3>
29+
<h3>{{ viewDate | calendarDate:(view + 'ViewTitle'):'en':weekStartsOn:excludeDays }}</h3>
3030
</div>
3131
<div class="col-md-4">
3232
<div class="btn-group">

demos/demo-modules/i18n/component.ts

+2-13
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,10 @@
11
import { Component, ChangeDetectionStrategy } from '@angular/core';
2-
import {
3-
CalendarEvent,
4-
CalendarDateFormatter,
5-
DAYS_OF_WEEK
6-
} from 'angular-calendar';
7-
import { CustomDateFormatter } from './custom-date-formatter.provider';
2+
import { CalendarEvent, DAYS_OF_WEEK } from 'angular-calendar';
83

94
@Component({
105
selector: 'mwl-demo-component',
116
changeDetection: ChangeDetectionStrategy.OnPush,
12-
templateUrl: 'template.html',
13-
providers: [
14-
{
15-
provide: CalendarDateFormatter,
16-
useClass: CustomDateFormatter
17-
}
18-
]
7+
templateUrl: 'template.html'
198
})
209
export class DemoComponent {
2110
view: string = 'month';

demos/demo-modules/i18n/custom-date-formatter.provider.ts

-11
This file was deleted.

demos/demo-modules/i18n/sources.ts

-7
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,6 @@ export const sources = [
66
highlighted: require('!!raw-loader!highlightjs-loader?lang=typescript!./component')
77
}
88
},
9-
{
10-
filename: 'custom-date-formatter.provider.ts',
11-
contents: {
12-
raw: require('!!raw-loader!./custom-date-formatter.provider'),
13-
highlighted: require('!!raw-loader!highlightjs-loader?lang=typescript!./custom-date-formatter.provider')
14-
}
15-
},
169
{
1710
filename: 'template.html',
1811
contents: {

src/modules/common/calendar-angular-date-formatter.provider.ts

+24-7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
import { DatePipe } from '@angular/common';
66
import { Injectable } from '@angular/core';
77
import { DateAdapter } from '../../date-adapters/date-adapter';
8+
import { getWeekViewPeriod } from './util';
89

910
/**
1011
* This will use the angular date pipe to do all date formatting. It is the default date formatter used by the calendar.
@@ -55,15 +56,31 @@ export class CalendarAngularDateFormatter
5556
/**
5657
* The week view title
5758
*/
58-
public weekViewTitle({ date, locale }: DateFormatterParams): string {
59-
const year: string = new DatePipe(locale).transform(
59+
public weekViewTitle({
60+
date,
61+
locale,
62+
weekStartsOn,
63+
excludeDays,
64+
daysInWeek
65+
}: DateFormatterParams): string {
66+
const { viewStart, viewEnd } = getWeekViewPeriod(
67+
this.dateAdapter,
6068
date,
61-
'y',
62-
null,
63-
locale
69+
weekStartsOn,
70+
excludeDays,
71+
daysInWeek
6472
);
65-
const weekNumber: number = this.dateAdapter.getISOWeek(date);
66-
return `Week ${weekNumber} of ${year}`;
73+
const format = (dateToFormat: Date, showYear: boolean) =>
74+
new DatePipe(locale).transform(
75+
dateToFormat,
76+
'MMM d' + (showYear ? ', yyyy' : ''),
77+
null,
78+
locale
79+
);
80+
return `${format(
81+
viewStart,
82+
viewStart.getUTCFullYear() !== viewEnd.getUTCFullYear()
83+
)} - ${format(viewEnd, true)}`;
6784
}
6885

6986
/**

src/modules/common/calendar-date-formatter.interface.ts

+16
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,22 @@ export interface DateFormatterParams {
1111
* The users preferred locale.
1212
*/
1313
locale?: string;
14+
15+
/**
16+
* The start day number of the week
17+
*/
18+
weekStartsOn?: number;
19+
20+
/**
21+
* An array of day indexes (0 = sunday, 1 = monday etc) that will be hidden on the view
22+
*/
23+
excludeDays?: number[];
24+
25+
/**
26+
* The number of days in a week. Can be used to create a shorter or longer week view.
27+
* The first day of the week will always be the `viewDate`
28+
*/
29+
daysInWeek?: number;
1430
}
1531

1632
/**

src/modules/common/calendar-date.pipe.ts

+15-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,20 @@ export class CalendarDatePipe implements PipeTransform {
1717
@Inject(LOCALE_ID) private locale: string
1818
) {}
1919

20-
transform(date: Date, method: string, locale: string = this.locale): string {
21-
return this.dateFormatter[method]({ date, locale });
20+
transform(
21+
date: Date,
22+
method: string,
23+
locale: string = this.locale,
24+
weekStartsOn: number = 0,
25+
excludeDays: number[] = [],
26+
daysInWeek?: number
27+
): string {
28+
return this.dateFormatter[method]({
29+
date,
30+
locale,
31+
weekStartsOn,
32+
excludeDays,
33+
daysInWeek
34+
});
2235
}
2336
}

src/modules/common/calendar-moment-date-formatter.provider.ts

+28-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import {
33
CalendarDateFormatterInterface,
44
DateFormatterParams
55
} from './calendar-date-formatter.interface';
6+
import { getWeekViewPeriod } from './util';
7+
import { DateAdapter } from '../../date-adapters/date-adapter';
68

79
export const MOMENT: InjectionToken<string> = new InjectionToken('Moment');
810

@@ -27,7 +29,10 @@ export class CalendarMomentDateFormatter
2729
/**
2830
* @hidden
2931
*/
30-
constructor(@Inject(MOMENT) private moment: any) {}
32+
constructor(
33+
@Inject(MOMENT) private moment: any,
34+
private dateAdapter: DateAdapter
35+
) {}
3136

3237
/**
3338
* The month view header week day labels
@@ -80,10 +85,28 @@ export class CalendarMomentDateFormatter
8085
/**
8186
* The week view title
8287
*/
83-
public weekViewTitle({ date, locale }: DateFormatterParams): string {
84-
return this.moment(date)
85-
.locale(locale)
86-
.format('[Week] W [of] YYYY');
88+
public weekViewTitle({
89+
date,
90+
locale,
91+
weekStartsOn,
92+
excludeDays,
93+
daysInWeek
94+
}: DateFormatterParams): string {
95+
const { viewStart, viewEnd } = getWeekViewPeriod(
96+
this.dateAdapter,
97+
date,
98+
weekStartsOn,
99+
excludeDays,
100+
daysInWeek
101+
);
102+
const format = (dateToFormat: Date, showYear: boolean) =>
103+
this.moment(dateToFormat)
104+
.locale(locale)
105+
.format('MMM D' + (showYear ? ', YYYY' : ''));
106+
return `${format(
107+
viewStart,
108+
viewStart.getUTCFullYear() !== viewEnd.getUTCFullYear()
109+
)} - ${format(viewEnd, true)}`;
87110
}
88111

89112
/**

src/modules/common/calendar-native-date-formatter.provider.ts

+28-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import {
44
} from './calendar-date-formatter.interface';
55
import { Injectable } from '@angular/core';
66
import { DateAdapter } from '../../date-adapters/date-adapter';
7+
import { getWeekViewPeriod } from './util';
8+
import show = Mocha.reporters.Base.cursor.show;
79

810
/**
911
* This will use <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Intl" target="_blank">Intl</a> API to do all date formatting.
@@ -62,12 +64,32 @@ export class CalendarNativeDateFormatter
6264
/**
6365
* The week view title
6466
*/
65-
public weekViewTitle({ date, locale }: DateFormatterParams): string {
66-
const year: string = new Intl.DateTimeFormat(locale, {
67-
year: 'numeric'
68-
}).format(date);
69-
const weekNumber: number = this.dateAdapter.getISOWeek(date);
70-
return `Week ${weekNumber} of ${year}`;
67+
public weekViewTitle({
68+
date,
69+
locale,
70+
weekStartsOn,
71+
excludeDays,
72+
daysInWeek
73+
}: DateFormatterParams): string {
74+
const { viewStart, viewEnd } = getWeekViewPeriod(
75+
this.dateAdapter,
76+
date,
77+
weekStartsOn,
78+
excludeDays,
79+
daysInWeek
80+
);
81+
82+
const format = (dateToFormat: Date, showYear: boolean) =>
83+
new Intl.DateTimeFormat(locale, {
84+
day: 'numeric',
85+
month: 'short',
86+
year: showYear ? 'numeric' : undefined
87+
}).format(dateToFormat);
88+
89+
return `${format(
90+
viewStart,
91+
viewStart.getUTCFullYear() !== viewEnd.getUTCFullYear()
92+
)} - ${format(viewEnd, true)}`;
7193
}
7294

7395
/**

src/modules/common/util.ts

+33
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,36 @@ export function shouldFireDroppedEvent(
136136
(!dropEvent.dropData.event.allDay && allDay))
137137
);
138138
}
139+
140+
export function getWeekViewPeriod(
141+
dateAdapter: DateAdapter,
142+
viewDate: Date,
143+
weekStartsOn: number,
144+
excluded: number[] = [],
145+
daysInWeek?: number
146+
): { viewStart: Date; viewEnd: Date } {
147+
let viewStart = daysInWeek
148+
? dateAdapter.startOfDay(viewDate)
149+
: dateAdapter.startOfWeek(viewDate, { weekStartsOn });
150+
if (excluded.indexOf(dateAdapter.getDay(viewStart)) > -1) {
151+
viewStart = dateAdapter.subDays(
152+
addDaysWithExclusions(dateAdapter, viewStart, 1, excluded),
153+
1
154+
);
155+
}
156+
if (daysInWeek) {
157+
const viewEnd = dateAdapter.endOfDay(
158+
addDaysWithExclusions(dateAdapter, viewStart, daysInWeek - 1, excluded)
159+
);
160+
return { viewStart, viewEnd };
161+
} else {
162+
let viewEnd = dateAdapter.endOfWeek(viewDate, { weekStartsOn });
163+
if (excluded.indexOf(dateAdapter.getDay(viewEnd)) > -1) {
164+
viewEnd = dateAdapter.addDays(
165+
addDaysWithExclusions(dateAdapter, viewEnd, -1, excluded),
166+
1
167+
);
168+
}
169+
return { viewStart, viewEnd };
170+
}
171+
}

0 commit comments

Comments
 (0)