From a8361b52cf6ef8b4595838668566b2918313f049 Mon Sep 17 00:00:00 2001 From: Maurizio Vitale Date: Wed, 11 Dec 2019 20:57:58 +0000 Subject: [PATCH] Making sure the people does not change the original obj reference (#5325) --- .../widgets/group/group-cloud.widget.html | 3 +- .../widgets/group/group-cloud.widget.ts | 17 +------- .../widgets/people/people-cloud.widget.html | 3 +- .../widgets/people/people-cloud.widget.ts | 17 +------- .../group/components/group-cloud.component.ts | 41 +++++++++++-------- .../components/people-cloud.component.spec.ts | 24 ----------- .../components/people-cloud.component.ts | 31 ++++++++------ 7 files changed, 48 insertions(+), 88 deletions(-) diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/group/group-cloud.widget.html b/lib/process-services-cloud/src/lib/form/components/widgets/group/group-cloud.widget.html index 19cf3c3799..ce616eb15a 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/group/group-cloud.widget.html +++ b/lib/process-services-cloud/src/lib/form/components/widgets/group/group-cloud.widget.html @@ -7,8 +7,7 @@ [readOnly]="field.readOnly" [roles]="roles" [searchGroupsControl]="search" - (selectGroup)="onSelectGroup($event)" - (removeGroup)="onRemoveGroup($event)" + (changedGroups)="onChangedGroup($event)" [preSelectGroups]="preSelectGroup"> diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/group/group-cloud.widget.ts b/lib/process-services-cloud/src/lib/form/components/widgets/group/group-cloud.widget.ts index ad62f6a801..f1b9f18843 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/group/group-cloud.widget.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/group/group-cloud.widget.ts @@ -78,21 +78,8 @@ export class GroupCloudWidgetComponent extends WidgetComponent implements OnInit this.onDestroy$.complete(); } - onSelectGroup(group: IdentityGroupModel) { - this.field.value = [...this.preSelectGroup, group]; - this.onFieldChanged(this.field); - } - - onRemoveGroup(group: IdentityGroupModel) { - if (this.isMultipleMode()) { - const indexToRemove = this.preSelectGroup.findIndex((selectedUser) => { return selectedUser.id === group.id; }); - if (indexToRemove > -1) { - this.preSelectGroup.splice(indexToRemove, 1); - } - } else { - this.preSelectGroup = []; - } - this.field.value = [...this.preSelectGroup]; + onChangedGroup(groups) { + this.field.value = [...groups]; this.onFieldChanged(this.field); } diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/people/people-cloud.widget.html b/lib/process-services-cloud/src/lib/form/components/widgets/people/people-cloud.widget.html index e3f0baf406..194dc153b5 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/people/people-cloud.widget.html +++ b/lib/process-services-cloud/src/lib/form/components/widgets/people/people-cloud.widget.html @@ -8,8 +8,7 @@ [title]="title" [readOnly]="field.readOnly" [searchUserCtrl]="search" - (selectUser)="onSelectUser($event)" - (removeUser)="onRemoveUser($event)" + (changedUsers)="onChangedUser($event)" [roles]="roles" [mode]="mode"> diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/people/people-cloud.widget.ts b/lib/process-services-cloud/src/lib/form/components/widgets/people/people-cloud.widget.ts index 6b59ad2ca3..30c4f8dfc8 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/people/people-cloud.widget.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/people/people-cloud.widget.ts @@ -79,21 +79,8 @@ export class PeopleCloudWidgetComponent extends WidgetComponent implements OnIni this.onDestroy$.complete(); } - onSelectUser(user: IdentityUserModel) { - this.field.value = [...this.preSelectUsers, user]; - this.onFieldChanged(this.field); - } - - onRemoveUser(user: IdentityUserModel) { - if (this.isMultipleMode()) { - const indexToRemove = this.preSelectUsers.findIndex((selectedUser) => { return selectedUser.id === user.id; }); - if (indexToRemove > -1) { - this.preSelectUsers.splice(indexToRemove, 1); - } - } else { - this.preSelectUsers = []; - } - this.field.value = [...this.preSelectUsers]; + onChangedUser(users) { + this.field.value = [...users]; this.onFieldChanged(this.field); } diff --git a/lib/process-services-cloud/src/lib/group/components/group-cloud.component.ts b/lib/process-services-cloud/src/lib/group/components/group-cloud.component.ts index d42d58e4ce..202dde6466 100644 --- a/lib/process-services-cloud/src/lib/group/components/group-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/group/components/group-cloud.component.ts @@ -92,6 +92,10 @@ export class GroupCloudComponent implements OnInit, OnChanges, OnDestroy { @Output() removeGroup = new EventEmitter(); + /** Emitted when a group selection change. */ + @Output() + changedGroups = new EventEmitter(); + @ViewChild('groupInput') private groupInput: ElementRef; @@ -203,21 +207,20 @@ export class GroupCloudComponent implements OnInit, OnChanges, OnDestroy { } } - isGroupAlreadySelected(group: IdentityGroupModel): boolean { - const result = this.selectedGroups.find((selectedGroup: IdentityGroupModel) => { - return selectedGroup.id === group.id; - }); + private isGroupAlreadySelected(group: IdentityGroupModel): boolean { + if (this.selectedGroups && this.selectedGroups.length > 0 && this.isMultipleMode()) { + const result = this.selectedGroups.find((selectedGroup: IdentityGroupModel) => { + return selectedGroup.id === group.id; + }); - return !!result; + return !!result; + } + return false; } private loadPreSelectGroups() { if (this.isMultipleMode()) { - this.selectedGroups = []; - this.preSelectGroups.forEach((group: IdentityGroupModel) => { - this.selectedGroups.push(group); - }); - const groups = this.removeDuplicatedGroups(this.selectedGroups); + const groups = this.removeDuplicatedGroups([...this.preSelectGroups]); this.selectedGroups = [...groups]; this.selectedGroups$.next(this.selectedGroups); } else { @@ -240,31 +243,33 @@ export class GroupCloudComponent implements OnInit, OnChanges, OnDestroy { map((filteredGroup: { hasRole: boolean, group: IdentityGroupModel }) => filteredGroup.group)); } - onSelect(selectedGroup: IdentityGroupModel) { + onSelect(group: IdentityGroupModel) { + this.selectGroup.emit(group); if (this.isMultipleMode()) { - if (!this.isGroupAlreadySelected(selectedGroup)) { - this.selectedGroups.push(selectedGroup); + if (!this.isGroupAlreadySelected(group)) { + this.selectedGroups.push(group); this.selectedGroups$.next(this.selectedGroups); - this.selectGroup.emit(selectedGroup); this.searchGroups$.next([]); } this.groupInput.nativeElement.value = ''; this.searchGroupsControl.setValue(''); } else { - this.selectGroup.emit(selectedGroup); + this.selectedGroups = [group]; } + this.changedGroups.emit(this.selectedGroups); this.clearError(); this.resetSearchGroups(); } - onRemove(selectedGroup: IdentityGroupModel) { - this.removeGroup.emit(selectedGroup); + onRemove(removedGroup: IdentityGroupModel) { + this.removeGroup.emit(removedGroup); const indexToRemove = this.selectedGroups.findIndex((group: IdentityGroupModel) => { - return group.id === selectedGroup.id; + return group.id === removedGroup.id; }); this.selectedGroups.splice(indexToRemove, 1); this.selectedGroups$.next(this.selectedGroups); + this.changedGroups.emit(this.selectedGroups); } private resetSearchGroups() { diff --git a/lib/process-services-cloud/src/lib/people/components/people-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/people/components/people-cloud.component.spec.ts index fded3f2598..1502ea2175 100644 --- a/lib/process-services-cloud/src/lib/people/components/people-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/people/components/people-cloud.component.spec.ts @@ -475,30 +475,6 @@ describe('PeopleCloudComponent', () => { done(); }); }); - - it('Should be able to remove preselected users if readonly property set to false', (done) => { - component.mode = 'multiple'; - const removeUserSpy = spyOn(component.removeUser, 'emit'); - component.preSelectUsers = [ - { id: mockUsers[0].id, username: mockUsers[0].username, readonly: false }, - { id: mockUsers[1].id, username: mockUsers[1].username, readonly: false } - ]; - fixture.detectChanges(); - const chipList = fixture.nativeElement.querySelectorAll('mat-chip-list mat-chip'); - const removeIcon = fixture.nativeElement.querySelector('[data-automation-id="adf-people-cloud-chip-remove-icon-first-name-1 last-name-1"]'); - expect(chipList.length).toBe(2); - expect(component.preSelectUsers[0].readonly).toBe(false, 'Removable'); - expect(component.preSelectUsers[1].readonly).toBe(false, 'Removable'); - removeIcon.click(); - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(removeUserSpy).toHaveBeenCalled(); - expect(component.preSelectUsers.length).toBe(1); - expect(component.preSelectUsers[0].readonly).toBeFalsy(); - done(); - }); - }); }); describe('Multiple Mode and Pre-selected users with validate flag', () => { diff --git a/lib/process-services-cloud/src/lib/people/components/people-cloud.component.ts b/lib/process-services-cloud/src/lib/people/components/people-cloud.component.ts index 0134287d0b..eac1be95a0 100644 --- a/lib/process-services-cloud/src/lib/people/components/people-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/people/components/people-cloud.component.ts @@ -93,6 +93,10 @@ export class PeopleCloudComponent implements OnInit, OnChanges, OnDestroy { @Output() removeUser = new EventEmitter(); + /** Emitted when a user selection change. */ + @Output() + changedUsers = new EventEmitter(); + /** Emitted when an warning occurs. */ @Output() warning = new EventEmitter(); @@ -105,6 +109,7 @@ export class PeopleCloudComponent implements OnInit, OnChanges, OnDestroy { private searchUsersSubject: BehaviorSubject; private onDestroy$ = new Subject(); + selectedUsers: IdentityUserModel[] = []; selectedUsers$: Observable; searchUsers$: Observable; _subscriptAnimationState: string = 'enter'; @@ -118,6 +123,7 @@ export class PeopleCloudComponent implements OnInit, OnChanges, OnDestroy { } ngOnInit() { + this.selectedUsers = [...this.preSelectUsers]; this.initSubjects(); this.initSearch(); @@ -326,8 +332,8 @@ export class PeopleCloudComponent implements OnInit, OnChanges, OnDestroy { } private isUserAlreadySelected(user: IdentityUserModel): boolean { - if (this.preSelectUsers && this.preSelectUsers.length > 0 && this.isMultipleMode()) { - const result = this.preSelectUsers.find((selectedUser) => { + if (this.selectedUsers && this.selectedUsers.length > 0 && this.isMultipleMode()) { + const result = this.selectedUsers.find((selectedUser) => { return selectedUser.id === user.id || selectedUser.email === user.email || selectedUser.username === user.username; }); @@ -379,8 +385,8 @@ export class PeopleCloudComponent implements OnInit, OnChanges, OnDestroy { const users = await this.validatePreselectUsers(); if (users && users.length > 0) { this.checkPreselectValidationErrors(); - this.preSelectUsers = [...users]; - this.selectedUsersSubject.next(users); + this.selectedUsers = [...users]; + this.selectedUsersSubject.next(this.selectedUsers); } else { this.checkPreselectValidationErrors(); } @@ -404,29 +410,30 @@ export class PeopleCloudComponent implements OnInit, OnChanges, OnDestroy { } onSelect(user: IdentityUserModel) { + this.selectUser.emit(user); if (this.isMultipleMode()) { - if (!this.isUserAlreadySelected(user)) { - this.preSelectUsers.push(user); - this.selectedUsersSubject.next(this.preSelectUsers); - this.selectUser.emit(user); + this.selectedUsers.push(user); + this.selectedUsersSubject.next(this.selectedUsers); } this.userInput.nativeElement.value = ''; this.searchUserCtrl.setValue(''); } else { - this.selectUser.emit(user); + this.selectedUsers = [user]; } + this.changedUsers.emit(this.selectedUsers); this.clearError(); this.resetSearchUsers(); } onRemove(user: IdentityUserModel) { - const indexToRemove = this.preSelectUsers.findIndex((selectedUser) => { return selectedUser.id === user.id; }); - this.preSelectUsers.splice(indexToRemove, 1); - this.selectedUsersSubject.next(this.preSelectUsers); this.removeUser.emit(user); + const indexToRemove = this.selectedUsers.findIndex((selectedUser) => { return selectedUser.id === user.id; }); + this.selectedUsers.splice(indexToRemove, 1); + this.selectedUsersSubject.next(this.selectedUsers); + this.changedUsers.emit(this.selectedUsers); } getDisplayName(user): string {