mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[APPS-2108] date-fns adapter for datetime pickers, many datetime parsing and validation fixes (#8992)
* migrate cloud date widget to date-fns, fix test bugs * [ci:force] update docs * [ci:force] remove commented out code * [APPS-2232] date cell validator, unit tests * improved moment adapter, code cleanup * datetime adapter, many code fixes * code review fixes * code cleanup * cleanup * fix max datetime validation, update tests * remove e2e already covered by unit tests * fix search date range * remove fake demo shell e2e for search * remove fake demo shell e2e for search page * cleanup e2e * migrate dynamic table to date-fns * fix e2e formatting * migrate protractor to unit tests * cleanup e2e
This commit is contained in:
@@ -7,29 +7,26 @@
|
||||
<mat-form-field class="adf-date-widget" [class.adf-left-label-input-datepicker]="field.leftLabels" [hideRequiredMarker]="true">
|
||||
<label class="adf-label" *ngIf="!field.leftLabels" [attr.for]="field.id">{{field.name | translate }} ({{field.dateDisplayFormat}})<span class="adf-asterisk"
|
||||
*ngIf="isRequired()">*</span></label>
|
||||
<input matInput
|
||||
[id]="field.id"
|
||||
[value]="field.value"
|
||||
[required]="isRequired()"
|
||||
[disabled]="field.readOnly"
|
||||
(change)="onDateChanged($any($event).srcElement.value)"
|
||||
[placeholder]="field.placeholder"
|
||||
[matTooltip]="field.tooltip"
|
||||
(blur)="markAsTouched()"
|
||||
matTooltipPosition="above"
|
||||
matTooltipShowDelay="1000">
|
||||
<mat-datepicker-toggle matSuffix [for]="datePicker" [disabled]="field.readOnly" ></mat-datepicker-toggle>
|
||||
<input matInput [matDatepicker]="datePicker"
|
||||
[id]="field.id"
|
||||
[(ngModel)]="value"
|
||||
[required]="field.required"
|
||||
[placeholder]="field.placeholder"
|
||||
[min]="minDate"
|
||||
[max]="maxDate"
|
||||
[disabled]="field.readOnly"
|
||||
[matTooltip]="field.tooltip"
|
||||
matTooltipPosition="above"
|
||||
matTooltipShowDelay="1000"
|
||||
(dateChange)="onDateChanged($event)"
|
||||
(blur)="markAsTouched()">
|
||||
<mat-datepicker-toggle matSuffix [for]="datePicker" [disabled]="field.readOnly"></mat-datepicker-toggle>
|
||||
<mat-datepicker #datePicker
|
||||
[startAt]="startAt"
|
||||
[disabled]="field.readOnly">
|
||||
</mat-datepicker>
|
||||
</mat-form-field>
|
||||
<error-widget [error]="field.validationSummary"></error-widget>
|
||||
<error-widget *ngIf="isInvalidFieldRequired() && isTouched()" required="{{ 'FORM.FIELD.REQUIRED' | translate }}"></error-widget>
|
||||
<mat-datepicker #datePicker [touchUi]="true" [startAt]="field.value | adfMomentDate: field.dateDisplayFormat" [disabled]="field.readOnly"></mat-datepicker>
|
||||
<input
|
||||
type="hidden"
|
||||
[matDatepicker]="datePicker"
|
||||
[value]="field.value | adfMomentDate: field.dateDisplayFormat"
|
||||
[min]="minDate"
|
||||
[max]="maxDate"
|
||||
[disabled]="field.readOnly"
|
||||
(dateInput)="onDateChanged($any($event).targetElement.value)">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -17,18 +17,20 @@
|
||||
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { DateCloudWidgetComponent } from './date-cloud.widget';
|
||||
import { FormFieldModel, FormModel, FormFieldTypes } from '@alfresco/adf-core';
|
||||
import moment from 'moment';
|
||||
import { FormFieldModel, FormModel, FormFieldTypes, DateFieldValidator, MinDateFieldValidator, MaxDateFieldValidator } from '@alfresco/adf-core';
|
||||
import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { DATE_FORMAT_CLOUD } from '../../../../models/date-format-cloud.model';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { DateAdapter } from '@angular/material/core';
|
||||
import { isEqual, subDays, addDays } from 'date-fns';
|
||||
|
||||
describe('DateWidgetComponent', () => {
|
||||
|
||||
let widget: DateCloudWidgetComponent;
|
||||
let fixture: ComponentFixture<DateCloudWidgetComponent>;
|
||||
let element: HTMLElement;
|
||||
let adapter: DateAdapter<Date>;
|
||||
let form: FormModel;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
@@ -37,7 +39,13 @@ describe('DateWidgetComponent', () => {
|
||||
ProcessServiceCloudTestingModule
|
||||
]
|
||||
});
|
||||
|
||||
form = new FormModel();
|
||||
form.fieldValidators = [new DateFieldValidator(), new MinDateFieldValidator(), new MaxDateFieldValidator()];
|
||||
|
||||
fixture = TestBed.createComponent(DateCloudWidgetComponent);
|
||||
adapter = fixture.debugElement.injector.get(DateAdapter);
|
||||
|
||||
widget = fixture.componentInstance;
|
||||
element = fixture.nativeElement;
|
||||
});
|
||||
@@ -52,13 +60,14 @@ describe('DateWidgetComponent', () => {
|
||||
|
||||
widget.ngOnInit();
|
||||
|
||||
const expected = moment(minValue, DATE_FORMAT_CLOUD);
|
||||
expect(widget.minDate.isSame(expected)).toBeTruthy();
|
||||
const expected = adapter.parse(minValue, widget.DATE_FORMAT);
|
||||
expect(isEqual(widget.minDate, expected)).toBeTrue();
|
||||
});
|
||||
|
||||
it('should date field be present', () => {
|
||||
const minValue = '1982-03-13';
|
||||
widget.field = new FormFieldModel(null, {
|
||||
widget.field = new FormFieldModel(form, {
|
||||
type: FormFieldTypes.DATE,
|
||||
minValue
|
||||
});
|
||||
|
||||
@@ -70,29 +79,29 @@ describe('DateWidgetComponent', () => {
|
||||
|
||||
it('should setup max value for date picker', () => {
|
||||
const maxValue = '1982-03-13';
|
||||
widget.field = new FormFieldModel(null, {
|
||||
widget.field = new FormFieldModel(form, {
|
||||
type: FormFieldTypes.DATE,
|
||||
maxValue
|
||||
});
|
||||
widget.ngOnInit();
|
||||
|
||||
const expected = moment(maxValue, DATE_FORMAT_CLOUD);
|
||||
expect(widget.maxDate.isSame(expected)).toBeTruthy();
|
||||
const expected = adapter.parse(maxValue, widget.DATE_FORMAT);
|
||||
expect(isEqual(widget.maxDate, expected)).toBeTrue();
|
||||
});
|
||||
|
||||
it('should eval visibility on date changed', () => {
|
||||
spyOn(widget, 'onFieldChanged').and.callThrough();
|
||||
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
const field = new FormFieldModel(form, {
|
||||
type: FormFieldTypes.DATE,
|
||||
id: 'date-field-id',
|
||||
name: 'date-name',
|
||||
value: '9999-9-9',
|
||||
type: 'date',
|
||||
readOnly: 'false'
|
||||
});
|
||||
|
||||
widget.field = field;
|
||||
const todayDate = moment().format(DATE_FORMAT_CLOUD);
|
||||
widget.onDateChanged({ value: todayDate });
|
||||
widget.onDateChanged({ value: adapter.today() } as any);
|
||||
|
||||
expect(widget.onFieldChanged).toHaveBeenCalledWith(field);
|
||||
});
|
||||
@@ -105,48 +114,46 @@ describe('DateWidgetComponent', () => {
|
||||
});
|
||||
|
||||
it('should show visible date widget', async () => {
|
||||
widget.field = new FormFieldModel(new FormModel(), {
|
||||
widget.field = new FormFieldModel(form, {
|
||||
id: 'date-field-id',
|
||||
name: 'date-name',
|
||||
// always stored as dd-MM-yyyy
|
||||
value: '9999-9-9',
|
||||
type: 'date',
|
||||
readOnly: 'false'
|
||||
type: FormFieldTypes.DATE
|
||||
});
|
||||
widget.field.isVisible = true;
|
||||
widget.ngOnInit();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
expect(element.querySelector('#date-field-id')).toBeDefined();
|
||||
expect(element.querySelector('#date-field-id')).not.toBeNull();
|
||||
|
||||
const dateElement = element.querySelector<HTMLInputElement>('#date-field-id');
|
||||
expect(dateElement.value).toContain('9-9-9999');
|
||||
expect(dateElement).not.toBeNull();
|
||||
|
||||
expect(dateElement?.value).toContain('9-9-9999');
|
||||
});
|
||||
|
||||
it('should show the correct format type', async () => {
|
||||
widget.field = new FormFieldModel(new FormModel(), {
|
||||
widget.field = new FormFieldModel(form, {
|
||||
id: 'date-field-id',
|
||||
name: 'date-name',
|
||||
value: '9999-30-12',
|
||||
type: 'date',
|
||||
readOnly: 'false'
|
||||
// always stored as dd-MM-yyyy
|
||||
value: '30-12-9999',
|
||||
type: FormFieldTypes.DATE,
|
||||
dateDisplayFormat: 'YYYY-DD-MM'
|
||||
});
|
||||
widget.field.isVisible = true;
|
||||
widget.field.dateDisplayFormat = 'YYYY-DD-MM';
|
||||
widget.ngOnInit();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
expect(element.querySelector('#date-field-id')).toBeDefined();
|
||||
expect(element.querySelector('#date-field-id')).not.toBeNull();
|
||||
|
||||
const dateElement = element.querySelector<HTMLInputElement>('#date-field-id');
|
||||
expect(dateElement.value).toContain('9999-30-12');
|
||||
});
|
||||
|
||||
it('should disable date button when is readonly', async () => {
|
||||
widget.field = new FormFieldModel(new FormModel(), {
|
||||
widget.field = new FormFieldModel(form, {
|
||||
id: 'date-field-id',
|
||||
name: 'date-name',
|
||||
value: '9999-9-9',
|
||||
type: 'date',
|
||||
type: FormFieldTypes.DATE,
|
||||
readOnly: 'false'
|
||||
});
|
||||
widget.field.isVisible = true;
|
||||
@@ -170,7 +177,7 @@ describe('DateWidgetComponent', () => {
|
||||
id: 'date-field-id',
|
||||
name: 'date-name',
|
||||
value: 'aa',
|
||||
type: 'date',
|
||||
type: FormFieldTypes.DATE,
|
||||
readOnly: 'false'
|
||||
});
|
||||
widget.field.isVisible = true;
|
||||
@@ -184,31 +191,31 @@ describe('DateWidgetComponent', () => {
|
||||
});
|
||||
|
||||
it('should display always the json value', async () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
const field = new FormFieldModel(form, {
|
||||
id: 'date-field-id',
|
||||
name: 'date-name',
|
||||
value: '12-30-9999',
|
||||
type: 'date',
|
||||
readOnly: 'false'
|
||||
// always stored as dd-MM-yyyy
|
||||
value: '30-12-9999',
|
||||
type: FormFieldTypes.DATE,
|
||||
readOnly: 'false',
|
||||
dateDisplayFormat: 'MM-DD-YYYY'
|
||||
});
|
||||
field.isVisible = true;
|
||||
field.dateDisplayFormat = 'MM-DD-YYYY';
|
||||
widget.field = field;
|
||||
widget.ngOnInit();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(element.querySelector('#date-field-id')).toBeDefined();
|
||||
expect(element.querySelector('#date-field-id')).not.toBeNull();
|
||||
const dateElement: any = element.querySelector('#date-field-id');
|
||||
const dateElement = element.querySelector<HTMLInputElement>('#date-field-id');
|
||||
expect(dateElement).toBeDefined();
|
||||
expect(dateElement.value).toContain('12-30-9999');
|
||||
|
||||
widget.field.value = '03-02-2020';
|
||||
|
||||
fixture.componentInstance.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(dateElement.value).toContain('03-02-2020');
|
||||
expect(dateElement.value).toContain('02-03-2020');
|
||||
});
|
||||
|
||||
describe('when form model has left labels', () => {
|
||||
@@ -285,7 +292,8 @@ describe('DateWidgetComponent', () => {
|
||||
|
||||
describe('Set dynamic dates', () => {
|
||||
it('should min date equal to the today date minus minimum date range value', async () => {
|
||||
widget.field = new FormFieldModel(null, {
|
||||
widget.field = new FormFieldModel(form, {
|
||||
type: FormFieldTypes.DATE,
|
||||
dynamicDateRangeSelection: true,
|
||||
minDateRangeValue: 4
|
||||
});
|
||||
@@ -293,13 +301,13 @@ describe('DateWidgetComponent', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const todayDate = moment().format(DATE_FORMAT_CLOUD);
|
||||
const expected = moment(todayDate).subtract(widget.field.minDateRangeValue, 'days');
|
||||
expect(widget.minDate).toEqual(expected);
|
||||
const expected = subDays(adapter.today(), widget.field.minDateRangeValue);
|
||||
expect(widget.minDate.toDateString()).toBe(expected.toDateString());
|
||||
});
|
||||
|
||||
it('should min date and max date be undefined if dynamic min and max date are not set', async () => {
|
||||
widget.field = new FormFieldModel(null, {
|
||||
widget.field = new FormFieldModel(form, {
|
||||
type: FormFieldTypes.DATE,
|
||||
dynamicDateRangeSelection: true
|
||||
});
|
||||
|
||||
@@ -311,7 +319,8 @@ describe('DateWidgetComponent', () => {
|
||||
});
|
||||
|
||||
it('should max date be undefined if only minimum date range value is set', async () => {
|
||||
widget.field = new FormFieldModel(null, {
|
||||
widget.field = new FormFieldModel(form, {
|
||||
type: FormFieldTypes.DATE,
|
||||
dynamicDateRangeSelection: true,
|
||||
minDateRangeValue: 4
|
||||
});
|
||||
@@ -323,7 +332,8 @@ describe('DateWidgetComponent', () => {
|
||||
});
|
||||
|
||||
it('should min date be undefined if only maximum date range value is set', async () => {
|
||||
widget.field = new FormFieldModel(null, {
|
||||
widget.field = new FormFieldModel(form, {
|
||||
type: FormFieldTypes.DATE,
|
||||
dynamicDateRangeSelection: true,
|
||||
maxDateRangeValue: 4
|
||||
});
|
||||
@@ -335,7 +345,8 @@ describe('DateWidgetComponent', () => {
|
||||
});
|
||||
|
||||
it('should max date equal to the today date plus maximum date range value', async () => {
|
||||
widget.field = new FormFieldModel(null, {
|
||||
widget.field = new FormFieldModel(form, {
|
||||
type: FormFieldTypes.DATE,
|
||||
dynamicDateRangeSelection: true,
|
||||
maxDateRangeValue: 5
|
||||
});
|
||||
@@ -343,13 +354,13 @@ describe('DateWidgetComponent', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const todayDate = moment().format(DATE_FORMAT_CLOUD);
|
||||
const expected = moment(todayDate).add(widget.field.maxDateRangeValue, 'days');
|
||||
expect(widget.maxDate).toEqual(expected);
|
||||
const expected = addDays(adapter.today(), widget.field.maxDateRangeValue);
|
||||
expect(widget.maxDate.toDateString()).toBe(expected.toDateString());
|
||||
});
|
||||
|
||||
it('should maxDate and minDate be undefined if minDateRangeValue and maxDateRangeValue are null', async () => {
|
||||
widget.field = new FormFieldModel(null, {
|
||||
widget.field = new FormFieldModel(form, {
|
||||
type: FormFieldTypes.DATE,
|
||||
dynamicDateRangeSelection: true,
|
||||
maxDateRangeValue: null,
|
||||
minDateRangeValue: null
|
||||
@@ -363,7 +374,8 @@ describe('DateWidgetComponent', () => {
|
||||
});
|
||||
|
||||
it('should minDate be undefined if minDateRangeValue is null and maxDateRangeValue is greater than 0', async () => {
|
||||
widget.field = new FormFieldModel(null, {
|
||||
widget.field = new FormFieldModel(form, {
|
||||
type: FormFieldTypes.DATE,
|
||||
dynamicDateRangeSelection: true,
|
||||
maxDateRangeValue: 15,
|
||||
minDateRangeValue: null
|
||||
@@ -377,7 +389,8 @@ describe('DateWidgetComponent', () => {
|
||||
});
|
||||
|
||||
it('should maxDate be undefined if maxDateRangeValue is null and minDateRangeValue is greater than 0', async () => {
|
||||
widget.field = new FormFieldModel(null, {
|
||||
widget.field = new FormFieldModel(form, {
|
||||
type: FormFieldTypes.DATE,
|
||||
dynamicDateRangeSelection: true,
|
||||
maxDateRangeValue: null,
|
||||
minDateRangeValue: 10
|
||||
@@ -392,8 +405,10 @@ describe('DateWidgetComponent', () => {
|
||||
|
||||
describe('check date validation by dynamic date ranges', () => {
|
||||
it('should minValue be equal to today date minus minDateRangeValue', async () => {
|
||||
spyOn(widget, 'getTodaysFormattedDate').and.returnValue('2022-07-22');
|
||||
widget.field = new FormFieldModel(null, {
|
||||
spyOn(adapter, 'today').and.returnValue(new Date('2022-07-22'));
|
||||
|
||||
widget.field = new FormFieldModel(form, {
|
||||
type: FormFieldTypes.DATE,
|
||||
dynamicDateRangeSelection: true,
|
||||
maxDateRangeValue: null,
|
||||
minDateRangeValue: 1,
|
||||
@@ -404,16 +419,16 @@ describe('DateWidgetComponent', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const expectedMinValueString = '2022-07-21';
|
||||
|
||||
expect(widget.field.minValue).toEqual(expectedMinValueString);
|
||||
expect(widget.field.minValue).toEqual('21-07-2022');
|
||||
expect(widget.maxDate).toBeUndefined();
|
||||
expect(widget.field.maxValue).toBeNull();
|
||||
});
|
||||
|
||||
it('should maxValue be equal to today date plus maxDateRangeValue', async () => {
|
||||
spyOn(widget, 'getTodaysFormattedDate').and.returnValue('2022-07-22');
|
||||
widget.field = new FormFieldModel(null, {
|
||||
spyOn(adapter, 'today').and.returnValue(new Date('2022-07-22'));
|
||||
|
||||
widget.field = new FormFieldModel(form, {
|
||||
type: FormFieldTypes.DATE,
|
||||
dynamicDateRangeSelection: true,
|
||||
maxDateRangeValue: 8,
|
||||
minDateRangeValue: null,
|
||||
@@ -424,16 +439,16 @@ describe('DateWidgetComponent', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const expectedMaxValueString = '2022-07-30';
|
||||
|
||||
expect(widget.field.maxValue).toEqual(expectedMaxValueString);
|
||||
expect(widget.field.maxValue).toEqual('30-07-2022');
|
||||
expect(widget.minDate).toBeUndefined();
|
||||
expect(widget.field.minValue).toBeNull();
|
||||
});
|
||||
|
||||
it('should maxValue and minValue be null if maxDateRangeValue and minDateRangeValue are null', async () => {
|
||||
spyOn(widget, 'getTodaysFormattedDate').and.returnValue('2022-07-22');
|
||||
widget.field = new FormFieldModel(null, {
|
||||
spyOn(adapter, 'today').and.returnValue(new Date('2022-07-22'));
|
||||
|
||||
widget.field = new FormFieldModel(form, {
|
||||
type: FormFieldTypes.DATE,
|
||||
dynamicDateRangeSelection: true,
|
||||
maxDateRangeValue: null,
|
||||
minDateRangeValue: null,
|
||||
@@ -451,8 +466,10 @@ describe('DateWidgetComponent', () => {
|
||||
});
|
||||
|
||||
it('should maxValue and minValue not be null if maxDateRangeVale and minDateRangeValue are not null', async () => {
|
||||
spyOn(widget, 'getTodaysFormattedDate').and.returnValue('2022-07-22');
|
||||
widget.field = new FormFieldModel(null, {
|
||||
spyOn(adapter, 'today').and.returnValue(new Date('2022-07-22'));
|
||||
|
||||
widget.field = new FormFieldModel(form, {
|
||||
type: FormFieldTypes.DATE,
|
||||
dynamicDateRangeSelection: true,
|
||||
maxDateRangeValue: 8,
|
||||
minDateRangeValue: 10,
|
||||
@@ -463,11 +480,8 @@ describe('DateWidgetComponent', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const expectedMaxValueString = '2022-07-30';
|
||||
const expectedMinValueString = '2022-07-12';
|
||||
|
||||
expect(widget.field.maxValue).toEqual(expectedMaxValueString);
|
||||
expect(widget.field.minValue).toEqual(expectedMinValueString);
|
||||
expect(widget.field.minValue).toEqual('12-07-2022');
|
||||
expect(widget.field.maxValue).toEqual('30-07-2022');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -17,22 +17,20 @@
|
||||
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
|
||||
import { Component, OnInit, ViewEncapsulation, OnDestroy } from '@angular/core';
|
||||
import { Component, OnInit, ViewEncapsulation, OnDestroy, Input } from '@angular/core';
|
||||
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
|
||||
import moment, { Moment } from 'moment';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import {
|
||||
MOMENT_DATE_FORMATS, MomentDateAdapter, WidgetComponent,
|
||||
UserPreferencesService, UserPreferenceValues, FormService
|
||||
} from '@alfresco/adf-core';
|
||||
import { DATE_FORMAT_CLOUD } from '../../../../models/date-format-cloud.model';
|
||||
import { WidgetComponent, FormService, AdfDateFnsAdapter, DateFnsUtils } from '@alfresco/adf-core';
|
||||
import { MatDatepickerInputEvent } from '@angular/material/datepicker';
|
||||
import { CLOUD_FORM_DATE_FORMATS } from '../../../date-formats';
|
||||
import { addDays, subDays } from 'date-fns';
|
||||
|
||||
@Component({
|
||||
selector: 'date-widget',
|
||||
providers: [
|
||||
{ provide: DateAdapter, useClass: MomentDateAdapter },
|
||||
{ provide: MAT_DATE_FORMATS, useValue: MOMENT_DATE_FORMATS }],
|
||||
{ provide: MAT_DATE_FORMATS, useValue: CLOUD_FORM_DATE_FORMATS },
|
||||
{ provide: DateAdapter, useClass: AdfDateFnsAdapter }
|
||||
],
|
||||
templateUrl: './date-cloud.widget.html',
|
||||
styleUrls: ['./date-cloud.widget.scss'],
|
||||
host: {
|
||||
@@ -50,52 +48,58 @@ import { DATE_FORMAT_CLOUD } from '../../../../models/date-format-cloud.model';
|
||||
})
|
||||
export class DateCloudWidgetComponent extends WidgetComponent implements OnInit, OnDestroy {
|
||||
typeId = 'DateCloudWidgetComponent';
|
||||
readonly DATE_FORMAT = 'dd-MM-yyyy';
|
||||
|
||||
minDate: Moment;
|
||||
maxDate: Moment;
|
||||
minDate: Date;
|
||||
maxDate: Date;
|
||||
startAt: Date;
|
||||
|
||||
/**
|
||||
* Current date value.
|
||||
* The value is always stored in the format `dd-MM-yyyy`,
|
||||
* but displayed in the UI component using `dateDisplayFormat`
|
||||
*/
|
||||
@Input()
|
||||
value: any = null;
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(public formService: FormService,
|
||||
private dateAdapter: DateAdapter<Moment>,
|
||||
private userPreferencesService: UserPreferencesService) {
|
||||
private dateAdapter: DateAdapter<Date>) {
|
||||
super(formService);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.userPreferencesService
|
||||
.select(UserPreferenceValues.Locale)
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(locale => this.dateAdapter.setLocale(locale));
|
||||
|
||||
const momentDateAdapter = this.dateAdapter as MomentDateAdapter;
|
||||
momentDateAdapter.overrideDisplayFormat = this.field.dateDisplayFormat;
|
||||
if (this.field.dateDisplayFormat) {
|
||||
const adapter = this.dateAdapter as AdfDateFnsAdapter;
|
||||
adapter.displayFormat = this.field.dateDisplayFormat;
|
||||
}
|
||||
|
||||
if (this.field) {
|
||||
if (this.field.dynamicDateRangeSelection) {
|
||||
const today = this.getTodaysFormattedDate();
|
||||
if (Number.isInteger(this.field.minDateRangeValue)) {
|
||||
this.minDate = moment(today).subtract(this.field.minDateRangeValue, 'days');
|
||||
this.field.minValue = this.minDate.format(DATE_FORMAT_CLOUD);
|
||||
this.minDate = subDays(this.dateAdapter.today(), this.field.minDateRangeValue);
|
||||
this.field.minValue = DateFnsUtils.formatDate(this.minDate, this.DATE_FORMAT);
|
||||
}
|
||||
if (Number.isInteger(this.field.maxDateRangeValue)) {
|
||||
this.maxDate = moment(today).add(this.field.maxDateRangeValue, 'days');
|
||||
this.field.maxValue = this.maxDate.format(DATE_FORMAT_CLOUD);
|
||||
this.maxDate = addDays(this.dateAdapter.today(), this.field.maxDateRangeValue);
|
||||
this.field.maxValue = DateFnsUtils.formatDate(this.maxDate, this.DATE_FORMAT);
|
||||
}
|
||||
} else {
|
||||
if (this.field.minValue) {
|
||||
this.minDate = moment(this.field.minValue, DATE_FORMAT_CLOUD);
|
||||
this.minDate = this.dateAdapter.parse(this.field.minValue, this.DATE_FORMAT);
|
||||
}
|
||||
|
||||
if (this.field.maxValue) {
|
||||
this.maxDate = moment(this.field.maxValue, DATE_FORMAT_CLOUD);
|
||||
this.maxDate = this.dateAdapter.parse(this.field.maxValue, this.DATE_FORMAT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getTodaysFormattedDate() {
|
||||
return moment().format(DATE_FORMAT_CLOUD);
|
||||
if (this.field.value) {
|
||||
this.startAt = this.dateAdapter.parse(this.field.value, this.DATE_FORMAT);
|
||||
this.value = this.dateAdapter.parse(this.field.value, this.DATE_FORMAT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
@@ -103,13 +107,16 @@ export class DateCloudWidgetComponent extends WidgetComponent implements OnInit,
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
onDateChanged(newDateValue) {
|
||||
const date = moment(newDateValue, this.field.dateDisplayFormat, true);
|
||||
if (date.isValid()) {
|
||||
this.field.value = date.format(this.field.dateDisplayFormat);
|
||||
onDateChanged(event: MatDatepickerInputEvent<Date>) {
|
||||
const value = event.value;
|
||||
const input = event.targetElement as HTMLInputElement;
|
||||
|
||||
if (value) {
|
||||
this.field.value = this.dateAdapter.format(value, this.DATE_FORMAT);
|
||||
} else {
|
||||
this.field.value = newDateValue;
|
||||
this.field.value = input.value;
|
||||
}
|
||||
|
||||
this.onFieldChanged(this.field);
|
||||
}
|
||||
}
|
||||
|
38
lib/process-services-cloud/src/lib/form/date-formats.ts
Normal file
38
lib/process-services-cloud/src/lib/form/date-formats.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { MatDateFormats } from '@angular/material/core';
|
||||
|
||||
/**
|
||||
* Provides date/time display formatting for the cloud components.
|
||||
*
|
||||
* Notes for developers: display formats are different from the storage formats.
|
||||
* Components have a fixed format for saving dates and datetime values,
|
||||
* while dynamic format for UI display.
|
||||
*/
|
||||
export const CLOUD_FORM_DATE_FORMATS: MatDateFormats = {
|
||||
parse: {
|
||||
dateInput: 'yyyy-MM-dd'
|
||||
},
|
||||
display: {
|
||||
dateInput: 'yyyy-MM-dd',
|
||||
monthLabel: 'LLL',
|
||||
monthYearLabel: 'LLL uuuu',
|
||||
dateA11yLabel: 'PP',
|
||||
monthYearA11yLabel: 'LLLL uuuu'
|
||||
}
|
||||
};
|
@@ -40,3 +40,4 @@ export * from './services/content-cloud-node-selector.service';
|
||||
export * from './services/process-cloud-content.service';
|
||||
|
||||
export * from './form-cloud.module';
|
||||
export * from './date-formats';
|
||||
|
Reference in New Issue
Block a user