mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ADF-3919] Add roles filtering to adf-cloud-group (#4238)
* [ADF-3919] Split group roles permission service into two * [ADF-3909] Added roles filtering title input * [ADF-3909] Added candate users and groups to task models * [ADF-3909] Used group component in start task * [ADF-3909] Updated docs * [ADF-3909] Added disabling for multi selection * [ADF-3909] Improved task creation logic * [ADF-3909] Changed assignee selection mechanism * * Added role filtering to groups* Updated unit tests to the recent changes* Created getGroupDetailsById and checkGroupHasGivenRole in groupService* Updated unit test to the groupService * * After rebase * * Changed method name checkGroupHasGivenRole to checkGroupHasRole * * After rebase
This commit is contained in:
committed by
Maurizio Vitale
parent
08cdb2f7c3
commit
3b455524b9
@@ -22,7 +22,7 @@ import { Observable, of, BehaviorSubject } from 'rxjs';
|
||||
import { GroupModel, GroupSearchParam } from '../models/group.model';
|
||||
import { GroupCloudService } from '../services/group-cloud.service';
|
||||
import { debounceTime } from 'rxjs/internal/operators/debounceTime';
|
||||
import { distinctUntilChanged, switchMap, flatMap, mergeMap, filter, tap } from 'rxjs/operators';
|
||||
import { distinctUntilChanged, switchMap, mergeMap, filter, tap } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-cloud-group',
|
||||
@@ -44,12 +44,14 @@ export class GroupCloudComponent implements OnInit {
|
||||
static MODE_SINGLE = 'single';
|
||||
static MODE_MULTIPLE = 'multiple';
|
||||
|
||||
@ViewChild('groupInput') groupInput: ElementRef<HTMLInputElement>;
|
||||
|
||||
/** Name of the application. If specified this shows the users who have access to the app. */
|
||||
@Input()
|
||||
appName: string;
|
||||
|
||||
/** Title of the field */
|
||||
@Input()
|
||||
title: string;
|
||||
|
||||
/** User selection mode (single/multiple). */
|
||||
@Input()
|
||||
mode: string = GroupCloudComponent.MODE_SINGLE;
|
||||
@@ -58,6 +60,10 @@ export class GroupCloudComponent implements OnInit {
|
||||
@Input()
|
||||
preSelectGroups: GroupModel[] = [];
|
||||
|
||||
/** Role names of the groups to be listed. */
|
||||
@Input()
|
||||
roles: string[] = [];
|
||||
|
||||
/** Emitted when a group is selected. */
|
||||
@Output()
|
||||
selectGroup: EventEmitter<GroupModel> = new EventEmitter<GroupModel>();
|
||||
@@ -66,6 +72,9 @@ export class GroupCloudComponent implements OnInit {
|
||||
@Output()
|
||||
removeGroup: EventEmitter<GroupModel> = new EventEmitter<GroupModel>();
|
||||
|
||||
@ViewChild('groupInput')
|
||||
private groupInput: ElementRef<HTMLInputElement>;
|
||||
|
||||
private selectedGroups: GroupModel[] = [];
|
||||
|
||||
private searchGroups: GroupModel[] = [];
|
||||
@@ -86,6 +95,10 @@ export class GroupCloudComponent implements OnInit {
|
||||
|
||||
searchedValue = '';
|
||||
|
||||
isFocused: boolean;
|
||||
|
||||
isDisabled: boolean;
|
||||
|
||||
constructor(private groupService: GroupCloudService) {
|
||||
this.selectedGroupsSubject = new BehaviorSubject<GroupModel[]>(this.selectedGroups);
|
||||
this.searchGroupsSubject = new BehaviorSubject<GroupModel[]>(this.searchGroups);
|
||||
@@ -94,7 +107,10 @@ export class GroupCloudComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.loadPreSelectGroups();
|
||||
if (this.hasPreSelectGroups()) {
|
||||
this.loadPreSelectGroups();
|
||||
}
|
||||
|
||||
this.initSearch();
|
||||
|
||||
if (this.appName) {
|
||||
@@ -112,6 +128,17 @@ export class GroupCloudComponent implements OnInit {
|
||||
|
||||
initSearch() {
|
||||
this.searchGroupsControl.valueChanges.pipe(
|
||||
filter((value) => {
|
||||
return typeof value === 'string';
|
||||
}),
|
||||
tap((value) => {
|
||||
this.searchedValue = value;
|
||||
if (value) {
|
||||
this.setError();
|
||||
} else {
|
||||
this.clearError();
|
||||
}
|
||||
}),
|
||||
debounceTime(500),
|
||||
distinctUntilChanged(),
|
||||
tap(() => {
|
||||
@@ -119,75 +146,68 @@ export class GroupCloudComponent implements OnInit {
|
||||
}),
|
||||
switchMap((inputValue) => {
|
||||
const queryParams = this.createSearchParam(inputValue);
|
||||
return this.findGroupsByName(queryParams);
|
||||
return this.groupService.findGroupsByName(queryParams);
|
||||
}),
|
||||
mergeMap((groups) => {
|
||||
return groups;
|
||||
}),
|
||||
filter((group: any) => {
|
||||
return !this.isGroupAlreadySelected(group);
|
||||
}),
|
||||
mergeMap((group: any) => {
|
||||
if (this.clientId) {
|
||||
return this.checkGroupHasClientRoleMapping(group);
|
||||
if (this.appName) {
|
||||
return this.checkGroupHasAccess(group.id).pipe(
|
||||
mergeMap((hasRole) => {
|
||||
return hasRole ? of(group) : of();
|
||||
})
|
||||
);
|
||||
} else if (this.hasRoles()) {
|
||||
return this.filterGroupsByRoles(group);
|
||||
} else {
|
||||
return of(group);
|
||||
}
|
||||
})
|
||||
).subscribe((searchedGroup) => {
|
||||
this.searchGroups.push(searchedGroup);
|
||||
this.clearError();
|
||||
this.searchGroupsSubject.next(this.searchGroups);
|
||||
});
|
||||
}
|
||||
|
||||
findGroupsByName(searchParam: GroupSearchParam): Observable<GroupModel> {
|
||||
return this.groupService.findGroupsByName(searchParam).pipe(
|
||||
flatMap((groups: GroupModel[]) => {
|
||||
this.searchedValue = searchParam.name;
|
||||
if (this.searchedValue && !this.hasGroups(groups)) {
|
||||
this.setError();
|
||||
}
|
||||
return groups;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
checkGroupHasClientRoleMapping(group: GroupModel): Observable<GroupModel> {
|
||||
return this.groupService.checkGroupHasClientRoleMapping(group.id, this.clientId).pipe(
|
||||
mergeMap((hasRole: boolean) => {
|
||||
if (hasRole) {
|
||||
return of(group);
|
||||
} else {
|
||||
this.setError();
|
||||
return of();
|
||||
}
|
||||
})
|
||||
);
|
||||
checkGroupHasAccess(groupId: string): Observable<boolean> {
|
||||
if (this.hasRoles()) {
|
||||
return this.groupService.checkGroupHasAnyClientAppRole(groupId, this.clientId, this.roles);
|
||||
} else {
|
||||
return this.groupService.checkGroupHasClientApp(groupId, this.clientId);
|
||||
}
|
||||
}
|
||||
|
||||
isGroupAlreadySelected(group: GroupModel): boolean {
|
||||
if (this.hasGroups(this.selectedGroups)) {
|
||||
const result = this.selectedGroups.filter((selectedGroup: GroupModel) => {
|
||||
return selectedGroup.id === group.id;
|
||||
});
|
||||
if (this.hasGroups(result)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
const result = this.selectedGroups.find((selectedGroup: GroupModel) => {
|
||||
return selectedGroup.id === group.id;
|
||||
});
|
||||
|
||||
return !!result;
|
||||
}
|
||||
|
||||
private loadPreSelectGroups() {
|
||||
if (this.hasGroups(this.preSelectGroups)) {
|
||||
if (this.isMultipleMode()) {
|
||||
this.preSelectGroups.forEach((group: GroupModel) => {
|
||||
this.selectedGroups.push(group);
|
||||
});
|
||||
} else {
|
||||
this.searchGroupsControl.setValue(this.preSelectGroups[0]);
|
||||
this.onSelect(this.preSelectGroups[0]);
|
||||
}
|
||||
if (this.isMultipleMode()) {
|
||||
this.preSelectGroups.forEach((group: GroupModel) => {
|
||||
this.selectedGroups.push(group);
|
||||
});
|
||||
} else {
|
||||
this.searchGroupsControl.setValue(this.preSelectGroups[0]);
|
||||
this.onSelect(this.preSelectGroups[0]);
|
||||
}
|
||||
}
|
||||
|
||||
filterGroupsByRoles(group: GroupModel): Observable<GroupModel> {
|
||||
return this.groupService.checkGroupHasRole(group.id, this.roles).pipe(
|
||||
mergeMap((hasRole) => {
|
||||
return hasRole ? of(group) : of();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
onSelect(selectedGroup: GroupModel) {
|
||||
if (this.isMultipleMode()) {
|
||||
if (!this.isGroupAlreadySelected(selectedGroup)) {
|
||||
@@ -226,42 +246,31 @@ export class GroupCloudComponent implements OnInit {
|
||||
return group ? group.name : '';
|
||||
}
|
||||
|
||||
private hasGroups(groups: GroupModel[]): boolean {
|
||||
return groups && groups.length > 0;
|
||||
private hasPreSelectGroups(): boolean {
|
||||
return this.preSelectGroups && this.preSelectGroups.length > 0;
|
||||
}
|
||||
|
||||
createSearchParam(value: any): GroupSearchParam {
|
||||
let queryParams: GroupSearchParam = { name: '' };
|
||||
if (this.isString(value)) {
|
||||
queryParams.name = value.trim();
|
||||
} else {
|
||||
queryParams.name = value.name.trim();
|
||||
}
|
||||
private createSearchParam(value: string): GroupSearchParam {
|
||||
const queryParams: GroupSearchParam = { name: value };
|
||||
return queryParams;
|
||||
}
|
||||
|
||||
isString(value: any): boolean {
|
||||
return typeof value === 'string';
|
||||
}
|
||||
|
||||
setValidationError() {
|
||||
if (this.hasGroups(this.searchGroups)) {
|
||||
this.clearError();
|
||||
} else {
|
||||
this.setError();
|
||||
}
|
||||
private hasRoles(): boolean {
|
||||
return this.roles && this.roles.length > 0;
|
||||
}
|
||||
|
||||
private disableSearch() {
|
||||
this.searchGroupsControl.disable();
|
||||
this.isDisabled = true;
|
||||
}
|
||||
|
||||
private enableSearch() {
|
||||
this.searchGroupsControl.enable();
|
||||
this.isDisabled = false;
|
||||
}
|
||||
|
||||
private setError() {
|
||||
this.searchGroupsControl.setErrors({invalid: true});
|
||||
this.searchGroupsControl.setErrors({ invalid: true });
|
||||
}
|
||||
|
||||
private clearError() {
|
||||
@@ -271,4 +280,12 @@ export class GroupCloudComponent implements OnInit {
|
||||
hasError(): boolean {
|
||||
return this.searchGroupsControl && this.searchGroupsControl.errors && this.searchGroupsControl.errors.invalid;
|
||||
}
|
||||
|
||||
setFocus(isFocused: boolean) {
|
||||
this.isFocused = isFocused;
|
||||
}
|
||||
|
||||
hasErrorMessage(): boolean {
|
||||
return !this.isFocused && this.hasError();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user