This is an automated email from the ASF dual-hosted git repository. hshpak pushed a commit to branch feat/DATALAB-2883/view-additional-info-about-images in repository https://gitbox.apache.org/repos/asf/incubator-datalab.git
commit 74ff6711c1dfa96a4364189dd9ec89a4c332dec1 Author: Hennadii_Shpak <[email protected]> AuthorDate: Fri Jul 8 13:00:11 2022 +0300 [DATALAB-2883] finished modal info window about images --- .../pipes/library-name-normalize/index.ts} | 15 ++-- .../library-name-normalize.pipe.ts} | 29 ++++---- .../pipes/truncate-text-pipe/truncate-text.pipe.ts | 8 +-- .../webapp/src/app/core/util/sortUtils.ts | 2 +- .../detail-dialog/detail-dialog.component.html | 68 +++++++++--------- .../detail-dialog/detail-dialog.component.ts | 10 +-- .../image-detail-dialog.component.html | 83 ++++++++++++++++++++++ .../image-detail-dialog.component.scss} | 56 +++++++++++---- .../image-detail-dialog.component.ts | 50 +++++++++++++ .../image-detail-dialog.module.ts} | 23 ++++-- .../library-info-modal.component.html} | 22 ++---- .../library-info-modal.component.scss} | 20 +----- .../library-info-modal.component.ts} | 29 ++++---- .../library-info-modal.module.ts} | 15 ++-- .../share-image/share-image-dialog.component.html} | 0 .../share-image/share-image-dialog.component.scss} | 0 .../share-image/share-image-dialog.component.ts} | 15 ++-- .../share-image/share-image-dialog.module.ts} | 12 ++-- .../src/app/resources/images/images.component.html | 6 +- .../src/app/resources/images/images.component.ts | 24 +++---- .../src/app/resources/images/images.model.ts | 23 ++++++ .../webapp/src/app/resources/resources.module.ts | 8 ++- .../src/main/resources/webapp/src/styles.scss | 9 +++ 23 files changed, 355 insertions(+), 172 deletions(-) diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.module.ts b/services/self-service/src/main/resources/webapp/src/app/core/pipes/library-name-normalize/index.ts similarity index 74% copy from services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.module.ts copy to services/self-service/src/main/resources/webapp/src/app/core/pipes/library-name-normalize/index.ts index bd7a99d1d..48f7e5a22 100644 --- a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.module.ts +++ b/services/self-service/src/main/resources/webapp/src/app/core/pipes/library-name-normalize/index.ts @@ -19,15 +19,12 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { ShareImageComponent } from './share-image.component'; -import { NotificationDialogComponent } from '../notification-dialog'; - - +import { LibraryNameNormalizePipe } from './library-name-normalize.pipe'; @NgModule({ - declarations: [ ShareImageComponent ], - imports: [ CommonModule ], - entryComponents: [ShareImageComponent], - exports: [ ShareImageComponent ] + imports: [CommonModule], + declarations: [LibraryNameNormalizePipe], + exports: [LibraryNameNormalizePipe] }) -export class ShareImageModule { } + +export class LibraryNameNormalizePipeModule { } diff --git a/services/self-service/src/main/resources/webapp/src/app/core/pipes/truncate-text-pipe/truncate-text.pipe.ts b/services/self-service/src/main/resources/webapp/src/app/core/pipes/library-name-normalize/library-name-normalize.pipe.ts similarity index 66% copy from services/self-service/src/main/resources/webapp/src/app/core/pipes/truncate-text-pipe/truncate-text.pipe.ts copy to services/self-service/src/main/resources/webapp/src/app/core/pipes/library-name-normalize/library-name-normalize.pipe.ts index f497deecc..3782c3a8e 100644 --- a/services/self-service/src/main/resources/webapp/src/app/core/pipes/truncate-text-pipe/truncate-text.pipe.ts +++ b/services/self-service/src/main/resources/webapp/src/app/core/pipes/library-name-normalize/library-name-normalize.pipe.ts @@ -17,20 +17,23 @@ * under the License. */ -import { Pipe, PipeTransform } from "@angular/core"; +import {Pipe, PipeTransform} from '@angular/core'; -const MAX_SYMBOLS_COUNT = 255; +const libNameList = { + os_pkg: 'Apt/Yum', + pip3: 'Python 3', + r_pkg: 'R packages', + java: 'Java', + others: 'Others' +}; -@Pipe({ - name: 'truncateTextPipe' -}) -export class TruncateTextPipe implements PipeTransform { - transform(text: string, limit: number = MAX_SYMBOLS_COUNT): string { - if (!text) { - return '' - } - return text.length > limit - ? `${text.substring(0, limit)}...` - : text +@Pipe({name: 'libNameNormalize'}) + +export class LibraryNameNormalizePipe implements PipeTransform { + transform(libGroupName: string): string { + if (!libGroupName) { + return ''; } + return libNameList[libGroupName]; + } } diff --git a/services/self-service/src/main/resources/webapp/src/app/core/pipes/truncate-text-pipe/truncate-text.pipe.ts b/services/self-service/src/main/resources/webapp/src/app/core/pipes/truncate-text-pipe/truncate-text.pipe.ts index f497deecc..28ddf9e3d 100644 --- a/services/self-service/src/main/resources/webapp/src/app/core/pipes/truncate-text-pipe/truncate-text.pipe.ts +++ b/services/self-service/src/main/resources/webapp/src/app/core/pipes/truncate-text-pipe/truncate-text.pipe.ts @@ -17,7 +17,7 @@ * under the License. */ -import { Pipe, PipeTransform } from "@angular/core"; +import { Pipe, PipeTransform } from '@angular/core'; const MAX_SYMBOLS_COUNT = 255; @@ -27,10 +27,10 @@ const MAX_SYMBOLS_COUNT = 255; export class TruncateTextPipe implements PipeTransform { transform(text: string, limit: number = MAX_SYMBOLS_COUNT): string { if (!text) { - return '' + return ''; } - return text.length > limit + return text.length > limit ? `${text.substring(0, limit)}...` - : text + : text; } } diff --git a/services/self-service/src/main/resources/webapp/src/app/core/util/sortUtils.ts b/services/self-service/src/main/resources/webapp/src/app/core/util/sortUtils.ts index fa220dacf..9e06ec163 100644 --- a/services/self-service/src/main/resources/webapp/src/app/core/util/sortUtils.ts +++ b/services/self-service/src/main/resources/webapp/src/app/core/util/sortUtils.ts @@ -56,7 +56,7 @@ export class SortUtils { } public static flatDeep(arr, d = 1) { - return d > 0 + return d > 0 ? arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? this.flatDeep(val, d - 1) : val), []) : arr.slice(); } diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.html index 3397676b2..80c11d635 100644 --- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.html +++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.html @@ -68,15 +68,15 @@ <!-- </a>--> <!-- </p> --> <ng-container *ngFor="let item of notebook.exploratory_urls"> - <span - class="d-none" - *ngIf="item.description.toLowerCase() === 'ungit' + <span + class="d-none" + *ngIf="item.description.toLowerCase() === 'ungit' && notebook.exploratory_urls[0].description.toLowerCase().indexOf('zeppelin') !== -1; else ungit" ></span> <ng-template #ungit> <p (mouseleave)="hideCopyIcon()"> <span class="description">{{item.description}}: </span> - <a + <a (mouseover)="showCopyIcon(item.description)" (click)="logAction(notebook.name, item.description)" class="ellipsis none-select resources-url" matTooltip="{{item.url}}" @@ -87,11 +87,11 @@ > {{item.url | truncateTextPipe: urlMaxLength}} </a> - <span - (click)="logAction(notebook.name, item.description, 'Copy');$event.stopPropagation()" - *ngIf="isCopyIconVissible[item.description]" - [matTooltip]="isCopied ? 'Copy ' + item.description + ' url': 'Copied'" - matTooltipPosition="above" + <span + (click)="logAction(notebook.name, item.description, 'Copy');$event.stopPropagation()" + *ngIf="isCopyIconVissible[item.description]" + [matTooltip]="isCopied ? 'Copy ' + item.description + ' url': 'Copied'" + matTooltipPosition="above" class="copy-icon-wrapper" > <span class="link-icon" (click)="copyLink(item.url)" > @@ -105,22 +105,22 @@ </div> <div class="scroll-box" id="scrolling" *ngIf="data.type === 'resource'"> <div class="detail-info" *ngIf="!notebook.error_message"> - <p>Edge Node IP Address {{notebook.node_ip}}</p> + <p>Edge Node IP Address {{notebook.node_ip}} </p> <p *ngIf="notebook.status === 'running'">Up time {{upTimeInHours}} hour(s) since {{notebook.time ? (notebook.time | longDate) : "not specified."}} </p> <p *ngIf="notebook.url?.length">Open following URL(s) in your browser to access this box:</p> <div class="links_block"> <ng-container *ngFor="let item of notebook.url"> - <span - class="d-none" - *ngIf="item.description.toLowerCase() === 'ungit' + <span + class="d-none" + *ngIf="item.description.toLowerCase() === 'ungit' && notebook.template_name.toLowerCase().indexOf('zeppelin ') !== -1; else ungit" ></span> <ng-template #ungit> <p (mouseleave)="hideCopyIcon()"> <span class="description">{{item.description}}: </span> - <a + <a (mouseover)="showCopyIcon(item.description)" (click)="logAction(notebook.name, item.description)" class="ellipsis none-select resources-url" matTooltip="{{item.url}}" @@ -131,11 +131,11 @@ > {{item.url | truncateTextPipe: urlMaxLength}} </a> - <span - (click)="logAction(notebook.name, item.description, 'Copy');$event.stopPropagation()" - *ngIf="isCopyIconVissible[item.description]" - [matTooltip]="isCopied ? 'Copy ' + item.description + ' url': 'Copied'" - matTooltipPosition="above" + <span + (click)="logAction(notebook.name, item.description, 'Copy');$event.stopPropagation()" + *ngIf="isCopyIconVissible[item.description]" + [matTooltip]="isCopied ? 'Copy ' + item.description + ' url': 'Copied'" + matTooltipPosition="above" class="copy-icon-wrapper" > <span class="link-icon" (click)="copyLink(item.url)" > @@ -199,7 +199,7 @@ <!-- [ngClass]="{'not-allow': !this.bucketStatus['view'] || !thisdata.buckets.length}"--> <!-- (click)="bucketBrowser(notebook.bucket_name, notebook.endpoint, this.bucketStatus['view'] && thisdata.buckets.length)"--> <!-- >--> - <span + <span class="description open-bucket" [matTooltip]="!this.bucketStatus['view'] ? 'You have not permission to open bucket' @@ -209,8 +209,8 @@ [matTooltipClass]="'full-size-tooltip'" [ngClass]="{'not-allow': !this.bucketStatus['view'] || !this.data.buckets.length}" (click)="bucketBrowser( - notebook.cloud_provider !== 'azure' ? notebook.bucket_name : notebook.account_name + '.' + notebook.bucket_name, - notebook.endpoint, + notebook.cloud_provider !== 'azure' ? notebook.bucket_name : notebook.account_name + '.' + notebook.bucket_name, + notebook.endpoint, this.bucketStatus['view'] && this.data.buckets.length )" > @@ -265,10 +265,10 @@ </p> --> </div> - <div - class="checkbox-group" + <div + class="checkbox-group" *ngIf="notebook.image !== 'docker.datalab-zeppelin'; else not_support" - [hidden]="notebook.status !== 'running' || notebook.image === 'docker.datalab-superset' + [hidden]="notebook.status !== 'running' || notebook.image === 'docker.datalab-superset' || notebook.image === 'docker.datalab-jupyterlab'" > <label> @@ -277,15 +277,15 @@ <div class="checkbox-group"> <form [formGroup]="configurationForm" novalidate> <div class="config-details" *ngIf="configuration?.nativeElement['checked'] || false"> - <textarea - formControlName="configuration_parameters" + <textarea + formControlName="configuration_parameters" id="config" - placeholder="Cluster configuration template, JSON" + placeholder="Cluster configuration template, JSON" data-gramm_editor="false" ></textarea> - <span + <span class="danger_color" - *ngIf="!configurationForm.controls.configuration_parameters.valid + *ngIf="!configurationForm.controls.configuration_parameters.valid && configurationForm.controls['configuration_parameters'].dirty" > Configuration parameters is not in a valid format @@ -320,10 +320,10 @@ <div *ngFor="let url of odahu.url" class="odahu-links"> <div class="odahu-link"> <span class="description">{{url.description }}: </span> - <a - class="ellipsis" - matTooltip="{{ url.url}}" - matTooltipPosition="above" + <a + class="ellipsis" + matTooltip="{{ url.url}}" + matTooltipPosition="above" href="{{ url.url}}" target="_blank" > diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.ts index 15845a6b2..c855f765a 100644 --- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.ts +++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.ts @@ -151,10 +151,10 @@ export class DetailDialogComponent implements OnInit { bucketName = this.isBucketAllowed ? bucketName : this.data.buckets[0].children[0].name; // bucketName = 'ofuks-1304-pr2-local-bucket'; this.dialog.open(BucketBrowserComponent, { data: - { - bucket: bucketName, - endpoint: endpoint, - bucketStatus: this.bucketStatus, + { + bucket: bucketName, + endpoint: endpoint, + bucketStatus: this.bucketStatus, buckets: this.data.buckets }, panelClass: 'modal-fullscreen' } @@ -164,7 +164,7 @@ export class DetailDialogComponent implements OnInit { public showCopyIcon(element) { this.isCopyIconVissible[element] = true; } - + public hideCopyIcon() { for (const key in this.isCopyIconVissible) { this.isCopyIconVissible[key] = false; diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-detail-dialog/image-detail-dialog.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-detail-dialog/image-detail-dialog.component.html new file mode 100644 index 000000000..70262a064 --- /dev/null +++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-detail-dialog/image-detail-dialog.component.html @@ -0,0 +1,83 @@ +<!-- + ~ 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. + --> + +<div class="detail-dialog" id="dialog-box"> + <header class="dialog-header header-white"> + <button type="button" class="close" (click)="dialogRef.close()">×</button> + </header> + + <div> + <table class="detail-header"> + <tr> + <td>{{ data.image.name }}</td> + <td>{{ data.image.project }}</td> + <td>{{ data.image.instanceName }}</td> + <td> + <span class="status" [ngClass]="data.image.status.toLowerCase()"> + {{ data.image.status | titlecase }} + </span> + </td> + </tr> + </table> + + <div class="content-box"> + <div *ngIf="data.image.description" class="image__description--wrapper"> + <p + [matTooltip]="data.image.description" + matTooltipPosition="above" + [matTooltipDisabled]="data.image.description.length < maxDescriptionLength" + class="image__description"> + {{ data.image.description | truncateTextPipe : maxDescriptionLength}} + </p> + </div> + + <div class="image__template--wrapper"> + <span class="modal-row__item modal-row__item--title">Template name</span> + <span class="modal-row__item">{{ data.image.application }}</span> + </div> + + <div class="image__libraries--wrapper"> + <span class="modal-row__item modal-row__item--title">Installed libraries` groups</span> + <div class="language__wrapper modal-row__item"> + <div *ngIf="data.image.libraries.length; else notAvailable"> + <div *ngFor="let library of data.image.libraries" class="library__wrapper"> + <span>{{library.group | libNameNormalize}}</span> + <i (click)="onLibraryInfo(library)" class="material-icons library__info">info</i> + </div> + </div> + <ng-template #notAvailable> + <span class="no-libraries">No additional libraries installed</span> + </ng-template> + </div> + </div> + <div class="image__provider--wrapper"> + <span class="modal-row__item modal-row__item--title">Provider</span> + <span class="modal-row__item">{{ data.image.cloudProvider }}</span> + </div> + <div class="image__creation-date--wrapper"> + <span class="modal-row__item modal-row__item--title">Creation date</span> + <span class="modal-row__item">{{data.image.timestamp | localDate : 'short'}} </span> + </div> + <div class="image__creator--wrapper"> + <span class="modal-row__item modal-row__item--title">Creator</span> + <span class="modal-row__item">{{ data.image.user }}</span> + </div> + </div> + </div> +</div> diff --git a/services/self-service/src/main/resources/webapp/src/app/core/pipes/truncate-text-pipe/truncate-text.pipe.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-detail-dialog/image-detail-dialog.component.scss similarity index 59% copy from services/self-service/src/main/resources/webapp/src/app/core/pipes/truncate-text-pipe/truncate-text.pipe.ts copy to services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-detail-dialog/image-detail-dialog.component.scss index f497deecc..c73b2d111 100644 --- a/services/self-service/src/main/resources/webapp/src/app/core/pipes/truncate-text-pipe/truncate-text.pipe.ts +++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-detail-dialog/image-detail-dialog.component.scss @@ -17,20 +17,46 @@ * under the License. */ -import { Pipe, PipeTransform } from "@angular/core"; - -const MAX_SYMBOLS_COUNT = 255; - -@Pipe({ - name: 'truncateTextPipe' -}) -export class TruncateTextPipe implements PipeTransform { - transform(text: string, limit: number = MAX_SYMBOLS_COUNT): string { - if (!text) { - return '' - } - return text.length > limit - ? `${text.substring(0, limit)}...` - : text +.image__description { + font-size: 12px; + text-align: justify; +} + +.content-box > div { + display: flex; + justify-content: space-between; + padding: 10px 0; +} + +.content-box > div { + &:not(:last-child) { + border-bottom: 1px solid #edf1f5; + } +} + +.modal-row__item { + width: 50%; + + &--title { + font-weight: 500; + } +} + +.library { + &__wrapper { + display: flex; + justify-content: space-between; + + &:not(:last-child) { + margin-bottom: 10px; } + } + + &__info { + cursor: pointer; + } +} + +.no-libraries { + color: rgba(113, 138, 165, 0.5); } 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 new file mode 100644 index 000000000..2659ee7d0 --- /dev/null +++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-detail-dialog/image-detail-dialog.component.ts @@ -0,0 +1,50 @@ +/* + * 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 { Component, Inject, OnInit } from '@angular/core'; +import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material/dialog'; +import {Library, ModalData} from '../../images'; +import {LibraryInfoModalComponent} from '../library-info-modal/library-info-modal.component'; + +@Component({ + selector: 'datalab-image-detail-dialog', + templateUrl: './image-detail-dialog.component.html', + styleUrls: [ + './image-detail-dialog.component.scss', + '../detail-dialog/detail-dialog.component.scss' + ] +}) + +export class ImageDetailDialogComponent { + maxDescriptionLength: number = 170; + constructor( + public dialogRef: MatDialogRef<ImageDetailDialogComponent>, + @Inject(MAT_DIALOG_DATA) public data: ModalData, + private dialog: MatDialog, + ) { } + + onLibraryInfo(library: Library): void { + this.dialog.open(LibraryInfoModalComponent, { + data: { + library + }, + panelClass: 'library-dialog-container' + }); + } +} diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.module.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-detail-dialog/image-detail-dialog.module.ts similarity index 55% copy from services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.module.ts copy to services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-detail-dialog/image-detail-dialog.module.ts index bd7a99d1d..44a9cbc6c 100644 --- a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.module.ts +++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/image-detail-dialog/image-detail-dialog.module.ts @@ -19,15 +19,24 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { ShareImageComponent } from './share-image.component'; -import { NotificationDialogComponent } from '../notification-dialog'; +import { ImageDetailDialogComponent } from './image-detail-dialog.component'; +import { TruncateTextPipeModule } from '../../../core/pipes/truncate-text-pipe'; +import {LocalDatePipeModule} from '../../../core/pipes/local-date-pipe'; +import {MatTooltipModule} from '@angular/material/tooltip'; +import {LibraryNameNormalizePipeModule} from '../../../core/pipes/library-name-normalize'; @NgModule({ - declarations: [ ShareImageComponent ], - imports: [ CommonModule ], - entryComponents: [ShareImageComponent], - exports: [ ShareImageComponent ] + declarations: [ ImageDetailDialogComponent ], + imports: [ + CommonModule, + TruncateTextPipeModule, + LocalDatePipeModule, + MatTooltipModule, + LibraryNameNormalizePipeModule + ], + exports: [ ImageDetailDialogComponent ], + entryComponents: [ ImageDetailDialogComponent ] }) -export class ShareImageModule { } +export class ImageDetailDialogModule { } diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/library-info-modal/library-info-modal.component.html similarity index 61% copy from services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.component.html copy to services/self-service/src/main/resources/webapp/src/app/resources/exploratory/library-info-modal/library-info-modal.component.html index a6f1d1e2a..df0e9e5c1 100644 --- a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.component.html +++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/library-info-modal/library-info-modal.component.html @@ -17,23 +17,15 @@ ~ under the License. --> -<div id="dialog-box"> +<div class="detail-dialog" id="dialog-box"> <header class="dialog-header"> - <h4 class="modal-title">Share Image: <span>{{imageName}}</span></h4> + <h1 class="modal__title">Installed libraries</h1> <button type="button" class="close" (click)="dialogRef.close()">×</button> </header> - <section class="content"> - <p class="description"> - The image will be shared with all current Regular Users on the project with all the data and code. - </p> - <p class="question center"> - Do you want proceed? - </p> - <div class="text-center m-top-30 m-bott-10"> - <button type="button" class="butt mat-raised-button" (click)="dialogRef.close()">No</button> - <button type="button" class="butt butt-success mat-raised-button" - (click)="onShare()">Yes - </button> + + <div class="content-box"> + <div class="library__wrapper" *ngFor="let library of data.library.add_pkgs"> + <span>{{library}}</span> </div> - </section> + </div> </div> diff --git a/services/self-service/src/main/resources/webapp/src/app/core/pipes/truncate-text-pipe/truncate-text.pipe.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/library-info-modal/library-info-modal.component.scss similarity index 65% copy from services/self-service/src/main/resources/webapp/src/app/core/pipes/truncate-text-pipe/truncate-text.pipe.ts copy to services/self-service/src/main/resources/webapp/src/app/resources/exploratory/library-info-modal/library-info-modal.component.scss index f497deecc..e7e365b0f 100644 --- a/services/self-service/src/main/resources/webapp/src/app/core/pipes/truncate-text-pipe/truncate-text.pipe.ts +++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/library-info-modal/library-info-modal.component.scss @@ -1,4 +1,4 @@ -/* +/*! * 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 @@ -17,20 +17,6 @@ * under the License. */ -import { Pipe, PipeTransform } from "@angular/core"; - -const MAX_SYMBOLS_COUNT = 255; - -@Pipe({ - name: 'truncateTextPipe' -}) -export class TruncateTextPipe implements PipeTransform { - transform(text: string, limit: number = MAX_SYMBOLS_COUNT): string { - if (!text) { - return '' - } - return text.length > limit - ? `${text.substring(0, limit)}...` - : text - } +.modal__title { + font-size: 12px; } diff --git a/services/self-service/src/main/resources/webapp/src/app/core/pipes/truncate-text-pipe/truncate-text.pipe.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/library-info-modal/library-info-modal.component.ts similarity index 60% copy from services/self-service/src/main/resources/webapp/src/app/core/pipes/truncate-text-pipe/truncate-text.pipe.ts copy to services/self-service/src/main/resources/webapp/src/app/resources/exploratory/library-info-modal/library-info-modal.component.ts index f497deecc..e6c8d2c1e 100644 --- a/services/self-service/src/main/resources/webapp/src/app/core/pipes/truncate-text-pipe/truncate-text.pipe.ts +++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/library-info-modal/library-info-modal.component.ts @@ -17,20 +17,21 @@ * under the License. */ -import { Pipe, PipeTransform } from "@angular/core"; +import {Component, Inject, OnInit} from '@angular/core'; +import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; -const MAX_SYMBOLS_COUNT = 255; - -@Pipe({ - name: 'truncateTextPipe' +@Component({ + selector: 'datalab-library-info-modal', + templateUrl: './library-info-modal.component.html', + styleUrls: [ + './library-info-modal.component.scss', + '../detail-dialog/detail-dialog.component.scss' + ] }) -export class TruncateTextPipe implements PipeTransform { - transform(text: string, limit: number = MAX_SYMBOLS_COUNT): string { - if (!text) { - return '' - } - return text.length > limit - ? `${text.substring(0, limit)}...` - : text - } +export class LibraryInfoModalComponent { + + constructor( + public dialogRef: MatDialogRef<LibraryInfoModalComponent>, + @Inject(MAT_DIALOG_DATA) public data: any, + ) { } } diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.module.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/library-info-modal/library-info-modal.module.ts similarity index 74% copy from services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.module.ts copy to services/self-service/src/main/resources/webapp/src/app/resources/exploratory/library-info-modal/library-info-modal.module.ts index bd7a99d1d..80cd1f853 100644 --- a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.module.ts +++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/library-info-modal/library-info-modal.module.ts @@ -19,15 +19,16 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { ShareImageComponent } from './share-image.component'; -import { NotificationDialogComponent } from '../notification-dialog'; +import {LibraryInfoModalComponent} from './library-info-modal.component'; @NgModule({ - declarations: [ ShareImageComponent ], - imports: [ CommonModule ], - entryComponents: [ShareImageComponent], - exports: [ ShareImageComponent ] + declarations: [LibraryInfoModalComponent], + imports: [ + CommonModule + ], + exports: [LibraryInfoModalComponent], + entryComponents: [LibraryInfoModalComponent] }) -export class ShareImageModule { } +export class LibraryInfoModalModule { } diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/share-image/share-image-dialog.component.html similarity index 100% rename from services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.component.html rename to services/self-service/src/main/resources/webapp/src/app/resources/exploratory/share-image/share-image-dialog.component.html diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/share-image/share-image-dialog.component.scss similarity index 100% rename from services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.component.scss rename to services/self-service/src/main/resources/webapp/src/app/resources/exploratory/share-image/share-image-dialog.component.scss diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/share-image/share-image-dialog.component.ts similarity index 78% rename from services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.component.ts rename to services/self-service/src/main/resources/webapp/src/app/resources/exploratory/share-image/share-image-dialog.component.ts index 8afa9a088..25bd72c62 100644 --- a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.component.ts +++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/share-image/share-image-dialog.component.ts @@ -19,23 +19,22 @@ import { Component, Inject } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { ImagesService } from '../../../resources/images/images.service'; +import { ImagesService } from '../../images/images.service'; import { UserImagesPageService } from '../../../core/services'; -import { Toaster_Message } from '../../../resources/images'; +import { ModalData, Toaster_Message } from '../../images'; import { ToastrService } from 'ngx-toastr'; -import { tap } from 'rxjs/operators'; @Component({ selector: 'datalab-share-image', - templateUrl: './share-image.component.html', - styleUrls: ['./share-image.component.scss'] + templateUrl: './share-image-dialog.component.html', + styleUrls: ['./share-image-dialog.component.scss'] }) -export class ShareImageComponent { +export class ShareImageDialogComponent { imageName!: string; constructor( - public dialogRef: MatDialogRef<ShareImageComponent>, - @Inject(MAT_DIALOG_DATA) public data: any, + public dialogRef: MatDialogRef<ShareImageDialogComponent>, + @Inject(MAT_DIALOG_DATA) public data: ModalData, private imagesService: ImagesService, private userImagesPageService: UserImagesPageService, private toastr: ToastrService, diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.module.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/share-image/share-image-dialog.module.ts similarity index 73% rename from services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.module.ts rename to services/self-service/src/main/resources/webapp/src/app/resources/exploratory/share-image/share-image-dialog.module.ts index bd7a99d1d..158aa0d09 100644 --- a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/share-image/share-image.module.ts +++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/share-image/share-image-dialog.module.ts @@ -19,15 +19,15 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { ShareImageComponent } from './share-image.component'; -import { NotificationDialogComponent } from '../notification-dialog'; +import { ShareImageDialogComponent } from './share-image-dialog.component'; +import { NotificationDialogComponent } from '../../../shared/modal-dialog/notification-dialog'; @NgModule({ - declarations: [ ShareImageComponent ], + declarations: [ ShareImageDialogComponent ], imports: [ CommonModule ], - entryComponents: [ShareImageComponent], - exports: [ ShareImageComponent ] + entryComponents: [ShareImageDialogComponent], + exports: [ ShareImageDialogComponent ] }) -export class ShareImageModule { } +export class ShareImageDialogModule { } 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 9f85994d0..0f9ea1c9e 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 @@ -227,9 +227,9 @@ <td mat-cell *matCellDef="let element" class="settings actions-col"> <div class="button--wrapper"> - <span class="currency_details" > - <i class="material-icons">help_outline</i> - </span> + <span class="currency_details" (click)="onImageInfo(element)"> + <i class="material-icons">help_outline</i> + </span> <span #settings class="actions" (click)="actions.toggle($event, settings)"></span> </div> <bubble-up #actions class="list-menu" position="bottom-left" alternative="top-left"> 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 afb464fa3..a5abe8513 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 @@ -26,10 +26,11 @@ import { HealthStatusService, UserImagesPageService } from '../../core/services' import { ImageModel, ProjectModel, ShareImageAllUsersParams } from './images.model'; import { Image_Table_Column_Headers, Image_Table_Titles, Localstorage_Key, Shared_Status, Toaster_Message } from './images.config'; import { MatDialog } from '@angular/material/dialog'; -import { ShareImageComponent } from '../../shared/modal-dialog/share-image/share-image.component'; +import { ShareImageDialogComponent } from '../exploratory/share-image/share-image-dialog.component'; import { Observable } from 'rxjs'; import { ImagesService } from './images.service'; import { ProgressBarService } from '../../core/services/progress-bar.service'; +import { ImageDetailDialogComponent } from '../exploratory/image-detail-dialog/image-detail-dialog.component'; @Component({ selector: 'datalab-images', @@ -105,8 +106,17 @@ export class ImagesComponent implements OnInit { this.activeProjectName = ''; } + onImageInfo(image: ImageModel): void { + this.dialog.open(ImageDetailDialogComponent, { + data: { + image + }, + panelClass: 'modal-md' + }); + } + onShare(image: ImageModel): void { - this.dialog.open(ShareImageComponent, { + this.dialog.open(ShareImageDialogComponent, { data: { image }, @@ -159,16 +169,6 @@ export class ImagesComponent implements OnInit { this.userName = localStorage.getItem(Localstorage_Key.userName); } - private shareImageAllUsers(image: ImageModel): Observable<ProjectModel[]> { - const shareParams: ShareImageAllUsersParams = { - imageName: image.name, - projectName: image.project, - endpoint: image.endpoint - }; - - return this.userImagesPageService.shareImageAllUsers(shareParams); - } - get isProjectsMoreThanOne(): boolean { return this.projectList.length > 1; } 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 8c0735950..24ce705bc 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 @@ -17,6 +17,9 @@ export interface ImageModel { status: 'created' | 'creating' | 'terminated' | 'terminating' | 'failed'; user: string; isSelected?: boolean; + libraries: Library[]; + computationalLibraries: Library[]; + clusterConfig: ClusterConfig; } export interface ShareImageAllUsersParams { @@ -24,3 +27,23 @@ export interface ShareImageAllUsersParams { projectName: string; endpoint: string; } + +export interface ModalData { + image: ImageModel; +} + +export interface Library { + add_pkgs: string[]; + available_versions: string[]; + error_message: string; + group: string; + name: string; + status: string; + version: string; +} + +export interface ClusterConfig { + Classification: string; + Properties: Record<string, any>; + Configurations: any[]; +} diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/resources.module.ts b/services/self-service/src/main/resources/webapp/src/app/resources/resources.module.ts index 885328fc2..931e037d6 100644 --- a/services/self-service/src/main/resources/webapp/src/app/resources/resources.module.ts +++ b/services/self-service/src/main/resources/webapp/src/app/resources/resources.module.ts @@ -36,7 +36,9 @@ import {CheckboxModule} from '../shared/checkbox'; import {BubbleModule} from '../shared'; import { CapitalizeFirstLetterPipeModule } from '../core/pipes'; import { LocalDatePipeModule } from '../core/pipes/local-date-pipe'; -import { ShareImageModule } from '../shared/modal-dialog/share-image/share-image.module'; +import { ShareImageDialogModule } from './exploratory/share-image/share-image-dialog.module'; +import { ImageDetailDialogModule } from './exploratory/image-detail-dialog/image-detail-dialog.module'; +import {LibraryInfoModalModule} from './exploratory/library-info-modal/library-info-modal.module'; @NgModule({ imports: [ @@ -53,7 +55,9 @@ import { ShareImageModule } from '../shared/modal-dialog/share-image/share-image BubbleModule, CapitalizeFirstLetterPipeModule, LocalDatePipeModule, - ShareImageModule + ShareImageDialogModule, + ImageDetailDialogModule, + LibraryInfoModalModule, ], declarations: [ ResourcesComponent, diff --git a/services/self-service/src/main/resources/webapp/src/styles.scss b/services/self-service/src/main/resources/webapp/src/styles.scss index 5bc005390..cd4e9d727 100644 --- a/services/self-service/src/main/resources/webapp/src/styles.scss +++ b/services/self-service/src/main/resources/webapp/src/styles.scss @@ -572,3 +572,12 @@ ace_scrollbar { .timezone-mat-select { max-width: 350px !important; } + +.library-dialog-container .mat-dialog-container { + width: 300px; + max-height: 210px; +} + +.library-dialog-container ::-webkit-scrollbar { + width: 3px !important; +} --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
