From 11bac7e796fda659ebeec27a83bd3caa8a4a6e66 Mon Sep 17 00:00:00 2001 From: Suzana Dirla Date: Fri, 25 May 2018 15:45:55 +0300 Subject: [PATCH] [ADF-3042] Use the custom date adapter from adf-core on Search Date Range widget (#3394) -fix localization -fix tests -show parse error --- .../search-date-range.component.html | 8 ++-- .../search-date-range.component.spec.ts | 14 +++---- .../search-date-range.component.ts | 34 +++++---------- lib/core/utils/momentDateAdapter.ts | 42 +++++++++++-------- 4 files changed, 46 insertions(+), 52 deletions(-) diff --git a/lib/content-services/search/components/search-date-range/search-date-range.component.html b/lib/content-services/search/components/search-date-range/search-date-range.component.html index bb69773a0b..f4c2321dc8 100644 --- a/lib/content-services/search/components/search-date-range/search-date-range.component.html +++ b/lib/content-services/search/components/search-date-range/search-date-range.component.html @@ -7,13 +7,13 @@ (focusout)="onChangedHandler($event, from)"> - + {{ 'SEARCH.FILTER.VALIDATION.REQUIRED-VALUE' | translate }} {{ 'SEARCH.FILTER.VALIDATION.BEYOND-MAX-DATE' | translate }} - + {{ 'SEARCH.FILTER.VALIDATION.INVALID-DATE' | translate: { requiredFormat: datePickerDateFormat } }} @@ -27,7 +27,7 @@ (focusout)="onChangedHandler($event, to)"> - + {{ 'SEARCH.FILTER.VALIDATION.REQUIRED-VALUE' | translate }} @@ -36,7 +36,7 @@ {{ 'SEARCH.FILTER.VALIDATION.BEYOND-MAX-DATE' | translate }} - + {{ 'SEARCH.FILTER.VALIDATION.INVALID-DATE' | translate: { requiredFormat: datePickerDateFormat } }} diff --git a/lib/content-services/search/components/search-date-range/search-date-range.component.spec.ts b/lib/content-services/search/components/search-date-range/search-date-range.component.spec.ts index 6ae2fcebaf..1fe77b86e9 100644 --- a/lib/content-services/search/components/search-date-range/search-date-range.component.spec.ts +++ b/lib/content-services/search/components/search-date-range/search-date-range.component.spec.ts @@ -15,11 +15,11 @@ * limitations under the License. */ -import { CustomMomentDateAdapter, SearchDateRangeComponent } from './search-date-range.component'; +import { SearchDateRangeComponent } from './search-date-range.component'; import { Observable } from 'rxjs/Observable'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ContentTestingModule } from '../../../testing/content.testing.module'; -import { setupTestBed } from '@alfresco/adf-core'; +import { setupTestBed, MomentDateAdapter } from '@alfresco/adf-core'; import { By } from '@angular/platform-browser'; import { TranslateService } from '@ngx-translate/core'; @@ -34,9 +34,9 @@ describe('SearchDateRangeComponent', () => { const localeFixture = 'it'; const dateFormatFixture = 'DD-MMM-YY'; - const buildAdapter = (): CustomMomentDateAdapter => { - const dateAdapter = new CustomMomentDateAdapter(null); - dateAdapter.customDateFormat = null; + const buildAdapter = (): MomentDateAdapter => { + const dateAdapter = new MomentDateAdapter(); + dateAdapter.overrideDisplyaFormat = null; return dateAdapter; }; @@ -72,14 +72,14 @@ describe('SearchDateRangeComponent', () => { it('should setup the format of the date from configuration', () => { component.settings = {field: 'cm:created', dateFormat: dateFormatFixture}; component.ngOnInit(); - expect(theDateAdapter.customDateFormat).toBe(dateFormatFixture); + expect(theDateAdapter.overrideDisplyaFormat).toBe(dateFormatFixture); }); it('should setup form control with formatted valid date on change', () => { component.settings = {field: 'cm:created', dateFormat: dateFormatFixture}; component.ngOnInit(); - const inputString = '20.feb.18'; + const inputString = '20-feb-18'; const momentFromInput = moment(inputString, dateFormatFixture); expect(momentFromInput.isValid()).toBeTruthy(); diff --git a/lib/content-services/search/components/search-date-range/search-date-range.component.ts b/lib/content-services/search/components/search-date-range/search-date-range.component.ts index 308e38f8a9..9fd23fd46a 100644 --- a/lib/content-services/search/components/search-date-range/search-date-range.component.ts +++ b/lib/content-services/search/components/search-date-range/search-date-range.component.ts @@ -18,7 +18,7 @@ import { OnInit, Component, ViewEncapsulation } from '@angular/core'; import { FormControl, Validators, FormGroup } from '@angular/forms'; import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core'; -import { MomentDateAdapter, MAT_MOMENT_DATE_FORMATS } from '@angular/material-moment-adapter'; +import { MomentDateAdapter, MOMENT_DATE_FORMATS } from '@alfresco/adf-core'; import { SearchWidget } from '../../search-widget.interface'; import { SearchWidgetSettings } from '../../search-widget-settings.interface'; @@ -31,29 +31,13 @@ declare let moment: any; const DEFAULT_FORMAT_DATE: string = 'DD/MM/YYYY'; -export class CustomMomentDateAdapter extends MomentDateAdapter { - customDateFormat: string; - - parse(value: any, parseFormat: any): any { - const dateFormat = this.customDateFormat ? this.customDateFormat : DEFAULT_FORMAT_DATE; - - return super.parse(value, dateFormat); - } - - format(value: Moment, displayFormat: string): string { - const dateFormat = this.customDateFormat ? this.customDateFormat : DEFAULT_FORMAT_DATE; - - return super.format(value, dateFormat); - } -} - @Component({ selector: 'adf-search-date-range', templateUrl: './search-date-range.component.html', styleUrls: ['./search-date-range.component.scss'], providers: [ - {provide: DateAdapter, useClass: CustomMomentDateAdapter, deps: [MAT_DATE_LOCALE]}, - {provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS} + {provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE]}, + {provide: MAT_DATE_FORMATS, useValue: MOMENT_DATE_FORMATS} ], encapsulation: ViewEncapsulation.None, host: { class: 'adf-search-date-range' } @@ -80,8 +64,8 @@ export class SearchDateRangeComponent implements SearchWidget, OnInit { if (this.settings) { this.datePickerDateFormat = this.settings.dateFormat || DEFAULT_FORMAT_DATE; } - const theCustomDateAdapter = this.dateAdapter; - theCustomDateAdapter.customDateFormat = this.datePickerDateFormat; + const theCustomDateAdapter = this.dateAdapter; + theCustomDateAdapter.overrideDisplyaFormat = this.datePickerDateFormat; this.userPreferencesService.select(UserPreferenceValues.Locale).subscribe((locale) => { this.setLocale(locale); @@ -99,7 +83,7 @@ export class SearchDateRangeComponent implements SearchWidget, OnInit { to: this.to }); - this.maxDate = moment().startOf('day'); + this.maxDate = this.dateAdapter.today().startOf('day'); } apply(model: { from: string, to: string }, isValid: boolean) { @@ -128,7 +112,7 @@ export class SearchDateRangeComponent implements SearchWidget, OnInit { if (inputValue) { const formatDate = this.dateAdapter.parse(inputValue, this.datePickerDateFormat); - if (formatDate.isValid()) { + if (formatDate && formatDate.isValid()) { formControl.setValue(formatDate); } } @@ -138,4 +122,8 @@ export class SearchDateRangeComponent implements SearchWidget, OnInit { this.dateAdapter.setLocale(locale); moment.locale(locale); } + + hasParseError(formControl) { + return formControl.hasError('matDatepickerParse') && formControl.getError('matDatepickerParse').text; + } } diff --git a/lib/core/utils/momentDateAdapter.ts b/lib/core/utils/momentDateAdapter.ts index 2f6fab1649..5ef710b927 100644 --- a/lib/core/utils/momentDateAdapter.ts +++ b/lib/core/utils/momentDateAdapter.ts @@ -89,7 +89,7 @@ export class MomentDateAdapter extends DateAdapter { } clone(date: Moment): Moment { - return date.clone(); + return date.clone().locale(this.locale); } createDate(year: number, month: number, date: number): Moment { @@ -97,33 +97,37 @@ export class MomentDateAdapter extends DateAdapter { } today(): Moment { - return moment(); + return moment().locale(this.locale); } parse(value: any, parseFormat: any): Moment { - let m = moment(value, parseFormat, true); - if (!m.isValid()) { - m = moment(value, this.overrideDisplyaFormat); - } - if (m.isValid()) { - // if user omits year, it defaults to 2001, so check for that issue. - if (m.year() === 2001 && value.indexOf('2001') === -1) { - // if 2001 not actually in the value string, change to current year - const currentYear = new Date().getFullYear(); - m.set('year', currentYear); - // if date is in the future, set previous year - if (m.isAfter(moment())) { - m.set('year', currentYear - 1); + + if (value && typeof value === 'string') { + let m = moment(value, parseFormat, this.locale, true); + if (!m.isValid()) { + // use strict parsing because Moment's parser is very forgiving, and this can lead to undesired behavior. + m = moment(value, this.overrideDisplyaFormat, this.locale, true); + } + if (m.isValid()) { + // if user omits year, it defaults to 2001, so check for that issue. + if (m.year() === 2001 && value.indexOf('2001') === -1) { + // if 2001 not actually in the value string, change to current year + const currentYear = new Date().getFullYear(); + m.set('year', currentYear); + // if date is in the future, set previous year + if (m.isAfter(moment())) { + m.set('year', currentYear - 1); + } } } return m; - } else { - return null; } + + return value ? moment(value).locale(this.locale) : null; } format(date: Moment, displayFormat: any): string { - + date = this.clone(date); displayFormat = this.overrideDisplyaFormat ? this.overrideDisplyaFormat : displayFormat; if (date && date.format) { @@ -150,6 +154,8 @@ export class MomentDateAdapter extends DateAdapter { } setLocale(locale: any): void { + super.setLocale(locale); + this.localeData = moment.localeData(locale); }