mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ADF-3042] Use the custom date adapter from adf-core on Search Date Range widget (#3394)
-fix localization -fix tests -show parse error
This commit is contained in:
committed by
Eugenio Romano
parent
85ff224e26
commit
11bac7e796
@@ -7,13 +7,13 @@
|
|||||||
(focusout)="onChangedHandler($event, from)">
|
(focusout)="onChangedHandler($event, from)">
|
||||||
<mat-datepicker-toggle matSuffix [for]="fromDatepicker"></mat-datepicker-toggle>
|
<mat-datepicker-toggle matSuffix [for]="fromDatepicker"></mat-datepicker-toggle>
|
||||||
<mat-datepicker #fromDatepicker></mat-datepicker>
|
<mat-datepicker #fromDatepicker></mat-datepicker>
|
||||||
<mat-error *ngIf="from.hasError('required') && !from.hasError('matDatepickerParse')">
|
<mat-error *ngIf="from.hasError('required') && !hasParseError(from)">
|
||||||
{{ 'SEARCH.FILTER.VALIDATION.REQUIRED-VALUE' | translate }}
|
{{ 'SEARCH.FILTER.VALIDATION.REQUIRED-VALUE' | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
<mat-error *ngIf="from.hasError('matDatepickerMax')">
|
<mat-error *ngIf="from.hasError('matDatepickerMax')">
|
||||||
{{ 'SEARCH.FILTER.VALIDATION.BEYOND-MAX-DATE' | translate }}
|
{{ 'SEARCH.FILTER.VALIDATION.BEYOND-MAX-DATE' | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
<mat-error *ngIf="from.hasError('matDatepickerParse')">
|
<mat-error *ngIf="hasParseError(from)">
|
||||||
{{ 'SEARCH.FILTER.VALIDATION.INVALID-DATE' | translate: { requiredFormat: datePickerDateFormat } }}
|
{{ 'SEARCH.FILTER.VALIDATION.INVALID-DATE' | translate: { requiredFormat: datePickerDateFormat } }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
(focusout)="onChangedHandler($event, to)">
|
(focusout)="onChangedHandler($event, to)">
|
||||||
<mat-datepicker-toggle matSuffix [for]="toDatepicker"></mat-datepicker-toggle>
|
<mat-datepicker-toggle matSuffix [for]="toDatepicker"></mat-datepicker-toggle>
|
||||||
<mat-datepicker #toDatepicker></mat-datepicker>
|
<mat-datepicker #toDatepicker></mat-datepicker>
|
||||||
<mat-error *ngIf="to.hasError('required') && !to.hasError('matDatepickerParse')">
|
<mat-error *ngIf="to.hasError('required') && !hasParseError(to)">
|
||||||
{{ 'SEARCH.FILTER.VALIDATION.REQUIRED-VALUE' | translate }}
|
{{ 'SEARCH.FILTER.VALIDATION.REQUIRED-VALUE' | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
<mat-error *ngIf="to.hasError('matDatepickerMin')">
|
<mat-error *ngIf="to.hasError('matDatepickerMin')">
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
<mat-error *ngIf="to.hasError('matDatepickerMax')">
|
<mat-error *ngIf="to.hasError('matDatepickerMax')">
|
||||||
{{ 'SEARCH.FILTER.VALIDATION.BEYOND-MAX-DATE' | translate }}
|
{{ 'SEARCH.FILTER.VALIDATION.BEYOND-MAX-DATE' | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
<mat-error *ngIf="to.hasError('matDatepickerParse')">
|
<mat-error *ngIf="hasParseError(to)">
|
||||||
{{ 'SEARCH.FILTER.VALIDATION.INVALID-DATE' | translate: { requiredFormat: datePickerDateFormat } }}
|
{{ 'SEARCH.FILTER.VALIDATION.INVALID-DATE' | translate: { requiredFormat: datePickerDateFormat } }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
@@ -15,11 +15,11 @@
|
|||||||
* limitations under the License.
|
* 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 { Observable } from 'rxjs/Observable';
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { ContentTestingModule } from '../../../testing/content.testing.module';
|
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 { By } from '@angular/platform-browser';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
@@ -34,9 +34,9 @@ describe('SearchDateRangeComponent', () => {
|
|||||||
const localeFixture = 'it';
|
const localeFixture = 'it';
|
||||||
const dateFormatFixture = 'DD-MMM-YY';
|
const dateFormatFixture = 'DD-MMM-YY';
|
||||||
|
|
||||||
const buildAdapter = (): CustomMomentDateAdapter => {
|
const buildAdapter = (): MomentDateAdapter => {
|
||||||
const dateAdapter = new CustomMomentDateAdapter(null);
|
const dateAdapter = new MomentDateAdapter();
|
||||||
dateAdapter.customDateFormat = null;
|
dateAdapter.overrideDisplyaFormat = null;
|
||||||
return dateAdapter;
|
return dateAdapter;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -72,14 +72,14 @@ describe('SearchDateRangeComponent', () => {
|
|||||||
it('should setup the format of the date from configuration', () => {
|
it('should setup the format of the date from configuration', () => {
|
||||||
component.settings = {field: 'cm:created', dateFormat: dateFormatFixture};
|
component.settings = {field: 'cm:created', dateFormat: dateFormatFixture};
|
||||||
component.ngOnInit();
|
component.ngOnInit();
|
||||||
expect(theDateAdapter.customDateFormat).toBe(dateFormatFixture);
|
expect(theDateAdapter.overrideDisplyaFormat).toBe(dateFormatFixture);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should setup form control with formatted valid date on change', () => {
|
it('should setup form control with formatted valid date on change', () => {
|
||||||
component.settings = {field: 'cm:created', dateFormat: dateFormatFixture};
|
component.settings = {field: 'cm:created', dateFormat: dateFormatFixture};
|
||||||
component.ngOnInit();
|
component.ngOnInit();
|
||||||
|
|
||||||
const inputString = '20.feb.18';
|
const inputString = '20-feb-18';
|
||||||
const momentFromInput = moment(inputString, dateFormatFixture);
|
const momentFromInput = moment(inputString, dateFormatFixture);
|
||||||
expect(momentFromInput.isValid()).toBeTruthy();
|
expect(momentFromInput.isValid()).toBeTruthy();
|
||||||
|
|
||||||
|
@@ -18,7 +18,7 @@
|
|||||||
import { OnInit, Component, ViewEncapsulation } from '@angular/core';
|
import { OnInit, Component, ViewEncapsulation } from '@angular/core';
|
||||||
import { FormControl, Validators, FormGroup } from '@angular/forms';
|
import { FormControl, Validators, FormGroup } from '@angular/forms';
|
||||||
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core';
|
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 { SearchWidget } from '../../search-widget.interface';
|
||||||
import { SearchWidgetSettings } from '../../search-widget-settings.interface';
|
import { SearchWidgetSettings } from '../../search-widget-settings.interface';
|
||||||
@@ -31,29 +31,13 @@ declare let moment: any;
|
|||||||
|
|
||||||
const DEFAULT_FORMAT_DATE: string = 'DD/MM/YYYY';
|
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({
|
@Component({
|
||||||
selector: 'adf-search-date-range',
|
selector: 'adf-search-date-range',
|
||||||
templateUrl: './search-date-range.component.html',
|
templateUrl: './search-date-range.component.html',
|
||||||
styleUrls: ['./search-date-range.component.scss'],
|
styleUrls: ['./search-date-range.component.scss'],
|
||||||
providers: [
|
providers: [
|
||||||
{provide: DateAdapter, useClass: CustomMomentDateAdapter, deps: [MAT_DATE_LOCALE]},
|
{provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE]},
|
||||||
{provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS}
|
{provide: MAT_DATE_FORMATS, useValue: MOMENT_DATE_FORMATS}
|
||||||
],
|
],
|
||||||
encapsulation: ViewEncapsulation.None,
|
encapsulation: ViewEncapsulation.None,
|
||||||
host: { class: 'adf-search-date-range' }
|
host: { class: 'adf-search-date-range' }
|
||||||
@@ -80,8 +64,8 @@ export class SearchDateRangeComponent implements SearchWidget, OnInit {
|
|||||||
if (this.settings) {
|
if (this.settings) {
|
||||||
this.datePickerDateFormat = this.settings.dateFormat || DEFAULT_FORMAT_DATE;
|
this.datePickerDateFormat = this.settings.dateFormat || DEFAULT_FORMAT_DATE;
|
||||||
}
|
}
|
||||||
const theCustomDateAdapter = <CustomMomentDateAdapter> <any> this.dateAdapter;
|
const theCustomDateAdapter = <MomentDateAdapter> <any> this.dateAdapter;
|
||||||
theCustomDateAdapter.customDateFormat = this.datePickerDateFormat;
|
theCustomDateAdapter.overrideDisplyaFormat = this.datePickerDateFormat;
|
||||||
|
|
||||||
this.userPreferencesService.select(UserPreferenceValues.Locale).subscribe((locale) => {
|
this.userPreferencesService.select(UserPreferenceValues.Locale).subscribe((locale) => {
|
||||||
this.setLocale(locale);
|
this.setLocale(locale);
|
||||||
@@ -99,7 +83,7 @@ export class SearchDateRangeComponent implements SearchWidget, OnInit {
|
|||||||
to: this.to
|
to: this.to
|
||||||
});
|
});
|
||||||
|
|
||||||
this.maxDate = moment().startOf('day');
|
this.maxDate = this.dateAdapter.today().startOf('day');
|
||||||
}
|
}
|
||||||
|
|
||||||
apply(model: { from: string, to: string }, isValid: boolean) {
|
apply(model: { from: string, to: string }, isValid: boolean) {
|
||||||
@@ -128,7 +112,7 @@ export class SearchDateRangeComponent implements SearchWidget, OnInit {
|
|||||||
|
|
||||||
if (inputValue) {
|
if (inputValue) {
|
||||||
const formatDate = this.dateAdapter.parse(inputValue, this.datePickerDateFormat);
|
const formatDate = this.dateAdapter.parse(inputValue, this.datePickerDateFormat);
|
||||||
if (formatDate.isValid()) {
|
if (formatDate && formatDate.isValid()) {
|
||||||
formControl.setValue(formatDate);
|
formControl.setValue(formatDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,4 +122,8 @@ export class SearchDateRangeComponent implements SearchWidget, OnInit {
|
|||||||
this.dateAdapter.setLocale(locale);
|
this.dateAdapter.setLocale(locale);
|
||||||
moment.locale(locale);
|
moment.locale(locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasParseError(formControl) {
|
||||||
|
return formControl.hasError('matDatepickerParse') && formControl.getError('matDatepickerParse').text;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -89,7 +89,7 @@ export class MomentDateAdapter extends DateAdapter<Moment> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
clone(date: Moment): Moment {
|
clone(date: Moment): Moment {
|
||||||
return date.clone();
|
return date.clone().locale(this.locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
createDate(year: number, month: number, date: number): Moment {
|
createDate(year: number, month: number, date: number): Moment {
|
||||||
@@ -97,33 +97,37 @@ export class MomentDateAdapter extends DateAdapter<Moment> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
today(): Moment {
|
today(): Moment {
|
||||||
return moment();
|
return moment().locale(this.locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
parse(value: any, parseFormat: any): Moment {
|
parse(value: any, parseFormat: any): Moment {
|
||||||
let m = moment(value, parseFormat, true);
|
|
||||||
if (!m.isValid()) {
|
if (value && typeof value === 'string') {
|
||||||
m = moment(value, this.overrideDisplyaFormat);
|
let m = moment(value, parseFormat, this.locale, true);
|
||||||
}
|
if (!m.isValid()) {
|
||||||
if (m.isValid()) {
|
// use strict parsing because Moment's parser is very forgiving, and this can lead to undesired behavior.
|
||||||
// if user omits year, it defaults to 2001, so check for that issue.
|
m = moment(value, this.overrideDisplyaFormat, this.locale, true);
|
||||||
if (m.year() === 2001 && value.indexOf('2001') === -1) {
|
}
|
||||||
// if 2001 not actually in the value string, change to current year
|
if (m.isValid()) {
|
||||||
const currentYear = new Date().getFullYear();
|
// if user omits year, it defaults to 2001, so check for that issue.
|
||||||
m.set('year', currentYear);
|
if (m.year() === 2001 && value.indexOf('2001') === -1) {
|
||||||
// if date is in the future, set previous year
|
// if 2001 not actually in the value string, change to current year
|
||||||
if (m.isAfter(moment())) {
|
const currentYear = new Date().getFullYear();
|
||||||
m.set('year', currentYear - 1);
|
m.set('year', currentYear);
|
||||||
|
// if date is in the future, set previous year
|
||||||
|
if (m.isAfter(moment())) {
|
||||||
|
m.set('year', currentYear - 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return m;
|
return m;
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return value ? moment(value).locale(this.locale) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
format(date: Moment, displayFormat: any): string {
|
format(date: Moment, displayFormat: any): string {
|
||||||
|
date = this.clone(date);
|
||||||
displayFormat = this.overrideDisplyaFormat ? this.overrideDisplyaFormat : displayFormat;
|
displayFormat = this.overrideDisplyaFormat ? this.overrideDisplyaFormat : displayFormat;
|
||||||
|
|
||||||
if (date && date.format) {
|
if (date && date.format) {
|
||||||
@@ -150,6 +154,8 @@ export class MomentDateAdapter extends DateAdapter<Moment> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setLocale(locale: any): void {
|
setLocale(locale: any): void {
|
||||||
|
super.setLocale(locale);
|
||||||
|
|
||||||
this.localeData = moment.localeData(locale);
|
this.localeData = moment.localeData(locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user