[ADF-2255] added refresh visibility before validation check (#2965)

* [ADF-2225] added check visibility before validation and refactored the visibility template check

* [ADF-2255] added refresh visibility before validation check

* [ADF-2225] readded deprecation signatures
This commit is contained in:
Vito
2018-02-20 15:45:23 +00:00
committed by Eugenio Romano
parent 1ae5558126
commit 36836d0119
32 changed files with 184 additions and 353 deletions

View File

@@ -20,11 +20,13 @@ import { MaterialModule } from '../../../material.module';
import { ErrorWidgetComponent } from '../widgets/error/error.component'; import { ErrorWidgetComponent } from '../widgets/error/error.component';
import { FormRenderingService } from './../../services/form-rendering.service'; import { FormRenderingService } from './../../services/form-rendering.service';
import { WidgetVisibilityService } from './../../services/widget-visibility.service'; import { WidgetVisibilityService } from './../../services/widget-visibility.service';
import { CheckboxWidgetComponent } from './../widgets/checkbox/checkbox.widget';
import { FormFieldModel, FormFieldTypes, FormModel } from './../widgets/core/index'; import { FormFieldModel, FormFieldTypes, FormModel } from './../widgets/core/index';
import { InputMaskDirective } from './../widgets/text/text-mask.component'; import { InputMaskDirective } from './../widgets/text/text-mask.component';
import { TextWidgetComponent } from './../widgets/text/text.widget'; import { TextWidgetComponent, CheckboxWidgetComponent, WidgetComponent } from '../widgets/index';
import { FormFieldComponent } from './form-field.component'; import { FormFieldComponent } from './form-field.component';
import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing';
import { FormService } from '../../services/form.service';
import { EcmModelService } from '../../services/ecm-model.service';
describe('FormFieldComponent', () => { describe('FormFieldComponent', () => {
@@ -35,22 +37,33 @@ describe('FormFieldComponent', () => {
let formRenderingService: FormRenderingService; let formRenderingService: FormRenderingService;
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
MaterialModule MaterialModule
], ],
declarations: [ declarations: [
FormFieldComponent, FormFieldComponent,
TextWidgetComponent, WidgetComponent,
CheckboxWidgetComponent, TextWidgetComponent,
InputMaskDirective, CheckboxWidgetComponent,
ErrorWidgetComponent], InputMaskDirective,
providers: [ ErrorWidgetComponent],
FormRenderingService, providers: [
WidgetVisibilityService FormRenderingService,
] WidgetVisibilityService,
}) FormService,
.compileComponents(); EcmModelService
]
});
TestBed.overrideModule(BrowserDynamicTestingModule, {
set: {
entryComponents: [WidgetComponent, TextWidgetComponent, CheckboxWidgetComponent]
}
});
TestBed.compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {
@@ -60,9 +73,14 @@ describe('FormFieldComponent', () => {
form = new FormModel(); form = new FormModel();
}); });
xit('should create default component instance', () => { afterEach(() => {
fixture.destroy();
});
it('should create default component instance', () => {
let field = new FormFieldModel(form, { let field = new FormFieldModel(form, {
type: FormFieldTypes.TEXT type: FormFieldTypes.TEXT,
id: 'FAKE-TXT-WIDGET'
}); });
component.field = field; component.field = field;
@@ -72,9 +90,10 @@ describe('FormFieldComponent', () => {
expect(component.componentRef.componentType).toBe(TextWidgetComponent); expect(component.componentRef.componentType).toBe(TextWidgetComponent);
}); });
xit('should create custom component instance', () => { it('should create custom component instance', () => {
let field = new FormFieldModel(form, { let field = new FormFieldModel(form, {
type: FormFieldTypes.TEXT type: FormFieldTypes.TEXT,
id: 'FAKE-TXT-WIDGET'
}); });
formRenderingService.setComponentTypeResolver(FormFieldTypes.TEXT, () => CheckboxWidgetComponent, true); formRenderingService.setComponentTypeResolver(FormFieldTypes.TEXT, () => CheckboxWidgetComponent, true);
@@ -87,7 +106,8 @@ describe('FormFieldComponent', () => {
it('should require component type to be resolved', () => { it('should require component type to be resolved', () => {
let field = new FormFieldModel(form, { let field = new FormFieldModel(form, {
type: FormFieldTypes.TEXT type: FormFieldTypes.TEXT,
id: 'FAKE-TXT-WIDGET'
}); });
spyOn(formRenderingService, 'resolveComponentType').and.returnValue(null); spyOn(formRenderingService, 'resolveComponentType').and.returnValue(null);
@@ -98,4 +118,41 @@ describe('FormFieldComponent', () => {
expect(component.componentRef).toBeUndefined(); expect(component.componentRef).toBeUndefined();
}); });
it('should hide the field when it is not visible', () => {
let field = new FormFieldModel(form, {
type: FormFieldTypes.TEXT,
id: 'FAKE-TXT-WIDGET'
});
component.field = field;
component.field.isVisible = false;
fixture.detectChanges();
expect(fixture.nativeElement.querySelector('#field-FAKE-TXT-WIDGET-container').hidden).toBeTruthy();
});
it('should show the field when it is visible', () => {
let field = new FormFieldModel(form, {
type: FormFieldTypes.TEXT,
id: 'FAKE-TXT-WIDGET'
});
component.field = field;
fixture.detectChanges();
expect(fixture.nativeElement.querySelector('#field-FAKE-TXT-WIDGET-container').hidden).toBeFalsy();
});
it('should hide a visible element', () => {
let field = new FormFieldModel(form, {
type: FormFieldTypes.TEXT,
id: 'FAKE-TXT-WIDGET'
});
component.field = field;
fixture.detectChanges();
expect(fixture.nativeElement.querySelector('#field-FAKE-TXT-WIDGET-container').hidden).toBeFalsy();
component.field.isVisible = false;
fixture.detectChanges();
expect(fixture.nativeElement.querySelector('#field-FAKE-TXT-WIDGET-container').hidden).toBeTruthy();
});
}); });

View File

@@ -40,7 +40,8 @@ declare var adf: any;
@Component({ @Component({
selector: 'adf-form-field, form-field', selector: 'adf-form-field, form-field',
template: ` template: `
<div [hidden]="!field?.isVisible" <div [id]="'field-'+field?.id+'-container'"
[hidden]="!field?.isVisible"
[class.adf-focus]="focus" [class.adf-focus]="focus"
(focusin)="focusToggle()" (focusin)="focusToggle()"
(focusout)="focusToggle()"> (focusout)="focusToggle()">
@@ -96,7 +97,8 @@ export class FormFieldComponent implements OnInit, OnDestroy {
instance.field = this.field; instance.field = this.field;
instance.fieldChanged.subscribe(field => { instance.fieldChanged.subscribe(field => {
if (field && this.field.form) { if (field && this.field.form) {
this.visibilityService.refreshVisibility(this.field.form); this.visibilityService.refreshVisibility(field.form);
field.form.onFormFieldChanged(field);
} }
}); });
} }

View File

@@ -19,7 +19,7 @@
</mat-card-header> </mat-card-header>
<mat-card-content> <mat-card-content>
<div *ngIf="form.hasTabs()"> <div *ngIf="form.hasTabs()">
<tabs-widget [tabs]="form.tabs" (formTabChanged)="checkVisibility($event);"></tabs-widget> <tabs-widget [tabs]="form.tabs" (formTabChanged)="onFieldChanged($event);"></tabs-widget>
</div> </div>
<div *ngIf="!form.hasTabs() && form.hasFields()"> <div *ngIf="!form.hasTabs() && form.hasFields()">

View File

@@ -62,6 +62,10 @@ describe('FormComponent UI and visibiltiy', () => {
service = fixture.debugElement.injector.get(FormService); service = fixture.debugElement.injector.get(FormService);
}); });
afterEach(() => {
fixture.destroy();
});
it('should create instance of FormComponent', () => { it('should create instance of FormComponent', () => {
expect(fixture.componentInstance instanceof FormComponent).toBe(true, 'should create FormComponent'); expect(fixture.componentInstance instanceof FormComponent).toBe(true, 'should create FormComponent');
}); });
@@ -124,12 +128,13 @@ describe('FormComponent UI and visibiltiy', () => {
component.ngOnChanges({ 'taskId': change }); component.ngOnChanges({ 'taskId': change });
fixture.detectChanges(); fixture.detectChanges();
let firstEl = fixture.debugElement.query(By.css('#country')); let firstEl = fixture.debugElement.query(By.css('#field-country-container'));
expect(firstEl).toBeNull(); expect(firstEl.nativeElement.hidden).toBeTruthy();
let secondEl = fixture.debugElement.query(By.css('#name')); let secondEl = fixture.debugElement.query(By.css('#name'));
expect(secondEl).not.toBeNull(); expect(secondEl).not.toBeNull();
expect(secondEl).toBeDefined(); expect(secondEl).toBeDefined();
expect(fixture.nativeElement.querySelector('#field-name-container').hidden).toBeFalsy();
}); });
it('should hide the field based on the previous one', () => { it('should hide the field based on the previous one', () => {
@@ -143,9 +148,10 @@ describe('FormComponent UI and visibiltiy', () => {
let firstEl = fixture.debugElement.query(By.css('#name')); let firstEl = fixture.debugElement.query(By.css('#name'));
expect(firstEl).not.toBeNull(); expect(firstEl).not.toBeNull();
expect(firstEl).toBeDefined(); expect(firstEl).toBeDefined();
expect(fixture.nativeElement.querySelector('#field-name-container').hidden).toBeFalsy();
let secondEl = fixture.debugElement.query(By.css('#country')); let secondEl = fixture.debugElement.query(By.css('#field-country-container'));
expect(secondEl).toBeNull(); expect(secondEl.nativeElement.hidden).toBeTruthy();
}); });
it('should show the hidden field when the visibility condition change to true', () => { it('should show the hidden field when the visibility condition change to true', () => {
@@ -156,20 +162,19 @@ describe('FormComponent UI and visibiltiy', () => {
component.ngOnChanges({ 'taskId': change }); component.ngOnChanges({ 'taskId': change });
fixture.detectChanges(); fixture.detectChanges();
let firstEl = fixture.debugElement.query(By.css('#country')); let firstEl = fixture.debugElement.query(By.css('#field-country-container'));
expect(firstEl).toBeNull(); expect(firstEl.nativeElement.hidden).toBeTruthy();
const secondEl = fixture.debugElement.query(By.css('#name')); const secondEl = fixture.debugElement.query(By.css('#field-name-container'));
expect(secondEl).not.toBeNull(); expect(secondEl.nativeElement.hidden).toBeFalsy();
let el = secondEl.nativeElement; let inputElement = fixture.nativeElement.querySelector('#name');
inputElement.value = 'italy';
el.value = 'italy'; inputElement.dispatchEvent(new Event('input'));
el.dispatchEvent(new Event('input'));
fixture.detectChanges(); fixture.detectChanges();
firstEl = fixture.debugElement.query(By.css('#country')); firstEl = fixture.debugElement.query(By.css('#field-country-container'));
expect(firstEl).not.toBeNull(); expect(firstEl.nativeElement.hidden).toBeFalsy();
}); });
}); });

View File

@@ -9,7 +9,7 @@
[required]="isRequired()" [required]="isRequired()"
[value]="field.value" [value]="field.value"
[(ngModel)]="field.value" [(ngModel)]="field.value"
(ngModelChange)="checkVisibility(field)" (ngModelChange)="onFieldChanged(field)"
[disabled]="field.readOnly" [disabled]="field.readOnly"
placeholder="{{field.placeholder}}"> placeholder="{{field.placeholder}}">
</mat-form-field> </mat-form-field>

View File

@@ -5,7 +5,7 @@
[required]="field.required" [required]="field.required"
[disabled]="field.readOnly || readOnly" [disabled]="field.readOnly || readOnly"
[(ngModel)]="field.value" [(ngModel)]="field.value"
(change)="onChange()"> (ngModelChange)="onFieldChanged(field)">
{{field.name}} {{field.name}}
<span *ngIf="field.required">*</span> <span *ngIf="field.required">*</span>
</mat-checkbox> </mat-checkbox>

View File

@@ -18,7 +18,6 @@
/* tslint:disable:component-selector no-input-rename */ /* tslint:disable:component-selector no-input-rename */
import { Component, ViewEncapsulation } from '@angular/core'; import { Component, ViewEncapsulation } from '@angular/core';
import { WidgetVisibilityService } from '../../../services/widget-visibility.service';
import { FormService } from './../../../services/form.service'; import { FormService } from './../../../services/form.service';
import { baseHost , WidgetComponent } from './../widget.component'; import { baseHost , WidgetComponent } from './../widget.component';
@@ -30,12 +29,8 @@ import { baseHost , WidgetComponent } from './../widget.component';
}) })
export class CheckboxWidgetComponent extends WidgetComponent { export class CheckboxWidgetComponent extends WidgetComponent {
constructor(private visibilityService: WidgetVisibilityService, public formService: FormService) { constructor(public formService: FormService) {
super(formService); super(formService);
} }
onChange() {
this.visibilityService.refreshVisibility(this.field.form);
}
} }

View File

@@ -1,17 +1,17 @@
<div [hidden]="!(content?.isGroup() && content?.isVisible)" class="container-widget__header"> <div [hidden]="!content?.isGroup()" class="container-widget__header">
<h4 class="container-widget__header-text" id="container-header" <h4 class="container-widget__header-text" id="container-header"
[class.collapsible]="content?.isCollapsible()"> [class.collapsible]="content?.isCollapsible()">
<button *ngIf="content?.isCollapsible()" <button *ngIf="content?.isCollapsible()"
mat-icon-button mat-icon-button
class="mdl-button--icon" class="mdl-button--icon"
(click)="onExpanderClicked()"> (click)="onExpanderClicked()">
<mat-icon>{{ content?.isExpanded ? 'expand_less' : 'expand_more' }}</mat-icon> <mat-icon>{{ content?.isExpanded ? 'expand_more' : 'expand_less' }}</mat-icon>
</button> </button>
<span (click)="onExpanderClicked()" id="container-header-label">{{content.name}}</span> <span (click)="onExpanderClicked()" id="container-header-label">{{content.name}}</span>
</h4> </h4>
</div> </div>
<section class="grid-list" [ngClass]="{'hidden':!(content?.isVisible && content?.isExpanded)}"> <section class="grid-list" *ngIf="content?.isExpanded">
<div class="grid-list-item" *ngFor="let field of fields" [style.width]="getColumnWith(field)"> <div class="grid-list-item" *ngFor="let field of fields" [style.width]="getColumnWith(field)">
<form-field *ngIf="field" [field]="field"></form-field> <form-field *ngIf="field" [field]="field"></form-field>
</div> </div>

View File

@@ -17,7 +17,7 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ActivitiContentService } from '../../../services/activiti-alfresco.service'; import { ActivitiContentService } from '../../../services/activiti-alfresco.service';
import { fakeFormJson } from '../../../../mock';
import { MaterialModule } from '../../../../material.module'; import { MaterialModule } from '../../../../material.module';
import { WIDGET_DIRECTIVES } from '../index'; import { WIDGET_DIRECTIVES } from '../index';
import { MASK_DIRECTIVE } from '../index'; import { MASK_DIRECTIVE } from '../index';
@@ -36,7 +36,6 @@ describe('ContainerWidgetComponent', () => {
let widget: ContainerWidgetComponent; let widget: ContainerWidgetComponent;
let fixture: ComponentFixture<ContainerWidgetComponent>; let fixture: ComponentFixture<ContainerWidgetComponent>;
let element: HTMLElement;
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
@@ -54,11 +53,13 @@ describe('ContainerWidgetComponent', () => {
beforeEach(() => { beforeEach(() => {
fixture = TestBed.createComponent(ContainerWidgetComponent); fixture = TestBed.createComponent(ContainerWidgetComponent);
element = fixture.nativeElement;
widget = fixture.componentInstance; widget = fixture.componentInstance;
}); });
afterEach(() => {
fixture.destroy();
});
it('should wrap field with model instance', () => { it('should wrap field with model instance', () => {
let field = new FormFieldModel(null); let field = new FormFieldModel(null);
widget.field = field; widget.field = field;
@@ -125,83 +126,6 @@ describe('ContainerWidgetComponent', () => {
widget.onFieldChanged(fakeField); widget.onFieldChanged(fakeField);
}); });
describe('when template is ready', () => {
let fakeContainerVisible;
let fakeContainerInvisible;
beforeEach(() => {
fakeContainerVisible = new ContainerWidgetComponentModel(new FormFieldModel(new FormModel(fakeFormJson), {
fieldType: FormFieldTypes.GROUP,
id: 'fake-cont-id-1',
name: 'fake-cont-1-name',
type: FormFieldTypes.GROUP
}));
fakeContainerInvisible = new ContainerWidgetComponentModel(new FormFieldModel(new FormModel(fakeFormJson), {
fieldType: FormFieldTypes.GROUP,
id: 'fake-cont-id-2',
name: 'fake-cont-2-name',
type: FormFieldTypes.GROUP
}));
fakeContainerVisible.field.isVisible = true;
fakeContainerInvisible.field.isVisible = false;
});
afterEach(() => {
fixture.destroy();
TestBed.resetTestingModule();
});
it('should show the container header when it is visible', () => {
widget.content = fakeContainerVisible;
fixture.detectChanges();
fixture.whenStable()
.then(() => {
expect(element.querySelector('.container-widget__header').classList.contains('hidden')).toBe(false);
expect(element.querySelector('#container-header-label')).toBeDefined();
expect(element.querySelector('#container-header-label').innerHTML).toContain('fake-cont-1-name');
});
});
it('should not show the container header when it is not visible', () => {
widget.content = fakeContainerInvisible;
fixture.detectChanges();
fixture.whenStable()
.then(() => {
expect(element.querySelector('.container-widget__header').getAttribute('hidden')).not.toBeNull();
});
});
it('should hide header when it becomes not visible', async(() => {
widget.content = fakeContainerVisible;
fixture.detectChanges();
widget.fieldChanged.subscribe((res) => {
widget.content.field.isVisible = false;
fixture.detectChanges();
fixture.whenStable()
.then(() => {
expect(element.querySelector('.container-widget__header').getAttribute('hidden')).not.toBeNull();
});
});
widget.onFieldChanged(null);
}));
it('should show header when it becomes visible', async(() => {
widget.content = fakeContainerInvisible;
widget.fieldChanged.subscribe((res) => {
widget.content.field.isVisible = true;
fixture.detectChanges();
fixture.whenStable()
.then(() => {
expect(element.querySelector('#container-header')).toBeDefined();
expect(element.querySelector('#container-header')).not.toBeNull();
expect(element.querySelector('#container-header-label')).toBeDefined();
expect(element.querySelector('#container-header-label').innerHTML).toContain('fake-cont-2-name');
});
});
widget.onFieldChanged(null);
}));
});
describe('fields', () => { describe('fields', () => {
it('should serializes the content fields', () => { it('should serializes the content fields', () => {

View File

@@ -85,7 +85,6 @@ export class FormFieldModel extends FormWidgetModel {
set value(v: any) { set value(v: any) {
this._value = v; this._value = v;
this.validate();
this.updateForm(); this.updateForm();
} }

View File

@@ -1,4 +1,4 @@
<div class="{{field.className}}" *ngIf="field?.isVisible" <div class="{{field.className}}"
id="data-time-widget" [class.adf-invalid]="!field.isValid || field.validationSummary.message"> id="data-time-widget" [class.adf-invalid]="!field.isValid || field.validationSummary.message">
<mat-form-field class="adf-date-time-widget"> <mat-form-field class="adf-date-time-widget">
<label class="adf-label" [attr.for]="field.id">{{field.name}} ({{field.dateDisplayFormat}})<span *ngIf="isRequired()">*</span></label> <label class="adf-label" [attr.for]="field.id">{{field.name}} ({{field.dateDisplayFormat}})<span *ngIf="isRequired()">*</span></label>

View File

@@ -102,7 +102,7 @@ describe('DateTimeWidgetComponent', () => {
}); });
it('should eval visibility on date changed', () => { it('should eval visibility on date changed', () => {
spyOn(widget, 'checkVisibility').and.callThrough(); spyOn(widget, 'onFieldChanged').and.callThrough();
let field = new FormFieldModel(new FormModel(), { let field = new FormFieldModel(new FormModel(), {
id: 'date-field-id', id: 'date-field-id',
@@ -115,7 +115,7 @@ describe('DateTimeWidgetComponent', () => {
widget.field = field; widget.field = field;
widget.onDateChanged({ value: moment('13-03-1982 10:00 AM') }); widget.onDateChanged({ value: moment('13-03-1982 10:00 AM') });
expect(widget.checkVisibility).toHaveBeenCalledWith(field); expect(widget.onFieldChanged).toHaveBeenCalledWith(field);
}); });
describe('template check', () => { describe('template check', () => {
@@ -173,6 +173,7 @@ describe('DateTimeWidgetComponent', () => {
fixture.detectChanges(); fixture.detectChanges();
fixture.whenStable() fixture.whenStable()
.then(() => { .then(() => {
fixture.detectChanges();
expect(element.querySelector('#date-field-id')).toBeDefined(); expect(element.querySelector('#date-field-id')).toBeDefined();
expect(element.querySelector('#date-field-id')).not.toBeNull(); expect(element.querySelector('#date-field-id')).not.toBeNull();
let dateElement: any = element.querySelector('#date-field-id'); let dateElement: any = element.querySelector('#date-field-id');
@@ -180,74 +181,6 @@ describe('DateTimeWidgetComponent', () => {
}); });
})); }));
it('should hide not visible date widget', async(() => {
widget.field = new FormFieldModel(new FormModel(), {
id: 'date-field-id',
name: 'date-name',
value: '12-30-9999 10:30 AM',
dateDisplayFormat: 'MM-DD-YYYY HH:mm A',
type: 'datetime',
readOnly: 'false'
});
fixture.detectChanges();
expect(element.querySelector('#data-time-widget')).not.toBeNull();
widget.field.isVisible = false;
fixture.detectChanges();
fixture.whenStable()
.then(() => {
fixture.detectChanges();
expect(element.querySelector('#data-time-widget')).toBeNull();
});
}));
it('should become visibile if the visibility change to true', async(() => {
widget.field = new FormFieldModel(new FormModel(), {
id: 'date-field-id',
name: 'date-name',
value: '12-30-9999 10:30 AM',
dateDisplayFormat: 'MM-DD-YYYY HH:mm A',
type: 'datetime',
readOnly: 'false'
});
widget.field.isVisible = false;
fixture.detectChanges();
expect(element.querySelector('#data-time-widget')).toBeNull();
widget.fieldChanged.subscribe((field) => {
field.isVisible = true;
fixture.detectChanges();
fixture.whenStable()
.then(() => {
expect(element.querySelector('#data-time-widget')).toBeDefined();
expect(element.querySelector('#data-time-widget')).not.toBeNull();
let dateElement: any = element.querySelector('#date-field-id');
expect(dateElement.value).toContain('12-30-9999 10:30 AM');
});
});
widget.checkVisibility(widget.field);
}));
it('should be hided if the visibility change to false', async(() => {
widget.field = new FormFieldModel(new FormModel(), {
id: 'date-field-id',
name: 'date-name',
value: '12-30-9999 10:30 AM',
dateDisplayFormat: 'MM-DD-YYYY HH:mm A',
type: 'datetime',
readOnly: 'false'
});
fixture.detectChanges();
expect(element.querySelector('#data-time-widget')).not.toBeNull();
widget.fieldChanged.subscribe((field) => {
field.isVisible = false;
fixture.detectChanges();
fixture.whenStable()
.then(() => {
expect(element.querySelector('#data-time-widget')).toBeNull();
});
});
widget.checkVisibility(widget.field);
}));
it('should disable date button when is readonly', async(() => { it('should disable date button when is readonly', async(() => {
widget.field = new FormFieldModel(new FormModel(), { widget.field = new FormFieldModel(new FormModel(), {
id: 'date-field-id', id: 'date-field-id',

View File

@@ -80,7 +80,7 @@ export class DateTimeWidgetComponent extends WidgetComponent implements OnInit {
} else { } else {
this.field.value = null; this.field.value = null;
} }
this.checkVisibility(this.field); this.onFieldChanged(this.field);
} }
} }

View File

@@ -1,4 +1,4 @@
<div class="{{field.className}}" *ngIf="field?.isVisible" id="data-widget" [class.adf-invalid]="!field.isValid || field.validationSummary.message"> <div class="{{field.className}}" id="data-widget" [class.adf-invalid]="!field.isValid || field.validationSummary.message">
<mat-form-field class="adf-date-widget"> <mat-form-field class="adf-date-widget">
<label class="adf-label" [attr.for]="field.id">{{field.name}} ({{field.dateDisplayFormat}})<span *ngIf="isRequired()">*</span></label> <label class="adf-label" [attr.for]="field.id">{{field.name}} ({{field.dateDisplayFormat}})<span *ngIf="isRequired()">*</span></label>
<input matInput <input matInput

View File

@@ -94,7 +94,7 @@ describe('DateWidgetComponent', () => {
}); });
it('should eval visibility on date changed', () => { it('should eval visibility on date changed', () => {
spyOn(widget, 'checkVisibility').and.callThrough(); spyOn(widget, 'onFieldChanged').and.callThrough();
let field = new FormFieldModel(new FormModel(), { let field = new FormFieldModel(new FormModel(), {
id: 'date-field-id', id: 'date-field-id',
@@ -107,7 +107,7 @@ describe('DateWidgetComponent', () => {
widget.field = field; widget.field = field;
widget.onDateChanged({ value: moment('12/12/2012') }); widget.onDateChanged({ value: moment('12/12/2012') });
expect(widget.checkVisibility).toHaveBeenCalledWith(field); expect(widget.onFieldChanged).toHaveBeenCalledWith(field);
}); });
describe('template check', () => { describe('template check', () => {
@@ -169,45 +169,6 @@ describe('DateWidgetComponent', () => {
}); });
})); }));
it('should hide not visible date widget', async(() => {
widget.field.isVisible = false;
fixture.detectChanges();
fixture.whenStable()
.then(() => {
fixture.detectChanges();
expect(element.querySelector('#data-widget')).toBeNull();
});
}));
it('should become visibile if the visibility change to true', async(() => {
widget.field.isVisible = false;
fixture.detectChanges();
widget.fieldChanged.subscribe((field) => {
field.isVisible = true;
fixture.detectChanges();
fixture.whenStable()
.then(() => {
expect(element.querySelector('#date-field-id')).toBeDefined();
expect(element.querySelector('#date-field-id')).not.toBeNull();
let dateElement: any = element.querySelector('#date-field-id');
expect(dateElement.value).toContain('9-9-9999');
});
});
widget.checkVisibility(widget.field);
}));
it('should be hided if the visibility change to false', async(() => {
widget.fieldChanged.subscribe((field) => {
field.isVisible = false;
fixture.detectChanges();
fixture.whenStable()
.then(() => {
expect(element.querySelector('#data-widget')).toBeNull();
});
});
widget.checkVisibility(widget.field);
}));
it('should disable date button when is readonly', async(() => { it('should disable date button when is readonly', async(() => {
widget.field.readOnly = false; widget.field.readOnly = false;
fixture.detectChanges(); fixture.detectChanges();

View File

@@ -77,7 +77,7 @@ export class DateWidgetComponent extends WidgetComponent implements OnInit {
} else { } else {
this.field.value = null; this.field.value = null;
} }
this.checkVisibility(this.field); this.onFieldChanged(this.field);
} }
} }

View File

@@ -1,12 +1,12 @@
<div class="adf-dropdown-widget {{field.className}}" <div class="adf-dropdown-widget {{field.className}}"
[class.adf-invalid]="!field.isValid" [class.adf-readonly]="field.readOnly" *ngIf="field?.isVisible"> [class.adf-invalid]="!field.isValid" [class.adf-readonly]="field.readOnly">
<label class="adf-label" [attr.for]="field.id">{{field.name}}<span *ngIf="isRequired()">*</span></label> <label class="adf-label" [attr.for]="field.id">{{field.name}}<span *ngIf="isRequired()">*</span></label>
<mat-form-field> <mat-form-field>
<mat-select class="adf-select" <mat-select class="adf-select"
[id]="field.id" [id]="field.id"
[(ngModel)]="field.value" [(ngModel)]="field.value"
[disabled]="field.readOnly" [disabled]="field.readOnly"
(ngModelChange)="checkVisibility(field)"> (ngModelChange)="onFieldChanged(field)">
<mat-option *ngFor="let opt of field.options" <mat-option *ngFor="let opt of field.options"
[value]="getOptionValue(opt, field.value)" [value]="getOptionValue(opt, field.value)"
[id]="opt.id">{{opt.name}} [id]="opt.id">{{opt.name}}

View File

@@ -188,27 +188,6 @@ describe('DropdownWidgetComponent', () => {
}); });
})); }));
it('should be not visible when isVisible is false', async(() => {
widget.field.isVisible = false;
fixture.detectChanges();
fixture.whenStable()
.then(() => {
let dropDownElement: HTMLSelectElement = <HTMLSelectElement> element.querySelector('#dropdown-id');
expect(dropDownElement).toBeNull();
});
}));
it('should became visible when isVisible is true', async(() => {
widget.field.isVisible = false;
fixture.detectChanges();
expect(element.querySelector('#dropdown-id')).toBeNull();
widget.field.isVisible = true;
fixture.detectChanges();
fixture.whenStable()
.then(() => {
expect(element.querySelector('#dropdown-id')).not.toBeNull();
});
}));
}); });
describe('and dropdown is populated via processDefinitionId', () => { describe('and dropdown is populated via processDefinitionId', () => {

View File

@@ -20,7 +20,6 @@
import { LogService } from '../../../../services/log.service'; import { LogService } from '../../../../services/log.service';
import { Component, OnInit, ViewEncapsulation } from '@angular/core'; import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { FormService } from '../../../services/form.service'; import { FormService } from '../../../services/form.service';
import { WidgetVisibilityService } from '../../../services/widget-visibility.service';
import { FormFieldOption } from './../core/form-field-option'; import { FormFieldOption } from './../core/form-field-option';
import { baseHost , WidgetComponent } from './../widget.component'; import { baseHost , WidgetComponent } from './../widget.component';
@@ -34,7 +33,6 @@ import { baseHost , WidgetComponent } from './../widget.component';
export class DropdownWidgetComponent extends WidgetComponent implements OnInit { export class DropdownWidgetComponent extends WidgetComponent implements OnInit {
constructor(public formService: FormService, constructor(public formService: FormService,
private visibilityService: WidgetVisibilityService,
private logService: LogService) { private logService: LogService) {
super(formService); super(formService);
} }
@@ -97,10 +95,6 @@ export class DropdownWidgetComponent extends WidgetComponent implements OnInit {
return optionValue; return optionValue;
} }
checkVisibility() {
this.visibilityService.refreshVisibility(this.field.form);
}
handleError(error: any) { handleError(error: any) {
this.logService.error(error); this.logService.error(error);
} }

View File

@@ -1,5 +1,5 @@
<div class="{{field.className}}" <div class="{{field.className}}"
[class.adf-invalid]="!isValid()" *ngIf="field?.isVisible"> [class.adf-invalid]="!isValid()">
<div class="adf-label">{{content.name}}<span *ngIf="isRequired()">*</span></div> <div class="adf-label">{{content.name}}<span *ngIf="isRequired()">*</span></div>
<div *ngIf="!editMode"> <div *ngIf="!editMode">

View File

@@ -118,7 +118,11 @@ describe('DynamicTableWidgetComponent', () => {
element = fixture.nativeElement; element = fixture.nativeElement;
widget = fixture.componentInstance; widget = fixture.componentInstance;
widget.content = table; widget.content = table;
widget.field = field;
});
afterEach(() => {
fixture.destroy();
}); });
it('should select row on click', () => { it('should select row on click', () => {

View File

@@ -1,6 +1,6 @@
<div class="adf-group-widget {{field.className}}" <div class="adf-group-widget {{field.className}}"
[class.is-dirty]="value" [class.is-dirty]="value"
[class.adf-invalid]="!field.isValid" [class.adf-readonly]="field.readOnly" id="functional-group-div" *ngIf="field.isVisible"> [class.adf-invalid]="!field.isValid" [class.adf-readonly]="field.readOnly" id="functional-group-div">
<mat-form-field> <mat-form-field>
<label class="adf-label" [attr.for]="field.id">{{field.name}}<span *ngIf="isRequired()">*</span></label> <label class="adf-label" [attr.for]="field.id">{{field.name}}<span *ngIf="isRequired()">*</span></label>
<input matInput <input matInput

View File

@@ -9,7 +9,7 @@
[id]="field.id" [id]="field.id"
[required]="isRequired()" [required]="isRequired()"
[(ngModel)]="field.value" [(ngModel)]="field.value"
(ngModelChange)="checkVisibility(field)" (ngModelChange)="onFieldChanged(field)"
[disabled]="field.readOnly || readOnly" [disabled]="field.readOnly || readOnly"
placeholder="{{field.placeholder}}"> placeholder="{{field.placeholder}}">
</textarea> </textarea>

View File

@@ -10,7 +10,7 @@
[required]="isRequired()" [required]="isRequired()"
[value]="field.value" [value]="field.value"
[(ngModel)]="field.value" [(ngModel)]="field.value"
(ngModelChange)="checkVisibility(field)" (ngModelChange)="onFieldChanged(field)"
[disabled]="field.readOnly" [disabled]="field.readOnly"
placeholder="{{field.placeholder}}"> placeholder="{{field.placeholder}}">
</mat-form-field> </mat-form-field>

View File

@@ -2,8 +2,7 @@
[class.is-dirty]="value" [class.is-dirty]="value"
[class.adf-invalid]="!field.isValid" [class.adf-invalid]="!field.isValid"
[class.adf-readonly]="field.readOnly" [class.adf-readonly]="field.readOnly"
id="people-widget-content" id="people-widget-content">
*ngIf="field.isVisible">
<mat-form-field> <mat-form-field>
<label class="adf-label" [attr.for]="field.id">{{field.name}}<span *ngIf="isRequired()">*</span></label> <label class="adf-label" [attr.for]="field.id">{{field.name}}<span *ngIf="isRequired()">*</span></label>
<input #inputValue <input #inputValue

View File

@@ -1,5 +1,5 @@
<div class="adf-radio-buttons-widget {{field.className}}" <div class="adf-radio-buttons-widget {{field.className}}"
[class.adf-invalid]="!field.isValid" [class.adf-readonly]="field.readOnly" [id]="field.id" *ngIf="field?.isVisible"> [class.adf-invalid]="!field.isValid" [class.adf-readonly]="field.readOnly" [id]="field.id">
<div class="adf-radio-button-container"> <div class="adf-radio-button-container">
<label class="adf-label" [attr.for]="field.id">{{field.name}}<span *ngIf="isRequired()">*</span></label> <label class="adf-label" [attr.for]="field.id">{{field.name}}<span *ngIf="isRequired()">*</span></label>
<mat-radio-group class="adf-radio-group" [(ngModel)]="field.value"> <mat-radio-group class="adf-radio-group" [(ngModel)]="field.value">

View File

@@ -20,7 +20,6 @@ import { Observable } from 'rxjs/Observable';
import { EcmModelService } from '../../../services/ecm-model.service'; import { EcmModelService } from '../../../services/ecm-model.service';
import { FormService } from '../../../services/form.service'; import { FormService } from '../../../services/form.service';
import { WidgetVisibilityService } from '../../../services/widget-visibility.service';
import { MaterialModule } from '../../../../material.module'; import { MaterialModule } from '../../../../material.module';
import { ContainerModel } from '../core/container.model'; import { ContainerModel } from '../core/container.model';
import { FormFieldTypes } from '../core/form-field-types'; import { FormFieldTypes } from '../core/form-field-types';
@@ -34,12 +33,10 @@ describe('RadioButtonsWidgetComponent', () => {
let formService: FormService; let formService: FormService;
let widget: RadioButtonsWidgetComponent; let widget: RadioButtonsWidgetComponent;
let visibilityService: WidgetVisibilityService;
beforeEach(() => { beforeEach(() => {
formService = new FormService(null, null, null); formService = new FormService(null, null, null);
visibilityService = new WidgetVisibilityService(null, null); widget = new RadioButtonsWidgetComponent(formService, null);
widget = new RadioButtonsWidgetComponent(formService, visibilityService, null);
widget.field = new FormFieldModel(new FormModel(), { restUrl: '<url>' }); widget.field = new FormFieldModel(new FormModel(), { restUrl: '<url>' });
}); });
@@ -119,8 +116,8 @@ describe('RadioButtonsWidgetComponent', () => {
expect(formService.getRestFieldValues).toHaveBeenCalled(); expect(formService.getRestFieldValues).toHaveBeenCalled();
}); });
xit('should update the field value when an option is selected', () => { it('should update the field value when an option is selected', () => {
spyOn(widget, 'checkVisibility').and.stub(); spyOn(widget, 'onFieldChanged').and.returnValue(Observable.of({}));
widget.onOptionClick('fake-opt'); widget.onOptionClick('fake-opt');
expect(widget.field.value).toEqual('fake-opt'); expect(widget.field.value).toEqual('fake-opt');
@@ -131,7 +128,6 @@ describe('RadioButtonsWidgetComponent', () => {
let fixture: ComponentFixture<RadioButtonsWidgetComponent>; let fixture: ComponentFixture<RadioButtonsWidgetComponent>;
let element: HTMLElement; let element: HTMLElement;
let stubFormService: FormService; let stubFormService: FormService;
let stubVisibilityService: WidgetVisibilityService;
let restOption: FormFieldOption[] = [{ id: 'opt-1', name: 'opt-name-1' }, { let restOption: FormFieldOption[] = [{ id: 'opt-1', name: 'opt-name-1' }, {
id: 'opt-2', id: 'opt-2',
name: 'opt-name-2' name: 'opt-name-2'
@@ -141,7 +137,7 @@ describe('RadioButtonsWidgetComponent', () => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ MaterialModule ], imports: [ MaterialModule ],
declarations: [RadioButtonsWidgetComponent, ErrorWidgetComponent], declarations: [RadioButtonsWidgetComponent, ErrorWidgetComponent],
providers: [FormService, EcmModelService, WidgetVisibilityService] providers: [FormService, EcmModelService]
}).compileComponents().then(() => { }).compileComponents().then(() => {
fixture = TestBed.createComponent(RadioButtonsWidgetComponent); fixture = TestBed.createComponent(RadioButtonsWidgetComponent);
radioButtonWidget = fixture.componentInstance; radioButtonWidget = fixture.componentInstance;
@@ -158,7 +154,6 @@ describe('RadioButtonsWidgetComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
stubFormService = fixture.debugElement.injector.get(FormService); stubFormService = fixture.debugElement.injector.get(FormService);
stubVisibilityService = fixture.debugElement.injector.get(WidgetVisibilityService);
spyOn(stubFormService, 'getRestFieldValues').and.returnValue(Observable.of(restOption)); spyOn(stubFormService, 'getRestFieldValues').and.returnValue(Observable.of(restOption));
radioButtonWidget.field = new FormFieldModel(new FormModel({ taskId: 'task-id' }), { radioButtonWidget.field = new FormFieldModel(new FormModel({ taskId: 'task-id' }), {
id: 'radio-id', id: 'radio-id',
@@ -172,7 +167,7 @@ describe('RadioButtonsWidgetComponent', () => {
fixture.detectChanges(); fixture.detectChanges();
})); }));
it('should show visible radio buttons', async(() => { it('should show radio buttons', async(() => {
expect(element.querySelector('#radio-id')).toBeDefined(); expect(element.querySelector('#radio-id')).toBeDefined();
expect(element.querySelector('#radio-id-opt-1-input')).not.toBeNull(); expect(element.querySelector('#radio-id-opt-1-input')).not.toBeNull();
expect(element.querySelector('#radio-id-opt-1')).not.toBeNull(); expect(element.querySelector('#radio-id-opt-1')).not.toBeNull();
@@ -180,29 +175,15 @@ describe('RadioButtonsWidgetComponent', () => {
expect(element.querySelector('#radio-id-opt-2')).not.toBeNull(); expect(element.querySelector('#radio-id-opt-2')).not.toBeNull();
})); }));
it('should not show invisible radio buttons', async(() => { it('should trigger field changed event on click', async(() => {
radioButtonWidget.field.isVisible = false;
fixture.detectChanges();
fixture.whenStable()
.then(() => {
expect(element.querySelector('#radio-id')).toBeNull();
expect(element.querySelector('#radio-id-opt-1-input')).toBeNull();
expect(element.querySelector('#radio-id-opt-2-input')).toBeNull();
});
}));
it('should evaluate visibility on option click', async(() => {
spyOn(stubVisibilityService, 'evaluateVisibility').and.returnValue(false);
let option: HTMLElement = <HTMLElement> element.querySelector('#radio-id-opt-1-input'); let option: HTMLElement = <HTMLElement> element.querySelector('#radio-id-opt-1-input');
expect(element.querySelector('#radio-id')).not.toBeNull(); expect(element.querySelector('#radio-id')).not.toBeNull();
expect(option).not.toBeNull(); expect(option).not.toBeNull();
option.click(); option.click();
fixture.detectChanges(); widget.fieldChanged.subscribe(field => {
fixture.whenStable() expect(element.querySelector('#radio-id')).toBeNull();
.then(() => { expect(element.querySelector('#radio-id-opt-1-input')).toBeNull();
expect(element.querySelector('#radio-id')).toBeNull(); });
expect(element.querySelector('#radio-id-opt-1-input')).toBeNull();
});
})); }));
}); });

View File

@@ -20,7 +20,6 @@
import { LogService } from '../../../../services/log.service'; import { LogService } from '../../../../services/log.service';
import { Component, OnInit, ViewEncapsulation } from '@angular/core'; import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { FormService } from '../../../services/form.service'; import { FormService } from '../../../services/form.service';
import { WidgetVisibilityService } from '../../../services/widget-visibility.service';
import { FormFieldOption } from './../core/form-field-option'; import { FormFieldOption } from './../core/form-field-option';
import { baseHost , WidgetComponent } from './../widget.component'; import { baseHost , WidgetComponent } from './../widget.component';
@@ -34,7 +33,6 @@ import { baseHost , WidgetComponent } from './../widget.component';
export class RadioButtonsWidgetComponent extends WidgetComponent implements OnInit { export class RadioButtonsWidgetComponent extends WidgetComponent implements OnInit {
constructor(public formService: FormService, constructor(public formService: FormService,
private visibilityService: WidgetVisibilityService,
private logService: LogService) { private logService: LogService) {
super(formService); super(formService);
} }
@@ -81,11 +79,7 @@ export class RadioButtonsWidgetComponent extends WidgetComponent implements OnIn
onOptionClick(optionSelected: any) { onOptionClick(optionSelected: any) {
this.field.value = optionSelected; this.field.value = optionSelected;
this.checkVisibility(); this.fieldChanged.emit(this.field);
}
checkVisibility() {
this.visibilityService.refreshVisibility(this.field.form);
} }
handleError(error: any) { handleError(error: any) {

View File

@@ -3,7 +3,7 @@
[class.is-dirty]="value" [class.is-dirty]="value"
[class.adf-invalid]="!field.isValid" [class.adf-invalid]="!field.isValid"
[class.adf-readonly]="field.readOnly" [class.adf-readonly]="field.readOnly"
id="typehead-div" *ngIf="field.isVisible"> id="typehead-div">
<mat-form-field> <mat-form-field>
<label class="adf-label" [attr.for]="field.id">{{field.name}}</label> <label class="adf-label" [attr.for]="field.id">{{field.name}}</label>
<input matInput class="adf-input" <input matInput class="adf-input"

View File

@@ -21,7 +21,6 @@ import { Observable } from 'rxjs/Observable';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { EcmModelService } from '../../../services/ecm-model.service'; import { EcmModelService } from '../../../services/ecm-model.service';
import { FormService } from '../../../services/form.service'; import { FormService } from '../../../services/form.service';
import { WidgetVisibilityService } from '../../../services/widget-visibility.service';
import { MaterialModule } from '../../../../material.module'; import { MaterialModule } from '../../../../material.module';
import { FormFieldOption } from '../core/form-field-option'; import { FormFieldOption } from '../core/form-field-option';
import { FormFieldTypes } from '../core/form-field-types'; import { FormFieldTypes } from '../core/form-field-types';
@@ -34,13 +33,12 @@ describe('TypeaheadWidgetComponent', () => {
let formService: FormService; let formService: FormService;
let widget: TypeaheadWidgetComponent; let widget: TypeaheadWidgetComponent;
let visibilityService: WidgetVisibilityService;
beforeEach(() => { beforeEach(() => {
formService = new FormService(null, null, null); formService = new FormService(null, null, null);
visibilityService = new WidgetVisibilityService(null, null); widget = new TypeaheadWidgetComponent(formService, null);
widget = new TypeaheadWidgetComponent(formService, visibilityService, null);
widget.field = new FormFieldModel(new FormModel({ taskId: 'task-id' })); widget.field = new FormFieldModel(new FormModel({ taskId: 'task-id' }));
widget.field.restUrl = 'whateverURL';
}); });
it('should request field values from service', () => { it('should request field values from service', () => {
@@ -52,7 +50,8 @@ describe('TypeaheadWidgetComponent', () => {
}); });
widget.field = new FormFieldModel(form, { widget.field = new FormFieldModel(form, {
id: fieldId id: fieldId,
restUrl: 'whateverURL'
}); });
spyOn(formService, 'getRestFieldValues').and.returnValue(Observable.create(observer => { spyOn(formService, 'getRestFieldValues').and.returnValue(Observable.create(observer => {
@@ -63,6 +62,23 @@ describe('TypeaheadWidgetComponent', () => {
expect(formService.getRestFieldValues).toHaveBeenCalledWith(taskId, fieldId); expect(formService.getRestFieldValues).toHaveBeenCalledWith(taskId, fieldId);
}); });
it('should not perform any request if restUrl is not present', () => {
const taskId = '<form-id>';
const fieldId = '<field-id>';
let form = new FormModel({
taskId: taskId
});
widget.field = new FormFieldModel(form, {
id: fieldId
});
spyOn(formService, 'getRestFieldValues');
widget.ngOnInit();
expect(formService.getRestFieldValues).not.toHaveBeenCalled();
});
it('should handle error when requesting fields with task id', () => { it('should handle error when requesting fields with task id', () => {
const taskId = '<form-id>'; const taskId = '<form-id>';
const fieldId = '<field-id>'; const fieldId = '<field-id>';
@@ -72,7 +88,8 @@ describe('TypeaheadWidgetComponent', () => {
}); });
widget.field = new FormFieldModel(form, { widget.field = new FormFieldModel(form, {
id: fieldId id: fieldId,
restUrl: 'whateverURL'
}); });
const err = 'Error'; const err = 'Error';
spyOn(formService, 'getRestFieldValues').and.returnValue(Observable.throw(err)); spyOn(formService, 'getRestFieldValues').and.returnValue(Observable.throw(err));
@@ -93,7 +110,8 @@ describe('TypeaheadWidgetComponent', () => {
}); });
widget.field = new FormFieldModel(form, { widget.field = new FormFieldModel(form, {
id: fieldId id: fieldId,
restUrl: 'whateverURL'
}); });
const err = 'Error'; const err = 'Error';
spyOn(formService, 'getRestFieldValuesByProcessId').and.returnValue(Observable.throw(err)); spyOn(formService, 'getRestFieldValuesByProcessId').and.returnValue(Observable.throw(err));
@@ -114,6 +132,7 @@ describe('TypeaheadWidgetComponent', () => {
observer.complete(); observer.complete();
})); }));
widget.field.value = '2'; widget.field.value = '2';
widget.field.restUrl = 'whateverURL';
widget.ngOnInit(); widget.ngOnInit();
expect(formService.getRestFieldValues).toHaveBeenCalled(); expect(formService.getRestFieldValues).toHaveBeenCalled();
@@ -130,6 +149,7 @@ describe('TypeaheadWidgetComponent', () => {
})); }));
widget.field.value = '3'; widget.field.value = '3';
widget.field.restUrl = 'whateverURL';
widget.ngOnInit(); widget.ngOnInit();
expect(formService.getRestFieldValues).toHaveBeenCalled(); expect(formService.getRestFieldValues).toHaveBeenCalled();
@@ -156,6 +176,7 @@ describe('TypeaheadWidgetComponent', () => {
observer.next([]); observer.next([]);
observer.complete(); observer.complete();
})); }));
widget.field.restUrl = 'whateverURL';
spyOn(widget.field, 'updateForm').and.callThrough(); spyOn(widget.field, 'updateForm').and.callThrough();
widget.ngOnInit(); widget.ngOnInit();
@@ -205,7 +226,7 @@ describe('TypeaheadWidgetComponent', () => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [MaterialModule], imports: [MaterialModule],
declarations: [TypeaheadWidgetComponent, ErrorWidgetComponent], declarations: [TypeaheadWidgetComponent, ErrorWidgetComponent],
providers: [ FormService, EcmModelService, WidgetVisibilityService ] providers: [ FormService, EcmModelService]
}).compileComponents().then(() => { }).compileComponents().then(() => {
fixture = TestBed.createComponent(TypeaheadWidgetComponent); fixture = TestBed.createComponent(TypeaheadWidgetComponent);
typeaheadWidgetComponent = fixture.componentInstance; typeaheadWidgetComponent = fixture.componentInstance;
@@ -249,14 +270,13 @@ describe('TypeaheadWidgetComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
stubFormService = fixture.debugElement.injector.get(FormService); stubFormService = fixture.debugElement.injector.get(FormService);
visibilityService = fixture.debugElement.injector.get(WidgetVisibilityService);
spyOn(visibilityService, 'refreshVisibility').and.stub();
spyOn(stubFormService, 'getRestFieldValues').and.returnValue(Observable.of(fakeOptionList)); spyOn(stubFormService, 'getRestFieldValues').and.returnValue(Observable.of(fakeOptionList));
typeaheadWidgetComponent.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), { typeaheadWidgetComponent.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
id: 'typeahead-id', id: 'typeahead-id',
name: 'typeahead-name', name: 'typeahead-name',
type: FormFieldTypes.TYPEAHEAD, type: FormFieldTypes.TYPEAHEAD,
readOnly: false readOnly: false,
restUrl: 'whateverURL'
}); });
typeaheadWidgetComponent.field.isVisible = true; typeaheadWidgetComponent.field.isVisible = true;
fixture.detectChanges(); fixture.detectChanges();
@@ -322,22 +342,12 @@ describe('TypeaheadWidgetComponent', () => {
expect(element.querySelector('.adf-error-text').textContent).toContain('FORM.FIELD.VALIDATOR.INVALID_VALUE'); expect(element.querySelector('.adf-error-text').textContent).toContain('FORM.FIELD.VALIDATOR.INVALID_VALUE');
}); });
})); }));
it('should hide not visible typeahead', async(() => {
typeaheadWidgetComponent.field.isVisible = false;
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(element.querySelector('#typeahead-id')).toBeNull();
});
}));
}); });
describe('and typeahead is populated via processDefinitionId', () => { describe('and typeahead is populated via processDefinitionId', () => {
beforeEach(async(() => { beforeEach(async(() => {
stubFormService = fixture.debugElement.injector.get(FormService); stubFormService = fixture.debugElement.injector.get(FormService);
visibilityService = fixture.debugElement.injector.get(WidgetVisibilityService);
spyOn(visibilityService, 'refreshVisibility').and.stub();
spyOn(stubFormService, 'getRestFieldValuesByProcessId').and.returnValue(Observable.of(fakeOptionList)); spyOn(stubFormService, 'getRestFieldValuesByProcessId').and.returnValue(Observable.of(fakeOptionList));
typeaheadWidgetComponent.field = new FormFieldModel(new FormModel({ processDefinitionId: 'fake-process-id' }), { typeaheadWidgetComponent.field = new FormFieldModel(new FormModel({ processDefinitionId: 'fake-process-id' }), {
id: 'typeahead-id', id: 'typeahead-id',

View File

@@ -20,7 +20,6 @@
import { LogService } from '../../../../services/log.service'; import { LogService } from '../../../../services/log.service';
import { ENTER, ESCAPE } from '@angular/cdk/keycodes'; import { ENTER, ESCAPE } from '@angular/cdk/keycodes';
import { Component, OnInit, ViewEncapsulation } from '@angular/core'; import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { WidgetVisibilityService } from '../../../services/widget-visibility.service';
import { FormService } from './../../../services/form.service'; import { FormService } from './../../../services/form.service';
import { FormFieldOption } from './../core/form-field-option'; import { FormFieldOption } from './../core/form-field-option';
import { baseHost, WidgetComponent } from './../widget.component'; import { baseHost, WidgetComponent } from './../widget.component';
@@ -40,15 +39,14 @@ export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit
options: FormFieldOption[] = []; options: FormFieldOption[] = [];
constructor(public formService: FormService, constructor(public formService: FormService,
private visibilityService: WidgetVisibilityService,
private logService: LogService) { private logService: LogService) {
super(formService); super(formService);
} }
ngOnInit() { ngOnInit() {
if (this.field.form.taskId) { if (this.field.form.taskId && this.field.restUrl) {
this.getValuesByTaskId(); this.getValuesByTaskId();
} else if (this.field.form.processDefinitionId) { } else if (this.field.form.processDefinitionId && this.field.restUrl) {
this.getValuesByProcessDefinitionId(); this.getValuesByProcessDefinitionId();
} }
if (this.isReadOnlyType()) { if (this.isReadOnlyType()) {
@@ -74,8 +72,8 @@ export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit
this.value = toSelect.name; this.value = toSelect.name;
} }
} }
this.onFieldChanged(this.field);
this.field.updateForm(); this.field.updateForm();
this.visibilityService.refreshEntityVisibility(this.field);
}, },
err => this.handleError(err) err => this.handleError(err)
); );
@@ -99,8 +97,8 @@ export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit
this.value = toSelect.name; this.value = toSelect.name;
} }
} }
this.onFieldChanged(this.field);
this.field.updateForm(); this.field.updateForm();
this.visibilityService.refreshEntityVisibility(this.field);
}, },
err => this.handleError(err) err => this.handleError(err)
); );
@@ -141,7 +139,7 @@ export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit
if (item) { if (item) {
this.field.value = item.id; this.field.value = item.id;
this.value = item.name; this.value = item.name;
this.checkVisibility(); this.onFieldChanged(this.field);
} }
} }
@@ -157,10 +155,6 @@ export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit
this.logService.error(error); this.logService.error(error);
} }
checkVisibility() {
this.visibilityService.refreshVisibility(this.field.form);
}
isReadOnlyType(): boolean { isReadOnlyType(): boolean {
return this.field.type === 'readonly' ? true : false; return this.field.type === 'readonly' ? true : false;
} }

View File

@@ -93,7 +93,7 @@ describe('WidgetComponent', () => {
done(); done();
}); });
widget.checkVisibility(fakeField); widget.onFieldChanged(fakeField);
}); });
it('should eval isRequired state of the field', () => { it('should eval isRequired state of the field', () => {