mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
[ADF-1653] cleaned user suggestion when input type is an empty string (#2444)
* [ADF-1653] cleaned user suggestion when input type is an empty string * [ADF-1653] removed wrong fdescribe * [ADF-1653] improved behaviour of people widget * Removed fdescribe
This commit is contained in:
@@ -112,6 +112,10 @@ export class FormFieldModel extends FormWidgetModel {
|
|||||||
return this._isValid;
|
return this._isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
markAsInvalid() {
|
||||||
|
this._isValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
validate(): boolean {
|
validate(): boolean {
|
||||||
this.validationSummary = null;
|
this.validationSummary = null;
|
||||||
|
|
||||||
|
|||||||
@@ -166,6 +166,10 @@ export class FormModel {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
markAsInvalid() {
|
||||||
|
this._isValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates entire form and all form fields.
|
* Validates entire form and all form fields.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -17,8 +17,7 @@
|
|||||||
placeholder="{{field.placeholder}}"
|
placeholder="{{field.placeholder}}"
|
||||||
[mdAutocomplete]="auto">
|
[mdAutocomplete]="auto">
|
||||||
<md-autocomplete #auto="mdAutocomplete" (optionSelected)="onItemSelect($event.option.value)">
|
<md-autocomplete #auto="mdAutocomplete" (optionSelected)="onItemSelect($event.option.value)">
|
||||||
<md-option *ngFor="let user of users; let i = index"
|
<md-option *ngFor="let user of users; let i = index" [value]="user">
|
||||||
(click)="onItemClick(user, $event)" [value]="user">
|
|
||||||
<div class="adf-people-widget-row" id="adf-people-widget-user-{{i}}">
|
<div class="adf-people-widget-row" id="adf-people-widget-user-{{i}}">
|
||||||
<div class="adf-people-widget-pic">
|
<div class="adf-people-widget-pic">
|
||||||
{{getInitialUserName(user.firstName, user.lastName)}}
|
{{getInitialUserName(user.firstName, user.lastName)}}
|
||||||
|
|||||||
+80
-44
@@ -15,12 +15,15 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { OverlayContainer } from '@angular/cdk/overlay';
|
||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
import { CoreModule, LightUserRepresentation } from 'ng2-alfresco-core';
|
import { CoreModule, LightUserRepresentation } from 'ng2-alfresco-core';
|
||||||
import { Observable } from 'rxjs/Rx';
|
import { Observable } from 'rxjs/Rx';
|
||||||
import { ActivitiAlfrescoContentService } from '../../../services/activiti-alfresco.service';
|
import { ActivitiAlfrescoContentService } from '../../../services/activiti-alfresco.service';
|
||||||
import { FormService } from '../../../services/form.service';
|
import { FormService } from '../../../services/form.service';
|
||||||
import { MaterialModule } from '../../material.module';
|
import { MaterialModule } from '../../material.module';
|
||||||
|
import { FormFieldTypes } from '../core/form-field-types';
|
||||||
import { FormFieldModel } from '../core/form-field.model';
|
import { FormFieldModel } from '../core/form-field.model';
|
||||||
import { FormModel } from '../core/form.model';
|
import { FormModel } from '../core/form.model';
|
||||||
import { ErrorWidgetComponent } from '../error/error.component';
|
import { ErrorWidgetComponent } from '../error/error.component';
|
||||||
@@ -33,6 +36,7 @@ describe('PeopleWidgetComponent', () => {
|
|||||||
let fixture: ComponentFixture<PeopleWidgetComponent>;
|
let fixture: ComponentFixture<PeopleWidgetComponent>;
|
||||||
let element: HTMLElement;
|
let element: HTMLElement;
|
||||||
let formService: FormService;
|
let formService: FormService;
|
||||||
|
let overlayContainerElement: HTMLElement;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
@@ -47,7 +51,19 @@ describe('PeopleWidgetComponent', () => {
|
|||||||
providers: [
|
providers: [
|
||||||
FormService,
|
FormService,
|
||||||
EcmModelService,
|
EcmModelService,
|
||||||
ActivitiAlfrescoContentService
|
ActivitiAlfrescoContentService,
|
||||||
|
{provide: OverlayContainer, useFactory: () => {
|
||||||
|
overlayContainerElement = document.createElement('div');
|
||||||
|
overlayContainerElement.classList.add('cdk-overlay-container');
|
||||||
|
|
||||||
|
document.body.appendChild(overlayContainerElement);
|
||||||
|
|
||||||
|
// remove body padding to keep consistent cross-browser
|
||||||
|
document.body.style.padding = '0';
|
||||||
|
document.body.style.margin = '0';
|
||||||
|
|
||||||
|
return {getContainerElement: () => overlayContainerElement};
|
||||||
|
}}
|
||||||
]
|
]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
}));
|
||||||
@@ -101,20 +117,6 @@ describe('PeopleWidgetComponent', () => {
|
|||||||
expect(widget.value).toBe('John Doe');
|
expect(widget.value).toBe('John Doe');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should prevent default behaviour on option item click', () => {
|
|
||||||
let event = jasmine.createSpyObj('event', ['preventDefault']);
|
|
||||||
widget.onItemClick(null, event);
|
|
||||||
expect(event.preventDefault).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update values on item click', () => {
|
|
||||||
let item = new LightUserRepresentation({firstName: 'John', lastName: 'Doe'});
|
|
||||||
|
|
||||||
widget.onItemClick(item, null);
|
|
||||||
expect(widget.field.value).toBe(item);
|
|
||||||
expect(widget.value).toBe('John Doe');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require form field to setup values on init', () => {
|
it('should require form field to setup values on init', () => {
|
||||||
widget.field = null;
|
widget.field = null;
|
||||||
widget.ngOnInit();
|
widget.ngOnInit();
|
||||||
@@ -204,42 +206,76 @@ describe('PeopleWidgetComponent', () => {
|
|||||||
expect(formService.getWorkflowUsers).not.toHaveBeenCalled();
|
expect(formService.getWorkflowUsers).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update form on value flush', () => {
|
it('should reset users when the input field is blank string', () => {
|
||||||
spyOn(widget.field, 'updateForm').and.callThrough();
|
let fakeUser = new LightUserRepresentation({id: '1', email: 'ffff@fff'});
|
||||||
widget.flushValue();
|
widget.users.push(fakeUser);
|
||||||
expect(widget.field.updateForm).toHaveBeenCalled();
|
|
||||||
|
let keyboardEvent = new KeyboardEvent('keypress');
|
||||||
|
widget.value = '';
|
||||||
|
widget.onKeyUp(keyboardEvent);
|
||||||
|
|
||||||
|
expect(widget.users).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should flush value and update field', () => {
|
describe('when template is ready', () => {
|
||||||
widget.users = [
|
|
||||||
new LightUserRepresentation({firstName: 'Tony', lastName: 'Stark'}),
|
|
||||||
new LightUserRepresentation({firstName: 'John', lastName: 'Doe'})
|
|
||||||
];
|
|
||||||
widget.value = 'John Doe';
|
|
||||||
widget.flushValue();
|
|
||||||
|
|
||||||
expect(widget.value).toBe('John Doe');
|
let fakeUserResult = [
|
||||||
expect(widget.field.value).toBe(widget.users[1]);
|
{ id: 1001, firstName: 'Test01', lastName: 'Test01', email: 'test' },
|
||||||
|
{ id: 1002, firstName: 'Test02', lastName: 'Test02', email: 'test2' }];
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
spyOn(formService, 'getWorkflowUsers').and.returnValue(Observable.create(observer => {
|
||||||
|
observer.next(fakeUserResult);
|
||||||
|
observer.complete();
|
||||||
|
}));
|
||||||
|
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
|
||||||
|
id: 'people-id',
|
||||||
|
name: 'people-name',
|
||||||
|
type: FormFieldTypes.PEOPLE,
|
||||||
|
readOnly: false
|
||||||
|
});
|
||||||
|
fixture.detectChanges();
|
||||||
|
element = fixture.nativeElement;
|
||||||
|
}));
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
fixture.destroy();
|
||||||
|
TestBed.resetTestingModule();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be case insensitive when flushing field', () => {
|
it('should render the people component', () => {
|
||||||
widget.users = [
|
expect(element.querySelector('#people-widget-content')).not.toBeNull();
|
||||||
new LightUserRepresentation({firstName: 'Tony', lastName: 'Stark'}),
|
|
||||||
new LightUserRepresentation({firstName: 'John', lastName: 'Doe'})
|
|
||||||
];
|
|
||||||
widget.value = 'TONY sTaRk';
|
|
||||||
widget.flushValue();
|
|
||||||
|
|
||||||
expect(widget.value).toBe('Tony Stark');
|
|
||||||
expect(widget.field.value).toBe(widget.users[0]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should reset value and field on flush', () => {
|
it('should show an error message if the user is invalid', async(() => {
|
||||||
widget.value = 'Missing User';
|
let peopleHTMLElement: HTMLInputElement = <HTMLInputElement> element.querySelector('#people-id');
|
||||||
widget.field.value = {};
|
peopleHTMLElement.focus();
|
||||||
widget.flushValue();
|
widget.value = 'K';
|
||||||
|
peopleHTMLElement.value = 'K';
|
||||||
|
peopleHTMLElement.dispatchEvent(new Event('keyup'));
|
||||||
|
peopleHTMLElement.dispatchEvent(new Event('input'));
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
expect(element.querySelector('.adf-error-text')).not.toBeNull();
|
||||||
|
expect(element.querySelector('.adf-error-text').textContent).toContain('Invalid value provided');
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
expect(widget.value).toBeNull();
|
it('should show the people if the typed result match', async(() => {
|
||||||
expect(widget.field.value).toBeNull();
|
let peopleHTMLElement: HTMLInputElement = <HTMLInputElement> element.querySelector('#people-id');
|
||||||
|
peopleHTMLElement.focus();
|
||||||
|
widget.value = 'T';
|
||||||
|
peopleHTMLElement.value = 'T';
|
||||||
|
peopleHTMLElement.dispatchEvent(new Event('keyup'));
|
||||||
|
peopleHTMLElement.dispatchEvent(new Event('input'));
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(fixture.debugElement.query(By.css('#adf-people-widget-user-0'))).not.toBeNull();
|
||||||
|
expect(fixture.debugElement.query(By.css('#adf-people-widget-user-1'))).not.toBeNull();
|
||||||
});
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -71,30 +71,41 @@ export class PeopleWidgetComponent extends WidgetComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.isValueDefined() && this.value.trim().length === 0) {
|
||||||
|
this.oldValue = this.value;
|
||||||
|
this.field.validationSummary = '';
|
||||||
|
this.users = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isValueDefined() {
|
||||||
|
return this.value !== null && this.value !== undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
searchUsers() {
|
searchUsers() {
|
||||||
this.formService.getWorkflowUsers(this.value, this.groupId)
|
this.formService.getWorkflowUsers(this.value, this.groupId)
|
||||||
.subscribe((result: LightUserRepresentation[]) => {
|
.subscribe((result: LightUserRepresentation[]) => {
|
||||||
this.users = result || [];
|
this.users = result || [];
|
||||||
|
this.validateValue();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
flushValue() {
|
validateValue() {
|
||||||
let option = this.users.find(item => {
|
let validUserName = this.getUserFromValue();
|
||||||
let fullName = this.getDisplayName(item).toLocaleLowerCase();
|
if (validUserName) {
|
||||||
return (this.value && fullName === this.value.toLocaleLowerCase());
|
this.field.validationSummary = '';
|
||||||
});
|
this.field.value = validUserName;
|
||||||
|
this.value = this.getDisplayName(validUserName);
|
||||||
if (option) {
|
|
||||||
this.field.value = option;
|
|
||||||
this.value = this.getDisplayName(option);
|
|
||||||
} else {
|
} else {
|
||||||
this.field.value = null;
|
this.field.value = '';
|
||||||
this.value = null;
|
this.field.validationSummary = 'Invalid value provided';
|
||||||
|
this.field.markAsInvalid();
|
||||||
|
this.field.form.markAsInvalid();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.field.updateForm();
|
getUserFromValue() {
|
||||||
|
return this.users.find((user) => this.getDisplayName(user).toLocaleLowerCase() === this.value.toLocaleLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
getDisplayName(model: LightUserRepresentation) {
|
getDisplayName(model: LightUserRepresentation) {
|
||||||
@@ -102,20 +113,9 @@ export class PeopleWidgetComponent extends WidgetComponent implements OnInit {
|
|||||||
let displayName = `${model.firstName || ''} ${model.lastName || ''}`;
|
let displayName = `${model.firstName || ''} ${model.lastName || ''}`;
|
||||||
return displayName.trim();
|
return displayName.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
onItemClick(item: LightUserRepresentation, event: Event) {
|
|
||||||
if (item) {
|
|
||||||
this.field.value = item;
|
|
||||||
this.value = this.getDisplayName(item);
|
|
||||||
}
|
|
||||||
if (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onItemSelect(item: LightUserRepresentation) {
|
onItemSelect(item: LightUserRepresentation) {
|
||||||
if (item) {
|
if (item) {
|
||||||
this.field.value = item;
|
this.field.value = item;
|
||||||
|
|||||||
@@ -387,6 +387,7 @@ export class FormService {
|
|||||||
return Observable.of(user);
|
return Observable.of(user);
|
||||||
})
|
})
|
||||||
.combineAll()
|
.combineAll()
|
||||||
|
.defaultIfEmpty([])
|
||||||
.catch(err => this.handleError(err));
|
.catch(err => this.handleError(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user