Skip to content

Commit

Permalink
feat: remove direction option
Browse files Browse the repository at this point in the history
BREAKING CHANGE: confining the input to a single type is cleaner
  • Loading branch information
lamabiker committed Mar 16, 2020
1 parent 8aba90a commit 8eaa232
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 92 deletions.
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,11 @@ date2 = new Date('2020-03-13');
## API

```
{{ value_expression | dateInterval [ : singleDateOutlook [ : format [ : locale ] ] ] }}
{{ value_expression | dateInterval [ : format [ : locale ] ] ] }}
```

**value_expression** _string_ | _Date_ | _Array<string | date>_ : the input date(s). Can be a date-like string or a Date instance or an array of them. If the array contains more than 2 dates, it will fallback to the first one in the array.

**singleDateOutlook** _string_ 'backward' | 'forward' (default _'forward'_) : in the case of a single date, defines whether that date is a start or an end date (_i.e_ `Until <date>` or `Since <date>`)

**format** _string_ (default _'mediumDate'_): a date format string as used in Angular's [`formatDate`](https://angular.io/api/common/DatePipe#pre-defined-format-options) method. If the format doesn't display the day, but the month and year are the same, it will only display the end date.

**locale** _localestring_ (default _the app's locale, e.g `en-US`_): specify the locale when wanting to display one different from that of the app's. Current locale support: `en`, `fr`, `ru`.
Expand Down
2 changes: 1 addition & 1 deletion projects/ng-date-interval-showcase/e2e/src/app.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe('workspace-project App', () => {

it('should display welcome message', () => {
page.navigateTo();
expect(page.getTitleText()).toEqual('ng-date-interval-showcase app is running!');
expect(page.getTitleText()).toEqual('dateInterval pipe');
});

afterEach(async () => {
Expand Down
12 changes: 6 additions & 6 deletions projects/ng-date-interval-showcase/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ <h1><code>dateInterval</code> pipe</h1>
<mat-divider></mat-divider>

<br>
<pre><code [highlight]="demos.single_options"></code></pre>
<div>{{dates.single | dateInterval:'backward'}}</div>
<pre><code [highlight]="demos.single_forward"></code></pre>
<div>{{dates.single_forward | dateInterval}}</div>

<br>
<mat-divider></mat-divider>
Expand Down Expand Up @@ -60,28 +60,28 @@ <h1><code>dateInterval</code> pipe</h1>

<br>
<pre><code [highlight]="demos.localized.fr_simple"></code></pre>
<div>{{dates.multiple | dateInterval:'forward':'mediumDate':'fr-FR'}}</div>
<div>{{dates.multiple | dateInterval:'mediumDate':'fr-FR'}}</div>

<br>
<mat-divider></mat-divider>

<br>
<pre><code [highlight]="demos.localized.fr_sameMonth"></code></pre>
<div>{{dates.sameMonth | dateInterval:'forward':'mediumDate':'fr-FR'}}</div>
<div>{{dates.sameMonth | dateInterval:'mediumDate':'fr-FR'}}</div>

<br>
<mat-divider></mat-divider>

<br>
<pre><code [highlight]="demos.localized.ru_simple"></code></pre>
<div>{{dates.multiple | dateInterval:'forward':'mediumDate':'ru-RU'}}</div>
<div>{{dates.multiple | dateInterval:'mediumDate':'ru-RU'}}</div>

<br>
<mat-divider></mat-divider>

<br>
<pre><code [highlight]="demos.localized.ru_dateFormat"></code></pre>
<div>{{dates.multiple | dateInterval:'forward':'dd MMMM y':'ru-RU'}}</div>
<div>{{dates.multiple | dateInterval:'dd MMMM y':'ru-RU'}}</div>
</mat-card-content>
</mat-card>

Expand Down
12 changes: 10 additions & 2 deletions projects/ng-date-interval-showcase/src/app/app.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
import { DateIntervalPipe } from '../../../ng-date-interval/src/lib/date-interval.pipe';

import localeFr from '@angular/common/locales/fr';
import localeRu from '@angular/common/locales/ru';
import { registerLocaleData } from '@angular/common';

registerLocaleData(localeFr, 'fr-FR');
registerLocaleData(localeRu, 'ru-RU');

describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AppComponent]
declarations: [AppComponent, DateIntervalPipe]
}).compileComponents();
}));

