mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[APPS-2108] migrate date widget to Angular date picker (#8975)
* migrate date widget to Angular date picker * [ci:force] fix tests * [ci:force] fix tests * [ci:force] test fixes * [ci:force] missing label attributes * added type for value
This commit is contained in:
@@ -45,8 +45,6 @@ import { CoreTestingModule } from '../../testing';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { FormRenderingService } from '../services/form-rendering.service';
|
||||
import { TextWidgetComponent } from './widgets';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { DebugElement } from '@angular/core';
|
||||
import { FormRulesManager } from '../models/form-rules.model';
|
||||
|
||||
const typeIntoInput = (targetInput: HTMLInputElement, message: string) => {
|
||||
@@ -55,11 +53,6 @@ const typeIntoInput = (targetInput: HTMLInputElement, message: string) => {
|
||||
targetInput.dispatchEvent(new Event('input'));
|
||||
};
|
||||
|
||||
const typeIntoDate = (targetInput: DebugElement, date: { srcElement: { value: string } }) => {
|
||||
expect(targetInput).toBeTruthy('Expected input to set to be valid and not null');
|
||||
targetInput.triggerEventHandler('change', date);
|
||||
};
|
||||
|
||||
const expectElementToBeHidden = (targetElement: HTMLElement): void => {
|
||||
expect(targetElement).toBeTruthy();
|
||||
expect(targetElement.style.visibility).toBe('hidden', `${targetElement.id} should be hidden but it is not`);
|
||||
@@ -113,11 +106,13 @@ describe('Form Renderer Component', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const inputDateTestOne = fixture.debugElement.query(By.css('#Date0hwq20'));
|
||||
const inputDateTestOne = fixture.nativeElement.querySelector('#Date0hwq20') as HTMLInputElement;
|
||||
let displayTextElementContainer: HTMLInputElement = fixture.nativeElement.querySelector('#field-Text0pqd1u-container');
|
||||
expectElementToBeHidden(displayTextElementContainer);
|
||||
|
||||
typeIntoDate(inputDateTestOne, { srcElement: { value: '2019-11-19' } });
|
||||
inputDateTestOne.value = '2019-11-19';
|
||||
inputDateTestOne.dispatchEvent(new Event('change'));
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
@@ -130,11 +125,14 @@ describe('Form Renderer Component', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const inputDateTestOne = fixture.debugElement.query(By.css('#Date0hwq20'));
|
||||
const inputDateTestOne = fixture.nativeElement.querySelector('#Date0hwq20') as HTMLInputElement;
|
||||
|
||||
let displayTextElementContainer: HTMLDivElement = fixture.nativeElement.querySelector('#field-Text0uyqd3-container');
|
||||
expectElementToBeVisible(displayTextElementContainer);
|
||||
|
||||
typeIntoDate(inputDateTestOne, { srcElement: { value: '2019-11-19' } });
|
||||
inputDateTestOne.value = '2019-11-19';
|
||||
inputDateTestOne.dispatchEvent(new Event('change'));
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
|
@@ -1,26 +1,25 @@
|
||||
<div class="{{field.className}}" id="data-widget" [class.adf-invalid]="!field.isValid && isTouched()">
|
||||
<mat-form-field class="adf-date-widget" [hideRequiredMarker]="true">
|
||||
<label class="adf-label" [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"
|
||||
(blur)="markAsTouched()">
|
||||
<mat-datepicker-toggle matSuffix [for]="datePicker" [disabled]="field.readOnly" ></mat-datepicker-toggle>
|
||||
<mat-form-field [floatLabel]="'always'" class="adf-date-widget">
|
||||
<mat-label class="adf-label"
|
||||
[id]="field.id + '-label'"
|
||||
[attr.for]="field.id"
|
||||
>{{field.name | translate }} ({{field.dateDisplayFormat}})</mat-label>
|
||||
<input matInput [matDatepicker]="datePicker"
|
||||
[id]="field.id"
|
||||
[(ngModel)]="value"
|
||||
[required]="field.required"
|
||||
[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
|
||||
[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>
|
||||
|
@@ -1,11 +0,0 @@
|
||||
.adf {
|
||||
&-date-widget {
|
||||
.mat-form-field-suffix {
|
||||
top: 26px;
|
||||
}
|
||||
|
||||
.mat-form-field-label-wrapper {
|
||||
top: 20px;
|
||||
}
|
||||
}
|
||||
}
|
@@ -25,7 +25,6 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
import { FormFieldTypes } from '../core/form-field-types';
|
||||
|
||||
describe('DateWidgetComponent', () => {
|
||||
|
||||
let widget: DateWidgetComponent;
|
||||
let fixture: ComponentFixture<DateWidgetComponent>;
|
||||
let element: HTMLElement;
|
||||
@@ -101,7 +100,9 @@ describe('DateWidgetComponent', () => {
|
||||
readOnly: 'false'
|
||||
});
|
||||
widget.field = field;
|
||||
widget.onDateChanged({ value: moment('12/12/2012', widget.field.dateDisplayFormat) });
|
||||
widget.onDateChange({
|
||||
value: moment('12/12/2012', widget.field.dateDisplayFormat)
|
||||
} as any);
|
||||
|
||||
expect(widget.onFieldChanged).toHaveBeenCalledWith(field);
|
||||
});
|
||||
@@ -126,13 +127,6 @@ describe('DateWidgetComponent', () => {
|
||||
|
||||
expect(fixture.nativeElement.querySelector('.adf-invalid')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should be able to display label with asterix', () => {
|
||||
const asterisk: HTMLElement = element.querySelector('.adf-asterisk');
|
||||
|
||||
expect(asterisk).toBeTruthy();
|
||||
expect(asterisk.textContent).toEqual('*');
|
||||
});
|
||||
});
|
||||
|
||||
describe('template check', () => {
|
||||
@@ -142,7 +136,7 @@ describe('DateWidgetComponent', () => {
|
||||
TestBed.resetTestingModule();
|
||||
});
|
||||
|
||||
it('should show visible date widget', () => {
|
||||
it('should show visible date widget', async () => {
|
||||
widget.field = new FormFieldModel(new FormModel(), {
|
||||
id: 'date-field-id',
|
||||
name: 'date-name',
|
||||
@@ -153,15 +147,15 @@ describe('DateWidgetComponent', () => {
|
||||
widget.field.isVisible = true;
|
||||
|
||||
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).not.toBeNull();
|
||||
|
||||
const dateElement: any = element.querySelector('#date-field-id');
|
||||
expect(dateElement.value).toContain('9-9-9999');
|
||||
expect(dateElement?.value).toContain('9-9-9999');
|
||||
});
|
||||
|
||||
it('[C310335] - Should be able to change display format for Date widget', () => {
|
||||
it('[C310335] - Should be able to change display format for Date widget', async () => {
|
||||
widget.field = new FormFieldModel(new FormModel(), {
|
||||
id: 'date-field-id',
|
||||
name: 'date-name',
|
||||
@@ -173,25 +167,20 @@ describe('DateWidgetComponent', () => {
|
||||
widget.field.dateDisplayFormat = 'MM-DD-YYYY';
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
let dateElement: any = element.querySelector('#date-field-id');
|
||||
expect(dateElement.value).toContain('12-30-9999');
|
||||
|
||||
widget.field.value = '5-6-2019 00:00';
|
||||
widget.field.dateDisplayFormat = 'D-M-YYYY HH:mm';
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
dateElement = element.querySelector('#date-field-id');
|
||||
expect(dateElement.value).toContain('5-6-2019 00:00');
|
||||
let dateElement = element.querySelector<HTMLInputElement>('#date-field-id');
|
||||
expect(dateElement?.value).toContain('12-30-9999');
|
||||
|
||||
widget.field.value = '05.06.2019';
|
||||
widget.field.dateDisplayFormat = 'DD.MM.YYYY';
|
||||
|
||||
fixture.componentInstance.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
dateElement = element.querySelector('#date-field-id');
|
||||
expect(dateElement.value).toContain('05.06.2019');
|
||||
dateElement = element.querySelector<HTMLInputElement>('#date-field-id');
|
||||
expect(dateElement?.value).toContain('05.06.2019');
|
||||
});
|
||||
|
||||
it('should disable date button when is readonly', () => {
|
||||
@@ -233,7 +222,7 @@ describe('DateWidgetComponent', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should display always the json value', () => {
|
||||
it('should display always the json value', async () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
id: 'date-field-id',
|
||||
name: 'date-name',
|
||||
@@ -241,20 +230,23 @@ describe('DateWidgetComponent', () => {
|
||||
type: 'date',
|
||||
readOnly: 'false'
|
||||
});
|
||||
|
||||
field.isVisible = true;
|
||||
field.dateDisplayFormat = 'MM-DD-YYYY';
|
||||
widget.field = field;
|
||||
|
||||
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');
|
||||
expect(dateElement.value).toContain('12-30-9999');
|
||||
const dateElement = element.querySelector<HTMLInputElement>('#date-field-id');
|
||||
expect(dateElement?.value).toContain('12-30-9999');
|
||||
|
||||
widget.field.value = '03-02-2020';
|
||||
|
||||
fixture.componentInstance.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
expect(dateElement.value).toContain('03-02-2020');
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(dateElement?.value).toContain('03-02-2020');
|
||||
});
|
||||
});
|
||||
|
@@ -20,13 +20,14 @@
|
||||
import { UserPreferencesService, UserPreferenceValues } from '../../../../common/services/user-preferences.service';
|
||||
import { MomentDateAdapter } from '../../../../common/utils/moment-date-adapter';
|
||||
import { MOMENT_DATE_FORMATS } from '../../../../common/utils/moment-date-formats.model';
|
||||
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 { FormService } from '../../../services/form.service';
|
||||
import { WidgetComponent } from '../widget.component';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { MatDatepickerInputEvent } from '@angular/material/datepicker';
|
||||
|
||||
@Component({
|
||||
selector: 'date-widget',
|
||||
@@ -34,7 +35,6 @@ import { takeUntil } from 'rxjs/operators';
|
||||
{ provide: DateAdapter, useClass: MomentDateAdapter },
|
||||
{ provide: MAT_DATE_FORMATS, useValue: MOMENT_DATE_FORMATS }],
|
||||
templateUrl: './date.widget.html',
|
||||
styleUrls: ['./date.widget.scss'],
|
||||
host: {
|
||||
'(click)': 'event($event)',
|
||||
'(blur)': 'event($event)',
|
||||
@@ -54,6 +54,10 @@ export class DateWidgetComponent extends WidgetComponent implements OnInit, OnDe
|
||||
|
||||
minDate: Moment;
|
||||
maxDate: Moment;
|
||||
startAt: Moment;
|
||||
|
||||
@Input()
|
||||
value: any = null;
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
@@ -80,6 +84,9 @@ export class DateWidgetComponent extends WidgetComponent implements OnInit, OnDe
|
||||
if (this.field.maxValue) {
|
||||
this.maxDate = moment(this.field.maxValue, this.DATE_FORMAT);
|
||||
}
|
||||
|
||||
this.startAt = moment(this.field.value, this.field.dateDisplayFormat);
|
||||
this.value = moment(this.field.value, this.field.dateDisplayFormat);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,12 +95,15 @@ export class DateWidgetComponent extends WidgetComponent implements OnInit, OnDe
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
onDateChanged(newDateValue) {
|
||||
const date = moment(newDateValue, this.field.dateDisplayFormat, true);
|
||||
onDateChange(event: MatDatepickerInputEvent<Moment>) {
|
||||
const value = event.value;
|
||||
const input = event.targetElement as HTMLInputElement;
|
||||
|
||||
const date = moment(value, this.field.dateDisplayFormat, true);
|
||||
if (date.isValid()) {
|
||||
this.field.value = date.format(this.field.dateDisplayFormat);
|
||||
} else {
|
||||
this.field.value = newDateValue;
|
||||
this.field.value = input.value;
|
||||
}
|
||||
this.onFieldChanged(this.field);
|
||||
}
|
||||
|
@@ -267,7 +267,7 @@ describe('StartFormComponent', () => {
|
||||
const formFields = component.form.getFormFields();
|
||||
const labelField = formFields.find((field) => field.id === 'date');
|
||||
const dateWidget = fixture.debugElement.nativeElement.querySelector('date-widget');
|
||||
const dateLabelElement = fixture.debugElement.nativeElement.querySelector('#data-widget .mat-form-field-infix> .adf-label');
|
||||
const dateLabelElement = fixture.debugElement.nativeElement.querySelector('#date-label');
|
||||
|
||||
expect(dateWidget).toBeTruthy();
|
||||
expect(labelField.type).toBe('date');
|
||||
@@ -302,7 +302,7 @@ describe('StartFormComponent', () => {
|
||||
const inputElement = fixture.debugElement.nativeElement.querySelector('.adf-input');
|
||||
const inputLabelElement = fixture.debugElement.nativeElement.querySelector('.mat-form-field-infix > .adf-label');
|
||||
const dateElement = fixture.debugElement.nativeElement.querySelector('#billdate');
|
||||
const dateLabelElement = fixture.debugElement.nativeElement.querySelector('#data-widget .mat-form-field-infix> .adf-label');
|
||||
const dateLabelElement = fixture.debugElement.nativeElement.querySelector('#billdate-label');
|
||||
const selectElement = fixture.debugElement.nativeElement.querySelector('#claimtype');
|
||||
const selectLabelElement = fixture.debugElement.nativeElement.querySelector('.adf-dropdown-widget > .adf-label');
|
||||
|
||||
|
Reference in New Issue
Block a user