Adding role edit form

This commit is contained in:
Martin Stockhammer 2020-12-03 21:26:22 +01:00
parent 50b07ac06e
commit 83ee920941
52 changed files with 521 additions and 89 deletions

View File

@ -27,9 +27,9 @@ import {LoginComponent} from "./modules/shared/login/login.component";
import {SearchComponent} from './modules/repo/search/search.component';
import {BrowseComponent} from "./modules/repo/browse/browse.component";
import {UploadComponent} from "./modules/repo/upload/upload.component";
import {ManageRolesComponent} from "./modules/user/manage-roles/manage-roles.component";
import {ManageRolesComponent} from "./modules/security/manage-roles/manage-roles.component";
import {RoutingGuardService as Guard} from "./services/routing-guard.service";
import {SecurityConfigurationComponent} from "./modules/user/security-configuration/security-configuration.component";
import {SecurityConfigurationComponent} from "./modules/security/security-configuration/security-configuration.component";
/**
* You can use Guard (RoutingGuardService) for permission checking. The service needs data with one parameter 'perm',
@ -48,9 +48,9 @@ const routes: Routes = [
},
{
path: 'user', component: HomeComponent,canActivate:[Guard],data:{perm: 'menu.user.section'},
path: 'security', component: HomeComponent,canActivate:[Guard],data:{perm: 'menu.user.section'},
children: [
{path: 'users', loadChildren: () => import('./modules/user/user.module').then(m => m.UserModule)},
{path: 'users', loadChildren: () => import('./modules/security/user.module').then(m => m.UserModule)},
{path: 'roles', component: ManageRolesComponent},
{path: 'config', component: SecurityConfigurationComponent},
]

View File

@ -35,7 +35,7 @@ import {NavSubgroupDirective} from './directives/nav-subgroup.directive';
import {SearchComponent} from './modules/repo/search/search.component';
import {BrowseComponent} from './modules/repo/browse/browse.component';
import {UploadComponent} from './modules/repo/upload/upload.component';
import {SecurityConfigurationComponent} from './modules/user/security-configuration/security-configuration.component';
import {SecurityConfigurationComponent} from './modules/security/security-configuration/security-configuration.component';
import {CoreModule} from "./modules/core/core.module";
import {httpTranslateLoader, SharedModule} from "./modules/shared/shared.module";
import {TranslateCompiler, TranslateLoader, TranslateModule} from "@ngx-translate/core";

View File

@ -0,0 +1,7 @@
import { Application } from './application';
describe('Application', () => {
it('should create an instance', () => {
expect(new Application()).toBeTruthy();
});
});

View File

@ -0,0 +1,2 @@
export class Application {
}

View File

@ -0,0 +1,7 @@
import { RoleTemplate } from './role-template';
describe('RoleTemplate', () => {
it('should create an instance', () => {
expect(new RoleTemplate()).toBeTruthy();
});
});

View File

@ -0,0 +1,9 @@
export class RoleTemplate {
id:string
name:string
description:string
application_id:string
assignable:boolean
permanent:boolean
}

View File

@ -0,0 +1,25 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { RoleTree } from './role-tree';
describe('RoleTree', () => {
it('should create an instance', () => {
expect(new RoleTree()).toBeTruthy();
});
});

View File

@ -0,0 +1,26 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { Role } from './role';
import {Application} from "@app/model/application";
export class RoleTree {
userid: string
applications: Map<string, Application>
root_roles: Array<Role>
}

View File

@ -0,0 +1,25 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { Role } from './role';
describe('Role', () => {
it('should create an instance', () => {
expect(new Role()).toBeTruthy();
});
});

View File

@ -0,0 +1,38 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export class Role {
id: string
name: string
description: string
assignable: boolean
permanent: boolean
child: boolean
assigned: boolean
template_instance: boolean
application_id:string
model_id:string
resource:string
children: Array<Role>
// Web Internal attributes
enabled: boolean = true
level:number = -1
}

View File

@ -23,8 +23,8 @@ import { ManageUsersListComponent } from './users/manage-users-list/manage-users
import { ManageUsersAddComponent } from './users/manage-users-add/manage-users-add.component';
import { ManageUsersEditComponent } from './users/manage-users-edit/manage-users-edit.component';
import { ManageUsersDeleteComponent } from './users/manage-users-delete/manage-users-delete.component';
import {SharedModule} from "../shared/shared.module";
import {TranslateModule} from "@ngx-translate/core";
import {ManageUsersRolesComponent} from "./users/manage-users-roles/manage-users-roles.component";
import {RoutingGuardService as Guard} from "@app/services/routing-guard.service";
/**
@ -33,13 +33,17 @@ import {TranslateModule} from "@ngx-translate/core";
*/
const routes: Routes = [
{ path: '', component: ManageUsersComponent,
{ path: '', component: ManageUsersComponent,canActivate:[Guard],
data: { perm: 'menu.user.manage' },
children: [
{path: 'list', component: ManageUsersListComponent},
{path: 'add', component: ManageUsersAddComponent},
{path: 'edit/:userid', component: ManageUsersEditComponent},
{path: 'edit', redirectTo:'edit/guest' },
{path: 'delete/:userid', component: ManageUsersDeleteComponent},
{path: 'roles', component:ManageUsersRolesComponent},
{path: 'roles/:userid', component:ManageUsersRolesComponent},
{path: '', redirectTo:'list',pathMatch:'full'}
]
}
];

View File

@ -26,8 +26,8 @@ import {SharedModule} from "../shared/shared.module";
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
import {ManageUsersDeleteComponent} from './users/manage-users-delete/manage-users-delete.component';
import {UserRoutingModule} from "./user-routing.module";
import {TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { HttpClient } from '@angular/common/http';
import { ManageUsersRolesComponent } from './users/manage-users-roles/manage-users-roles.component';
import {RoutingGuardService} from "../../services/routing-guard.service";
@NgModule({
@ -36,7 +36,8 @@ import { HttpClient } from '@angular/common/http';
ManageUsersListComponent,
ManageUsersAddComponent,
ManageUsersEditComponent,
ManageUsersDeleteComponent
ManageUsersDeleteComponent,
ManageUsersRolesComponent
],
exports: [
ManageUsersComponent,

View File

@ -53,8 +53,10 @@ export class ManageUsersDeleteComponent implements OnInit, AfterViewInit {
if (result=='YES' && userId!=null && userId!='') {
let deleted = this.userService.deleteUser(userId).subscribe();
if (deleted) {
this.router.navigate(['/user','users','list']);
this.router.navigate(['/security','users','list']);
}
} else if (result=='NO') {
this.router.navigate(['/security','users','list']);
}
}, (reason) => {
console.log("Reason: " + reason);

View File

@ -56,8 +56,10 @@
<td>{{user.timestamp_last_login | date:'yyyy-MM-ddTHH:mm:ss'}}</td>
<td>{{user.timestamp_account_creation | date : 'yyyy-MM-ddTHH:mm:ss'}}</td>
<td>{{user.timestamp_last_password_change| date : 'yyyy-MM-ddTHH:mm:ss'}}</td>
<td><ng-container *ngIf="!user.permanent"><a [routerLink]="['..','edit', user.user_id]" [queryParams]="{editmode:true}" ><span class="fas fa-edit"></span></a>
&nbsp;&nbsp; <a *ngIf="!user.permanent" [routerLink]="['..','delete',user.user_id]"><span class="fas fa-user-minus"></span></a>
<td><ng-container *ngIf="!user.permanent">
<a [routerLink]="['..','edit', user.user_id]" [queryParams]="{editmode:true}" [attr.title]="'users.edit.head' |translate"><span class="fas fa-edit"></span></a>
&nbsp;&nbsp;<a [routerLink]="['..','delete',user.user_id]" [attr.title]="'users.delete.head'|translate"><span class="fas fa-user-minus"></span></a>
&nbsp;&nbsp;<a [routerLink]="['..','roles',user.user_id]" [attr.title]="'users.roles.head'|translate"><span class="fas fa-user-tag" ></span></a>
</ng-container>
</td>
</tr>

View File

@ -0,0 +1,50 @@
<h3>Roles</h3>
<table class="table">
<thead class="thead-light">
<tr class="d-flex">
<th class="col-3">Role</th>
<th class="col-2">Scope</th>
<th class="col-1">Assign</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let baseRole of baseRoles" class="d-flex">
<td class="col-3" [innerHTML]="getRoleContent(baseRole)"></td>
<td class="col-2">
{{baseRole.application_id}}
</td>
<td class="col-1">
<div class="form-check form-check-inline"><input class="form-check-input" type="checkbox"
[attr.disabled]="baseRole.enabled?null:true"
[attr.id]="baseRole.id"
[(ngModel)]="baseRole.assigned"
(change)="changeBaseAssignment(baseRole, $event)"
>
</div>
</td>
</tr>
</tbody>
</table>
<h3>Repository Roles</h3>
<table class="table">
<thead class="thead-light">
<tr class="d-flex">
<th scope="row" class="col-1">Repository</th>
<th scope="col" class="col-1" *ngFor="let templateRole of templateRoles$ | async">{{templateRole.name}}</th>
</tr>
</thead>
<tbody>
<tr class="d-flex" *ngFor="let res of templateRoleInstances | keyvalue" >
<td class="table-secondary col-1">{{res.key}}</td>
<td class="col-1 text-center" *ngFor="let templateRole of templateRoles$ | async">
<div class="form-check form-check-inline" *ngIf="getInstanceContent(templateRole, res.value) as role">
<input class="form-check-input" type="checkbox" [attr.id]="role.id"
[(ngModel)]="role.assigned" (ngModelChange)="changeInstAssignment(role, $event)"/>
</div>
</td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ManageUsersRolesComponent } from './manage-users-roles.component';
describe('ManageUsersRolesComponent', () => {
let component: ManageUsersRolesComponent;
let fixture: ComponentFixture<ManageUsersRolesComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ManageUsersRolesComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ManageUsersRolesComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,155 @@
import { Component, OnInit } from '@angular/core';
import { Role } from '@app/model/role';
import {UserService} from "@app/services/user.service";
import {ActivatedRoute} from "@angular/router";
import {filter, map, switchMap} from "rxjs/operators";
import {RoleTree} from "@app/model/role-tree";
import {RoleService} from "@app/services/role.service";
import {RoleTemplate} from "@app/model/role-template";
import {Observable} from "rxjs";
import {Util} from "@app/modules/shared/shared.module";
@Component({
selector: 'app-manage-users-roles',
templateUrl: './manage-users-roles.component.html',
styleUrls: ['./manage-users-roles.component.scss']
})
export class ManageUsersRolesComponent implements OnInit {
baseRoles : Array<Role>
guest: Role
registered: Role
// Map of (resource, [roles])
templateRoleInstances: Map<string, Array<Role>>
templateRoles$: Observable<RoleTemplate[]>;
constructor(private route : ActivatedRoute, private userService : UserService, private roleService : RoleService) {
this.route.params.pipe(
map(params => params.userid), filter(userid => userid!=null), switchMap(userid => userService.userRoleTree(userid))).subscribe(roleTree => {
this.parseRoleTree(roleTree);
});
}
ngOnInit(): void {
this.templateRoles$ = this.roleService.getTemplates();
}
private parseRoleTree(roleTree:RoleTree): void {
let roleTable = [];
for(let rootRole of roleTree.root_roles) {
roleTable = this.recurseRoleTree(rootRole, roleTable, 0);
}
this.baseRoles = roleTable;
let templateMap : Map<string,Array<Role>> = new Map<string, Array<Role>>();
for (let rootRole of roleTree.root_roles) {
templateMap = this.recurseTemplates(rootRole, templateMap, 0);
}
this.templateRoleInstances = templateMap;
}
private recurseRoleTree(role:Role, roles : Array<Role>, level:number) : Array<Role> {
if (role.id=='guest') {
this.guest = role;
} else if (role.id=='registered-user') {
this.registered = role;
}
role.enabled=true;
let newLevel;
if (!role.template_instance && role.assignable) {
role.level=level
roles.push(role);
newLevel = level+1;
} else {
newLevel = level;
}
for(let childRole of role.children) {
roles = this.recurseRoleTree(childRole, roles, newLevel);
}
return roles;
}
private recurseTemplates(role:Role, roles : Map<string, Array<Role>>, level:number) : Map<string, Array<Role>> {
role.enabled=true;
if (role.template_instance && role.assignable) {
role.level=level
let roleList = roles.get(role.resource)
if (roleList==null) {
roleList = []
}
roleList.push(role);
roles.set(role.resource, roleList);
}
for(let childRole of role.children) {
roles = this.recurseTemplates(childRole, roles, level+1);
}
return roles;
}
getRoleContent(role:Role) : string {
let level = role.level
let result = "";
for(let _i=0; _i<level; _i++) {
result = result + "&nbsp;<i class='fas fa-angle-double-right'></i>&nbsp;";
}
if (role.child) {
return result + role.name;
} else {
return "<strong>"+result+role.name+"</strong>"
}
}
changeBaseAssignment(role : Role, event) {
let cLevel=-1
let assignStatus;
if (role.id==this.guest.id) {
if (role.assigned) {
for (let cRole of this.baseRoles) {
if (cRole.id != this.guest.id) {
cRole.assigned = false;
cRole.enabled=true;
}
}
role.enabled = false;
}
} else {
this.guest.enabled = true;
for (let cRole of this.baseRoles) {
if (cRole.id == role.id) {
console.log("Value: " + cRole.assigned);
cLevel = cRole.level;
assignStatus = cRole.assigned;
if (assignStatus) {
this.guest.assigned = false;
} else {
if (!this.baseRoles.find(role=>role.assigned)) {
this.guest.assigned=true;
}
}
} else {
console.log("Level " + cLevel);
if (cLevel >= 0 && cLevel < cRole.level) {
if (assignStatus) {
cRole.assigned = true;
cRole.enabled = false;
} else {
cRole.enabled = true;
}
} else if (cLevel >= 0) {
break;
}
}
}
}
}
changeInstAssignment(role : Role, event) {
console.log("Change " + role.id);
console.log("Assignment changed "+JSON.stringify(event));
console.log("Event target "+event.target);
}
getInstanceContent(template:RoleTemplate, roles:Array<Role>) : Role {
return roles.find(role=>role.model_id==template.id)
}
}

View File

@ -19,13 +19,16 @@
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link" routerLink="/user/users/list" routerLinkActive="active" href="#">{{'users.list.head' | translate}}</a>
<a class="nav-link" routerLink="/security/users/list" routerLinkActive="active" href="#">{{'users.list.head' | translate}}</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/user/users/add" routerLinkActive="active" href="#">{{'users.add.head' |translate }}</a>
<a class="nav-link" routerLink="/security/users/add" routerLinkActive="active" href="#">{{'users.add.head' |translate }}</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/user/users/edit" routerLinkActive="active" href="#">{{'users.edit.head' |translate }}</a>
<a class="nav-link" routerLink="/security/users/edit" routerLinkActive="active" href="#">{{'users.edit.head' |translate }}</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/security/users/roles" routerLinkActive="active" href="#">{{'users.roles.head' |translate }}</a>
</li>
</ul>

View File

@ -16,8 +16,8 @@
* under the License.
*/
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import {NgModule} from '@angular/core';
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";
@ -29,42 +29,62 @@ import {TranslateHttpLoader} from "@ngx-translate/http-loader";
import {RouterModule} from "@angular/router";
@NgModule({
declarations: [
PaginatedEntitiesComponent,
SortedTableHeaderComponent,
SortedTableHeaderRowComponent
],
exports: [
CommonModule,
RouterModule,
TranslateModule,
NgbPaginationModule,
NgbTooltipModule,
PaginatedEntitiesComponent,
SortedTableHeaderComponent,
SortedTableHeaderRowComponent
],
imports: [
CommonModule,
RouterModule,
NgbPaginationModule,
NgbTooltipModule,
TranslateModule.forChild({
compiler: {
provide: TranslateCompiler,
useClass: TranslateMessageFormatCompiler
},
loader: {
provide: TranslateLoader,
useFactory: httpTranslateLoader,
deps: [HttpClient]
}
}),
]
declarations: [
PaginatedEntitiesComponent,
SortedTableHeaderComponent,
SortedTableHeaderRowComponent
],
exports: [
CommonModule,
RouterModule,
TranslateModule,
NgbPaginationModule,
NgbTooltipModule,
PaginatedEntitiesComponent,
SortedTableHeaderComponent,
SortedTableHeaderRowComponent
],
imports: [
CommonModule,
RouterModule,
NgbPaginationModule,
NgbTooltipModule,
TranslateModule.forChild({
compiler: {
provide: TranslateCompiler,
useClass: TranslateMessageFormatCompiler
},
loader: {
provide: TranslateLoader,
useFactory: httpTranslateLoader,
deps: [HttpClient]
}
}),
]
})
export class SharedModule { }
export class SharedModule {
}
export function httpTranslateLoader(http: HttpClient) {
return new TranslateHttpLoader(http);
return new TranslateHttpLoader(http);
}
export const Util = {
deepCopy(src: Object, dst: Object) {
Object.keys(src).forEach((key, idx) => {
let srcEl = src[key];
if (typeof (srcEl) == 'object') {
let dstEl;
if (!dst.hasOwnProperty(key)) {
dst[key] = {}
}
dstEl = dst[key];
this.deepCopy(srcEl, dstEl);
} else {
// console.debug("setting " + key + " = " + srcEl);
dst[key] = srcEl;
}
});
}
}

View File

@ -56,11 +56,11 @@
<div class="nav flex-column nav-pills" [appViewPermission]="perms.menu.user.section">
<a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true" data-toggle="pill"
role="tab" aria-controls="v-pills-home" aria-selected="false">{{'sidemenu.user.section'|translate}}</a>
<a class="nav-link my-0 py-0" id="users-manage" routerLink="/user/users" routerLinkActive="active" data-toggle="pill"
<a class="nav-link my-0 py-0" id="users-manage" routerLink="/security/users" routerLinkActive="active" data-toggle="pill"
role="tab" aria-controls="v-pills-browse" aria-selected="false">{{'sidemenu.user.users'|translate}}</a>
<a class="nav-link my-0 py-0" id="users-roles" routerLink="/user/roles" routerLinkActive="active" data-toggle="pill"
<a class="nav-link my-0 py-0" id="users-roles" routerLink="/security/roles" routerLinkActive="active" data-toggle="pill"
role="tab" aria-controls="v-pills-browse" aria-selected="false">{{'sidemenu.user.roles'|translate}}</a>
<a class="nav-link my-0 py-0" id="users-configuration" routerLink="/user/config" routerLinkActive="active" data-toggle="pill"
<a class="nav-link my-0 py-0" id="users-configuration" routerLink="/security/config" routerLinkActive="active" data-toggle="pill"
role="tab" aria-controls="v-pills-browse" aria-selected="false">{{'sidemenu.user.config'|translate}}</a>
</div>
<div class="nav flex-column nav-pills" >

View File

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { RoleService } from './role.service';
describe('RoleService', () => {
let service: RoleService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(RoleService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@ -0,0 +1,17 @@
import { Injectable } from '@angular/core';
import {ArchivaRequestService} from "@app/services/archiva-request.service";
import {RoleTemplate} from "@app/model/role-template";
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class RoleService {
constructor(private rest: ArchivaRequestService) { }
public getTemplates() : Observable<RoleTemplate[]> {
return this.rest.executeRestCall("get", "redback", "roles/templates", null);
}
}

View File

@ -17,15 +17,16 @@
*/
import {Injectable, OnDestroy, OnInit} from '@angular/core';
import {ArchivaRequestService} from "./archiva-request.service";
import {UserInfo} from '../model/user-info';
import {ArchivaRequestService} from "@app/services/archiva-request.service";
import {UserInfo} from '@app/model/user-info';
import {HttpErrorResponse, HttpResponse} from "@angular/common/http";
import {ErrorResult} from "../model/error-result";
import {ErrorResult} from "@app/model/error-result";
import {Observable, throwError} from "rxjs";
import {Permission} from '../model/permission';
import {PagedResult} from "../model/paged-result";
import {User} from '../model/user';
import {Permission} from '@app/model/permission';
import {PagedResult} from "@app/model/paged-result";
import {User} from '@app/model/user';
import {catchError, map} from "rxjs/operators";
import {RoleTree} from "@app/model/role-tree";
@Injectable({
providedIn: 'root'
@ -163,31 +164,6 @@ export class UserService implements OnInit, OnDestroy {
})
);
// return new Observable<Permission[]>((resultObserver) => {
// let permissionObserver = {
// next: (x: Permission[]) => {
// this.permissions = x;
// this.parsePermissions(x);
// resultObserver.next(this.permissions);
// },
// error: (err: HttpErrorResponse) => {
// console.log("Error " + (JSON.stringify(err)));
// let result = err.error as ErrorResult
// if (result.error_messages != null) {
// for (let msg of result.error_messages) {
// console.debug('Observer got an error: ' + msg.error_key)
// }
// }
// this.resetPermissions();
// resultObserver.error(err);
// },
// complete: () => {
// resultObserver.complete();
// }
// };
// infoObserver.subscribe(permissionObserver);
//
// });
}
resetPermissions() {
@ -352,4 +328,17 @@ export class UserService implements OnInit, OnDestroy {
}), map((httpResponse: HttpResponse<string>) => httpResponse.status == 200));
}
public userRoleTree(userid:String): Observable<RoleTree> {
return this.rest.executeResponseCall<RoleTree>("get", "redback","users/"+userid+"/roletree", null).pipe(
catchError((error: HttpErrorResponse)=>{
if (error.status==404) {
console.error("User not found: " + userid);
return [];
} else {
return throwError(this.rest.getTranslatedErrorResult(error));
}
})
).pipe(map((httpResponse:HttpResponse<RoleTree>)=>httpResponse.body))
}
}

View File

@ -109,10 +109,14 @@
}
},
"delete": {
"head":"Delete User",
"modal": {
"title": "Delete User",
"text": "Are you sure? <br/> Do you want to delete the user <strong>{user_id}</strong>?"
}
},
"roles": {
"head": "Edit Roles"
}
},
"search": {

View File

@ -15,6 +15,11 @@
"lib": [
"es2018",
"dom"
]
],
"paths": {
"@app/*": ["src/app/*"],
"@app/model/*":["src/app/model/*"],
"@app/services/*": ["src/app/services/*"],
}
}
}