This is an automated email from the ASF dual-hosted git repository. hshpak pushed a commit to branch feat/DATALAB-2871/uncheck-image-permission-for-not-admin-group-during-a-new-group-creation in repository https://gitbox.apache.org/repos/asf/incubator-datalab.git
commit a3a6f9831a6ca877e7e4db93d515995b01db4c53 Author: Hennadii_Shpak <[email protected]> AuthorDate: Fri Jul 1 17:12:14 2022 +0300 [DATALAB-2871] implemented logic by uncheck image permission for not admin group --- .../project-form/project-form.component.html | 116 ++++++++++----------- .../app/administration/roles/roles.component.html | 73 ++++++------- .../app/administration/roles/roles.component.ts | 4 + .../multi-level-select-dropdown.component.html | 10 +- .../multi-level-select-dropdown.component.ts | 75 +++++++++---- 5 files changed, 157 insertions(+), 121 deletions(-) diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/project/project-form/project-form.component.html b/services/self-service/src/main/resources/webapp/src/app/administration/project/project-form/project-form.component.html index cd76e97f5..774f04980 100644 --- a/services/self-service/src/main/resources/webapp/src/app/administration/project/project-form/project-form.component.html +++ b/services/self-service/src/main/resources/webapp/src/app/administration/project/project-form/project-form.component.html @@ -41,10 +41,10 @@ <span class="upload-icon"></span> Upload <input (change)="onFileChange($event)" type="file" name="file" accept=".pub" /> </span> - <button - mat-raised-button - type="button" - class="butt butt-generate" + <button + mat-raised-button + type="button" + class="butt butt-generate" [ngClass]="{ 'not-allowed' : item }" (click)="generateUserAccessKey()" > @@ -57,19 +57,19 @@ </div> </div> <div class="text-center m-bott-10"> - <button - mat-raised-button - type="button" - class="butt" - [disabled]="item" + <button + mat-raised-button + type="button" + class="butt" + [disabled]="item" (click)="reset()" > Clear </button> - <button - mat-raised-button - type="button" - class="butt next" + <button + mat-raised-button + type="button" + class="butt next" matStepperNext > Next @@ -88,18 +88,18 @@ <div class="control-group m-bott-10"> <label class="label">Project name</label> <div class="control"> - <input - type="text" - formControlName="name" + <input + type="text" + formControlName="name" placeholder="Enter project name" - (blur)="generateProjectTag($event)" + (blur)="generateProjectTag($event)" [ngClass]="{ 'not-allowed' : item }" /> <span class="error" *ngIf="projectForm?.controls.name.hasError('duplication')"> This project name already exists. </span> - <span - class="error" + <span + class="error" *ngIf="!projectForm?.controls.name.valid && !projectForm?.controls.name.hasError('duplication') && !projectForm?.controls.name.hasError('limit') @@ -114,10 +114,10 @@ <div class="control-group m-bott-10"> <label class="label">Project tag</label> <div class="control"> - <input - readonly - type="text" - formControlName="tag" + <input + readonly + type="text" + formControlName="tag" placeholder="< equal to project name >" class="not-allowed" /> @@ -127,10 +127,10 @@ <label class="label">Endpoints</label> <div class="control selector-wrapper"> <mat-form-field> - <mat-select + <mat-select multiple - disableOptionCentering - formControlName="endpoints" + disableOptionCentering + formControlName="endpoints" placeholder="Select endpoints" panelClass="crete-project-dialog scrolling" > @@ -143,16 +143,16 @@ <i class="material-icons">clear</i> None </a> </mat-option> - <mat-option - *ngFor="let endpoint of endpointsList" + <mat-option + *ngFor="let endpoint of endpointsList" [value]="endpoint.name" [disabled]="isDisabled(endpoint.name) || endpoint.status !== 'ACTIVE'" > {{ endpoint.name === 'local' ? endpoint.name : endpoint.name + (endpoint.status !== 'ACTIVE' ? ' (inactive)' : '')}} </mat-option> - <mat-option - *ngIf="!endpointsList.length" - class="multiple-select empty ml-10" + <mat-option + *ngIf="!endpointsList.length" + class="multiple-select empty ml-10" disabled > Endpoints list is empty @@ -167,26 +167,26 @@ </div> <div class="text-center m-bott-10"> - <button - mat-raised-button - type="button" - class="butt" - [disabled]="item" + <button + mat-raised-button + type="button" + class="butt" + [disabled]="item" (click)="reset()" > Clear </button> - <button - mat-raised-button - matStepperPrevious + <button + mat-raised-button + matStepperPrevious class="butt" > <i class="material-icons arrow-icon">keyboard_arrow_left</i>Back </button> - <button - mat-raised-button - type="button" - class="butt next" + <button + mat-raised-button + type="button" + class="butt next" matStepperNext > Next<i class="material-icons arrow-icon">keyboard_arrow_right</i> @@ -204,10 +204,10 @@ <label class="label">Groups</label> <div class="control selector-wrapper"> <mat-form-field> - <mat-select + <mat-select multiple - disableOptionCentering - formControlName="groups" + disableOptionCentering + formControlName="groups" placeholder="Select user groups" panelClass="crete-project-dialog scrolling" > @@ -238,26 +238,26 @@ <!-- <span class="hold-label">Use shared image</span>--> <!-- </mat-slide-toggle>--> <!-- </div>--> - <button - mat-raised-button - type="button" - class="butt" - [disabled]="item" + <button + mat-raised-button + type="button" + class="butt" + [disabled]="item" (click)="reset()" > Clear </button> - <button - mat-raised-button - matStepperPrevious + <button + mat-raised-button + matStepperPrevious class="butt" > <i class="material-icons arrow-icon">keyboard_arrow_left</i>Back </button> - <button - mat-raised-button - type="button" - class="butt butt-success" + <button + mat-raised-button + type="button" + class="butt butt-success" [disabled]="!projectForm.valid" (click)="confirm(projectForm.value)" > 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 index c5d04a74e..451085bb0 100644 --- 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 @@ -23,10 +23,10 @@ matTooltipPosition="above" [matTooltipDisabled]="healthStatus?.admin" > - <button - mat-raised-button - class="butt add-group" - (click)="stepperView = !stepperView" + <button + mat-raised-button + class="butt add-group" + (click)="onAddGroupClick()" [disabled]="!healthStatus?.admin" > <i class="material-icons">people_outline</i>Add group @@ -40,12 +40,12 @@ <mat-step [completed]='false'> <ng-template matStepLabel>Groups</ng-template> <div class="inner-step mat-reset"> - <input - [validator]="groupValidation()" - type="text" - placeholder="Enter group name" + <input + [validator]="groupValidation()" + type="text" + placeholder="Enter group name" [(ngModel)]="setupGroup" - #setupGroupName="ngModel" + #setupGroupName="ngModel" /> <div class="error" *ngIf="setupGroupName.errors?.patterns && setupGroupName.dirty"> Group name can only contain letters, numbers, hyphens and '_'. @@ -58,14 +58,14 @@ </div> </div> <div class="text-center m-bott-10"> - <button - mat-raised-button - (click)="resetDialog()" + <button + mat-raised-button + (click)="resetDialog()" class="butt" > Cancel </button> - <button + <button mat-raised-button matStepperNext class="butt" [disabled]="!setupGroup || setupGroupName.errors?.long || setupGroupName.errors?.duplicate || setupGroupName.errors?.patterns" @@ -103,6 +103,7 @@ <multi-level-select-dropdown (selectionChange)="onUpdate($event)" name="roles" + [isAddGroup]="true" [items]="rolesList" [model]="setupRoles" [isAdmin]="healthStatus?.admin" @@ -114,16 +115,16 @@ <i class="material-icons arrow-icon">keyboard_arrow_left</i> Back </button> - <button - mat-raised-button - (click)="resetDialog()" + <button + mat-raised-button + (click)="resetDialog()" class="butt" > Cancel </button> - <button - mat-raised-button - (click)="manageAction('create', 'group')" + <button + mat-raised-button + (click)="manageAction('create', 'group')" class="butt butt-success" [disabled]="!setupGroup || setupGroupName.errors?.patterns || setupGroupName.errors?.duplicate || !setupRoles.length" > @@ -143,7 +144,7 @@ <td mat-cell *matCellDef="let element" class="name"> <div class="d-flex"> <span - class="ellipsis" + class="ellipsis" [matTooltip]="element.group" matTooltipPosition="above" [matTooltipClass]="'full-size-tooltip'"> @@ -172,23 +173,23 @@ <th mat-header-cell *matHeaderCellDef class="users"> Users </th> <td mat-cell *matCellDef="let element" class="users-list ani"> <mat-form-field class="chip-list"> - <input - #user - matInput - placeholder="Enter user login" + <input + #user + matInput + placeholder="Enter user login" pattern="[@.-_0-9a-zA-Z]" - (keydown.enter)="addUser(user, element);" + (keydown.enter)="addUser(user, element);" (keyup)="checkIfUserAdded(element, user.value)" /> - <button - mat-icon-button - matSuffix - (click)="addUser(user, element); user.value = ''" + <button + mat-icon-button + matSuffix + (click)="addUser(user, element); user.value = ''" [disabled]="element.isUserAdded" > - <mat-icon - matTooltip="User is already added to this group" - matTooltipPosition="above" + <mat-icon + matTooltip="User is already added to this group" + matTooltipPosition="above" [matTooltipDisabled]="!element.isUserAdded" > person_add @@ -218,7 +219,7 @@ <th mat-header-cell *matHeaderCellDef class="actions"></th> <td mat-cell *matCellDef="let element" class="actions"> <div class="actions-wrapper"> - <span + <span class="action-disabled" matTooltip="Only admin can delete group." matTooltipPosition="above" @@ -233,10 +234,10 @@ </span> </span> - <span - class="apply ani big-icon" + <span + class="apply ani big-icon" matTooltip="Group cannot be updated without any selected role" - matTooltipPosition="above" + matTooltipPosition="above" [matTooltipDisabled]="element.selected_roles.length > 0" [ngClass]="{ 'not-allowed' : !element.selected_roles.length || isGroupChanded(element)}" (click)="manageAction('update', 'group', element)" diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/roles/roles.component.ts b/services/self-service/src/main/resources/webapp/src/app/administration/roles/roles.component.ts index 1f9b8ac06..9739eaf86 100644 --- a/services/self-service/src/main/resources/webapp/src/app/administration/roles/roles.component.ts +++ b/services/self-service/src/main/resources/webapp/src/app/administration/roles/roles.component.ts @@ -320,6 +320,10 @@ export class RolesComponent implements OnInit { user.value = ''; } + onAddGroupClick(): void { + this.stepperView = !this.stepperView; + } + private normalizeUserList(userNameList: string): string[] { if (userNameList.includes(',')) { return userNameList.split(',') diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/multi-level-select-dropdown/multi-level-select-dropdown.component.html b/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/multi-level-select-dropdown/multi-level-select-dropdown.component.html index 1d6fda68c..615396950 100644 --- a/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/multi-level-select-dropdown/multi-level-select-dropdown.component.html +++ b/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/multi-level-select-dropdown/multi-level-select-dropdown.component.html @@ -51,13 +51,13 @@ class="header-checkbox" [checked]="selectedAllInCattegory(item.type)" [someChecked]="selectedSomeInCattegory(item.type)" - (toggleSelection)="toggleselectedCategory(model, item.type)" + (toggleSelection)="toggleSelectedCategory(model, item.type)" ></datalab-checkbox> {{labels[item.type] || item.type | titlecase}} </a> </li> - <li + <li class="role-item" role="presentation" *ngIf="model && isOpenCategory[item.type] && item.type !== 'COMPUTATIONAL_SHAPE' && item.type !== 'NOTEBOOK_SHAPE'" @@ -75,9 +75,9 @@ {{item.role}} </a> </li> - <li - class="role-item" - role="presentation" + <li + class="role-item" + role="presentation" (click)="toggleItemsForCloud(item.type + item.cloud, $event)" *ngIf="model && isOpenCategory[item.type] && item.type === 'COMPUTATIONAL_SHAPE' && item.cloud !== items[i - 1].cloud || model && isOpenCategory[item.type] && item.type === 'NOTEBOOK_SHAPE' && item.type !== items[i - 1].type diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/multi-level-select-dropdown/multi-level-select-dropdown.component.ts b/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/multi-level-select-dropdown/multi-level-select-dropdown.component.ts index 0a2300fa2..ff5e75ada 100644 --- a/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/multi-level-select-dropdown/multi-level-select-dropdown.component.ts +++ b/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/multi-level-select-dropdown/multi-level-select-dropdown.component.ts @@ -20,6 +20,17 @@ import { Input, Output, Component, EventEmitter } from '@angular/core'; import { SortUtils } from '../../../core/util'; +export interface Rights { + role: string; + type: string; + cloud: string; +} + +export enum TypeOfRights { + admin = 'ADMINISTRATION', + img = 'IMAGE' +} + @Component({ selector: 'multi-level-select-dropdown', templateUrl: 'multi-level-select-dropdown.component.html', @@ -29,7 +40,8 @@ import { SortUtils } from '../../../core/util'; export class MultiLevelSelectDropdownComponent { @Input() items: Array<any>; - @Input() model: Array<any>; + @Input() model: Rights[]; + @Input() isAddGroup: boolean = false; @Input() type: string; @Input() isAdmin: boolean; @Output() selectionChange: EventEmitter<{}> = new EventEmitter(); @@ -45,27 +57,28 @@ export class MultiLevelSelectDropdownComponent { }; public selectedList: any; - constructor() {} - - toggleSelectedOptions( model, value, event?) { + toggleSelectedOptions( model: Rights[], value: Rights, event?): void { if (event) event.preventDefault(); const currRole = model.filter(v => v.role === value.role).length; - currRole ? this.model = model.filter(v => v.role !== value.role) : model.push(value); + currRole ? this.model = this.checkUserRights(model, value) : model.push(value); this.onUpdate(event); } - toggleselectedCategory( model, value, event?) { + toggleSelectedCategory(model: Rights[], value: string, event?): void { if (event) event.preventDefault(); const categoryItems = this.items.filter(role => role.type === value); - this.selectedAllInCattegory(value) ? this.model = this.model.filter(role => role.type !== value) : categoryItems.forEach(role => { - if (!model.filter(mod => mod.role === role.role).length) { - this.model.push(role); - } - }); + + this.selectedAllInCattegory(value) + ? this.model = this.checkUserRights(value) + : categoryItems.forEach(role => { + if (!model.filter(mod => mod.role === role.role).length) { + this.model.push(role); + } + }); this.onUpdate(event); } - toggleSelectedCloud( model, category, cloud, event?) { + toggleSelectedCloud( model, category, cloud, event?): void { if (event) event.preventDefault(); const categoryItems = this.items.filter(role => role.type === category && role.cloud === cloud); this.selectedAllInCloud(category, cloud) ? this.model = this.model.filter(role => { @@ -79,14 +92,14 @@ export class MultiLevelSelectDropdownComponent { this.onUpdate(event); } - selectAllOptions($event) { + selectAllOptions($event): void { $event.preventDefault(); this.model = [...this.items]; this.onUpdate($event); $event.preventDefault(); } - deselectAllOptions($event) { + deselectAllOptions($event): void { this.model = []; this.onUpdate($event); $event.preventDefault(); @@ -97,7 +110,7 @@ export class MultiLevelSelectDropdownComponent { this.selectionChange.emit({ model: this.model, type: this.type, $event }); } - public toggleItemsForLable(label, $event) { + public toggleItemsForLable(label, $event): void { this.isOpenCategory[label] = !this.isOpenCategory[label]; this.isCloudOpen[label + 'AWS'] = false; this.isCloudOpen[label + 'GCP'] = false; @@ -105,40 +118,58 @@ export class MultiLevelSelectDropdownComponent { $event.preventDefault(); } - public toggleItemsForCloud(label, $event) { + public toggleItemsForCloud(label, $event): void { this.isCloudOpen[label] = !this.isCloudOpen[label]; $event.preventDefault(); } - public selectedAllInCattegory(category) { + public selectedAllInCattegory(category): boolean { const selected = this.model.filter(role => role.type === category); const categoryItems = this.items.filter(role => role.type === category); return selected.length === categoryItems.length; } - public selectedSomeInCattegory(category) { + public selectedSomeInCattegory(category): boolean { const selected = this.model.filter(role => role.type === category); const categoryItems = this.items.filter(role => role.type === category); return selected.length && selected.length !== categoryItems.length; } - public selectedAllInCloud(category, cloud) { + public selectedAllInCloud(category, cloud): boolean { const selected = this.model.filter(role => role.type === category && role.cloud === cloud); const categoryItems = this.items.filter(role => role.type === category && role.cloud === cloud); return selected.length === categoryItems.length; } - public selectedSomeInCloud(category, cloud) { + public selectedSomeInCloud(category, cloud): boolean { const selected = this.model.filter(role => role.type === category && role.cloud === cloud); const categoryItems = this.items.filter(role => role.type === category && role.cloud === cloud); return selected.length && selected.length !== categoryItems.length; } - public checkInModel(item) { - return this.model.filter(v => v.role === item).length; + public checkInModel(item): boolean { + return !!this.model.filter(v => v.role === item).length; } public getSelectedRolesList() { return this.model.map(role => role.role); } + + private checkUserRights(value: string): Rights[]; + private checkUserRights(model: Rights[], value: Rights): Rights[]; + private checkUserRights(...args: any[]): Rights[] { + if (args.length === 1) { + const [ value ] = args; + + const filteredModelList = this.model.filter(role => role.type !== value); + const isNeedUncheckImage = value === TypeOfRights.admin && this.isAddGroup; + return isNeedUncheckImage ? filteredModelList.filter(role => role.type !== TypeOfRights.img) : filteredModelList; + } else { + const [model, value] = args; + + const filteredModelList = model.filter(v => v.role !== value.role); + const isNeedUncheckImage = this.isAddGroup && value.type === TypeOfRights.admin; + return isNeedUncheckImage ? filteredModelList.filter(role => role.type !== TypeOfRights.img) : filteredModelList; + } + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
