diff options
author | Martin Stockhammer <martin_s@apache.org> | 2020-12-21 21:38:49 +0100 |
---|---|---|
committer | Martin Stockhammer <martin_s@apache.org> | 2020-12-21 21:38:49 +0100 |
commit | b247e09a9e06a92b3d304950276834ebba48c0e2 (patch) | |
tree | 9637aeb2b2b306317630458e1038e5487896f8e3 /archiva-modules/archiva-web | |
parent | b988a30f2c3f9b718953b70e2130337ec4ffe6d2 (diff) | |
download | archiva-b247e09a9e06a92b3d304950276834ebba48c0e2.tar.gz archiva-b247e09a9e06a92b3d304950276834ebba48c0e2.zip |
Adding user role assignment
Diffstat (limited to 'archiva-modules/archiva-web')
8 files changed, 297 insertions, 55 deletions
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.html b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.html index b146c72b6..bf6dd1e09 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.html +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.html @@ -18,9 +18,9 @@ <form class="mt-3 mb-3" [formGroup]="userForm" (ngSubmit)="onSubmit()"> <div class="form-group row col-md-8"> - <div class="col-md-1" >{{'form.edit' |translate}} <span + <div class="col-md-1">{{'form.edit' |translate}} <span class="fas fa-edit"></span></div> - <div class="col-md-6" > + <div class="col-md-6"> <input class="form-check-input" type="checkbox" [value]="editMode" [checked]="editMode" (change)="editMode=!editMode" > @@ -75,14 +75,14 @@ </div> </div> <div class="col-md-2" *ngIf="editMode"> - <button class="btn btn-primary" type="submit" - [disabled]="userForm.invalid || !userForm.dirty">{{'form.button.save'|translate}}</button> + <button class="btn btn-primary" type="submit" + [disabled]="userForm.invalid || !userForm.dirty">{{'form.button.save'|translate}}</button> </div> </div> </form> <hr/> <ngb-accordion activeIds="parents,children,permissions"> - <ngb-panel id="parents" > + <ngb-panel id="parents"> <ng-template ngbPanelHeader let-opened="opened"> <div class="d-flex align-items-center justify-content-between"> <button ngbPanelToggle class="btn btn-link text-left shadow-none"> @@ -92,27 +92,28 @@ </div> </ng-template> <ng-template ngbPanelContent> - <ng-container *ngIf="editRole?.parents.length>0"> - <ul class="list-group" *ngFor="let parentRole of editRole?.parents"> - <li class="list-group-item"><a routerLink="../{{parentRole?.id}}">{{parentRole?.name}}</a></li> - </ul> - </ng-container> + <ng-container *ngIf="editRole?.parents.length>0"> + <ul class="list-group" *ngFor="let parentRole of editRole?.parents"> + <li class="list-group-item"><a routerLink="../{{parentRole?.id}}">{{parentRole?.name}}</a></li> + </ul> + </ng-container> </ng-template> </ngb-panel> <ngb-panel id="children"> <ng-template ngbPanelHeader let-opened="opened"> <div class="d-flex align-items-center justify-content-between"> - <button ngbPanelToggle class="btn btn-link text-left shadow-none"><h3>{{'roles.edit.children'|translate}}</h3></button> - <ng-container *ngIf="!opened"><i class="fa fa-eye-slash"></i></ng-container> - <ng-container *ngIf="opened"><i class="fa fa-eye"></i></ng-container> + <button ngbPanelToggle class="btn btn-link text-left shadow-none"> + <h3>{{'roles.edit.children'|translate}}</h3></button> + <ng-container *ngIf="!opened"><i class="fa fa-eye-slash"></i></ng-container> + <ng-container *ngIf="opened"><i class="fa fa-eye"></i></ng-container> </div> </ng-template> <ng-template ngbPanelContent> - <ng-container *ngIf="editRole?.children.length>0"> - <ul class="list-group" *ngFor="let childRole of editRole?.children"> - <li class="list-group-item"><a routerLink="../{{childRole?.id}}">{{childRole?.name}}</a></li> - </ul> - </ng-container> + <ng-container *ngIf="editRole?.children.length>0"> + <ul class="list-group" *ngFor="let childRole of editRole?.children"> + <li class="list-group-item"><a routerLink="../{{childRole?.id}}">{{childRole?.name}}</a></li> + </ul> + </ng-container> </ng-template> </ngb-panel> @@ -120,44 +121,138 @@ <ng-template ngbPanelHeader let-opened="opened"> <div class="d-flex align-items-center justify-content-between"> - <button ngbPanelToggle class="btn btn-link text-left shadow-none"><h3>{{'roles.edit.permissions'|translate}}</h3></button> - <ng-container *ngIf="!opened"><i class="fa fa-eye-slash"></i></ng-container> - <ng-container *ngIf="opened"><i class="fa fa-eye"></i></ng-container> + <button ngbPanelToggle class="btn btn-link text-left shadow-none"> + <h3>{{'roles.edit.permissions'|translate}}</h3></button> + <ng-container *ngIf="!opened"><i class="fa fa-eye-slash"></i></ng-container> + <ng-container *ngIf="opened"><i class="fa fa-eye"></i></ng-container> </div> </ng-template> <ng-template ngbPanelContent> - <ng-container *ngIf="editRole"> - <table class="table"> - <thead> - <tr> - <th>{{'permissions.attributes.permission'|translate}}</th> - <th>{{'permissions.attributes.operation'|translate}}</th> - <th>{{'permissions.attributes.resource'|translate}}</th> - </tr> - </thead> - <tbody *ngFor="let perm of editRole.permissions"> - <tr> - <td>{{perm.name}}</td> - <td>{{perm.operation.name}}</td> - <td>{{perm.resource.identifier}}</td> - </tr> - </tbody> + <ng-container *ngIf="editRole"> + <table class="table"> + <thead> + <tr> + <th>{{'permissions.attributes.permission'|translate}}</th> + <th>{{'permissions.attributes.operation'|translate}}</th> + <th>{{'permissions.attributes.resource'|translate}}</th> + </tr> + </thead> + <tbody *ngFor="let perm of editRole.permissions"> + <tr> + <td>{{perm.name}}</td> + <td>{{perm.operation.name}}</td> + <td>{{perm.resource.identifier}}</td> + </tr> + </tbody> - </table> - </ng-container> + </table> + </ng-container> </ng-template> </ngb-panel> <ngb-panel> <ng-template ngbPanelHeader let-opened="opened"> <div class="d-flex align-items-center justify-content-between"> - <button ngbPanelToggle class="btn btn-link text-left shadow-none"><h3>{{'roles.edit.users'|translate}}</h3></button> + <button ngbPanelToggle class="btn btn-link text-left shadow-none"> + <h3>{{'roles.edit.users'|translate}}</h3></button> <ng-container *ngIf="!opened"><i class="fa fa-eye-slash"></i></ng-container> <ng-container *ngIf="opened"><i class="fa fa-eye"></i></ng-container> </div> </ng-template> - <ng-template ngbPanelContent > - <h3>There are the users</h3> + <ng-template ngbPanelContent> + <h4>{{'roles.edit.usersParents'|translate}}</h4> + <app-paginated-entities [service]="roleUserParentService" pageSize="5" [(sortField)]="userParentSortField" + [(sortOrder)]="userParentSortOrder" [displayControlsIfSinglePage]="false" + #userParentSection> + + <ng-container *ngIf="userParentSection.items$ |async as itemLoader"> + <ng-template [ngIf]="itemLoader.loading"> + <div class="spinner-border text-primary" role="status"> + <span class="sr-only">Loading...</span> + </div> + </ng-template> + </ng-container> + <ng-container *ngIf="userParentSection.items$ |stripLoading|async as userItem"> + <table class="table table-striped table-bordered"> + <thead class="thead-light"> + <tr sorted [sortFieldEmitter]="userParentSection.sortFieldChange" + [sortOrderEmitter]="userParentSection.sortOrderChange" + [toggleObserver]="userParentSection"> + <app-th-sorted [fieldArray]="['user_id']" + contentText="users.attributes.user_id"></app-th-sorted> + <app-th-sorted [fieldArray]="['full_name']" + contentText="users.attributes.full_name"></app-th-sorted> + </tr> + </thead> + <tbody> + <tr *ngFor="let user of userItem.data"> + <td><span data-toggle="tooltip" placement="left" + ngbTooltip="{{user.id}}">{{user.user_id}}</span> + </td> + <td>{{user.full_name}}</td> + </tr> + </tbody> + </table> + </ng-container> + </app-paginated-entities> + <hr/> + <h4>{{'roles.edit.usersInstance'|translate}}</h4> + <app-paginated-entities [service]="roleUserService" pageSize="5" [(sortField)]="userSortField" + [(sortOrder)]="userSortOrder" + [displayIfEmpty]="false" [displayKeyIfEmpty]="'roles.edit.noUsersAssigned'" + #userSection> + + <ng-container *ngIf="userSection.items$ |async as itemLoader"> + <ng-template [ngIf]="itemLoader.loading"> + <div class="spinner-border text-primary" role="status"> + <span class="sr-only">Loading...</span> + </div> + </ng-template> + </ng-container> + <ng-container *ngIf="userSection.items$ |stripLoading|async as userItem"> + <table class="table table-striped table-bordered"> + <thead class="thead-light"> + <tr sorted [sortFieldEmitter]="userSection.sortFieldChange" + [sortOrderEmitter]="userSection.sortOrderChange" + [toggleObserver]="userSection"> + <app-th-sorted [fieldArray]="['user_id']" + contentText="users.attributes.user_id"></app-th-sorted> + <app-th-sorted [fieldArray]="['full_name']" + contentText="users.attributes.full_name"></app-th-sorted> + </tr> + </thead> + <tbody> + <tr *ngFor="let user of userItem.data"> + <td><span data-toggle="tooltip" placement="left" + ngbTooltip="{{user.id}}">{{user.user_id}}</span> + </td> + <td>{{user.full_name}}</td> + </tr> + </tbody> + </table> + </ng-container> + </app-paginated-entities> + <hr/> + <form class="mt-2"> + <ng-template #userResultTemplate let-r="result" let-t="term"> + <ngb-highlight [result]="r.user_id + '-' + r.full_name" [term]="t"></ngb-highlight> + </ng-template> + <div class="form-group"> + <label for="typeahead-http">{{'roles.edit.assignUserSearch'|translate}}</label> + <input id="typeahead-http" type="text" class="form-control col-md-2" + name="userSearchField" + [class.is-invalid]="userSearchFailed" [resultTemplate]="userResultTemplate" + [inputFormatter]="getUserId" + [placement]="'top'" + [(ngModel)]="userSearchModel" [ngbTypeahead]="searchUser" placeholder="User Search"/> + <small *ngIf="userSearching" + class="form-text text-muted">{{'form.searching' |translate}}</small> + <div class="invalid-feedback" + *ngIf="userSearchFailed">{{'roles.edit.userSearchFailed'|translate}}</div> + </div> + <button class="btn btn-primary" (click)="assignUserRole()">{{'roles.edit.assignButton'|translate}}</button> + </form> + </ng-template> </ngb-panel> diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.ts index b5d033f01..71655fe19 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.ts @@ -20,12 +20,17 @@ import {AfterContentInit, Component, EventEmitter, OnInit, Output} from '@angula import {ActivatedRoute} from "@angular/router"; import {FormBuilder, Validators} from "@angular/forms"; import {RoleService} from "@app/services/role.service"; -import {catchError, filter, map, switchMap, tap} from "rxjs/operators"; +import {catchError, debounceTime, distinctUntilChanged, filter, map, switchMap, tap} from "rxjs/operators"; import {Role} from '@app/model/role'; import {ErrorResult} from "@app/model/error-result"; import {EditBaseComponent} from "@app/modules/shared/edit-base.component"; -import {forkJoin, iif, Observable, of, pipe, zip} from 'rxjs'; +import {forkJoin, Observable, of, zip} from 'rxjs'; import {RoleUpdate} from "@app/model/role-update"; +import {EntityService} from "@app/model/entity-service"; +import {User} from '@app/model/user'; +import {PagedResult} from "@app/model/paged-result"; +import {UserService} from "@app/services/user.service"; +import {UserInfo} from '@app/model/user-info'; @Component({ selector: 'app-manage-roles-edit', @@ -38,12 +43,23 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements editProperties = ['id', 'name', 'description', 'template_instance', 'resource', 'assignable']; originRole; roleCache: Map<string, Role> = new Map<string, Role>(); + roleUserService: EntityService<User> + roleUserParentService: EntityService<User>; + userSortField = ["id"]; + userSortOrder = "asc"; + userParentSortField = ["id"]; + userParentSortOrder = "asc"; + + userSearching:boolean=false; + userSearchFailed:boolean=false; + + public userSearchModel:any; @Output() roleIdEvent: EventEmitter<string> = new EventEmitter<string>(true); - constructor(private route: ActivatedRoute, private roleService: RoleService, public fb: FormBuilder) { + constructor(private route: ActivatedRoute, public roleService: RoleService, private userService: UserService, public fb: FormBuilder) { super(fb); super.init(fb.group({ id: [''], @@ -53,6 +69,7 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements template_instance: [''], assignable: [''] }, {})); + } createEntity(): Role { @@ -75,6 +92,14 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements this.editRole = role; this.originRole = role; this.copyToForm(this.editProperties, this.editRole); + const fRoleService = this.roleService; + const roleId = role.id; + this.roleUserService = function (searchTerm: string, offset: number, limit: number, orderBy: string[], order: string): Observable<PagedResult<User>> { + return fRoleService.queryAssignedUsers(roleId, searchTerm, offset, limit, orderBy, order); + }; + this.roleUserParentService = function (searchTerm: string, offset: number, limit: number, orderBy: string[], order: string): Observable<PagedResult<User>> { + return fRoleService.queryAssignedParentUsers(roleId, searchTerm, offset, limit, orderBy, order, true); + }; }, error => { this.editRole = new Role(); }); @@ -165,5 +190,39 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements } } + searchUser = (text$: Observable<string>) => + text$.pipe( + debounceTime(300), + distinctUntilChanged(), + tap(() => this.userSearching = true), + switchMap(term => + this.userService.query(term, 0, 10).pipe( + tap(() => this.userSearchFailed = false), + map(pagedResult=> + pagedResult.data), + catchError(() => { + this.userSearchFailed = true; + return of([]); + })) + ), + tap(() => this.userSearching = false) + ) + + getUserId(item:UserInfo) : string { + return item.user_id; + } + + assignUserRole() { + let userId; + if (typeof(this.userSearchModel)=='string') { + userId=this.userSearchModel; + } else { + if (this.userSearchModel.user_id) { + userId = this.userSearchModel.user_id; + } + } + console.log("Assigning user " + userId) + } + } diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/users/manage-users-list/manage-users-list.component.html b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/users/manage-users-list/manage-users-list.component.html index d87fc57ef..f72b3e702 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/users/manage-users-list/manage-users-list.component.html +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/users/manage-users-list/manage-users-list.component.html @@ -19,14 +19,14 @@ <app-paginated-entities [service]="service" pageSize="10" [(sortField)]="sortField" [(sortOrder)]="sortOrder" #parent> - <ng-container *ngIf="parent.items$ |async as roleItemLoader"> - <ng-template [ngIf]="roleItemLoader.loading"> + <ng-container *ngIf="parent.items$ |async as itemLoader"> + <ng-template [ngIf]="itemLoader.loading"> <div class="spinner-border text-primary" role="status"> <span class="sr-only">Loading...</span> </div> </ng-template> </ng-container> - <ng-container *ngIf="parent.items$ |stripLoading|async as roleItem"> + <ng-container *ngIf="parent.items$ |stripLoading|async as userItem"> <table class="table table-striped table-bordered"> <thead class="thead-light"> @@ -54,11 +54,11 @@ <app-th-sorted [fieldArray]="['created']" contentText="users.attributes.created"></app-th-sorted> <app-th-sorted [fieldArray]="['last_password_change']" contentText="users.attributes.last_password_change"></app-th-sorted> - <th>Action</th> + <th>{{'headers.action'|translate}}</th> </tr> </thead> <tbody> - <tr *ngFor="let user of roleItem.data" + <tr *ngFor="let user of userItem.data" [ngClass]="(user.permanent||user.readOnly)?'table-secondary':''"> <td><span data-toggle="tooltip" placement="left" ngbTooltip="{{user.id}}">{{user.user_id}}</span> </td> diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.html b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.html index ce0a6a50a..879ff98bc 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.html +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.html @@ -16,8 +16,9 @@ ~ under the License. --> +<ng-template [ngIf]="(displayIfEmpty || (total$|async)>0)" [ngIfElse]="noContent" > <form class="mt-3 mb-3"> - <div class="form-row align-items-center"> + <div class="form-row align-items-center" *ngIf="displayControlsIfSinglePage||(multiplePages$|async)"> <div class="col-lg-4 col-md-2 col-sm-1"> <label class="sr-only" for="searchQuery">{{'search.label' |translate}}</label> <input type="text" class="form-control" id="searchQuery" placeholder="{{'search.input'|translate}}" #searchTerm @@ -33,6 +34,11 @@ <ng-content></ng-content> -<ngb-pagination [collectionSize]="total$|async" [pageSize]="pageSize" [maxSize]="pagination.maxSize" [rotate]="pagination.rotate" +<ngb-pagination *ngIf="displayControlsIfSinglePage||(multiplePages$|async)" + [collectionSize]="total$|async" [pageSize]="pageSize" [maxSize]="pagination.maxSize" [rotate]="pagination.rotate" [boundaryLinks]="pagination.boundaryLinks" [ellipses]="pagination.ellipses" [(page)]="page" (pageChange)="changePage($event)" aria-label="Pagination"></ngb-pagination> +</ng-template> +<ng-template #noContent> + {{displayKeyIfEmpty|translate}} +</ng-template>
\ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.ts index cc62ac6a8..d2157d804 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.ts @@ -94,6 +94,26 @@ export class PaginatedEntitiesComponent<T> implements OnInit, FieldToggle, After } /** + * If true, all controls are displayed, if the total count is 0 + */ + @Input() + displayIfEmpty:boolean=true; + /** + * Sets the translation key, for the text to display, if displayIfEmpty=false and the total count is 0. + */ + @Input() + displayKeyIfEmpty:string='form.emptyContent'; + + /** + * If set to true, all controls are displayed, even if there is only one page to display. + * Otherwise the controls are not displayed, if there is only a single page of results. + */ + @Input() + displayControlsIfSinglePage:boolean=true; + + + + /** * The current page that is selected */ page = 1; @@ -124,6 +144,13 @@ export class PaginatedEntitiesComponent<T> implements OnInit, FieldToggle, After */ items$: Observable<LoadingValue<PagedResult<T>>>; + /** + * true, if the current page result value represents a result with multiple pages, + * otherwise false. + */ + multiplePages$:Observable<boolean>; + + private pageStream: Subject<number> = new Subject<number>(); private searchTermStream: Subject<string> = new Subject<string>(); @@ -153,6 +180,7 @@ export class PaginatedEntitiesComponent<T> implements OnInit, FieldToggle, After ), share()); this.total$ = source.pipe(filter(val=>val.hasValue()),map(val=>val.value),pluck('pagination', 'total_count')); this.items$ = source; + this.multiplePages$ = source.pipe(filter(val => val.hasValue()), map(val => val.value.pagination.total_count >= val.value.pagination.limit)); } search(terms: string) { diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/shared.module.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/shared.module.ts index 042057637..76bd9845f 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/shared.module.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/shared.module.ts @@ -21,7 +21,13 @@ import {CommonModule} from '@angular/common'; import {PaginatedEntitiesComponent} from "./paginated-entities/paginated-entities.component"; import {SortedTableHeaderComponent} from "./sorted-table-header/sorted-table-header.component"; import {SortedTableHeaderRowComponent} from "./sorted-table-header-row/sorted-table-header-row.component"; -import {NgbAccordionModule, NgbModalModule, NgbPaginationModule, NgbTooltipModule} from "@ng-bootstrap/ng-bootstrap"; +import { + NgbAccordionModule, + NgbModalModule, + NgbPaginationModule, + NgbTooltipModule, + NgbTypeaheadModule +} from "@ng-bootstrap/ng-bootstrap"; import {TranslateCompiler, TranslateLoader, TranslateModule} from "@ngx-translate/core"; import {TranslateMessageFormatCompiler} from "ngx-translate-messageformat-compiler"; import {HttpClient} from "@angular/common/http"; @@ -49,6 +55,7 @@ export { PageQuery } from './model/page-query'; NgbTooltipModule, NgbAccordionModule, NgbModalModule, + NgbTypeaheadModule, PaginatedEntitiesComponent, SortedTableHeaderComponent, SortedTableHeaderRowComponent, diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/role.service.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/role.service.ts index 99424a0df..aeabc33d7 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/role.service.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/role.service.ts @@ -25,6 +25,7 @@ import {HttpResponse} from "@angular/common/http"; import {PagedResult} from "@app/model/paged-result"; import {UserInfo} from "@app/model/user-info"; import {RoleUpdate} from "@app/model/role-update"; +import { User } from '@app/model/user'; @Injectable({ providedIn: 'root' @@ -61,6 +62,44 @@ export class RoleService { }); } + public queryAssignedUsers(roleId: string, + searchTerm: string, offset: number = 0, limit: number = 5, + orderBy: string[] = ['id'], order: string = 'asc'): Observable<PagedResult<User>> { + if (searchTerm == null) { + searchTerm = "" + } + if (orderBy == null || orderBy.length == 0) { + orderBy = ['id']; + } + return this.rest.executeRestCall<PagedResult<User>>("get", "redback", "roles/" + roleId + "/user", { + 'q': searchTerm, + 'offset': offset, + 'limit': limit, + 'orderBy': orderBy, + 'order': order + }); + } + + public queryAssignedParentUsers(roleId: string, + searchTerm: string, offset: number = 0, limit: number = 5, + orderBy: string[] = ['id'], order: string = 'asc', parentsOnly:boolean=true): Observable<PagedResult<User>> { + if (searchTerm == null) { + searchTerm = "" + } + if (orderBy == null || orderBy.length == 0) { + orderBy = ['id']; + } + const recurseFlag = parentsOnly ? 'parentsOnly' : 'true'; + return this.rest.executeRestCall<PagedResult<User>>("get", "redback", "roles/" + roleId + "/user", { + 'recurse':recurseFlag, + 'q': searchTerm, + 'offset': offset, + 'limit': limit, + 'orderBy': orderBy, + 'order': order + }); + } + public getRole(roleId:string) : Observable<Role> { return this.rest.executeRestCall("get", "redback", "roles/" + roleId, null); } diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/assets/i18n/en.json b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/assets/i18n/en.json index d094e3976..297c9f21d 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/assets/i18n/en.json +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/assets/i18n/en.json @@ -136,7 +136,13 @@ "parents": "Parents", "children": "Children", "permissions": "Permissions", - "users": "Users" + "users": "Users", + "usersInstance": "Users Assigned to this Role", + "usersParents": "Users Assigned to Parent Roles", + "noUsersAssigned": "There are no users assigned to this role", + "assignUserSearch": "Search and assign users to this role", + "userSearchFailed": "Sorry, could not load users", + "assignButton": "Assign" }, "attributes": { "id": "Identifier", @@ -172,7 +178,9 @@ "no": "No", "save": "Save Changes" }, - "edit": "Edit" + "edit": "Edit", + "emptyContent": "No values", + "searching": "Searching ..." }, "headers": { "action": "Action" |