Skip to content

Commit

Permalink
feat(week-view): make the week view title work with no config with i18n
Browse files Browse the repository at this point in the history
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
  • Loading branch information
mattlewis92 committed Aug 6, 2018
1 parent 4bfac45 commit aa7edd9
Show file tree
Hide file tree
Showing 17 changed files with 230 additions and 113 deletions.
10 changes: 7 additions & 3 deletions demos/demo-modules/exclude-days/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
ChangeDetectionStrategy,
ViewEncapsulation
} from '@angular/core';
import { CalendarEvent } from 'angular-calendar';
import { CalendarEvent, DAYS_OF_WEEK } from 'angular-calendar';
import { colors } from '../demo-utils/colors';

@Component({
Expand All @@ -22,15 +22,19 @@ export class DemoComponent {
start: new Date('2016-01-08'),
end: new Date('2016-01-10'),
title: 'One day excluded event',
color: colors.red
color: colors.red,
allDay: true
},
{
start: new Date('2016-01-01'),
end: new Date('2016-01-09'),
title: 'Multiple weeks event'
title: 'Multiple weeks event',
allDay: true
}
];

// exclude weekends
excludeDays: number[] = [0, 6];

weekStartsOn = DAYS_OF_WEEK.SUNDAY;
}
2 changes: 1 addition & 1 deletion demos/demo-modules/exclude-days/template.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
</div>
</div>
<div class="col-md-4">
<h3>{{ viewDate | calendarDate:(view + 'ViewTitle'):'en' }}</h3>
<h3>{{ viewDate | calendarDate:(view + 'ViewTitle'):'en':weekStartsOn:excludeDays }}</h3>
</div>
<div class="col-md-4">
<div class="btn-group">
Expand Down
15 changes: 2 additions & 13 deletions demos/demo-modules/i18n/component.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,10 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import {
CalendarEvent,
CalendarDateFormatter,
DAYS_OF_WEEK
} from 'angular-calendar';
import { CustomDateFormatter } from './custom-date-formatter.provider';
import { CalendarEvent, DAYS_OF_WEEK } from 'angular-calendar';

