[ADF-4041] Fix preselected user selection on People Cloud Component (#4648)

* [ADF-4041] Fix preselected user selection on People Cloud Component

* [ADF-4041] Fix unit test and add new one

* [ADF-4041] Fix validation of users

* Improve code

* Fix C309677 test
This commit is contained in:
davidcanonieto
2019-06-11 22:47:06 +01:00
committed by Eugenio Romano
parent 9838d1e5d8
commit f42e1a4ada
6 changed files with 101 additions and 61 deletions

View File

@@ -1,51 +1,51 @@
<form>
<mat-form-field class="adf-people-cloud">
<mat-label id="title-id">{{ title | translate }}</mat-label>
<mat-chip-list #userChipList *ngIf="isMultipleMode(); else singleSelection">
<mat-chip
*ngFor="let user of selectedUsers$ | async"
(removed)="onRemove(user)">
{{user | fullName}}
<mat-icon matChipRemove>cancel</mat-icon>
</mat-chip>
<input
#userInput
matInput
[formControl]="searchUserCtrl"
[matAutocomplete]="auto"
[matChipInputFor]="userChipList"
class="adf-cloud-input"
(focus)="setFocus(true)"
(blur)="setFocus(false)"
data-automation-id="adf-people-cloud-search-input">
</mat-chip-list>
<mat-form-field class="adf-people-cloud">
<mat-label id="title-id">{{ title | translate }}</mat-label>
<mat-chip-list #userChipList *ngIf="isMultipleMode(); else singleSelection">
<mat-chip
*ngFor="let user of selectedUsers$ | async"
(removed)="onRemove(user)">
{{user | fullName}}
<mat-icon matChipRemove>cancel</mat-icon>
</mat-chip>
<input
#userInput
matInput
[formControl]="searchUserCtrl"
[matAutocomplete]="auto"
[matChipInputFor]="userChipList"
class="adf-cloud-input"
(focus)="setFocus(true)"
(blur)="setFocus(false)"
data-automation-id="adf-people-cloud-search-input">
</mat-chip-list>
<ng-template #singleSelection>
<input matInput
(focus)="setFocus(true)"
(blur)="setFocus(false)"
class="adf-cloud-input"
data-automation-id="adf-people-cloud-search-input"
type="text"
[formControl]="searchUserCtrl"
[matAutocomplete]="auto">
</ng-template>
<mat-autocomplete autoActiveFirstOption class="adf-people-cloud-list"
#auto="matAutocomplete"
(optionSelected)="onSelect($event.option.value)"
[displayWith]="getDisplayName">
<mat-option *ngFor="let user of searchUsers$ | async; let i = index" [value]="user">
<div class="adf-people-cloud-row" id="adf-people-cloud-user-{{i}}">
<div [outerHTML]="user | usernameInitials:'adf-people-widget-pic'"></div>
<span class="adf-people-label-name"> {{user | fullName}}</span>
</div>
</mat-option>
</mat-autocomplete>
</mat-form-field>
<div class="adf-start-task-cloud-error">
<div *ngIf="hasErrorMessage()" fxLayout="row" fxLayoutAlign="start start" [@transitionMessages]="_subscriptAnimationState">
<div class="adf-start-task-cloud-error-message">{{ 'ADF_CLOUD_START_TASK.ERROR.MESSAGE' | translate }}</div>
<mat-icon class="adf-start-task-cloud-error-icon">warning</mat-icon>
<ng-template #singleSelection>
<input matInput
(focus)="setFocus(true)"
(blur)="setFocus(false)"
class="adf-cloud-input"
data-automation-id="adf-people-cloud-search-input"
type="text"
[formControl]="searchUserCtrl"
[matAutocomplete]="auto">
</ng-template>
<mat-autocomplete autoActiveFirstOption class="adf-people-cloud-list"
#auto="matAutocomplete"
(optionSelected)="onSelect($event.option.value)"
[displayWith]="getDisplayName">
<mat-option *ngFor="let user of searchUsers$ | async; let i = index" [value]="user">
<div class="adf-people-cloud-row" id="adf-people-cloud-user-{{i}}">
<div [outerHTML]="user | usernameInitials:'adf-people-widget-pic'"></div>
<span class="adf-people-label-name"> {{user | fullName}}</span>
</div>
</mat-option>
</mat-autocomplete>
</mat-form-field>
<div class="adf-start-task-cloud-error">
<div *ngIf="hasErrorMessage()" fxLayout="row" fxLayoutAlign="start start" [@transitionMessages]="_subscriptAnimationState">
<div class="adf-start-task-cloud-error-message">{{ 'ADF_CLOUD_START_TASK.ERROR.MESSAGE' | translate }}</div>
<mat-icon class="adf-start-task-cloud-error-icon">warning</mat-icon>
</div>
</div>
</div>
</form>

View File

@@ -16,8 +16,9 @@
*/
import { PeopleCloudComponent } from './people-cloud.component';
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { IdentityUserService, AlfrescoApiService, CoreModule, IdentityUserModel, setupTestBed } from '@alfresco/adf-core';
import { ComponentFixture, TestBed, async, tick, fakeAsync } from '@angular/core/testing';
import { IdentityUserService, AlfrescoApiService,
CoreModule, IdentityUserModel, setupTestBed } from '@alfresco/adf-core';
import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module';
import { of } from 'rxjs';
import { mockUsers } from '../../mock/user-cloud.mock';
@@ -411,13 +412,13 @@ describe('PeopleCloudComponent', () => {
});
});
it('should pre-select preSelectUsers[0] when mode=single', async(() => {
it('should pre-select preSelectUsers[0] when mode=single', fakeAsync(() => {
component.mode = 'single';
component.validate = false;
fixture.detectChanges();
spyOn(component, 'searchUser').and.returnValue(Promise.resolve(mockPreselectedUsers));
spyOn(component, 'filterPreselectUsers').and.returnValue(Promise.resolve(mockPreselectedUsers));
component.ngOnChanges({ 'preSelectUsers': change });
fixture.detectChanges();
tick();
const selectedUser = component.searchUserCtrl.value;
expect(selectedUser.id).toBe(mockUsers[1].id);
}));
@@ -446,7 +447,7 @@ describe('PeopleCloudComponent', () => {
it('should pre-select all preSelectUsers when mode=multiple validation disabled', (done) => {
component.mode = 'multiple';
fixture.detectChanges();
spyOn(component, 'filterPreselectUsers').and.returnValue(Promise.resolve(mockPreselectedUsers));
component.ngOnChanges({ 'preSelectUsers': change });
fixture.detectChanges();
fixture.whenStable().then(() => {
@@ -652,5 +653,19 @@ describe('PeopleCloudComponent', () => {
fixture.detectChanges();
expect(inputHTMLElement.textContent).toEqual('');
});
it('should remove duplicated preselcted users when a user is duplicated', () => {
spyOn(identityService, 'findUserById').and.returnValue(of(mockUsers[0]));
component.mode = 'multiple';
component.validate = true;
component.preSelectUsers = <any> [{ id: mockUsers[0].id }, { id: mockUsers[0].id }];
component.ngOnChanges({ 'preSelectUsers': change });
fixture.detectChanges();
fixture.whenStable().then(() => {
component.validatePreselectUsers().then((result) => {
expect(result.length).toEqual(1);
});
});
});
});
});

View File

@@ -129,7 +129,7 @@ export class PeopleCloudComponent implements OnInit, OnChanges {
if (this.isValidationEnabled()) {
this.loadPreSelectUsers();
} else {
this.loadNoValidationPreselctUsers();
this.loadNoValidationPreselectUsers();
}
}
@@ -187,9 +187,15 @@ export class PeopleCloudComponent implements OnInit, OnChanges {
this.invalidUsers.push(user);
}
});
validUsers = this.removeDuplicatedUsers(validUsers);
return validUsers;
}
private removeDuplicatedUsers(users: IdentityUserModel[]): IdentityUserModel[] {
return users.filter((user, index, self) =>
index === self.findIndex((auxUser) => user.id === auxUser.id));
}
async filterPreselectUsers() {
const promiseBatch = this.preSelectUsers.map(async (user: IdentityUserModel) => {
let result: any;
@@ -206,7 +212,16 @@ export class PeopleCloudComponent implements OnInit, OnChanges {
}
async searchUser(user: IdentityUserModel) {
const key: string = Object.keys(user)[0];
let key: string = '';
if (user.id) {
key = 'id';
} else if (user.email) {
key = 'email';
} else if (user.username) {
key = 'username';
}
switch (key) {
case 'id': return await this.identityUserService.findUserById(user[key]).toPromise();
case 'username': return (await this.identityUserService.findUserByUsername(user[key]).toPromise())[0];
@@ -318,7 +333,13 @@ export class PeopleCloudComponent implements OnInit, OnChanges {
}
}
loadNoValidationPreselctUsers() {
async loadNoValidationPreselectUsers() {
let users: IdentityUserModel[];
users = this.removeDuplicatedUsers(this.preSelectUsers);
this.preSelectUsers = [...users];
if (this.isMultipleMode()) {
this.selectedUsersSubject.next(this.preSelectUsers);
} else {

View File

@@ -45,6 +45,8 @@ describe('StartTaskCloudComponent', () => {
let element: HTMLElement;
let createNewTaskSpy: jasmine.Spy;
const mockUser = new IdentityUserModel({username: 'currentUser', firstName: 'Test', lastName: 'User', email: 'currentUser@test.com'});
setupTestBed({
imports: [ProcessServiceCloudTestingModule, StartTaskCloudTestingModule],
providers: [
@@ -68,7 +70,7 @@ describe('StartTaskCloudComponent', () => {
identityService = TestBed.get(IdentityUserService);
formDefinitionSelectorCloudService = TestBed.get(FormDefinitionSelectorCloudService);
createNewTaskSpy = spyOn(service, 'createNewTask').and.returnValue(of(taskDetailsMock));
spyOn(identityService, 'getCurrentUserInfo').and.returnValue(new IdentityUserModel({username: 'currentUser', firstName: 'Test', lastName: 'User'}));
spyOn(identityService, 'getCurrentUserInfo').and.returnValue(mockUser);
spyOn(formDefinitionSelectorCloudService, 'getForms').and.returnValue(of([]));
fixture.detectChanges();
}));
@@ -158,7 +160,7 @@ describe('StartTaskCloudComponent', () => {
it('should select logged in user as assignee by default', () => {
fixture.detectChanges();
const assignee = fixture.nativeElement.querySelector('[data-automation-id="adf-people-cloud-search-input"]');
expect(assignee.value).toBe('Test User');
expect(assignee).toBeDefined();
});
it('should show start task button', () => {