This is an automated email from the ASF dual-hosted git repository. martin_s pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/archiva.git
commit 130e4a35e44c99fe0c6f6da95d21b76bcf8db1fc Author: Martin Stockhammer <[email protected]> AuthorDate: Fri Dec 18 21:29:24 2020 +0100 Adding role information --- .../src/main/archiva-web/src/app/model/role.ts | 6 + .../app/modules/security/role-routing.module.ts | 1 + .../manage-roles-edit.component.html | 144 ++++++++++++++++++++- .../manage-roles-edit.component.ts | 142 ++++++++++++++++++-- .../manage-roles-list.component.html | 3 + .../manage-roles-list.component.ts | 11 +- .../roles/manage-roles/manage-roles.component.ts | 1 - .../manage-users-edit.component.html | 2 +- .../src/app/modules/shared/edit-base.component.ts | 133 +++++++++++++++++++ .../src/app/modules/shared/shared.module.ts | 4 +- .../app/modules/shared/sorted-table-component.ts | 11 ++ .../archiva-web/src/app/services/role.service.ts | 9 +- .../src/main/archiva-web/src/assets/i18n/en.json | 20 ++- 13 files changed, 465 insertions(+), 22 deletions(-) diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/role.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/role.ts index 819d0f1..ac0b469 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/role.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/role.ts @@ -16,6 +16,8 @@ * under the License. */ +import {Permission} from "@app/model/permission"; + export class Role { id: string name: string @@ -29,7 +31,11 @@ export class Role { model_id:string resource:string + child_role_ids: Array<string> + parent_role_ids: Array<string> children: Array<Role> + parents: Array<Role> + permissions: Array<Permission> // Web Internal attributes enabled: boolean = true diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/role-routing.module.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/role-routing.module.ts index 6452e65..1be49d7 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/role-routing.module.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/role-routing.module.ts @@ -35,6 +35,7 @@ const routes: Routes = [ children: [ {path: 'list', component: ManageRolesListComponent}, {path: 'edit/:roleid', component: ManageRolesEditComponent}, + {path: 'edit', component: ManageRolesEditComponent}, {path: '', redirectTo: 'list', pathMatch: 'full'} ] } 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 292d9d5..d92d21c 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 @@ -16,4 +16,146 @@ ~ under the License. --> -<p>manage-roles-edit works!</p> +<form class="mt-3 mb-3" [formGroup]="userForm" (ngSubmit)="onSubmit()"> + <div class="form-group row col-md-8"> + <div class="col-md-1" *ngIf="editRole && !editRole.permanent">{{'form.edit' |translate}} <span + class="fas fa-edit"></span></div> + <div class="col-md-6" *ngIf="editRole && !editRole.permanent"> + <input class="form-check-input" type="checkbox" [value]="editMode" [checked]="editMode" + (change)="editMode=!editMode" + > + </div> + </div> + <div class="form-group row col-md-8"> + <label class="col-md-2 col-form-label" for="id">{{'roles.attributes.id' |translate}}</label> + <div class="col-md-6"> + <input type="text" formControlName="id" id="id" + [ngClass]="valid('id')" + [attr.readonly]="true"> + </div> + </div> + <div class="form-group row col-md-8"> + <label class="col-md-2 col-form-label" for="id">{{'roles.attributes.name' |translate}}</label> + <div class="col-md-6"> + <input type="text" formControlName="name" id="name" + [ngClass]="valid('name')" + [attr.readonly]="editMode?null:'true'"> + </div> + </div> + <div class="form-group row col-md-8"> + <label class="col-md-2 col-form-label" for="id">{{'roles.attributes.description' |translate}}</label> + <div class="col-md-6"> + <input type="text" formControlName="description" id="description" + [ngClass]="valid('description')" + [attr.readonly]="editMode?null:'true'"> + </div> + </div> + <div class="form-group row col-md-8"> + <label class="col-md-2 col-form-label" for="id">{{'roles.attributes.resource' |translate}}</label> + <div class="col-md-6"> + <input type="text" formControlName="resource" id="resource" + [ngClass]="valid('resource')" + [attr.readonly]="true"> + </div> + </div> + <div class="form-group row col-md-8"> + <div class="col-md-2"></div> + <div class="col-md-6"> + <div class="form-check"> + <input class="form-check-input" type="checkbox" formControlName="assignable" + id="assignable" [attr.disabled]="true"> + <label class="form-check-label " for="assignable"> + {{'roles.attributes.assignable'|translate}} + </label> + </div> + <div class="form-check"> + <input class="form-check-input" type="checkbox" formControlName="template_instance" + id="template_instance" [attr.disabled]="true"> + <label class="form-check-label " for="template_instance"> + {{'roles.attributes.template_instance'|translate}} + </label> + </div> + </div> + </div> +</form> +<hr/> +<ngb-accordion activeIds="parents,children,permissions"> + <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"><h3>{{'roles.edit.parents'|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?.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> + </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-template> + </ngb-panel> + + <ngb-panel id="permissions"> + <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> + </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> + + </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> + <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> + </ngb-panel> + +</ngb-accordion> 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 4a642cb..cbbd5d5 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 @@ -16,18 +16,144 @@ * under the License. */ -import { Component, OnInit } from '@angular/core'; +import {Component, EventEmitter, OnInit, Output} from '@angular/core'; +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 {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'; @Component({ - selector: 'app-manage-roles-edit', - templateUrl: './manage-roles-edit.component.html', - styleUrls: ['./manage-roles-edit.component.scss'] + selector: 'app-manage-roles-edit', + templateUrl: './manage-roles-edit.component.html', + styleUrls: ['./manage-roles-edit.component.scss'] }) -export class ManageRolesEditComponent implements OnInit { +export class ManageRolesEditComponent extends EditBaseComponent<Role> implements OnInit { - constructor() { } + parentsOpened: boolean - ngOnInit(): void { - } + editRole: Role; + editProperties = ['id', 'name', 'description', 'template_instance', 'resource', 'assignable']; + originRole; + roleCache: Map<string, Role> = new Map<string, Role>(); + + + @Output() + roleIdEvent: EventEmitter<string> = new EventEmitter<string>(true); + + constructor(private route: ActivatedRoute, private roleService: RoleService, public fb: FormBuilder) { + super(fb); + super.init(fb.group({ + id: ['', [Validators.required]], + name: ['', Validators.required], + description: [''], + resource: [''], + template_instance: [''], + assignable: [''] + }, {})); + } + + createEntity(): Role { + return new Role(); + } + + ngOnInit(): void { + this.route.params.pipe( + map(params => params.roleid), + filter(roleid => roleid != null), + tap(roleid => { + this.roleIdEvent.emit(roleid) + }), + switchMap((roleid: string) => this.roleService.getRole(roleid)), + switchMap((role: Role) => zip(of(role), + this.retrieveChildren(role), + this.retrieveParents(role))), + map((ra: [Role, Role[], Role[]]) => this.combine(ra)) + ).subscribe(role => { + this.editRole = role; + this.originRole = role; + this.copyToForm(this.editProperties, this.editRole); + }, error => { + this.editRole = new Role(); + }); + } + + /** + * Array of [role, children[], parents[]] + */ + combine(roleArray: [Role, Role[], Role[]]): Role { + roleArray[0].children = roleArray[1]; + roleArray[0].parents = roleArray[2]; + return roleArray[0]; + } + + private createRole(id: string): Role { + let role = new Role(); + role.id = id; + role.name='' + return role; + } + + getCachedRole(id : string) : Observable<Role> { + return of(id).pipe( + switchMap(( myId : string ) => { + if (this.roleCache.has(myId)) { + return of(this.roleCache.get(myId)); + } else { + return this.roleService.getRole(myId).pipe(tap(role => { + this.roleCache.set(role.id, role); + }),catchError(() => of(this.createRole(id)))); + } + })); + } + + retrieveChildren(role: Role): Observable<Role[]> { + // ForkJoin does not emit, if one of the observables is failing to emit a object + // -> we use catchError() + let children: Array<Observable<Role>> = [] + for (let child_id of role.child_role_ids) { + children.push(this.getCachedRole(child_id)); + } + if (children.length>0) { + return forkJoin(children); + } else { + return of([]); + } + } + + retrieveParents(role: Role): Observable<Role[]> { + let parents: Array<Observable<Role>> = [] + for (let parent_id of role.parent_role_ids) { + parents.push(this.getCachedRole(parent_id)); + } + if (parents.length>0) { + return forkJoin(parents); + } else { + return of([]); + } + } + + onSubmit() { + let role = this.copyFromForm(this.editProperties); + this.roleService.updateRole(role).pipe( + catchError((err: ErrorResult) => { + this.error = true; + this.success = false; + this.errorResult = err; + return []; + }) + ).subscribe(roleInfo => { + this.error = false; + this.success = true; + this.errorResult = null; + this.result = roleInfo; + this.editMode = false; + }); + + } } + diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-list/manage-roles-list.component.html b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-list/manage-roles-list.component.html index 8b21e6c..7d904e7 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-list/manage-roles-list.component.html +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-list/manage-roles-list.component.html @@ -26,6 +26,7 @@ <app-th-sorted [fieldArray]="['id']" contentText="roles.attributes.id"></app-th-sorted> <app-th-sorted [fieldArray]="['name']" contentText="roles.attributes.name" ></app-th-sorted> <app-th-sorted [fieldArray]="['description']" contentText="roles.attributes.description" ></app-th-sorted> + <app-th-sorted [fieldArray]="['assignable']" contentText="roles.attributes.assignable"></app-th-sorted> <app-th-sorted [fieldArray]="['template_instance']" contentText="roles.attributes.template_instance" ></app-th-sorted> <app-th-sorted [fieldArray]="['resource']" contentText="roles.attributes.resource" ></app-th-sorted> <th>Action</th> @@ -36,6 +37,8 @@ <td><span data-toggle="tooltip" placement="left" ngbTooltip="{{role.id}}">{{role.id}}</span></td> <td>{{role.name}}</td> <td>{{role.description}}</td> + <td><span class="far" [attr.aria-valuetext]="role.assignable" + [ngClass]="role.assignable?'fa-check-circle':'fa-circle'"></span></td> <td><span class="far" [attr.aria-valuetext]="role.template_instance" [ngClass]="role.template_instance?'fa-check-circle':'fa-circle'"></span></td> <td>{{role.resource}}</td> diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-list/manage-roles-list.component.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-list/manage-roles-list.component.ts index e3998d7..b49f64d 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-list/manage-roles-list.component.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-list/manage-roles-list.component.ts @@ -25,21 +25,20 @@ import {Observable} from "rxjs"; import {PagedResult} from "@app/model/paged-result"; import {UserInfo} from "@app/model/user-info"; import {RoleService} from "@app/services/role.service"; +import {SortedTableComponent} from "@app/modules/shared/sorted-table-component"; @Component({ selector: 'app-manage-roles-list', templateUrl: './manage-roles-list.component.html', styleUrls: ['./manage-roles-list.component.scss'] }) -export class ManageRolesListComponent implements OnInit { +export class ManageRolesListComponent extends SortedTableComponent<Role> implements OnInit { - service: EntityService<Role> - - constructor(private translator: TranslateService, private roleService : RoleService) { - this.service = function (searchTerm: string, offset: number, limit: number, orderBy: string[], order: string) : Observable<PagedResult<Role>> { + constructor(translator: TranslateService, roleService : RoleService) { + super(translator, function (searchTerm: string, offset: number, limit: number, orderBy: string[], order: string): Observable<PagedResult<Role>> { console.log("Retrieving data " + searchTerm + "," + offset + "," + limit + "," + orderBy + "," + order); return roleService.query(searchTerm, offset, limit, orderBy, order); - } + }); } ngOnInit(): void { diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles/manage-roles.component.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles/manage-roles.component.ts index f2a67dd..74af9c2 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles/manage-roles.component.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles/manage-roles.component.ts @@ -39,7 +39,6 @@ export class ManageRolesComponent implements OnInit { // console.log("Activating "+componentReference+" - "+JSON.stringify(componentReference,getCircularReplacer())) if (componentReference.roleIdEvent!=null) { let componentEmit : Observable<string> = componentReference.roleIdEvent.pipe( - tap(userid=>console.log("Event "+componentReference.class+" "+userid)), map((userid: string) => this.getSubPath(userid))); if (this.roleId$!=null) { this.roleId$ = merge(this.roleId$, componentEmit) diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/users/manage-users-edit/manage-users-edit.component.html b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/users/manage-users-edit/manage-users-edit.component.html index ba8becf..8f12e3b 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/users/manage-users-edit/manage-users-edit.component.html +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/users/manage-users-edit/manage-users-edit.component.html @@ -18,7 +18,7 @@ <form class="mt-3 mb-3" [formGroup]="userForm" (ngSubmit)="onSubmit()"> <div class="form-group row col-md-8" *ngIf="!editUser.permanent"> - <div class="col-md-1">Edit <span class="fas fa-edit"></span></div> + <div class="col-md-1">{{'form.edit' |translate}} <span class="fas fa-edit"></span></div> <div class="col-md-6"> <input class="form-check-input" type="checkbox" [value]="editMode" [checked]="editMode" (change)="editMode=!editMode" diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/edit-base.component.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/edit-base.component.ts new file mode 100644 index 0000000..29a1d0f --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/edit-base.component.ts @@ -0,0 +1,133 @@ +/* + * 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 {AbstractControl, FormBuilder, FormControl, FormGroup, ValidationErrors, ValidatorFn} from "@angular/forms"; +import {ErrorResult} from '@app/model/error-result'; + +export abstract class EditBaseComponent<T> { + + editProperties = ['id']; + success: boolean = false; + error: boolean = false; + errorResult: ErrorResult; + result: T; + formInitialValues; + public userForm : FormGroup; + public editMode: boolean; + + constructor(public fb: FormBuilder) { + + } + + init(userForm: FormGroup) : void { + this.userForm=userForm; + this.formInitialValues = userForm.value; + } + + abstract createEntity() : T; + abstract onSubmit(); + + public copyFromForm(properties: string[]): T { + let entity: any = this.createEntity(); + for (let prop of properties) { + entity[prop] = this.userForm.get(prop).value; + } + return entity; + } + + public copyToForm(properties: string[], user: T): void { + let propMap = {}; + for (let prop of properties) { + let propValue = user[prop] == null ? '' : user[prop]; + propMap[prop] = propValue; + } + this.userForm.patchValue(propMap); + } + + + valid(field: string): string[] { + if (this.editMode) { + let classArr = this.isValid(field); + return classArr.concat('form-control') + } else { + return ['form-control-plaintext']; + } + } + + isValid(field: string): string[] { + let formField = this.userForm.get(field); + if (formField.dirty || formField.touched) { + if (formField.valid) { + return ['is-valid'] + } else { + return ['is-invalid'] + } + } else { + return [''] + } + } + + forbiddenNameValidator(nameRe: RegExp): ValidatorFn { + return (control: AbstractControl): { [key: string]: any } | null => { + const forbidden = nameRe.test(control.value); + return forbidden ? {forbiddenName: {value: control.value}} : null; + }; + } + + getAllErrors(formGroup: FormGroup, errors: string[] = []) : string[] { + Object.keys(formGroup.controls).forEach(field => { + const control = formGroup.get(field); + if (control instanceof FormControl && control.errors != null) { + let keys = Object.keys(control.errors).map(errorKey=>field+'.'+errorKey); + errors = errors.concat(keys); + } else if (control instanceof FormGroup) { + errors = errors.concat(this.getAllErrors(control)); + } + }); + return errors; + } + + getAttributeErrors(control:string):string[] { + return Object.keys(this.userForm.get(control).errors); + } +} + +export function whitespaceValidator(): ValidatorFn { + return (control: AbstractControl): ValidationErrors | null => { + const hasWhitespace = /\s/g.test(control.value); + return hasWhitespace ? {containsWhitespace: {value: control.value}} : null; + }; +} +export function MustMatch(controlName: string, matchingControlName: string) : ValidatorFn { + return (formGroup: FormGroup): ValidationErrors | null => { + const control = formGroup.controls[controlName]; + const matchingControl = formGroup.controls[matchingControlName]; + + if (matchingControl.errors && !matchingControl.errors.mustMatch) { + // return if another validator has already found an error on the matchingControl + return; + } + + // set error on matchingControl if validation fails + if (control.value !== matchingControl.value) { + matchingControl.setErrors({mustMatch: true}); + } else { + matchingControl.setErrors(null); + } + } +} \ No newline at end of file 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 1030390..27978a3 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,12 +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 {NgbPaginationModule, NgbTooltipModule} from "@ng-bootstrap/ng-bootstrap"; +import {NgbAccordionModule, NgbPaginationModule, NgbTooltipModule} 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"; import {TranslateHttpLoader} from "@ngx-translate/http-loader"; import {RouterModule} from "@angular/router"; +import {SortedTableComponent} from "@app/modules/shared/sorted-table-component"; @NgModule({ @@ -41,6 +42,7 @@ import {RouterModule} from "@angular/router"; TranslateModule, NgbPaginationModule, NgbTooltipModule, + NgbAccordionModule, PaginatedEntitiesComponent, SortedTableHeaderComponent, SortedTableHeaderRowComponent diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/sorted-table-component.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/sorted-table-component.ts new file mode 100644 index 0000000..27423fa --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/sorted-table-component.ts @@ -0,0 +1,11 @@ +import {EntityService} from "@app/model/entity-service"; +import {TranslateService} from "@ngx-translate/core"; + +export class SortedTableComponent<T> { + + sortField = ["id"]; + sortOrder = "asc"; + + constructor(public translator : TranslateService, public service: EntityService<T>) { + } +} 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 79bee94..3de9919 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 @@ -45,7 +45,6 @@ export class RoleService { } public query(searchTerm: string, offset: number = 0, limit: number = 10, orderBy: string[] = ['id'], order: string = 'asc'): Observable<PagedResult<Role>> { - console.log("getRoleList " + searchTerm + "," + offset + "," + limit + "," + orderBy + "," + order); if (searchTerm == null) { searchTerm = "" } @@ -61,4 +60,12 @@ export class RoleService { }); } + public getRole(roleId:string) : Observable<Role> { + return this.rest.executeRestCall("get", "redback", "roles/" + roleId, null); + } + + public updateRole(role:Role) : Observable<Role> { + return this.rest.executeRestCall("put", "redback", "roles/" + role.id, role); + } + } 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 6c39c16..7bdf9b8 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 @@ -132,16 +132,29 @@ "head": "Roles List" }, "edit": { - "head": "Edit/View Role" + "head": "Edit/View Role", + "parents": "Parents", + "children": "Children", + "permissions": "Permissions", + "users": "Users" }, "attributes": { "id": "Identifier", "name": "Name", "description": "Description", - "template_instance": "Template Instance" + "template_instance": "Template Instance", + "resource": "Repository", + "assignable": "Assignable" } }, + "permissions": { + "attributes": { + "permission": "Permission", + "operation": "Operation", + "resource": "Resource" + } + }, "search": { "button": "Search", "label": "Enter your search term", @@ -158,7 +171,8 @@ "yes": "Yes", "no": "No", "save": "Save Changes" - } + }, + "edit": "Edit" }, "password": { "violations" : {