@Component({
selector: 'mwl-demo-component',
changeDetection: ChangeDetectionStrategy.OnPush,
templateUrl: 'template.html',
providers: [
{
provide: CalendarDateFormatter,
useClass: CustomDateFormatter
}
]
templateUrl: 'template.html'
})
export class DemoComponent {
view: string = 'month';
Expand Down
11 changes: 0 additions & 11 deletions demos/demo-modules/i18n/custom-date-formatter.provider.ts

This file was deleted.

7 changes: 0 additions & 7 deletions demos/demo-modules/i18n/sources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,6 @@ export const sources = [
highlighted: require('!!raw-loader!highlightjs-loader?lang=typescript!./component')
}
},
{
filename: 'custom-date-formatter.provider.ts',
contents: {
raw: require('!!raw-loader!./custom-date-formatter.provider'),
highlighted: require('!!raw-loader!highlightjs-loader?lang=typescript!./custom-date-formatter.provider')
}
},
{
filename: 'template.html',
contents: {
Expand Down
31 changes: 24 additions & 7 deletions src/modules/common/calendar-angular-date-formatter.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
import { DatePipe } from '@angular/common';
import { Injectable } from '@angular/core';
import { DateAdapter } from '../../date-adapters/date-adapter';
import { getWeekViewPeriod } from './util';

/**
* This will use the angular date pipe to do all date formatting. It is the default date formatter used by the calendar.
Expand Down Expand Up @@ -55,15 +56,31 @@ export class CalendarAngularDateFormatter
/**
* The week view title
*/
public weekViewTitle({ date, locale }: DateFormatterParams): string {
const year: string = new DatePipe(locale).transform(
public weekViewTitle({
date,
locale,
weekStartsOn,
excludeDays,
daysInWeek
}: DateFormatterParams): string {
const { viewStart, viewEnd } = getWeekViewPeriod(
this.dateAdapter,
date,
'y',
null,
locale
weekStartsOn,
excludeDays,
daysInWeek
);
const weekNumber: number = this.dateAdapter.getISOWeek(date);
return `Week ${weekNumber} of ${year}`;
const format = (dateToFormat: Date, showYear: boolean) =>
new DatePipe(locale).transform(
dateToFormat,
'MMM d' + (showYear ? ', yyyy' : ''),
null,
locale
);
return `${format(
viewStart,
viewStart.getUTCFullYear() !== viewEnd.getUTCFullYear()
)} - ${format(viewEnd, true)}`;
}

/**
Expand Down
16 changes: 16 additions & 0 deletions src/modules/common/calendar-date-formatter.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@ export interface DateFormatterParams {
* The users preferred locale.
*/
locale?: string;

/**
* The start day number of the week
*/
weekStartsOn?: number;

/**
* An array of day indexes (0 = sunday, 1 = monday etc) that will be hidden on the view
*/
excludeDays?: number[];

/**
* The number of days in a week. Can be used to create a shorter or longer week view.
* The first day of the week will always be the `viewDate`
*/
daysInWeek?: number;
}

/**
Expand Down
17 changes: 15 additions & 2 deletions src/modules/common/calendar-date.pipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,20 @@ export class CalendarDatePipe implements PipeTransform {
@Inject(LOCALE_ID) private locale: string
) {}

transform(date: Date, method: string, locale: string = this.locale): string {
return this.dateFormatter[method]({ date, locale });
transform(
date: Date,
method: string,
locale: string = this.locale,
weekStartsOn: number = 0,
excludeDays: number[] = [],
daysInWeek?: number
): string {
return this.dateFormatter[method]({
date,
locale,
weekStartsOn,
excludeDays,
daysInWeek
});
}
}
33 changes: 28 additions & 5 deletions src/modules/common/calendar-moment-date-formatter.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {
CalendarDateFormatterInterface,
DateFormatterParams
} from './calendar-date-formatter.interface';
import { getWeekViewPeriod } from './util';
import { DateAdapter } from '../../date-adapters/date-adapter';

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

Expand All @@ -27,7 +29,10 @@ export class CalendarMomentDateFormatter
/**
* @hidden
*/
constructor(@Inject(MOMENT) private moment: any) {}
constructor(
@Inject(MOMENT) private moment: any,
private dateAdapter: DateAdapter
) {}

/**
* The month view header week day labels
Expand Down Expand Up @@ -80,10 +85,28 @@ export class CalendarMomentDateFormatter
/**
* The week view title
*/
public weekViewTitle({ date, locale }: DateFormatterParams): string {
return this.moment(date)
.locale(locale)
.format('[Week] W [of] YYYY');
public weekViewTitle({
date,
locale,
weekStartsOn,
excludeDays,
daysInWeek
}: DateFormatterParams): string {
const { viewStart, viewEnd } = getWeekViewPeriod(
this.dateAdapter,
date,
weekStartsOn,
excludeDays,
daysInWeek
);
const format = (dateToFormat: Date, showYear: boolean) =>
this.moment(dateToFormat)
.locale(locale)
.format('MMM D' + (showYear ? ', YYYY' : ''));
return `${format(
viewStart,
viewStart.getUTCFullYear() !== viewEnd.getUTCFullYear()
)} - ${format(viewEnd, true)}`;
}

/**
Expand Down
34 changes: 28 additions & 6 deletions src/modules/common/calendar-native-date-formatter.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
} from './calendar-date-formatter.interface';
import { Injectable } from '@angular/core';
import { DateAdapter } from '../../date-adapters/date-adapter';
import { getWeekViewPeriod } from './util';
import show = Mocha.reporters.Base.cursor.show;

/**
* 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.
Expand Down Expand Up @@ -62,12 +64,32 @@ export class CalendarNativeDateFormatter
/**
* The week view title
*/
public weekViewTitle({ date, locale }: DateFormatterParams): string {
const year: string = new Intl.DateTimeFormat(locale, {
year: 'numeric'
}).format(date);
const weekNumber: number = this.dateAdapter.getISOWeek(date);
return `Week ${weekNumber} of ${year}`;
public weekViewTitle({
date,
locale,
weekStartsOn,
excludeDays,
daysInWeek
}: DateFormatterParams): string {
const { viewStart, viewEnd } = getWeekViewPeriod(
this.dateAdapter,
date,
weekStartsOn,
excludeDays,
daysInWeek
);

const format = (dateToFormat: Date, showYear: boolean) =>
new Intl.DateTimeFormat(locale, {
day: 'numeric',
month: 'short',
year: showYear ? 'numeric' : undefined
}).format(dateToFormat);

return `${format(
viewStart,
viewStart.getUTCFullYear() !== viewEnd.getUTCFullYear()
)} - ${format(viewEnd, true)}`;
}

/**
Expand Down
33 changes: 33 additions & 0 deletions src/modules/common/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,36 @@ export function shouldFireDroppedEvent(
(!dropEvent.dropData.event.allDay && allDay))
);
}

export function getWeekViewPeriod(
dateAdapter: DateAdapter,
viewDate: Date,
weekStartsOn: number,
excluded: number[] = [],
daysInWeek?: number
): { viewStart: Date; viewEnd: Date } {
let viewStart = daysInWeek
? dateAdapter.startOfDay(viewDate)
: dateAdapter.startOfWeek(viewDate, { weekStartsOn });
if (excluded.indexOf(dateAdapter.getDay(viewStart)) > -1) {
viewStart = dateAdapter.subDays(
addDaysWithExclusions(dateAdapter, viewStart, 1, excluded),
1
);
}
if (daysInWeek) {
const viewEnd = dateAdapter.endOfDay(
addDaysWithExclusions(dateAdapter, viewStart, daysInWeek - 1, excluded)
);
return { viewStart, viewEnd };
} else {
let viewEnd = dateAdapter.endOfWeek(viewDate, { weekStartsOn });
if (excluded.indexOf(dateAdapter.getDay(viewEnd)) > -1) {
viewEnd = dateAdapter.addDays(
addDaysWithExclusions(dateAdapter, viewEnd, -1, excluded),
1
);
}
return { viewStart, viewEnd };
}
}
Loading

0 comments on commit aa7edd9

Please sign in to comment.