mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ADF-4775] Make date widget compatible with APS1 and APS2 (#4966)
* [ADF-4775] Make date widget compatible with APS1 and APS2 * Refactor and create new cloud widget
This commit is contained in:
committed by
Eugenio Romano
parent
bf828b6389
commit
8adb9b2a25
@@ -28,7 +28,9 @@ import {
|
|||||||
RegExFieldValidator,
|
RegExFieldValidator,
|
||||||
RequiredFieldValidator,
|
RequiredFieldValidator,
|
||||||
MaxDateTimeFieldValidator,
|
MaxDateTimeFieldValidator,
|
||||||
MinDateTimeFieldValidator
|
MinDateTimeFieldValidator,
|
||||||
|
MaxDateFieldValidator,
|
||||||
|
MinDateFieldValidator
|
||||||
} from './form-field-validator';
|
} from './form-field-validator';
|
||||||
import { FormFieldModel } from './form-field.model';
|
import { FormFieldModel } from './form-field.model';
|
||||||
import { FormModel } from './form.model';
|
import { FormModel } from './form.model';
|
||||||
@@ -868,4 +870,192 @@ describe('FormFieldValidator', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('MaxDateFieldValidator', () => {
|
||||||
|
|
||||||
|
let validator: MaxDateFieldValidator;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
validator = new MaxDateFieldValidator();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should require maxValue defined', () => {
|
||||||
|
const field = new FormFieldModel(new FormModel(), {
|
||||||
|
type: FormFieldTypes.DATE
|
||||||
|
});
|
||||||
|
expect(validator.isSupported(field)).toBeFalsy();
|
||||||
|
|
||||||
|
field.maxValue = '9999-02-08';
|
||||||
|
expect(validator.isSupported(field)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support date widgets only', () => {
|
||||||
|
const field = new FormFieldModel(new FormModel(), {
|
||||||
|
type: FormFieldTypes.DATE,
|
||||||
|
maxValue: '9999-02-08'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(validator.isSupported(field)).toBeTruthy();
|
||||||
|
|
||||||
|
field.type = FormFieldTypes.TEXT;
|
||||||
|
expect(validator.isSupported(field)).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow empty values', () => {
|
||||||
|
const field = new FormFieldModel(new FormModel(), {
|
||||||
|
type: FormFieldTypes.DATE,
|
||||||
|
value: null,
|
||||||
|
maxValue: '9999-02-08'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(validator.validate(field)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should succeed for unsupported types', () => {
|
||||||
|
const field = new FormFieldModel(new FormModel(), {
|
||||||
|
type: FormFieldTypes.TEXT
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(validator.validate(field)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should succeed validating value checking the date', () => {
|
||||||
|
const field = new FormFieldModel(new FormModel(), {
|
||||||
|
type: FormFieldTypes.DATE,
|
||||||
|
value: '9999-02-08T00:00:00',
|
||||||
|
maxValue: '9999-02-09'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(validator.validate(field)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail validating value checking the date', () => {
|
||||||
|
const field = new FormFieldModel(new FormModel(), {
|
||||||
|
type: FormFieldTypes.DATE,
|
||||||
|
value: '9999-02-08T00:00:00',
|
||||||
|
maxValue: '9999-02-07'
|
||||||
|
});
|
||||||
|
|
||||||
|
field.validationSummary = new ErrorMessageModel();
|
||||||
|
expect(validator.validate(field)).toBeFalsy();
|
||||||
|
expect(field.validationSummary).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should validate with APS1 format', () => {
|
||||||
|
const field = new FormFieldModel(new FormModel(), {
|
||||||
|
type: FormFieldTypes.DATE,
|
||||||
|
value: '9999-02-08T00:00:00',
|
||||||
|
maxValue: '09-02-9999'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(validator.validate(field)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail validating with APS1 format', () => {
|
||||||
|
const field = new FormFieldModel(new FormModel(), {
|
||||||
|
type: FormFieldTypes.DATE,
|
||||||
|
value: '9999-02-08T00:00:00',
|
||||||
|
maxValue: '07-02-9999'
|
||||||
|
});
|
||||||
|
|
||||||
|
field.validationSummary = new ErrorMessageModel();
|
||||||
|
expect(validator.validate(field)).toBeFalsy();
|
||||||
|
expect(field.validationSummary).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('MinDateFieldValidator', () => {
|
||||||
|
|
||||||
|
let validator: MinDateFieldValidator;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
validator = new MinDateFieldValidator();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should require maxValue defined', () => {
|
||||||
|
const field = new FormFieldModel(new FormModel(), {
|
||||||
|
type: FormFieldTypes.DATE
|
||||||
|
});
|
||||||
|
expect(validator.isSupported(field)).toBeFalsy();
|
||||||
|
|
||||||
|
field.minValue = '9999-02-08';
|
||||||
|
expect(validator.isSupported(field)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support date widgets only', () => {
|
||||||
|
const field = new FormFieldModel(new FormModel(), {
|
||||||
|
type: FormFieldTypes.DATE,
|
||||||
|
minValue: '9999-02-08'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(validator.isSupported(field)).toBeTruthy();
|
||||||
|
|
||||||
|
field.type = FormFieldTypes.TEXT;
|
||||||
|
expect(validator.isSupported(field)).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow empty values', () => {
|
||||||
|
const field = new FormFieldModel(new FormModel(), {
|
||||||
|
type: FormFieldTypes.DATE,
|
||||||
|
value: null,
|
||||||
|
minValue: '9999-02-08'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(validator.validate(field)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should succeed for unsupported types', () => {
|
||||||
|
const field = new FormFieldModel(new FormModel(), {
|
||||||
|
type: FormFieldTypes.TEXT
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(validator.validate(field)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should succeed validating value checking the date', () => {
|
||||||
|
const field = new FormFieldModel(new FormModel(), {
|
||||||
|
type: FormFieldTypes.DATE,
|
||||||
|
value: '9999-02-08T00:00:00',
|
||||||
|
minValue: '9999-02-07'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(validator.validate(field)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail validating value checking the date', () => {
|
||||||
|
const field = new FormFieldModel(new FormModel(), {
|
||||||
|
type: FormFieldTypes.DATE,
|
||||||
|
value: '9999-02-08T00:00:00',
|
||||||
|
minValue: '9999-02-09'
|
||||||
|
});
|
||||||
|
|
||||||
|
field.validationSummary = new ErrorMessageModel();
|
||||||
|
expect(validator.validate(field)).toBeFalsy();
|
||||||
|
expect(field.validationSummary).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should validate with APS1 format', () => {
|
||||||
|
const field = new FormFieldModel(new FormModel(), {
|
||||||
|
type: FormFieldTypes.DATE,
|
||||||
|
value: '9999-02-08T00:00:00',
|
||||||
|
minValue: '07-02-9999'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(validator.validate(field)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail validating with APS1 format', () => {
|
||||||
|
const field = new FormFieldModel(new FormModel(), {
|
||||||
|
type: FormFieldTypes.DATE,
|
||||||
|
value: '9999-02-08T00:00:00',
|
||||||
|
minValue: '09-02-9999'
|
||||||
|
});
|
||||||
|
|
||||||
|
field.validationSummary = new ErrorMessageModel();
|
||||||
|
expect(validator.validate(field)).toBeFalsy();
|
||||||
|
expect(field.validationSummary).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -165,17 +165,15 @@ export class DateFieldValidator implements FormFieldValidator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MinDateFieldValidator implements FormFieldValidator {
|
export abstract class BoundaryDateFieldValidator implements FormFieldValidator {
|
||||||
|
|
||||||
private supportedTypes = [
|
DATE_FORMAT_CLOUD = 'YYYY-MM-DD';
|
||||||
|
DATE_FORMAT = 'DD-MM-YYYY';
|
||||||
|
|
||||||
|
supportedTypes = [
|
||||||
FormFieldTypes.DATE
|
FormFieldTypes.DATE
|
||||||
];
|
];
|
||||||
|
|
||||||
isSupported(field: FormFieldModel): boolean {
|
|
||||||
return field &&
|
|
||||||
this.supportedTypes.indexOf(field.type) > -1 && !!field.minValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
validate(field: FormFieldModel): boolean {
|
validate(field: FormFieldModel): boolean {
|
||||||
let isValid = true;
|
let isValid = true;
|
||||||
if (this.isSupported(field) && field.value && field.isVisible) {
|
if (this.isSupported(field) && field.value && field.isVisible) {
|
||||||
@@ -191,8 +189,20 @@ export class MinDateFieldValidator implements FormFieldValidator {
|
|||||||
return isValid;
|
return isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
private checkDate(field: FormFieldModel, dateFormat: string): boolean {
|
extractDateFormat(date: string): string {
|
||||||
const MIN_DATE_FORMAT = 'DD-MM-YYYY';
|
const brokenDownDate = date.split('-');
|
||||||
|
return brokenDownDate[0].length === 4 ? this.DATE_FORMAT_CLOUD : this.DATE_FORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract checkDate(field: FormFieldModel, dateFormat: string);
|
||||||
|
abstract isSupported(field: FormFieldModel);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MinDateFieldValidator extends BoundaryDateFieldValidator {
|
||||||
|
|
||||||
|
checkDate(field: FormFieldModel, dateFormat: string): boolean {
|
||||||
|
|
||||||
let isValid = true;
|
let isValid = true;
|
||||||
// remove time and timezone info
|
// remove time and timezone info
|
||||||
let fieldValueData;
|
let fieldValueData;
|
||||||
@@ -201,7 +211,9 @@ export class MinDateFieldValidator implements FormFieldValidator {
|
|||||||
} else {
|
} else {
|
||||||
fieldValueData = field.value;
|
fieldValueData = field.value;
|
||||||
}
|
}
|
||||||
const min = moment(field.minValue, MIN_DATE_FORMAT);
|
|
||||||
|
const minValueDateFormat = this.extractDateFormat(field.minValue);
|
||||||
|
const min = moment(field.minValue, minValueDateFormat);
|
||||||
|
|
||||||
if (fieldValueData.isBefore(min)) {
|
if (fieldValueData.isBefore(min)) {
|
||||||
field.validationSummary.message = `FORM.FIELD.VALIDATOR.NOT_LESS_THAN`;
|
field.validationSummary.message = `FORM.FIELD.VALIDATOR.NOT_LESS_THAN`;
|
||||||
@@ -210,47 +222,41 @@ export class MinDateFieldValidator implements FormFieldValidator {
|
|||||||
}
|
}
|
||||||
return isValid;
|
return isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isSupported(field: FormFieldModel): boolean {
|
||||||
|
return field &&
|
||||||
|
this.supportedTypes.indexOf(field.type) > -1 && !!field.minValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MaxDateFieldValidator implements FormFieldValidator {
|
export class MaxDateFieldValidator extends BoundaryDateFieldValidator {
|
||||||
|
|
||||||
MAX_DATE_FORMAT = 'DD-MM-YYYY';
|
checkDate(field: FormFieldModel, dateFormat: string): boolean {
|
||||||
|
|
||||||
private supportedTypes = [
|
let isValid = true;
|
||||||
FormFieldTypes.DATE
|
// remove time and timezone info
|
||||||
];
|
let fieldValueData;
|
||||||
|
if (typeof field.value === 'string') {
|
||||||
|
fieldValueData = moment(field.value.split('T')[0], dateFormat);
|
||||||
|
} else {
|
||||||
|
fieldValueData = field.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const maxValueDateFormat = this.extractDateFormat(field.maxValue);
|
||||||
|
const max = moment(field.maxValue, maxValueDateFormat);
|
||||||
|
|
||||||
|
if (fieldValueData.isAfter(max)) {
|
||||||
|
field.validationSummary.message = `FORM.FIELD.VALIDATOR.NOT_GREATER_THAN`;
|
||||||
|
field.validationSummary.attributes.set('maxValue', max.format(field.dateDisplayFormat).toLocaleUpperCase());
|
||||||
|
isValid = false;
|
||||||
|
}
|
||||||
|
return isValid;
|
||||||
|
}
|
||||||
|
|
||||||
isSupported(field: FormFieldModel): boolean {
|
isSupported(field: FormFieldModel): boolean {
|
||||||
return field &&
|
return field &&
|
||||||
this.supportedTypes.indexOf(field.type) > -1 && !!field.maxValue;
|
this.supportedTypes.indexOf(field.type) > -1 && !!field.maxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
validate(field: FormFieldModel): boolean {
|
|
||||||
if (this.isSupported(field) && field.value && field.isVisible) {
|
|
||||||
const dateFormat = field.dateDisplayFormat;
|
|
||||||
|
|
||||||
if (!DateFieldValidator.isValidDate(field.value, dateFormat)) {
|
|
||||||
field.validationSummary.message = 'FORM.FIELD.VALIDATOR.INVALID_DATE';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove time and timezone info
|
|
||||||
let d;
|
|
||||||
if (typeof field.value === 'string') {
|
|
||||||
d = moment(field.value.split('T')[0], dateFormat);
|
|
||||||
} else {
|
|
||||||
d = field.value;
|
|
||||||
}
|
|
||||||
const max = moment(field.maxValue, this.MAX_DATE_FORMAT);
|
|
||||||
|
|
||||||
if (d.isAfter(max)) {
|
|
||||||
field.validationSummary.message = `FORM.FIELD.VALIDATOR.NOT_GREATER_THAN`;
|
|
||||||
field.validationSummary.attributes.set('maxValue', max.format(field.dateDisplayFormat).toLocaleUpperCase());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MinDateTimeFieldValidator implements FormFieldValidator {
|
export class MinDateTimeFieldValidator implements FormFieldValidator {
|
||||||
|
@@ -41,7 +41,7 @@ import { takeUntil } from 'rxjs/operators';
|
|||||||
})
|
})
|
||||||
export class DateWidgetComponent extends WidgetComponent implements OnInit, OnDestroy {
|
export class DateWidgetComponent extends WidgetComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
DATE_FORMAT = 'DD/MM/YYYY';
|
DATE_FORMAT = 'DD-MM-YYYY';
|
||||||
|
|
||||||
minDate: Moment;
|
minDate: Moment;
|
||||||
maxDate: Moment;
|
maxDate: Moment;
|
||||||
|
@@ -0,0 +1,20 @@
|
|||||||
|
<div class="{{field.className}}" id="data-widget" [class.adf-invalid]="!field.isValid">
|
||||||
|
<mat-form-field class="adf-date-widget">
|
||||||
|
<label class="adf-label" [attr.for]="field.id">{{field.name | translate }} ({{field.dateDisplayFormat}})<span *ngIf="isRequired()">*</span></label>
|
||||||
|
<input matInput
|
||||||
|
[id]="field.id"
|
||||||
|
[matDatepicker]="datePicker"
|
||||||
|
[(ngModel)]="displayDate"
|
||||||
|
[required]="isRequired()"
|
||||||
|
[disabled]="field.readOnly"
|
||||||
|
[min]="minDate"
|
||||||
|
[max]="maxDate"
|
||||||
|
(focusout)="onDateChanged($event.srcElement.value)"
|
||||||
|
(dateChange)="onDateChanged($event)"
|
||||||
|
placeholder="{{field.placeholder}}">
|
||||||
|
<mat-datepicker-toggle matSuffix [for]="datePicker" [disabled]="field.readOnly" ></mat-datepicker-toggle>
|
||||||
|
</mat-form-field>
|
||||||
|
<error-widget [error]="field.validationSummary"></error-widget>
|
||||||
|
<error-widget *ngIf="isInvalidFieldRequired()" required="{{ 'FORM.FIELD.REQUIRED' | translate }}"></error-widget>
|
||||||
|
<mat-datepicker #datePicker [touchUi]="true" [startAt]="displayDate" ></mat-datepicker>
|
||||||
|
</div>
|
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
.adf {
|
||||||
|
&-date-widget {
|
||||||
|
.mat-form-field-suffix {
|
||||||
|
top: 26px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,184 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* 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 { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import { DateCloudWidgetComponent } from './date-cloud.widget';
|
||||||
|
import { setupTestBed, FormFieldModel, FormModel, CoreModule } from '@alfresco/adf-core';
|
||||||
|
import { FormCloudService } from '../../services/form-cloud.service';
|
||||||
|
import moment from 'moment-es6';
|
||||||
|
|
||||||
|
describe('DateWidgetComponent', () => {
|
||||||
|
|
||||||
|
let widget: DateCloudWidgetComponent;
|
||||||
|
let fixture: ComponentFixture<DateCloudWidgetComponent>;
|
||||||
|
let element: HTMLElement;
|
||||||
|
|
||||||
|
setupTestBed({
|
||||||
|
imports: [
|
||||||
|
NoopAnimationsModule,
|
||||||
|
CoreModule.forRoot()
|
||||||
|
],
|
||||||
|
declarations: [DateCloudWidgetComponent],
|
||||||
|
providers: [FormCloudService]
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
fixture = TestBed.createComponent(DateCloudWidgetComponent);
|
||||||
|
widget = fixture.componentInstance;
|
||||||
|
element = fixture.nativeElement;
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should setup min value for date picker', () => {
|
||||||
|
const minValue = '1982-03-13';
|
||||||
|
widget.field = new FormFieldModel(null, {
|
||||||
|
id: 'date-id',
|
||||||
|
name: 'date-name',
|
||||||
|
minValue: minValue
|
||||||
|
});
|
||||||
|
|
||||||
|
widget.ngOnInit();
|
||||||
|
|
||||||
|
const expected = moment(minValue, widget.DATE_FORMAT_CLOUD);
|
||||||
|
expect(widget.minDate.isSame(expected)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should date field be present', () => {
|
||||||
|
const minValue = '1982-03-13';
|
||||||
|
widget.field = new FormFieldModel(null, {
|
||||||
|
minValue: minValue
|
||||||
|
});
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(element.querySelector('#data-widget')).toBeDefined();
|
||||||
|
expect(element.querySelector('#data-widget')).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should setup max value for date picker', () => {
|
||||||
|
const maxValue = '1982-03-13';
|
||||||
|
widget.field = new FormFieldModel(null, {
|
||||||
|
maxValue: maxValue
|
||||||
|
});
|
||||||
|
widget.ngOnInit();
|
||||||
|
|
||||||
|
const expected = moment(maxValue, widget.DATE_FORMAT_CLOUD);
|
||||||
|
expect(widget.maxDate.isSame(expected)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should eval visibility on date changed', () => {
|
||||||
|
spyOn(widget, 'onFieldChanged').and.callThrough();
|
||||||
|
|
||||||
|
const field = new FormFieldModel(new FormModel(), {
|
||||||
|
id: 'date-field-id',
|
||||||
|
name: 'date-name',
|
||||||
|
value: '9999-9-9',
|
||||||
|
type: 'date',
|
||||||
|
readOnly: 'false'
|
||||||
|
});
|
||||||
|
|
||||||
|
widget.field = field;
|
||||||
|
|
||||||
|
widget.onDateChanged({ value: moment('12/12/2012') });
|
||||||
|
expect(widget.onFieldChanged).toHaveBeenCalledWith(field);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('template check', () => {
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
fixture.destroy();
|
||||||
|
TestBed.resetTestingModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show visible date widget', async(() => {
|
||||||
|
widget.field = new FormFieldModel(new FormModel(), {
|
||||||
|
id: 'date-field-id',
|
||||||
|
name: 'date-name',
|
||||||
|
value: '9999-9-9',
|
||||||
|
type: 'date',
|
||||||
|
readOnly: 'false'
|
||||||
|
});
|
||||||
|
widget.field.isVisible = true;
|
||||||
|
widget.ngOnInit();
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
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('9-9-9999');
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should show the correct format type', async(() => {
|
||||||
|
widget.field = new FormFieldModel(new FormModel(), {
|
||||||
|
id: 'date-field-id',
|
||||||
|
name: 'date-name',
|
||||||
|
value: '9999-30-12',
|
||||||
|
type: 'date',
|
||||||
|
readOnly: 'false'
|
||||||
|
});
|
||||||
|
widget.field.isVisible = true;
|
||||||
|
widget.field.dateDisplayFormat = 'YYYY-DD-MM';
|
||||||
|
widget.ngOnInit();
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable()
|
||||||
|
.then(() => {
|
||||||
|
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('9999-30-12');
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should disable date button when is readonly', async(() => {
|
||||||
|
widget.field = new FormFieldModel(new FormModel(), {
|
||||||
|
id: 'date-field-id',
|
||||||
|
name: 'date-name',
|
||||||
|
value: '9999-9-9',
|
||||||
|
type: 'date',
|
||||||
|
readOnly: 'false'
|
||||||
|
});
|
||||||
|
widget.field.isVisible = true;
|
||||||
|
widget.field.readOnly = false;
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
let dateButton = <HTMLButtonElement> element.querySelector('button');
|
||||||
|
expect(dateButton.disabled).toBeFalsy();
|
||||||
|
|
||||||
|
widget.field.readOnly = true;
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
dateButton = <HTMLButtonElement> element.querySelector('button');
|
||||||
|
expect(dateButton.disabled).toBeTruthy();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should set isValid to false when the value is not a correct date value', async(() => {
|
||||||
|
widget.field = new FormFieldModel(new FormModel(), {
|
||||||
|
id: 'date-field-id',
|
||||||
|
name: 'date-name',
|
||||||
|
value: 'aa',
|
||||||
|
type: 'date',
|
||||||
|
readOnly: 'false'
|
||||||
|
});
|
||||||
|
widget.field.isVisible = true;
|
||||||
|
widget.field.readOnly = false;
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(widget.field.isValid).toBeFalsy();
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
@@ -0,0 +1,91 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* tslint:disable:component-selector */
|
||||||
|
|
||||||
|
import { Component, OnInit, ViewEncapsulation, OnDestroy } from '@angular/core';
|
||||||
|
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material';
|
||||||
|
import moment from 'moment-es6';
|
||||||
|
import { Moment } from 'moment';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
import { MOMENT_DATE_FORMATS, MomentDateAdapter, baseHost, WidgetComponent,
|
||||||
|
UserPreferencesService, UserPreferenceValues, FormService } from '@alfresco/adf-core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'date-widget',
|
||||||
|
providers: [
|
||||||
|
{ provide: DateAdapter, useClass: MomentDateAdapter },
|
||||||
|
{ provide: MAT_DATE_FORMATS, useValue: MOMENT_DATE_FORMATS }],
|
||||||
|
templateUrl: './date-cloud.widget.html',
|
||||||
|
styleUrls: ['./date-cloud.widget.scss'],
|
||||||
|
host: baseHost,
|
||||||
|
encapsulation: ViewEncapsulation.None
|
||||||
|
})
|
||||||
|
export class DateCloudWidgetComponent extends WidgetComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
|
DATE_FORMAT_CLOUD = 'YYYY-MM-DD';
|
||||||
|
|
||||||
|
minDate: Moment;
|
||||||
|
maxDate: Moment;
|
||||||
|
displayDate: Moment;
|
||||||
|
|
||||||
|
private onDestroy$ = new Subject<boolean>();
|
||||||
|
|
||||||
|
constructor(public formService: FormService,
|
||||||
|
private dateAdapter: DateAdapter<Moment>,
|
||||||
|
private userPreferencesService: UserPreferencesService) {
|
||||||
|
super(formService);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.userPreferencesService
|
||||||
|
.select(UserPreferenceValues.Locale)
|
||||||
|
.pipe(takeUntil(this.onDestroy$))
|
||||||
|
.subscribe(locale => this.dateAdapter.setLocale(locale));
|
||||||
|
|
||||||
|
const momentDateAdapter = <MomentDateAdapter> this.dateAdapter;
|
||||||
|
momentDateAdapter.overrideDisplayFormat = this.field.dateDisplayFormat;
|
||||||
|
|
||||||
|
if (this.field) {
|
||||||
|
if (this.field.minValue) {
|
||||||
|
this.minDate = moment(this.field.minValue, this.DATE_FORMAT_CLOUD);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.field.maxValue) {
|
||||||
|
this.maxDate = moment(this.field.maxValue, this.DATE_FORMAT_CLOUD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.displayDate = moment(this.field.value, this.field.dateDisplayFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.onDestroy$.next(true);
|
||||||
|
this.onDestroy$.complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
onDateChanged(newDateValue) {
|
||||||
|
if (newDateValue && newDateValue.value) {
|
||||||
|
this.field.value = newDateValue.value.format(this.field.dateDisplayFormat);
|
||||||
|
} else if (newDateValue) {
|
||||||
|
this.field.value = newDateValue;
|
||||||
|
} else {
|
||||||
|
this.field.value = null;
|
||||||
|
}
|
||||||
|
this.onFieldChanged(this.field);
|
||||||
|
}
|
||||||
|
}
|
@@ -39,6 +39,7 @@ import { FormCloud } from '../models/form-cloud.model';
|
|||||||
import { TaskVariableCloud } from '../models/task-variable-cloud.model';
|
import { TaskVariableCloud } from '../models/task-variable-cloud.model';
|
||||||
import { DropdownCloudWidgetComponent } from './dropdown-cloud/dropdown-cloud.widget';
|
import { DropdownCloudWidgetComponent } from './dropdown-cloud/dropdown-cloud.widget';
|
||||||
import { AttachFileCloudWidgetComponent } from './attach-file-cloud-widget/attach-file-cloud-widget.component';
|
import { AttachFileCloudWidgetComponent } from './attach-file-cloud-widget/attach-file-cloud-widget.component';
|
||||||
|
import { DateCloudWidgetComponent } from './date-cloud/date-cloud.widget';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-cloud-form',
|
selector: 'adf-cloud-form',
|
||||||
@@ -112,6 +113,7 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges,
|
|||||||
});
|
});
|
||||||
this.formRenderingService.setComponentTypeResolver('upload', () => AttachFileCloudWidgetComponent, true);
|
this.formRenderingService.setComponentTypeResolver('upload', () => AttachFileCloudWidgetComponent, true);
|
||||||
this.formRenderingService.setComponentTypeResolver('dropdown', () => DropdownCloudWidgetComponent, true);
|
this.formRenderingService.setComponentTypeResolver('dropdown', () => DropdownCloudWidgetComponent, true);
|
||||||
|
this.formRenderingService.setComponentTypeResolver('date', () => DateCloudWidgetComponent, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
|
@@ -29,6 +29,7 @@ import { FormCustomOutcomesComponent } from './components/form-cloud-custom-outc
|
|||||||
import { DropdownCloudWidgetComponent } from './components/dropdown-cloud/dropdown-cloud.widget';
|
import { DropdownCloudWidgetComponent } from './components/dropdown-cloud/dropdown-cloud.widget';
|
||||||
import { AttachFileCloudWidgetComponent } from './components/attach-file-cloud-widget/attach-file-cloud-widget.component';
|
import { AttachFileCloudWidgetComponent } from './components/attach-file-cloud-widget/attach-file-cloud-widget.component';
|
||||||
import { ContentNodeSelectorModule } from '@alfresco/adf-content-services';
|
import { ContentNodeSelectorModule } from '@alfresco/adf-content-services';
|
||||||
|
import { DateCloudWidgetComponent } from './components/date-cloud/date-cloud.widget';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -49,7 +50,9 @@ import { ContentNodeSelectorModule } from '@alfresco/adf-content-services';
|
|||||||
FormDefinitionSelectorCloudComponent,
|
FormDefinitionSelectorCloudComponent,
|
||||||
FormCustomOutcomesComponent,
|
FormCustomOutcomesComponent,
|
||||||
DropdownCloudWidgetComponent,
|
DropdownCloudWidgetComponent,
|
||||||
AttachFileCloudWidgetComponent],
|
AttachFileCloudWidgetComponent,
|
||||||
|
DateCloudWidgetComponent
|
||||||
|
],
|
||||||
providers: [
|
providers: [
|
||||||
FormDefinitionSelectorCloudService,
|
FormDefinitionSelectorCloudService,
|
||||||
FormRenderingService
|
FormRenderingService
|
||||||
@@ -57,10 +60,15 @@ import { ContentNodeSelectorModule } from '@alfresco/adf-content-services';
|
|||||||
entryComponents: [
|
entryComponents: [
|
||||||
UploadCloudWidgetComponent,
|
UploadCloudWidgetComponent,
|
||||||
DropdownCloudWidgetComponent,
|
DropdownCloudWidgetComponent,
|
||||||
AttachFileCloudWidgetComponent
|
AttachFileCloudWidgetComponent,
|
||||||
|
DateCloudWidgetComponent
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
FormCloudComponent, UploadCloudWidgetComponent, FormDefinitionSelectorCloudComponent, FormCustomOutcomesComponent, AttachFileCloudWidgetComponent
|
FormCloudComponent,
|
||||||
|
UploadCloudWidgetComponent,
|
||||||
|
FormDefinitionSelectorCloudComponent,
|
||||||
|
FormCustomOutcomesComponent,
|
||||||
|
AttachFileCloudWidgetComponent
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class FormCloudModule {
|
export class FormCloudModule {
|
||||||
|
@@ -25,6 +25,7 @@ import { TaskCloudService } from '../../services/task-cloud.service';
|
|||||||
import { FormRenderingService } from '@alfresco/adf-core';
|
import { FormRenderingService } from '@alfresco/adf-core';
|
||||||
import { AttachFileCloudWidgetComponent } from '../../../form/components/attach-file-cloud-widget/attach-file-cloud-widget.component';
|
import { AttachFileCloudWidgetComponent } from '../../../form/components/attach-file-cloud-widget/attach-file-cloud-widget.component';
|
||||||
import { DropdownCloudWidgetComponent } from '../../../form/components/dropdown-cloud/dropdown-cloud.widget';
|
import { DropdownCloudWidgetComponent } from '../../../form/components/dropdown-cloud/dropdown-cloud.widget';
|
||||||
|
import { DateCloudWidgetComponent } from '../../../form/components/date-cloud/date-cloud.widget';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-cloud-task-form',
|
selector: 'adf-cloud-task-form',
|
||||||
@@ -98,6 +99,7 @@ export class TaskFormCloudComponent implements OnChanges {
|
|||||||
private formRenderingService: FormRenderingService) {
|
private formRenderingService: FormRenderingService) {
|
||||||
this.formRenderingService.setComponentTypeResolver('upload', () => AttachFileCloudWidgetComponent, true);
|
this.formRenderingService.setComponentTypeResolver('upload', () => AttachFileCloudWidgetComponent, true);
|
||||||
this.formRenderingService.setComponentTypeResolver('dropdown', () => DropdownCloudWidgetComponent, true);
|
this.formRenderingService.setComponentTypeResolver('dropdown', () => DropdownCloudWidgetComponent, true);
|
||||||
|
this.formRenderingService.setComponentTypeResolver('date', () => DateCloudWidgetComponent, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
|
Reference in New Issue
Block a user