Skip to content

Commit

Permalink
AAE-19102 Date should be formatted correctly on the task form conside…
Browse files Browse the repository at this point in the history
…ring specified display format
  • Loading branch information
tomgny committed Jun 27, 2024
1 parent 6cd2e57 commit 409ae4a
Show file tree
Hide file tree
Showing 12 changed files with 249 additions and 210 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ export class DateFieldValidator implements FormFieldValidator {

// Validates that the input string is a valid date formatted as <dateFormat> (default D-M-YYYY)
static isValidDate(inputDate: string, dateFormat: string = 'D-M-YYYY'): boolean {
// debugger;
return DateFnsUtils.isValidDate(inputDate, dateFormat);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ export class FormFieldModel extends FormWidgetModel {
if (isNumberValue(value)) {
dateValue = new Date(value);
} else {
// debugger;
dateValue = this.isDateTimeField(json)
? DateFnsUtils.parseDate(value, 'YYYY-MM-DD hh:mm A')
: DateFnsUtils.parseDate(value.split('T')[0], 'YYYY-M-D');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,7 @@
<input matInput
[matDatetimepicker]="datetimePicker"
[id]="field.id"
[(ngModel)]="value"
[required]="isRequired()"
[disabled]="field.readOnly"
(change)="onValueChanged($event)"
(dateChange)="onDateChanged($event)"
[formControl]="datetimeInputControl"
(keydown.enter)="datetimePicker.open()"
[placeholder]="field.placeholder"
[matTooltip]="field.tooltip"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ describe('DateTimeWidgetComponent', () => {
expect(widget.maxDate.toISOString()).toBe('1982-03-13T10:00:00.000Z');
});

it('should eval visibility on date changed', () => {
it('should eval visibility on date changed', async () => {
spyOn(widget, 'onFieldChanged').and.callThrough();

const field = new FormFieldModel(form, {
Expand All @@ -100,7 +100,11 @@ describe('DateTimeWidgetComponent', () => {
});

widget.field = field;
widget.onDateChanged({ value: new Date('1982-03-13T10:00:00.000Z') } as any);

fixture.detectChanges();
await fixture.whenStable();

widget.datetimeInputControl.setValue(new Date('1982-03-13T10:00:00.000Z'));

expect(widget.onFieldChanged).toHaveBeenCalledWith(field);
});
Expand All @@ -115,7 +119,7 @@ describe('DateTimeWidgetComponent', () => {

widget.field = field;

fixture.whenStable();
fixture.detectChanges();
await fixture.whenStable();

expect(field.isValid).toBeTrue();
Expand All @@ -131,12 +135,12 @@ describe('DateTimeWidgetComponent', () => {

widget.field = field;

fixture.whenStable();
fixture.detectChanges();
await fixture.whenStable();

widget.onDateChanged({ value: new Date('9999-09-12T09:10:00.000Z') } as any);
widget.datetimeInputControl.setValue(new Date('9999-09-12T09:10:00.000Z'));

expect(field.value).toBe('9999-09-12T09:10:00.000Z');
expect(field.value).toEqual(new Date('9999-09-12T09:10:00.000Z'));
expect(field.isValid).toBeTrue();
});

Expand All @@ -153,19 +157,15 @@ describe('DateTimeWidgetComponent', () => {
fixture.detectChanges();
await fixture.whenStable();

widget.onDateChanged({
value: null,
targetElement: {
value: '123abc'
}
} as any);
widget.datetimeInputControl.setValue('123abc');

fixture.detectChanges();
await fixture.whenStable();

expect(field.value).toBe('123abc');
expect(field.isValid).toBeFalse();
expect(field.validationSummary.message).toBe('D-M-YYYY hh:mm A');
expect(widget.datetimeInputControl.invalid).toBeTrue();
// expect(field.value).toBe('123abc');
// expect(field.isValid).toBeFalse();
// expect(field.validationSummary.message).toBe('D-M-YYYY hh:mm A');
});

it('should process direct keyboard input', async () => {
Expand All @@ -181,9 +181,10 @@ describe('DateTimeWidgetComponent', () => {
fixture.whenStable();
await fixture.whenStable();

widget.onValueChanged({ target: { value: '9999-09-12T09:10:00.000Z' } } as any);
const input = await loader.getHarness(MatInputHarness);
await input.setValue('9999-09-12T09:10:00.000Z');

expect(field.value).toBe('9999-09-12T09:10:00.000Z');
expect(field.value).toEqual(new Date('9999-09-12T09:10:00.000Z'));
expect(field.isValid).toBeTrue();
});

Expand All @@ -200,18 +201,11 @@ describe('DateTimeWidgetComponent', () => {
fixture.detectChanges();
await fixture.whenStable();

widget.onValueChanged({
target: {
value: '123abc'
}
} as any);

fixture.detectChanges();
await fixture.whenStable();
const input = await loader.getHarness(MatInputHarness);
await input.setValue('123abc');

expect(field.value).toBe('123abc');
expect(field.isValid).toBeFalse();
expect(field.validationSummary.message).toBe('D-M-YYYY hh:mm A');
expect(widget.datetimeInputControl.invalid).toBeTrue();
// expect(field.validationSummary.message).toBe('D-M-YYYY hh:mm A');
});

it('should allow empty dates when not required', async () => {
Expand All @@ -227,10 +221,14 @@ describe('DateTimeWidgetComponent', () => {
fixture.whenStable();
await fixture.whenStable();

widget.onDateChanged({ value: null, targetElement: { value: '' } } as any);
// widget.onDateChanged({ value: null, targetElement: { value: '' } } as any);
const input = await loader.getHarness(MatInputHarness);
await input.setValue('');

expect(field.value).toBe('');
expect(field.isValid).toBeTrue();
expect(widget.datetimeInputControl.value).toBe(null);
expect(widget.datetimeInputControl.valid).toBeTrue();
// expect(field.value).toBe('');
// expect(field.isValid).toBeTrue();
});

describe('when tooltip is set', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,20 @@
/* eslint-disable @angular-eslint/component-selector */

import { NgIf } from '@angular/common';
import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms';
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatTooltipModule } from '@angular/material/tooltip';
import { DatetimeAdapter, MAT_DATETIME_FORMATS, MatDatetimepickerInputEvent, MatDatetimepickerModule } from '@mat-datetimepicker/core';
import { DatetimeAdapter, MAT_DATETIME_FORMATS, MatDatetimepickerModule } from '@mat-datetimepicker/core';
import { TranslateModule } from '@ngx-translate/core';
import { isValid } from 'date-fns';
import { ADF_DATE_FORMATS, ADF_DATETIME_FORMATS, AdfDateFnsAdapter, AdfDateTimeFnsAdapter, DateFnsUtils } from '../../../../common';
import { FormService } from '../../../services/form.service';
import { ErrorWidgetComponent } from '../error/error.component';
import { WidgetComponent } from '../widget.component';
import { Subscription } from 'rxjs';

@Component({
selector: 'date-time-widget',
Expand All @@ -49,70 +50,71 @@ import { WidgetComponent } from '../widget.component';
MatFormFieldModule,
MatInputModule,
MatDatetimepickerModule,
FormsModule,
ReactiveFormsModule,
MatTooltipModule,
ErrorWidgetComponent
],
encapsulation: ViewEncapsulation.None
})
export class DateTimeWidgetComponent extends WidgetComponent implements OnInit {
export class DateTimeWidgetComponent extends WidgetComponent implements OnInit, OnDestroy {
minDate: Date;
maxDate: Date;

@Input()
value: any = null;
datetimeInputControl: FormControl;

private datetimeChangesSubscription: Subscription;

constructor(public formService: FormService, private dateAdapter: DateAdapter<Date>, private dateTimeAdapter: DatetimeAdapter<Date>) {
super(formService);
}

ngOnInit() {
if (this.field.dateDisplayFormat) {
this.initFormControl();
this.initDateAdapter();
this.initDateRange();
this.subscribeToDateChanges();
}

private subscribeToDateChanges(): void {
this.datetimeChangesSubscription = this.datetimeInputControl.valueChanges.subscribe((newDate: Date) => {
if (newDate && isValid(newDate)) {
this.field.value = newDate;
this.onFieldChanged(this.field);
}
});
}

private initDateAdapter(): void {
if (this.field?.dateDisplayFormat) {
const dateAdapter = this.dateAdapter as AdfDateFnsAdapter;
dateAdapter.displayFormat = this.field.dateDisplayFormat;

const dateTimeAdapter = this.dateTimeAdapter as AdfDateTimeFnsAdapter;
dateTimeAdapter.displayFormat = this.field.dateDisplayFormat;
}

if (this.field) {
if (this.field.minValue) {
this.minDate = DateFnsUtils.localToUtc(new Date(this.field.minValue));
}

if (this.field.maxValue) {
this.maxDate = DateFnsUtils.localToUtc(new Date(this.field.maxValue));
}

if (this.field.value) {
this.value = DateFnsUtils.localToUtc(new Date(this.field.value));
}
}
}

onValueChanged(event: Event) {
const input = event.target as HTMLInputElement;
const newValue = this.dateTimeAdapter.parse(input.value, this.field.dateDisplayFormat);

if (isValid(newValue)) {
this.field.value = DateFnsUtils.utcToLocal(newValue).toISOString();
} else {
this.field.value = input.value;
private initDateRange(): void {
if (this.field?.minValue) {
this.minDate = DateFnsUtils.localToUtc(new Date(this.field.minValue));
}

this.onFieldChanged(this.field);
if (this.field?.maxValue) {
this.maxDate = DateFnsUtils.localToUtc(new Date(this.field.maxValue));
}
}

onDateChanged(event: MatDatetimepickerInputEvent<Date>) {
const newValue = event.value;
const input = event.targetElement as HTMLInputElement;

if (newValue && isValid(newValue)) {
this.field.value = DateFnsUtils.utcToLocal(newValue).toISOString();
} else {
this.field.value = input.value;
}
private initFormControl(): void {
this.datetimeInputControl = new FormControl(
{
value: this.field?.value,
disabled: this.field?.readOnly || this.readOnly
},
this.isRequired() ? [Validators.required] : []
);
}

this.onFieldChanged(this.field);
ngOnDestroy(): void {
this.datetimeChangesSubscription?.unsubscribe();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,10 @@
<input matInput
[matDatepicker]="datePicker"
[id]="field.id"
[(ngModel)]="value"
[required]="field.required"
[formControl]="dateInputControl"
[placeholder]="field.placeholder"
[min]="minDate"
[max]="maxDate"
[disabled]="field.readOnly"
(dateChange)="onDateChange($event)"
(blur)="markAsTouched()">
<mat-datepicker-toggle matSuffix [for]="datePicker" [disabled]="field.readOnly"></mat-datepicker-toggle>
<mat-datepicker #datePicker
Expand Down
Loading

0 comments on commit 409ae4a

Please sign in to comment.