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 21, 2024
1 parent 16578bc commit 37da97b
Show file tree
Hide file tree
Showing 12 changed files with 253 additions and 213 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 @@ -362,13 +362,14 @@ 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');
}

if (isValidDate(dateValue)) {
return DateFnsUtils.formatDate(dateValue, this.dateDisplayFormat);
value = dateValue;
}
}

Expand Down Expand Up @@ -441,7 +442,7 @@ export class FormFieldModel extends FormWidgetModel {
}
case FormFieldTypes.DATE: {
if (typeof this.value === 'string' && this.value === 'today') {
this.value = DateFnsUtils.formatDate(new Date(), this.dateDisplayFormat);
this.value = new Date();
}

const dateValue = DateFnsUtils.parseDate(this.value, this.dateDisplayFormat);
Expand All @@ -457,7 +458,8 @@ export class FormFieldModel extends FormWidgetModel {
}
case FormFieldTypes.DATETIME: {
if (typeof this.value === 'string' && this.value === 'now') {
this.value = DateFnsUtils.formatDate(new Date(), this.dateDisplayFormat);
// this.value = DateFnsUtils.formatDate(new Date(), this.dateDisplayFormat);
this.value = new Date();
}

const dateTimeValue = this.value !== null ? new Date(this.value) : null;
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 37da97b

Please sign in to comment.