This is an automated email from the ASF dual-hosted git repository. ankovalyshyn pushed a commit to branch feature/projects in repository https://gitbox.apache.org/repos/asf/incubator-dlab.git
commit 9598995a4b353953870355a9733b97b3ae9ba4da Author: Andriana Kovalyshyn <[email protected]> AuthorDate: Thu May 30 13:26:00 2019 +0300 [DLAB-631]: moved manage roles functionality into separate page --- .../manage-roles-groups.component.html | 154 -------------------- .../group-name-validarion.directive.ts | 0 .../index.ts} | 36 +++-- .../app/administration/roles/roles.component.html | 161 +++++++++++++++++++++ .../roles.component.scss} | 0 .../roles.component.ts} | 82 +++++++++-- 6 files changed, 248 insertions(+), 185 deletions(-) diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-roles-groups/manage-roles-groups.component.html b/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-roles-groups/manage-roles-groups.component.html deleted file mode 100644 index b21d860..0000000 --- a/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-roles-groups/manage-roles-groups.component.html +++ /dev/null @@ -1,154 +0,0 @@ -<!-- - ~ 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. - --> - -<modal-dialog #bindDialog modalClass="manage-roles-dialog modal-xxl"> - <modal-header> - <h4 class="modal-title">Manage roles</h4> - </modal-header> - <modal-content> - <div class="content-box"> - <button mat-raised-button class="butt add-group" (click)="stepperView = !stepperView"> - <i class="material-icons">people_outline</i>Add group - </button> - <mat-horizontal-stepper #stepper *ngIf="stepperView" class="stepper roles ani"> - <mat-step> - <ng-template matStepLabel>Groups</ng-template> - <div class="inner-step mat-reset"> - <input [validator]="groupValidarion()" type="text" placeholder="Enter group name" [(ngModel)]="setupGroup" #setupGroupName="ngModel"> - <div class="danger_color" *ngIf="setupGroupName.errors?.patterns && setupGroupName.dirty">Group name can only contain letters, numbers, hyphens and '_'</div> - <div class="danger_color" *ngIf="setupGroupName.errors?.duplicate && setupGroupName.dirty">Group name already exists</div> - </div> - <div class="text-center m-bott-10"> - <button mat-raised-button (click)="resetDialog()" class="butt">Cancel</button> - <button mat-raised-button matStepperNext class="butt">Next<i class="material-icons">keyboard_arrow_right</i></button> - </div> - </mat-step> - <mat-step> - <ng-template matStepLabel>Roles</ng-template> - <div class="inner-step mat-reset"> - <div class="selector-wrapper"> - <!-- <multi-select-dropdown (selectionChange)="onUpdate($event)" [type]="'role'" [items]="rolesList" [model]="setupRoles"></multi-select-dropdown> --> - <mat-form-field> - <mat-select multiple [compareWith]="compareObjects" name="roles" [(value)]="setupRoles" placeholder="Select roles"> - <mat-option class="multiple-select" disabled> - <a class="select ani" (click)="selectAllOptions(setupRoles, rolesList)"> - <i class="material-icons">playlist_add_check</i> All - </a> - <a class="deselect ani" (click)="selectAllOptions(setupRoles)"> - <i class="material-icons">clear</i> None - </a> - </mat-option> - <mat-option *ngFor="let role of rolesList" [value]="role"> - {{ role }} - </mat-option> - </mat-select> - <button class="caret"> - <i class="material-icons">keyboard_arrow_down</i> - </button> - </mat-form-field> - </div> - </div> - <div class="text-center m-bott-10"> - <button mat-raised-button matStepperPrevious class="butt"><i class="material-icons">keyboard_arrow_left</i>Back</button> - <button mat-raised-button (click)="resetDialog()" class="butt">Cancel</button> - <button mat-raised-button matStepperNext class="butt">Next<i class="material-icons">keyboard_arrow_right</i></button> - </div> - </mat-step> - <mat-step> - <ng-template matStepLabel>Users</ng-template> - <div class="inner-step mat-reset"> - <input type="text" placeholder="Enter user login" [(ngModel)]="setupUser"> - </div> - <div class="text-center m-bott-10"> - <button mat-raised-button matStepperPrevious class="butt"><i class="material-icons">keyboard_arrow_left</i>Back</button> - <button mat-raised-button (click)="resetDialog()" class="butt">Cancel</button> - <button mat-raised-button (click)="manageAction('create', 'group')" class="butt butt-success" - [disabled]="!setupGroup || setupGroupName.errors?.pattern || !setupRoles.length > 0">Create</button> - </div> - </mat-step> - </mat-horizontal-stepper> - <mat-divider></mat-divider> - <div *ngIf="groupsData.length" class="ani"> - <table class="dashboard_table"> - <tr> - <th class="th_name groups">Name</th> - <th class="roles">Roles</th> - <th class="users">Users</th> - <th class="th_actions">Action</th> - </tr> - <tr *ngFor="let item of groupsData" class="dashboard_table_body filter-row"> - <td>{{ item.group }}</td> - <td class="roles mat-reset"> - <div class="selector-wrapper-edit"> - <mat-form-field> - <mat-select multiple [compareWith]="compareObjects" name="selected_roles" [(value)]="item.selected_roles" placeholder="Select roles"> - <mat-option class="multiple-select" disabled> - <a class="select ani" (click)="selectAllOptions(item, rolesList, 'selected_roles')"> - <i class="material-icons">playlist_add_check</i> All - </a> - <a class="deselect ani" (click)="selectAllOptions(item, null, 'selected_roles')"> - <i class="material-icons">clear</i> None - </a> - </mat-option> - <mat-option *ngFor="let role of rolesList" [value]="role"> - {{ role }} - </mat-option> - </mat-select> - <button class="caret ani"> - <i class="material-icons">keyboard_arrow_down</i> - </button> - </mat-form-field> - </div> - </td> - <td class="users-list ani"> - <mat-form-field class="chip-list"> - <input #user matInput placeholder="Enter user login" pattern="[@.-_0-9a-zA-Z]" (keydown.enter)="addUser(user.value, item); user.value = ''"> - <button mat-icon-button matSuffix (click)="addUser(user.value, item); user.value = ''"> - <mat-icon>person_add</mat-icon> - </button> - </mat-form-field> - <div class="list-selected list-container ani"> - <mat-chip-list> - <mat-chip *ngFor="let user of item.users"> - {{ user }} - <a class="material-icons" (click)="removeUser(item.users, user)">clear</a> - </mat-chip> - </mat-chip-list> - </div> - </td> - <td class="actions"> - <button mat-icon-button class="reset ani" (click)="manageAction('delete', 'group', item)"> - <i class="material-icons">close</i> - </button> - - <button mat-icon-button class="apply ani" matTooltip="Group cannot be updated without any selected role" - matTooltipPosition="above" - [matTooltipDisabled]="item.selected_roles.length > 0" - [ngClass]="{ 'not-allowed' : !item.selected_roles.length }" - (click)="manageAction('update', 'group', item)"> - <i class="material-icons">done</i> - </button> - </td> - </tr> - </table> - </div> - </div> - </modal-content> -</modal-dialog> - diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-roles-groups/group-name-validarion.directive.ts b/services/self-service/src/main/resources/webapp/src/app/administration/roles/group-name-validarion.directive.ts similarity index 100% copy from services/self-service/src/main/resources/webapp/src/app/administration/management/manage-roles-groups/group-name-validarion.directive.ts copy to services/self-service/src/main/resources/webapp/src/app/administration/roles/group-name-validarion.directive.ts diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-roles-groups/group-name-validarion.directive.ts b/services/self-service/src/main/resources/webapp/src/app/administration/roles/index.ts similarity index 50% rename from services/self-service/src/main/resources/webapp/src/app/administration/management/manage-roles-groups/group-name-validarion.directive.ts rename to services/self-service/src/main/resources/webapp/src/app/administration/roles/index.ts index e3f7207..d0c57cc 100644 --- a/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-roles-groups/group-name-validarion.directive.ts +++ b/services/self-service/src/main/resources/webapp/src/app/administration/roles/index.ts @@ -17,21 +17,25 @@ * under the License. */ -import { Directive, forwardRef, Input } from '@angular/core'; -import { AbstractControl, NG_VALIDATORS, Validator } from '@angular/forms'; +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -@Directive({ - selector: '[validator][ngModel],[group-dir][ngFormControl]', - providers: [{ - multi: true, - provide: NG_VALIDATORS, - useExisting: forwardRef(() => GroupNameValidationDirective) - }] -}) -export class GroupNameValidationDirective implements Validator { - @Input() validator: Function; +import { MaterialModule } from '../../shared/material.module'; +import { FormControlsModule } from '../../shared/form-controls'; +import { RolesComponent, ConfirmDeleteUserAccountDialogComponent } from './roles.component'; +import { GroupNameValidationDirective } from './group-name-validarion.directive'; - validate(control: AbstractControl): { [key: string]: any; } { - return this.validator(control); - } -} +@NgModule({ + imports: [ + CommonModule, + FormsModule, + ReactiveFormsModule, + MaterialModule, + FormControlsModule + ], + declarations: [RolesComponent, ConfirmDeleteUserAccountDialogComponent, GroupNameValidationDirective], + entryComponents: [ConfirmDeleteUserAccountDialogComponent], + exports: [RolesComponent] +}) +export class RolesModule { } \ No newline at end of file diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/roles/roles.component.html b/services/self-service/src/main/resources/webapp/src/app/administration/roles/roles.component.html new file mode 100644 index 0000000..cade0b6 --- /dev/null +++ b/services/self-service/src/main/resources/webapp/src/app/administration/roles/roles.component.html @@ -0,0 +1,161 @@ +<!-- + ~ 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. + --> + +<!-- <modal-dialog #bindDialog modalClass="manage-roles-dialog modal-xxl"> + <modal-header> + <h4 class="modal-title">Manage roles</h4> + </modal-header> + <modal-content> --> +<div class="content-box"> + <button mat-raised-button class="butt add-group" (click)="stepperView = !stepperView"> + <i class="material-icons">people_outline</i>Add group + </button> + <mat-horizontal-stepper #stepper *ngIf="stepperView" class="stepper roles ani"> + <mat-step> + <ng-template matStepLabel>Groups</ng-template> + <div class="inner-step mat-reset"> + <input [validator]="groupValidarion()" type="text" placeholder="Enter group name" [(ngModel)]="setupGroup" + #setupGroupName="ngModel"> + <div class="danger_color" *ngIf="setupGroupName.errors?.patterns && setupGroupName.dirty">Group name can only + contain letters, numbers, hyphens and '_'</div> + <div class="danger_color" *ngIf="setupGroupName.errors?.duplicate && setupGroupName.dirty">Group name already + exists</div> + </div> + <div class="text-center m-bott-10"> + <button mat-raised-button (click)="resetDialog()" class="butt">Cancel</button> + <button mat-raised-button matStepperNext class="butt">Next<i + class="material-icons">keyboard_arrow_right</i></button> + </div> + </mat-step> + <mat-step> + <ng-template matStepLabel>Roles</ng-template> + <div class="inner-step mat-reset"> + <div class="selector-wrapper"> + <!-- <multi-select-dropdown (selectionChange)="onUpdate($event)" [type]="'role'" [items]="rolesList" [model]="setupRoles"></multi-select-dropdown> --> + <mat-form-field> + <mat-select multiple [compareWith]="compareObjects" name="roles" [(value)]="setupRoles" + placeholder="Select roles"> + <mat-option class="multiple-select" disabled> + <a class="select ani" (click)="selectAllOptions(setupRoles, rolesList)"> + <i class="material-icons">playlist_add_check</i> All + </a> + <a class="deselect ani" (click)="selectAllOptions(setupRoles)"> + <i class="material-icons">clear</i> None + </a> + </mat-option> + <mat-option *ngFor="let role of rolesList" [value]="role"> + {{ role }} + </mat-option> + </mat-select> + <button class="caret"> + <i class="material-icons">keyboard_arrow_down</i> + </button> + </mat-form-field> + </div> + </div> + <div class="text-center m-bott-10"> + <button mat-raised-button matStepperPrevious class="butt"><i + class="material-icons">keyboard_arrow_left</i>Back</button> + <button mat-raised-button (click)="resetDialog()" class="butt">Cancel</button> + <button mat-raised-button matStepperNext class="butt">Next<i + class="material-icons">keyboard_arrow_right</i></button> + </div> + </mat-step> + <mat-step> + <ng-template matStepLabel>Users</ng-template> + <div class="inner-step mat-reset"> + <input type="text" placeholder="Enter user login" [(ngModel)]="setupUser"> + </div> + <div class="text-center m-bott-10"> + <button mat-raised-button matStepperPrevious class="butt"><i + class="material-icons">keyboard_arrow_left</i>Back</button> + <button mat-raised-button (click)="resetDialog()" class="butt">Cancel</button> + <button mat-raised-button (click)="manageAction('create', 'group')" class="butt butt-success" + [disabled]="!setupGroup || setupGroupName.errors?.pattern || !setupRoles.length > 0">Create</button> + </div> + </mat-step> + </mat-horizontal-stepper> + <mat-divider></mat-divider> + <div *ngIf="groupsData.length" class="ani"> + <table class="dashboard_table"> + <tr> + <th class="th_name groups">Name</th> + <th class="roles">Roles</th> + <th class="users">Users</th> + <th class="th_actions">Action</th> + </tr> + <tr *ngFor="let item of groupsData" class="dashboard_table_body filter-row"> + <td>{{ item.group }}</td> + <td class="roles mat-reset"> + <div class="selector-wrapper-edit"> + <mat-form-field> + <mat-select multiple [compareWith]="compareObjects" name="selected_roles" [(value)]="item.selected_roles" + placeholder="Select roles"> + <mat-option class="multiple-select" disabled> + <a class="select ani" (click)="selectAllOptions(item, rolesList, 'selected_roles')"> + <i class="material-icons">playlist_add_check</i> All + </a> + <a class="deselect ani" (click)="selectAllOptions(item, null, 'selected_roles')"> + <i class="material-icons">clear</i> None + </a> + </mat-option> + <mat-option *ngFor="let role of rolesList" [value]="role"> + {{ role }} + </mat-option> + </mat-select> + <button class="caret ani"> + <i class="material-icons">keyboard_arrow_down</i> + </button> + </mat-form-field> + </div> + </td> + <td class="users-list ani"> + <mat-form-field class="chip-list"> + <input #user matInput placeholder="Enter user login" pattern="[@.-_0-9a-zA-Z]" + (keydown.enter)="addUser(user.value, item); user.value = ''"> + <button mat-icon-button matSuffix (click)="addUser(user.value, item); user.value = ''"> + <mat-icon>person_add</mat-icon> + </button> + </mat-form-field> + <div class="list-selected list-container ani"> + <mat-chip-list> + <mat-chip *ngFor="let user of item.users"> + {{ user }} + <a class="material-icons" (click)="removeUser(item.users, user)">clear</a> + </mat-chip> + </mat-chip-list> + </div> + </td> + <td class="actions"> + <button mat-icon-button class="reset ani" (click)="manageAction('delete', 'group', item)"> + <i class="material-icons">close</i> + </button> + + <button mat-icon-button class="apply ani" matTooltip="Group cannot be updated without any selected role" + matTooltipPosition="above" [matTooltipDisabled]="item.selected_roles.length > 0" + [ngClass]="{ 'not-allowed' : !item.selected_roles.length }" (click)="manageAction('update', 'group', item)"> + <i class="material-icons">done</i> + </button> + </td> + </tr> + </table> + </div> +</div> +<!-- </modal-content> +</modal-dialog> --> \ No newline at end of file diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-roles-groups/manage-roles-groups.component.scss b/services/self-service/src/main/resources/webapp/src/app/administration/roles/roles.component.scss similarity index 100% rename from services/self-service/src/main/resources/webapp/src/app/administration/management/manage-roles-groups/manage-roles-groups.component.scss rename to services/self-service/src/main/resources/webapp/src/app/administration/roles/roles.component.scss diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-roles-groups/manage-roles-groups.component.ts b/services/self-service/src/main/resources/webapp/src/app/administration/roles/roles.component.ts similarity index 68% rename from services/self-service/src/main/resources/webapp/src/app/administration/management/manage-roles-groups/manage-roles-groups.component.ts rename to services/self-service/src/main/resources/webapp/src/app/administration/roles/roles.component.ts index bc91c94..8bc7b8d 100644 --- a/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-roles-groups/manage-roles-groups.component.ts +++ b/services/self-service/src/main/resources/webapp/src/app/administration/roles/roles.component.ts @@ -17,17 +17,20 @@ * under the License. */ -import { Component, OnInit, ViewChild, Output, EventEmitter, Inject } from '@angular/core'; -import { ValidatorFn, FormControl, NgModel } from '@angular/forms'; +import { Component, OnInit, Output, EventEmitter, Inject } from '@angular/core'; +import { ValidatorFn, FormControl } from '@angular/forms'; import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; -import { DICTIONARY } from '../../../../dictionary/global.dictionary'; +import { ToastrService } from 'ngx-toastr'; + +import { RolesGroupsService } from '../../core/services'; +import { DICTIONARY } from '../../../dictionary/global.dictionary'; @Component({ - selector: 'dlab-manage-roles-groups', - templateUrl: './manage-roles-groups.component.html', - styleUrls: ['../../../resources/resources-grid/resources-grid.component.css', './manage-roles-groups.component.scss'] + selector: 'dlab-roles', + templateUrl: './roles.component.html', + styleUrls: ['../../resources/resources-grid/resources-grid.component.css', './roles.component.scss'] }) -export class ManageRolesGroupsComponent implements OnInit { +export class RolesComponent implements OnInit { readonly DICTIONARY = DICTIONARY; public groupsData: Array<any> = []; @@ -41,23 +44,40 @@ export class ManageRolesGroupsComponent implements OnInit { public delimitersRegex = /[-_]?/g; public groupnamePattern = new RegExp(/^[a-zA-Z0-9_\-]+$/); - @ViewChild('bindDialog') bindDialog; @Output() manageRolesGroupAction: EventEmitter<{}> = new EventEmitter(); stepperView: boolean = false; - constructor(public dialog: MatDialog) { } + constructor( + public toastr: ToastrService, + public dialog: MatDialog, + private rolesService: RolesGroupsService + ) { } ngOnInit() { - this.bindDialog.onClosing = () => this.resetDialog(); + this.openManageRolesDialog() + } + + openManageRolesDialog() { + this.rolesService.getGroupsData().subscribe(group => { + this.rolesService.getRolesData().subscribe( + roles => this.open(group, roles), + error => this.toastr.error(error.message, 'Oops!')); + }, + error => this.toastr.error(error.message, 'Oops!')); } - public open(param, groups, roles): void { + getGroupsData() { + this.rolesService.getGroupsData().subscribe( + list => this.updateGroupData(list), + error => this.toastr.error(error.message, 'Oops!')); + } + + public open(groups, roles): void { this.roles = roles; this.rolesList = roles.map(role => role.description); this.updateGroupData(groups); this.stepperView = false; - this.bindDialog.open(param); } public onUpdate($event) { @@ -75,7 +95,7 @@ export class ManageRolesGroupsComponent implements OnInit { public manageAction(action: string, type: string, item?: any, value?) { if (action === 'create') { - this.manageRolesGroupAction.emit( + this.manageRolesGroups( { action, type, value: { name: this.setupGroup, users: this.setupUser ? this.setupUser.split(',').map(elem => elem.trim()) : [], @@ -95,11 +115,11 @@ export class ManageRolesGroupsComponent implements OnInit { const emitValue = (type === 'users') ? {action, type, id: item.name, value: { user: value, group: item.group }} : {action, type, id: item.name, value: item.group} ; - this.manageRolesGroupAction.emit(emitValue); + this.manageRolesGroups(emitValue); } }); } else if (action === 'update') { - this.manageRolesGroupAction.emit({action, type, value: { + this.manageRolesGroups({action, type, value: { name: item.group, roleIds: this.extractIds(this.roles, item.selected_roles), users: item.users || [] }}); @@ -107,6 +127,38 @@ export class ManageRolesGroupsComponent implements OnInit { this.resetDialog(); } + manageRolesGroups($event) { + switch ($event.action) { + case 'create': + this.rolesService.setupNewGroup($event.value).subscribe(res => { + this.toastr.success('Group creation success!', 'Created!'); + this.getGroupsData(); + }, () => this.toastr.error('Group creation failed!', 'Oops!')); + break; + case 'update': + this.rolesService.updateGroup($event.value).subscribe(res => { + this.toastr.success('Group data successfully updated!', 'Success!'); + this.getGroupsData(); + }, () => this.toastr.error('Failed group data updating!', 'Oops!')); + break; + case 'delete': + if ($event.type === 'users') { + this.rolesService.removeUsersForGroup($event.value).subscribe(res => { + this.toastr.success('Users was successfully deleted!', 'Success!'); + this.getGroupsData(); + }, () => this.toastr.error('Failed users deleting!', 'Oops!')); + } else if ($event.type === 'group') { + console.log('delete group'); + this.rolesService.removeGroupById($event.value).subscribe(res => { + this.toastr.success('Group was successfully deleted!', 'Success!'); + this.getGroupsData(); + }, () => this.toastr.error('Failed group deleting!', 'Oops!')); + } + break; + default: + } + } + public extractIds(sourceList, target) { return sourceList.reduce((acc, item) => { target.includes(item.description) && acc.push(item._id); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