Expand All @@ -24,6 +32,6 @@ describe('AppComponent', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement;
expect(compiled.querySelector('.content span').textContent).toContain('ng-date-interval-showcase app is running!');
expect(compiled.querySelector('h1').textContent).toContain('dateInterval pipe');
});
});
18 changes: 10 additions & 8 deletions projects/ng-date-interval-showcase/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Component } from '@angular/core';

const datesStr = `{
single: new Date(),
single: [null, new Date()],
single_forward: [new Date(), null],
multiple: ['2001-01-01', '2002-12-12'],
sameYear: ['2001-01-01', '2001-03-06'],
sameMonth: ['2001-01-01', '2001-01-06'],
Expand All @@ -17,13 +18,14 @@ export class AppComponent {

// Test subjects
dates = {
single: new Date(),
single: [null, new Date()],
single_forward: [new Date(), null],
multiple: ['2001-01-01', '2002-12-12'],
sameYear: ['2001-01-01', '2001-03-06'],
sameMonth: ['2001-01-01', '2001-01-06']
};

api = '{{ value_expression | dateInterval [ : singleDateOutlook [ : format [ : locale ] ] ] }}';
api = '{{ value_expression | dateInterval [ : format [ : locale ] ] ] }}';

// String demos
demos = {
Expand All @@ -32,12 +34,12 @@ export class AppComponent {
multiple: '{{dates.multiple | dateInterval}}',
sameYear: '{{dates.sameYear | dateInterval}}',
sameMonth: '{{dates.sameMonth | dateInterval}}',
single_options: `{{dates.single | dateInterval:'backward'}}`,
single_forward: `{{dates.single_forward | dateInterval}}`,
localized: {
fr_simple: `{{dates.multiple | dateInterval:'forward':'mediumDate':'fr-FR'}}`,
fr_sameMonth: `{{dates.sameMonth | dateInterval:'forward':'mediumDate':'fr-FR'}}`,
ru_simple: `{{dates.multiple | dateInterval:'forward':'mediumDate':'ru-RU'}}`,
ru_dateFormat: `{{dates.multiple | dateInterval:'forward':'dd MMMM y':'ru-RU'}}`
fr_simple: `{{dates.multiple | dateInterval:'mediumDate':'fr-FR'}}`,
fr_sameMonth: `{{dates.sameMonth | dateInterval:'mediumDate':'fr-FR'}}`,
ru_simple: `{{dates.multiple | dateInterval:'mediumDate':'ru-RU'}}`,
ru_dateFormat: `{{dates.multiple | dateInterval:'dd MMMM y':'ru-RU'}}`
}
};
}
37 changes: 9 additions & 28 deletions projects/ng-date-interval/src/lib/date-interval.pipe.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,15 @@ describe('DateIntervalPipe', () => {
expect(result).toEqual('From May 6, 2019 to Mar 6, 2020');
});

it('should take a single date in an array', () => {
const dates = [new Date('2019-05-06')];
const result = sut.transform(dates);
expect(result).toEqual('Since May 6, 2019');
});

it('should take a single date', () => {
const dates = new Date('2019-05-06');
const result = sut.transform(dates);
expect(result).toEqual('Since May 6, 2019');
});

it('should take an array with a date and a null value', () => {
const dates = [new Date('2019-05-06'), null];
const result = sut.transform(dates);
expect(result).toEqual('Since May 6, 2019');
});

it('should take an array with a date, a null value and a backward outlook', () => {
const dates = [new Date('2019-05-06'), null];
const result = sut.transform(dates, 'backward');
it('should take an array with a null value, a date and print a backward outlook', () => {
const dates = [null, new Date('2019-05-06')];
const result = sut.transform(dates);
expect(result).toEqual('Until May 6, 2019');
});

Expand All @@ -63,18 +51,11 @@ describe('DateIntervalPipe', () => {
expect(result2).toEqual('Since May 6, 2019');
});

it('should take a single date and accept backward direction option', () => {
const dates = [new Date('2019-05-06')];

const result1 = sut.transform(dates, 'backward');
expect(result1).toEqual('Until May 6, 2019');
});

it('should handle locale when specified', () => {
const dates = [new Date('2019-05-06')];
const dates = [new Date('2019-05-06'), new Date('2020-05-06')];
const format = 'mediumDate';
const result = sut.transform(dates, 'backward', format, 'fr-FR');
expect(result).toEqual(`Jusqu'au 6 mai 2019`);
const result = sut.transform(dates, format, 'fr-FR');
expect(result).toEqual(`Du 6 mai 2019 au 6 mai 2020`);
});

