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
@@ -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 { DropdownCloudWidgetComponent } from './dropdown-cloud/dropdown-cloud.widget';
|
||||
import { AttachFileCloudWidgetComponent } from './attach-file-cloud-widget/attach-file-cloud-widget.component';
|
||||
import { DateCloudWidgetComponent } from './date-cloud/date-cloud.widget';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-cloud-form',
|
||||
@@ -112,6 +113,7 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges,
|
||||
});
|
||||
this.formRenderingService.setComponentTypeResolver('upload', () => AttachFileCloudWidgetComponent, true);
|
||||
this.formRenderingService.setComponentTypeResolver('dropdown', () => DropdownCloudWidgetComponent, true);
|
||||
this.formRenderingService.setComponentTypeResolver('date', () => DateCloudWidgetComponent, true);
|
||||
}
|
||||
|
||||
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 { AttachFileCloudWidgetComponent } from './components/attach-file-cloud-widget/attach-file-cloud-widget.component';
|
||||
import { ContentNodeSelectorModule } from '@alfresco/adf-content-services';
|
||||
import { DateCloudWidgetComponent } from './components/date-cloud/date-cloud.widget';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -49,7 +50,9 @@ import { ContentNodeSelectorModule } from '@alfresco/adf-content-services';
|
||||
FormDefinitionSelectorCloudComponent,
|
||||
FormCustomOutcomesComponent,
|
||||
DropdownCloudWidgetComponent,
|
||||
AttachFileCloudWidgetComponent],
|
||||
AttachFileCloudWidgetComponent,
|
||||
DateCloudWidgetComponent
|
||||
],
|
||||
providers: [
|
||||
FormDefinitionSelectorCloudService,
|
||||
FormRenderingService
|
||||
@@ -57,10 +60,15 @@ import { ContentNodeSelectorModule } from '@alfresco/adf-content-services';
|
||||
entryComponents: [
|
||||
UploadCloudWidgetComponent,
|
||||
DropdownCloudWidgetComponent,
|
||||
AttachFileCloudWidgetComponent
|
||||
AttachFileCloudWidgetComponent,
|
||||
DateCloudWidgetComponent
|
||||
],
|
||||
exports: [
|
||||
FormCloudComponent, UploadCloudWidgetComponent, FormDefinitionSelectorCloudComponent, FormCustomOutcomesComponent, AttachFileCloudWidgetComponent
|
||||
FormCloudComponent,
|
||||
UploadCloudWidgetComponent,
|
||||
FormDefinitionSelectorCloudComponent,
|
||||
FormCustomOutcomesComponent,
|
||||
AttachFileCloudWidgetComponent
|
||||
]
|
||||
})
|
||||
export class FormCloudModule {
|
||||
|
@@ -25,6 +25,7 @@ import { TaskCloudService } from '../../services/task-cloud.service';
|
||||
import { FormRenderingService } from '@alfresco/adf-core';
|
||||
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 { DateCloudWidgetComponent } from '../../../form/components/date-cloud/date-cloud.widget';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-cloud-task-form',
|
||||
@@ -98,6 +99,7 @@ export class TaskFormCloudComponent implements OnChanges {
|
||||
private formRenderingService: FormRenderingService) {
|
||||
this.formRenderingService.setComponentTypeResolver('upload', () => AttachFileCloudWidgetComponent, true);
|
||||
this.formRenderingService.setComponentTypeResolver('dropdown', () => DropdownCloudWidgetComponent, true);
|
||||
this.formRenderingService.setComponentTypeResolver('date', () => DateCloudWidgetComponent, true);
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
|
Reference in New Issue
Block a user