mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ADF-5031][PeopleCloudComponent] [PeopleCloudComponent] Provide a way to make selected items read-only (not remove) (#5289)
* [DW-1618] Admin App -Application Instances - Able to delete all the admin users in Manage app permissions. * [ADF-5031] [PeopleCloudComponent] Do not delete selected users completely. * Added flag for not to remove last chip * Added unit tests to the changes. * * Added doc * * Changed removeLastChip to remove * * Added readonly strategy * Removed remove input * Updated unit tests * * Added tooltip * Hiding remove icon. * * Fixed unit tests
This commit is contained in:
committed by
Maurizio Vitale
parent
57df944bbf
commit
84dac48d9b
@@ -39,3 +39,25 @@ Allows one or more users to be selected (with auto-suggestion) based on the inpu
|
|||||||
| removeUser | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`IdentityUserModel`](../../../lib/core/models/identity-user.model.ts)`>` | Emitted when a selected user is removed in multi selection mode. |
|
| removeUser | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`IdentityUserModel`](../../../lib/core/models/identity-user.model.ts)`>` | Emitted when a selected user is removed in multi selection mode. |
|
||||||
| selectUser | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`IdentityUserModel`](../../../lib/core/models/identity-user.model.ts)`>` | Emitted when a user is selected. |
|
| selectUser | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`IdentityUserModel`](../../../lib/core/models/identity-user.model.ts)`>` | Emitted when a user is selected. |
|
||||||
| warning | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when an warning occurs. |
|
| warning | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when an warning occurs. |
|
||||||
|
|
||||||
|
## Details
|
||||||
|
|
||||||
|
### Read-only
|
||||||
|
|
||||||
|
You can use `readonly` property to make preselected users read-only in `multiple` mode.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const preSelectUsers = [
|
||||||
|
{ "id": "1", "username": "username1", "firstName": "user 1", "readonly": true },
|
||||||
|
{ "id": "2", "username": "username2", "firstName": "user 2", "readonly": false },
|
||||||
|
{ "id": "3", "username": "username3", "firstName": "user 3", "readonly": true }
|
||||||
|
];
|
||||||
|
```
|
||||||
|
```html
|
||||||
|
<adf-cloud-people
|
||||||
|
[mode]="'multiple'",
|
||||||
|
[preSelectUsers]="preSelectUsers">
|
||||||
|
</adf-cloud-people>
|
||||||
|
```
|
||||||
|
|
||||||
|
from above `preSelectUsers`, `username2` is removable from the `preSelectUsers` whereas `username1`, `username3` are readonly you can not remove them.
|
||||||
|
@@ -24,4 +24,5 @@ export interface IdentityUserModel {
|
|||||||
createdTimestamp?: any;
|
createdTimestamp?: any;
|
||||||
emailVerified?: boolean;
|
emailVerified?: boolean;
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
|
readonly?: boolean;
|
||||||
}
|
}
|
||||||
|
@@ -6,9 +6,11 @@
|
|||||||
*ngFor="let group of selectedGroups$ | async"
|
*ngFor="let group of selectedGroups$ | async"
|
||||||
[removable]="!(group.readonly)"
|
[removable]="!(group.readonly)"
|
||||||
(removed)="onRemove(group)"
|
(removed)="onRemove(group)"
|
||||||
|
matTooltip="{{ (group.readonly ? 'ADF_CLOUD_GROUPS.MANDATORY' : '') | translate }}"
|
||||||
[attr.data-automation-id]="'adf-cloud-group-chip-' + group.name">
|
[attr.data-automation-id]="'adf-cloud-group-chip-' + group.name">
|
||||||
{{group.name}}
|
{{group.name}}
|
||||||
<mat-icon
|
<mat-icon
|
||||||
|
*ngIf=!(group.readonly)
|
||||||
matChipRemove [attr.data-automation-id]="'adf-cloud-group-chip-remove-icon-' + group.name">
|
matChipRemove [attr.data-automation-id]="'adf-cloud-group-chip-remove-icon-' + group.name">
|
||||||
cancel
|
cancel
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
|
@@ -442,7 +442,7 @@ describe('GroupCloudComponent', () => {
|
|||||||
|
|
||||||
describe('Multiple Mode with read-only', () => {
|
describe('Multiple Mode with read-only', () => {
|
||||||
|
|
||||||
it('Should not be able to remove pre-selected groups if readonly property set to true', (done) => {
|
it('Should not show remove icon for pre-selected groups if readonly property set to true', (done) => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
const preselectedGroups = [
|
const preselectedGroups = [
|
||||||
{ id: mockIdentityGroups[0].id, name: mockIdentityGroups[0].name, readonly: true },
|
{ id: mockIdentityGroups[0].id, name: mockIdentityGroups[0].name, readonly: true },
|
||||||
@@ -451,7 +451,6 @@ describe('GroupCloudComponent', () => {
|
|||||||
component.preSelectGroups = preselectedGroups;
|
component.preSelectGroups = preselectedGroups;
|
||||||
const change = new SimpleChange(null, preselectedGroups, false);
|
const change = new SimpleChange(null, preselectedGroups, false);
|
||||||
component.mode = 'multiple';
|
component.mode = 'multiple';
|
||||||
const removeGroupSpy = spyOn(component.removeGroup, 'emit');
|
|
||||||
component.ngOnChanges({ 'preSelectGroups': change });
|
component.ngOnChanges({ 'preSelectGroups': change });
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
const chipList = fixture.nativeElement.querySelectorAll('mat-chip-list mat-chip');
|
const chipList = fixture.nativeElement.querySelectorAll('mat-chip-list mat-chip');
|
||||||
@@ -462,9 +461,7 @@ describe('GroupCloudComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
removeIcon.click();
|
expect(removeIcon).toBeNull();
|
||||||
fixture.detectChanges();
|
|
||||||
expect(removeGroupSpy).not.toHaveBeenCalled();
|
|
||||||
expect(component.preSelectGroups.length).toBe(2);
|
expect(component.preSelectGroups.length).toBe(2);
|
||||||
expect(component.preSelectGroups[0].readonly).toBe(true, 'Not removable');
|
expect(component.preSelectGroups[0].readonly).toBe(true, 'Not removable');
|
||||||
expect(component.preSelectGroups[1].readonly).toBe(true, 'Not removable');
|
expect(component.preSelectGroups[1].readonly).toBe(true, 'Not removable');
|
||||||
|
@@ -176,6 +176,7 @@
|
|||||||
},
|
},
|
||||||
"ADF_CLOUD_GROUPS": {
|
"ADF_CLOUD_GROUPS": {
|
||||||
"SEARCH-GROUP": "Groups",
|
"SEARCH-GROUP": "Groups",
|
||||||
|
"MANDATORY": "Mandatory",
|
||||||
"ERROR": {
|
"ERROR": {
|
||||||
"NOT_FOUND": "No group found with the name {{groupName}}"
|
"NOT_FOUND": "No group found with the name {{groupName}}"
|
||||||
}
|
}
|
||||||
|
@@ -4,9 +4,17 @@
|
|||||||
<mat-chip-list #userChipList *ngIf="isMultipleMode(); else singleSelection">
|
<mat-chip-list #userChipList *ngIf="isMultipleMode(); else singleSelection">
|
||||||
<mat-chip
|
<mat-chip
|
||||||
*ngFor="let user of selectedUsers$ | async"
|
*ngFor="let user of selectedUsers$ | async"
|
||||||
|
[removable]="!(user.readonly)"
|
||||||
|
[attr.data-automation-id]="'adf-people-cloud-chip-' + user.username"
|
||||||
|
matTooltip="{{ (user.readonly ? 'ADF_CLOUD_GROUPS.MANDATORY' : '') | translate }}"
|
||||||
(removed)="onRemove(user)">
|
(removed)="onRemove(user)">
|
||||||
{{user | fullName}}
|
{{user | fullName}}
|
||||||
<mat-icon matChipRemove>cancel</mat-icon>
|
<mat-icon
|
||||||
|
matChipRemove
|
||||||
|
*ngIf=!(user.readonly)
|
||||||
|
[attr.data-automation-id]="'adf-people-cloud-chip-remove-icon-' + user.username">
|
||||||
|
cancel
|
||||||
|
</mat-icon>
|
||||||
</mat-chip>
|
</mat-chip>
|
||||||
<input
|
<input
|
||||||
#userInput
|
#userInput
|
||||||
|
@@ -461,6 +461,59 @@ describe('PeopleCloudComponent', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Multiple Mode with read-only mode', () => {
|
||||||
|
|
||||||
|
it('Should not show remove icon for pre-selected users if readonly property set to true', (done) => {
|
||||||
|
component.mode = 'multiple';
|
||||||
|
const removeUserSpy = spyOn(component.removeUser, 'emit');
|
||||||
|
component.preSelectUsers = [
|
||||||
|
{ id: mockUsers[0].id, username: mockUsers[0].username, readonly: true },
|
||||||
|
{ id: mockUsers[1].id, username: mockUsers[1].username, readonly: true }
|
||||||
|
];
|
||||||
|
fixture.detectChanges();
|
||||||
|
const chipList = fixture.nativeElement.querySelectorAll('mat-chip-list mat-chip');
|
||||||
|
const removeIcon = <HTMLElement> 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).toBeTruthy();
|
||||||
|
expect(component.preSelectUsers[1].readonly).toBeTruthy();
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(removeIcon).toBeNull();
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(removeUserSpy).not.toHaveBeenCalled();
|
||||||
|
expect(component.preSelectUsers.length).toBe(2);
|
||||||
|
expect(component.preSelectUsers[0].readonly).toBe(true, 'Not removable');
|
||||||
|
expect(component.preSelectUsers[1].readonly).toBe(true, 'not removable');
|
||||||
|
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 = <HTMLElement> 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', () => {
|
describe('Multiple Mode and Pre-selected users with validate flag', () => {
|
||||||
|
|
||||||
const change = new SimpleChange(null, mockPreselectedUsers, false);
|
const change = new SimpleChange(null, mockPreselectedUsers, false);
|
||||||
|
Reference in New Issue
Block a user