it('should handle same year', () => {
Expand All @@ -97,19 +78,19 @@ describe('DateIntervalPipe', () => {

it('should handle same year with specified format (no days)', () => {
const dates = [new Date('2019-05-06'), new Date('2019-06-06')];
const result = sut.transform(dates, 'forward', 'MMM y');
const result = sut.transform(dates, 'MMM y');
expect(result).toEqual(`From May to Jun 2019`);
});

it('should handle same year with specified format (leading zero days)', () => {
const dates = [new Date('2019-05-06'), new Date('2019-06-06')];
const result = sut.transform(dates, 'forward', 'dd MMM y');
const result = sut.transform(dates, 'dd MMM y');
expect(result).toEqual(`From 06 May to 06 Jun 2019`);
});

it('should handle same year and same month with specified format (no days)', () => {
const dates = [new Date('2019-05-06'), new Date('2019-05-12')];
const result = sut.transform(dates, 'forward', 'MMM y');
const result = sut.transform(dates, 'MMM y');
expect(result).toEqual(`May 2019`);
});
});
46 changes: 10 additions & 36 deletions projects/ng-date-interval/src/lib/date-interval.pipe.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,29 @@
import { Pipe, PipeTransform, LOCALE_ID, Inject, Input } from '@angular/core';
import { ValidInput, InputDatesArray, DateOutlook, LocaleDateStringOptions } from '../types/types';
import { DatesArray, DateOutlook } from '../types/types';
import { formatDate } from '@angular/common';
import sentences from '../langs';

const defautDateFormat = 'mediumDate';
const defaultDateOutlook = 'forward';

@Pipe({
name: 'dateInterval'
})
export class DateIntervalPipe implements PipeTransform {
// These are set lower down
private singleDateOutlook: Readonly<DateOutlook>;
private format: Readonly<string>;
private normalizedInput: InputDatesArray;
private normalizedInput: DatesArray;

constructor(@Inject(LOCALE_ID) private locale: string) {}

transform(
input: ValidInput,
singleDateOutlook: DateOutlook = defaultDateOutlook,
format: string = defautDateFormat,
locale: string = this.locale
): string {
transform(input: DatesArray, format: string = defautDateFormat, locale: string = this.locale): string {
if (!input) return '';

// Set class properties
this.singleDateOutlook = singleDateOutlook;
this.format = format;
this.locale = locale;

// Get array of dates
this.normalizedInput = this.normalizeInput(input);
// Make sure the input isn't longer than 2 elements
this.normalizedInput = input.slice(0, 2);

const [startDate, endDate] = this.normalizedInput.map(this.formatDates.bind(this));

Expand Down Expand Up @@ -66,25 +60,6 @@ export class DateIntervalPipe implements PipeTransform {
return formatDate(item, this.format, this.locale);
}

private normalizeInput(input: Readonly<ValidInput>): InputDatesArray {
// If this input isn't an array, make it so
let inputArr = Array.isArray(input) ? input : [input];

// Filter out null values
inputArr = inputArr.filter(i => i);

if (inputArr.length === 1) {
inputArr.push(null); // [date, null]

if (this.singleDateOutlook === 'backward') {
inputArr.unshift(inputArr.pop()); // [null, date]
}
}

// Make sure the input isn't longer than 2 elements
return inputArr.slice(0, 2);
}

private interpolate(str: string, args: { [key: string]: string }): string {
for (const arg of Object.keys(args)) {
const regEx = new RegExp(`\{${arg}\}`, 'g');
Expand Down Expand Up @@ -135,11 +110,10 @@ export class DateIntervalPipe implements PipeTransform {
}

private get sentence(): string {
let type = 'default';
let type: DateOutlook = 'default';

if (this.normalizedInput.some(el => !el)) {
type = this.singleDateOutlook;
}
if (!this.normalizedInput[0]) type = 'backward';
if (!this.normalizedInput[1]) type = 'forward';

return sentences[this.locale.substring(0, 2)][type]; // ex: sentences.en.default
}
Expand Down
10 changes: 2 additions & 8 deletions projects/ng-date-interval/src/types/types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,2 @@
export type InputDatesArray = Array<string | Date>;
export type ValidInput = Array<string | Date> | string | Date;
export type DateOutlook = 'backward' | 'forward';
export interface LocaleDateStringOptions {
year?: 'numeric' | '2-digit';
month?: 'numeric' | '2-digit' | 'long' | 'short' | 'narrow';
day?: 'numeric' | '2-digit';
}
export type DatesArray = Array<string | Date>;
export type DateOutlook = 'backward' | 'forward' | 'default';

0 comments on commit 8eaa232

Please sign in to comment.