This is an automated email from the ASF dual-hosted git repository. hshpak pushed a commit to branch refactor/image-action-dialog in repository https://gitbox.apache.org/repos/asf/incubator-datalab.git
commit 936e9b13fa7995a8e8f0344c75b0a08388c4d88a Author: Hennadii_Shpak <[email protected]> AuthorDate: Tue Aug 30 16:57:56 2022 +0300 refactored code by action modal --- .../image-action-dialog.component.html | 10 ++-- .../image-action-dialog.component.scss | 4 ++ .../image-action-dialog.component.ts | 63 ++-------------------- .../image-detail-dialog.component.ts | 4 +- .../src/app/resources/images/images.component.html | 5 +- .../src/app/resources/images/images.component.ts | 58 +++++++++++--------- .../src/app/resources/images/images.config.ts | 5 ++ .../src/app/resources/images/images.model.ts | 10 +++- .../src/app/resources/images/images.service.ts | 42 +++++++++++++-- 9 files changed, 103 insertions(+), 98 deletions(-) diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-action-dialog/image-action-dialog.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-action-dialog/image-action-dialog.component.html index 8711f5f51..1ab9f2dc1 100644 --- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-action-dialog/image-action-dialog.component.html +++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-action-dialog/image-action-dialog.component.html @@ -19,13 +19,13 @@ <div id="dialog-box"> <header class="dialog-header"> - <h4 class="modal-title">{{title}}</h4> + <h4 class="modal-title">{{data.title}}</h4> <button type="button" class="close" (click)="dialogRef.close()">×</button> </header> <section class="content"> <p class="description" *ngIf="data.actionType === actionType.share"> The image - <span class="image-name">{{imageName}} </span> + <span class="shared-image-name">{{data.imageName}} </span> <span>will be shared with all current user groups on the project with all the data and code.</span> </p> <div *ngIf="data.actionType === actionType.terminate" class="terminate-action__wrapper"> @@ -34,10 +34,10 @@ <div class="status">Further status</div> </div> <div class="scrolling-content scrolling terminate-image-list__wrapper"> - <div class="image-name ellipsis">{{imageName}}</div> + <div class="image-name ellipsis">{{data.imageName}}</div> <div class="status terminated">Terminated</div> </div> - <p *ngIf="data.image.sharingStatus !== 'PRIVATE'" class="shared-warning">!The image is shared with other users.</p> + <p *ngIf="data.isShared" class="shared-warning">!The image is shared with other users.</p> </div> <p class="question center"> Do you want proceed? @@ -47,7 +47,7 @@ <button type="button" class="butt butt-success mat-raised-button" - (click)="onYesClick(data.actionType)">Yes + (click)="dialogRef.close()">Yes </button> </div> </section> diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-action-dialog/image-action-dialog.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-action-dialog/image-action-dialog.component.scss index e7a99e941..6facffe45 100644 --- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-action-dialog/image-action-dialog.component.scss +++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-action-dialog/image-action-dialog.component.scss @@ -44,6 +44,10 @@ font-weight: 200; } +.shared-image-name { + font-weight: 600; +} + .image-list { display: flex; justify-content: space-between; diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-action-dialog/image-action-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-action-dialog/image-action-dialog.component.ts index 7c0e9732a..bcb2feaf0 100644 --- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-action-dialog/image-action-dialog.component.ts +++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-action-dialog/image-action-dialog.component.ts @@ -17,74 +17,19 @@ * under the License. */ -import { Component, Inject, OnInit } from '@angular/core'; +import { Component, Inject } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { ImagesService } from '../../images/images.service'; -import { ImageActions, ImageActionType, ImageModalData, ImageParams, Toaster_Message } from '../../images'; -import { ToastrService } from 'ngx-toastr'; +import { ImageActions, ImageActionModalData } from '../../images'; @Component({ selector: 'datalab-image-action-dialog', templateUrl: './image-action-dialog.component.html', styleUrls: ['./image-action-dialog.component.scss'] }) -export class ImageActionDialogComponent implements OnInit { +export class ImageActionDialogComponent { readonly actionType: typeof ImageActions = ImageActions; - - imageName!: string; - title!: string; - constructor( public dialogRef: MatDialogRef<ImageActionDialogComponent>, - @Inject(MAT_DIALOG_DATA) public data: ImageModalData, - private imagesService: ImagesService, - private toastr: ToastrService, + @Inject(MAT_DIALOG_DATA) public data: ImageActionModalData, ) { } - - ngOnInit(): void { - this.imageName = this.data.image.name; - this.setTitle(); - } - - onYesClick(actionType: ImageActionType): void { - const actionConfig = this.getActionConfig(); - const actionHandler = actionConfig[actionType].bind(this); - return actionHandler(); - } - - private getActionConfig() { - return { - share: this.shareImage, - terminate: this.terminateImage - }; - } - - private terminateImage() { - const imageInfo = this.getImageInfo(); - this.dialogRef.close(); - this.imagesService.terminateImage(imageInfo, this.data.actionType) - .subscribe(); - } - - private shareImage(): void { - const imageInfo = this.getImageInfo(); - this.dialogRef.close(); - this.imagesService.shareImageAllUsers(imageInfo) - .subscribe( - () => this.toastr.success(Toaster_Message.successShare, 'Success!') - ); - } - - private setTitle(): void { - this.title = this.data.actionType === ImageActions.share ? 'Share Image' : 'Terminate image'; - } - - private getImageInfo(): ImageParams { - const { name, project, endpoint } = this.data.image; - return { - imageName: name, - projectName: project, - endpoint: endpoint - }; - } } diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-detail-dialog/image-detail-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-detail-dialog/image-detail-dialog.component.ts index a5bcbbd49..3c1948e09 100644 --- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-detail-dialog/image-detail-dialog.component.ts +++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-detail-dialog/image-detail-dialog.component.ts @@ -19,7 +19,7 @@ import { Component, Inject, OnInit } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; -import { LibraryInfoItem, Library, ImageModalData } from '../../images'; +import { LibraryInfoItem, Library, ImageDetailModalData } from '../../images'; import { LibraryInfoModalComponent } from '../library-info-modal/library-info-modal.component'; import { caseInsensitiveSortUtil } from '../../../core/util'; @@ -38,7 +38,7 @@ export class ImageDetailDialogComponent implements OnInit { constructor( public dialogRef: MatDialogRef<ImageDetailDialogComponent>, - @Inject(MAT_DIALOG_DATA) public data: ImageModalData, + @Inject(MAT_DIALOG_DATA) public data: ImageDetailModalData, private dialog: MatDialog, ) { } diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/images/images.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/images/images.component.html index 64cdcf6ab..508e3c1b2 100644 --- a/services/self-service/src/main/resources/webapp/src/app/resources/images/images.component.html +++ b/services/self-service/src/main/resources/webapp/src/app/resources/images/images.component.html @@ -317,13 +317,14 @@ <li *ngIf="element.imageUserPermissions.canShare"> <button class="action-button__share" - (click)="onShareClick(element)" + (click)="onActionClick(element, imageActionType.share)" > <i class="material-icons">screen_share</i> <span>Share</span> </button> </li> - <li *ngIf="element.imageUserPermissions.canTerminate" (click)="onTerminateClick(element)"> + <li *ngIf="element.imageUserPermissions.canTerminate" + (click)="onActionClick(element, imageActionType.terminate)"> <button class="action-button__share"> <i class="material-icons">phonelink_off</i> <span>Terminate</span> diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/images/images.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/images/images.component.ts index 687ba653d..3e77746f2 100644 --- a/services/self-service/src/main/resources/webapp/src/app/resources/images/images.component.ts +++ b/services/self-service/src/main/resources/webapp/src/app/resources/images/images.component.ts @@ -20,13 +20,20 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { Observable } from 'rxjs'; -import { map, tap} from 'rxjs/operators'; +import { map, switchMap, tap } from 'rxjs/operators'; import { ToastrService } from 'ngx-toastr'; import { GeneralEnvironmentStatus } from '../../administration/management/management.model'; import { ApplicationSecurityService, HealthStatusService } from '../../core/services'; -import { FilteredColumnList, ImageFilterFormDropdownData, ImageFilterFormValue, ImageModel, ProjectModel } from './images.model'; +import { + FilteredColumnList, + ImageActionType, + ImageFilterFormDropdownData, + ImageFilterFormValue, + ImageModel, + ProjectModel +} from './images.model'; import { Image_Table_Column_Headers, Image_Table_Titles, @@ -37,7 +44,10 @@ import { DropdownFieldNames, FilterFormInitialValue, ImageModelKeysForFilter, - DropdownSelectAllValue, FilterFormControlNames, ImageActions, + DropdownSelectAllValue, + FilterFormControlNames, + ImageActions, + Toaster_Message, } from './images.config'; import { ImageActionDialogComponent } from '../exploratory/image-action-dialog/image-action-dialog.component'; import { ImagesService } from './images.service'; @@ -63,6 +73,7 @@ export class ImagesComponent implements OnInit, OnDestroy { readonly imageStatus: typeof ImageStatuses = ImageStatuses; readonly columnFieldNames: typeof FilterFormControlNames = FilterFormControlNames; readonly dropdownFieldNames: typeof DropdownFieldNames = DropdownFieldNames; + readonly imageActionType: typeof ImageActions = ImageActions; isActionsOpen: boolean = false; healthStatus: GeneralEnvironmentStatus; @@ -122,7 +133,7 @@ export class ImagesComponent implements OnInit, OnDestroy { this.imagesService.changeCheckboxValue(this.checkboxSelected); } - onActionClick(): void { + onActionBtnClick(): void { this.isActionsOpen = !this.isActionsOpen; } @@ -149,31 +160,20 @@ export class ImagesComponent implements OnInit, OnDestroy { }); } - onShareClick(image: ImageModel): void { - this.dialog.open(ImageActionDialogComponent, { - data: { - image, - actionType: ImageActions.share - }, - panelClass: 'modal-sm' - }).afterClosed() - .subscribe(() => { - this.checkAuthorize(); - this.progressBarService.stopProgressBar(); - }); - } + onActionClick(image: ImageModel, actionType: ImageActionType): void { + const imageInfo = this.imagesService.createImageRequestInfo(image); + const data = this.imagesService.createActionDialogConfig(image, actionType); + const requestCallback = this.imagesService.getRequestByAction(actionType).bind(this.imagesService); - onTerminateClick(image: ImageModel): void { this.dialog.open(ImageActionDialogComponent, { - data: { - image, - actionType: ImageActions.terminate - }, + data, panelClass: 'modal-sm' }).afterClosed() - .subscribe(() => { - this.progressBarService.stopProgressBar(); - }); + .pipe( + switchMap(() => requestCallback(imageInfo, actionType)), + tap(() => this.callActionHelpers(actionType)) + ) + .subscribe(); } onFilterClick(): void { @@ -220,6 +220,14 @@ export class ImagesComponent implements OnInit, OnDestroy { this.imagesService.closeFilter(); } + private callActionHelpers(actionType: ImageActionType): void { + if (actionType === ImageActions.share) { + this.toastr.success(Toaster_Message.successShare, 'Success!'); + } + this.checkAuthorize(); + this.progressBarService.stopProgressBar(); + } + private checkAuthorize(): void { this.applicationSecurityService.isLoggedIn().subscribe(() => { this.getEnvironmentHealthStatus(); diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/images/images.config.ts b/services/self-service/src/main/resources/webapp/src/app/resources/images/images.config.ts index 5c15e2e42..ef7cb6289 100644 --- a/services/self-service/src/main/resources/webapp/src/app/resources/images/images.config.ts +++ b/services/self-service/src/main/resources/webapp/src/app/resources/images/images.config.ts @@ -117,3 +117,8 @@ export enum ImageActions { terminate = 'terminate' } +export enum ModalTitle { + share = 'Share image', + terminate = 'Terminate image' +} + diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/images/images.model.ts b/services/self-service/src/main/resources/webapp/src/app/resources/images/images.model.ts index b7e8ff75d..7957a0dda 100644 --- a/services/self-service/src/main/resources/webapp/src/app/resources/images/images.model.ts +++ b/services/self-service/src/main/resources/webapp/src/app/resources/images/images.model.ts @@ -43,9 +43,15 @@ export interface ImageParams { endpoint: string; } -export interface ImageModalData { - image: ImageModel; +export interface ImageActionModalData { actionType: ImageActionType; + title: string; + imageName: string; + isShared?: boolean; +} + +export interface ImageDetailModalData { + image: ImageModel; } export type ImageActionType = 'share' | 'terminate'; diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/images/images.service.ts b/services/self-service/src/main/resources/webapp/src/app/resources/images/images.service.ts index dfd92cd05..95667ecdc 100644 --- a/services/self-service/src/main/resources/webapp/src/app/resources/images/images.service.ts +++ b/services/self-service/src/main/resources/webapp/src/app/resources/images/images.service.ts @@ -10,10 +10,12 @@ import { ImageModel, ProjectImagesInfo, ProjectModel, - ImageParams, ImageActionType + ImageParams, + ImageActionType, + ImageActionModalData } from './images.model'; import { ApplicationServiceFacade, UserImagesPageService } from '../../core/services'; -import { ChangedColumnStartValue, FilterFormInitialValue } from './images.config'; +import { ChangedColumnStartValue, FilterFormInitialValue, ModalTitle, SharedStatus } from './images.config'; @Injectable({ providedIn: 'root' @@ -166,11 +168,45 @@ export class ImagesService { : []; } - checkIsPageFiltered() { + checkIsPageFiltered(): void { const isImageListFiltered = (<any>Object).values(this.$$filteredColumnState.value).some(item => Boolean(item)); this.$$isImageListFiltered.next(isImageListFiltered); } + createImageRequestInfo(image: ImageModel): ImageParams { + const { name, project, endpoint } = image; + return { + imageName: name, + projectName: project, + endpoint: endpoint + }; + } + + createActionDialogConfig(image: ImageModel, actionType: ImageActionType): ImageActionModalData { + const modalTitle = { + share: ModalTitle.share, + terminate: ModalTitle.terminate + }; + return { + title: modalTitle[actionType], + actionType, + imageName: image.name, + isShared: this.isImageShared(image) + }; + } + + getRequestByAction(actionType): Function { + const callbackList = { + share: this.shareImageAllUsers, + terminate: this.terminateImage + }; + return callbackList[actionType]; + } + + private isImageShared(image: ImageModel): boolean { + return image.sharingStatus !== SharedStatus.private; + } + private initImagePageInfo(imagePageInfo: ProjectImagesInfo): void { this.getImagePageData(imagePageInfo.projectImagesInfos); this.getDropdownDataList(imagePageInfo.filterData); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
