You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dlab.apache.org by dg...@apache.org on 2020/07/23 16:09:12 UTC

[incubator-dlab] branch develop updated: [DLAB-1750]: Changed library search, fixed issues for library page (#827)

This is an automated email from the ASF dual-hosted git repository.

dgnatyshyn pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-dlab.git


The following commit(s) were added to refs/heads/develop by this push:
     new 8ac13fd  [DLAB-1750]: Changed library search, fixed issues for library page (#827)
8ac13fd is described below

commit 8ac13fdebb74ee746fec8d3ec7e70781861f9378
Author: Dmytro Gnatyshyn <42...@users.noreply.github.com>
AuthorDate: Thu Jul 23 19:09:03 2020 +0300

    [DLAB-1750]: Changed library search, fixed issues for library page (#827)
    
    [DLAB-1750]: Changed library search, fixed issues for library page
---
 .../install-libraries.component.html               | 202 ++++++++++++++++-----
 .../install-libraries.component.scss               |  79 +++++---
 .../install-libraries.component.ts                 | 154 ++++++++--------
 .../src/main/resources/webapp/src/styles.scss      |   3 +-
 4 files changed, 296 insertions(+), 142 deletions(-)

diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.html
index 5d53b59..96f2bd6 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.html
@@ -52,61 +52,171 @@
               </div>
             </div>
           </div>
-          <p class="other-message">
-            <span *ngIf="group === 'others'">Other group can include libs from Python 2 and Python 3 groups</span>
-          </p>
-          <div class="search">
-            <mat-form-field class="chip-list">
-              <input
-                type="text"
-                [placeholder]="group === 'java' ?
-                'Enter library name in <groupId>:<artifactId>:<versionId> format' :
-                'Enter library name in <name>:<version> format(version is not required)'"
-                matInput
-                #trigger="matAutocompleteTrigger"
-                [formControl]="libSearch"
-                [value]="query"
-                [matAutocomplete]="auto"
-              >
-<!--              <span class="add-icon" [matTooltip]="(isInSelectedList || isInstalled) ? 'Current library dosen\'t exist' : 'You have already added or installed current library'"-->
-<!--              matTooltipPosition="above"-->
-<!--              [matTooltipDisabled] = "isLibExist && (isInSelectedList || isInstalled)"-->
-              <span class="add-icon">
-                <button  mat-icon-button class="btn" [disabled]="!isLibExist || query.length < 1 ||
-                isDuplicated({name: query.slice(0, query.indexOf(':')), version: query.slice(query.indexOf(':') + 1) || 'N/A'})" (click)="addLibrary(query);$event.stopPropagation()">
-                  <mat-icon matSuffix >add</mat-icon>
-                </button>
-              </span>
-
+          <div class="m-top-20" *ngIf="group !== 'java'; else javaGroup">
+            <div class="control-group constol-select">
+              <label class="label">Library name</label>
+              <div class="control control-relative">
+                <span class="other-message" *ngIf="group === 'others'">Other group can include libs from Python 2 and Python 3 groups</span>
+                <input
+                  type="text" [placeholder]="'Enter library name'"
+                  [(ngModel)]="lib.name"
+                  [disabled]="!group"
+                  [matAutocomplete]="auto"
+                  [formControl]="libSearch"
+                  #trigger="matAutocompleteTrigger"
+                  (keyup.enter)="addLibrary(lib)"
+                >
+              </div>
               <mat-autocomplete #auto="matAutocomplete" class="suggestions" >
-                <ng-template ngFor let-item [ngForOf]="filteredList" let-i="index" *ngIf="query.indexOf(':') === -1">
-                  <mat-option [ngClass]="{ 'not-allowed': isDuplicated(item) }">
-                    <div class="option" (click)="selectLibrary(item)">
-                      <a *ngIf="!isDuplicated(item)">
+                <ng-template ngFor let-item [ngForOf]="filteredList" let-i="index" *ngIf="!selectedLib">
+                  <mat-option >
+                    <div class="option" (click)="selectLibrary(item);$event.stopPropagation()" [ngClass]="{'not-allow': item.isInSelectedList}">
+                      <a *ngIf="!item.isInSelectedList">
                         <span [innerHTML]="item.name | highlight:query"></span>
-<!--                        <span *ngIf="item.version && item.version !== 'N/A'">{{ item.version }}</span>-->
                       </a>
-                      <span *ngIf="isInSelectedList || isInstalled">{{ item.name }}
-                        <span *ngIf="item.version && item.version !== 'N/A'">{{ item.version }}</span>
+                      <span *ngIf="item.isInSelectedList">{{ item.name }}
+                        <span *ngIf="item.version && item.version !== 'N/A' && item.isInstalled && !item.isInSelectedList">{{ item.version }}</span>
                       </span>
-
-                      <strong *ngIf="isInSelectedList">selected
+                      <strong *ngIf="item.isInSelectedList">selected
                         <i class="material-icons">done</i>
                       </strong>
-                      <strong *ngIf="isInstalled">installed
+                      <strong *ngIf="item.isInstalled && !item.isInSelectedList">installed
                         <i class="material-icons">done</i>
                       </strong>
                     </div>
                   </mat-option>
                 </ng-template>
-                <mat-option *ngIf="model.isEmpty(filteredList) && !validity_format && query.indexOf(':') === -1">
+                <mat-option *ngIf="model.isEmpty(filteredList) && !validity_format">
                   <span class="configuring">No matches found</span>
                 </mat-option>
                 <mat-option *ngIf="validity_format?.length > 0">
-                  <span class="configuring" *ngIf="query.indexOf(':') === -1">{{ validity_format }}</span >
+                  <span class="configuring" >{{ validity_format }}</span >
                 </mat-option>
               </mat-autocomplete>
-            </mat-form-field>
+            </div>
+            <div class="control-group control-select">
+              <label class="label">Library version</label>
+              <div class="control control-relative">
+                <input  type="text" [placeholder]="'Enter library version (optional)'" [(ngModel)]="lib.version" [disabled]="!lib.name" (keyup.enter)="addLibrary(lib)">
+                <span class="plus-icon"
+                      [ngClass]="{'not-allow': !this.selectedLib || this.selectedLib?.isInSelectedList}"
+                      matTooltip="Library is in selected list" matTooltipPosition="above" [matTooltipDisabled]="!this.selectedLib?.isInSelectedList"
+                >
+                  <mat-icon  (click)="addLibrary(lib)"  [ngClass]="{'not-allowed': !this.selectedLib || this.selectedLib?.isInSelectedList }">add</mat-icon>
+                </span>
+              </div>
+            </div>
+          </div>
+
+          <ng-template #javaGroup>
+            <div class="m-top-20">
+              <div class="control-group constol-select java-library-search">
+                <label class="label">Library</label>
+                <div class="control control-relative">
+                 <span class="other-message" *ngIf="lib.name.length && !this.selectedLib">groupId:artifactId:versionId</span>
+                 <input
+                    type="text" [placeholder]="'Enter library name in <groupId>:<artifactId>:<versionId> format'"
+                    [(ngModel)]="lib.name"
+                    [disabled]="!group"
+                    [matAutocomplete]="auto"
+                    [formControl]="libSearch"
+                    #trigger="matAutocompleteTrigger"
+                    (keyup.enter)="addLibrary(lib)"
+                  >
+                  <span
+                    class="plus-icon"
+                    [ngClass]="{'not-allow': !this.selectedLib || this.selectedLib?.isInSelectedList}"
+                    matTooltip="Library is in selected list" matTooltipPosition="above" [matTooltipDisabled]="!this.selectedLib?.isInSelectedList"
+                  >
+                  <mat-icon  (click)="addLibrary(lib)" (keyup.enter)="addLibrary(lib)" [ngClass]="{'not-allowed': !this.selectedLib || this.selectedLib?.isInSelectedList}">add</mat-icon>
+                </span>
+                </div>
+                <mat-autocomplete #auto="matAutocomplete" class="suggestions">
+                  <ng-template ngFor let-item [ngForOf]="filteredList" let-i="index" *ngIf="!selectedLib">
+                    <mat-option >
+                      <div class="option" (click)="selectLibrary(item);$event.stopPropagation()" [ngClass]="{'not-allow': item.isInSelectedList}">
+                        <a *ngIf="!item.isInSelectedList">
+                          <span [innerHTML]="item.name + ':' + item.version | highlight:query">
+                             <span>{{ item.version }}</span>
+                          </span>
+                        </a>
+                        <span *ngIf="item.isInSelectedList">{{ item.name }}
+                          <span *ngIf="item.version && item.version !== 'N/A'">{{ item.version }}</span>
+                      </span>
+                        <strong *ngIf="item.isInSelectedList">selected
+                          <i class="material-icons">done</i>
+                        </strong>
+                        <strong *ngIf="item.isInstalled && !item.isInSelectedList">installed
+                          <i class="material-icons">done</i>
+                        </strong>
+                      </div>
+                    </mat-option>
+                  </ng-template>
+                  <mat-option *ngIf="model.isEmpty(filteredList) && !validity_format">
+                    <span class="configuring">No matches found</span>
+                  </mat-option>
+                  <mat-option *ngIf="validity_format?.length > 0">
+                    <span class="configuring" >{{ validity_format }}</span >
+                  </mat-option>
+                </mat-autocomplete>
+              </div>
+            </div>
+          </ng-template>
+<!--          <p class="other-message">-->
+<!--            -->
+<!--          </p>-->
+          <div class="search">
+<!--            <mat-form-field class="chip-list">-->
+<!--              <input-->
+<!--                type="text"-->
+<!--                [placeholder]="group === 'java' ?-->
+<!--                'Enter library name in <groupId>:<artifactId>:<versionId> format' :-->
+<!--                'Enter library name in <name>:<version> format(version is not required)'"-->
+<!--                matInput-->
+<!--                #trigger="matAutocompleteTrigger"-->
+<!--                [formControl]="libSearch"-->
+<!--                [value]="query"-->
+<!--                [matAutocomplete]="auto"-->
+<!--              >-->
+<!--&lt;!&ndash;              <span class="add-icon" [matTooltip]="(isInSelectedList || isInstalled) ? 'Current library dosen\'t exist' : 'You have already added or installed current library'"&ndash;&gt;-->
+<!--&lt;!&ndash;              matTooltipPosition="above"&ndash;&gt;-->
+<!--&lt;!&ndash;              [matTooltipDisabled] = "isLibExist && (isInSelectedList || isInstalled)"&ndash;&gt;-->
+<!--              <span class="add-icon">-->
+<!--                <button  mat-icon-button class="btn" [disabled]="!isLibExist || query.length < 1 ||-->
+<!--                isDuplicated({name: query.slice(0, query.indexOf(':')), version: query.slice(query.indexOf(':') + 1) || 'N/A'})" (click)="addLibrary(query);$event.stopPropagation()">-->
+<!--                  <mat-icon matSuffix >add</mat-icon>-->
+<!--                </button>-->
+<!--              </span>-->
+
+<!--              <mat-autocomplete #auto="matAutocomplete" class="suggestions" >-->
+<!--                <ng-template ngFor let-item [ngForOf]="filteredList" let-i="index" *ngIf="query.indexOf(':') === -1">-->
+<!--                  <mat-option [ngClass]="{ 'not-allowed': isDuplicated(item) }">-->
+<!--                    <div class="option" (click)="selectLibrary(item)">-->
+<!--                      <a *ngIf="!isDuplicated(item)">-->
+<!--                        <span [innerHTML]="item.name | highlight:query"></span>-->
+<!--&lt;!&ndash;                        <span *ngIf="item.version && item.version !== 'N/A'">{{ item.version }}</span>&ndash;&gt;-->
+<!--                      </a>-->
+<!--                      <span *ngIf="isInSelectedList || isInstalled">{{ item.name }}-->
+<!--                        <span *ngIf="item.version && item.version !== 'N/A'">{{ item.version }}</span>-->
+<!--                      </span>-->
+
+<!--                      <strong *ngIf="isInSelectedList">selected-->
+<!--                        <i class="material-icons">done</i>-->
+<!--                      </strong>-->
+<!--                      <strong *ngIf="isInstalled">installed-->
+<!--                        <i class="material-icons">done</i>-->
+<!--                      </strong>-->
+<!--                    </div>-->
+<!--                  </mat-option>-->
+<!--                </ng-template>-->
+<!--                <mat-option *ngIf="model.isEmpty(filteredList) && !validity_format && query.indexOf(':') === -1">-->
+<!--                  <span class="configuring">No matches found</span>-->
+<!--                </mat-option>-->
+<!--                <mat-option *ngIf="validity_format?.length > 0">-->
+<!--                  <span class="configuring" *ngIf="query.indexOf(':') === -1">{{ validity_format }}</span >-->
+<!--                </mat-option>-->
+<!--              </mat-autocomplete>-->
+<!--            </mat-form-field>           -->
             <div class="list-selected list-container" id='scrolling'>
               <mat-chip-list *ngIf="model.selectedLibs.length && libs_uploaded">
                 <mat-chip *ngFor="let item of model.selectedLibs">
@@ -222,9 +332,11 @@
 <!--          </div>-->
           <ng-container *ngFor="let lib of filtredNotebookLibs">
             <mat-list-item class="table-item">
-            <div class="lib-name ellipsis">
-              <strong>{{ lib.name }}</strong>&nbsp;
-              <span *ngIf="lib.version  && lib.version !== 'N/A'">{{ lib.version }}</span>
+            <div class="lib-name lib-name-col ellipsis" >
+              <span [matTooltip]="lib.name + ' ' + lib.version" matTooltipPosition="above" class="lib-name-wrapper">
+                <span class="stong" >{{ lib.name }}</span>&nbsp;
+                <span *ngIf="lib.version  && lib.version !== 'N/A'">{{ lib.version }}</span>
+              </span>
             </div>
             <div class="lib-group-col">{{ groupsListMap[lib.group] }}</div>
             <div class="st-group">
@@ -232,8 +344,8 @@
                 <div class="wrap-col">
                   <div class="lib-destination-col">{{ item.resource }}</div>
                   <div class="lib-resource-type-col">{{ item.resourceType }}</div>
-                  <div class="lib-status-col" ngClass="{{ item.status.toLowerCase() || 'failed' }}">{{ item.status }}
-                    <div class="warn-action" *ngIf="(item.status === 'failed' || item.status === 'invalid version') && notebook?.status === 'running'">
+                  <div class="lib-status-col" ngClass="{{ item.status.toLowerCase() || 'failed' }}">{{ item.status.replace('_', ' ') }}
+                    <div class="warn-action" *ngIf="(item.status === 'failed' || item.status.toLowerCase() === 'invalid_version') && notebook?.status === 'running'">
                       <div *ngIf="!item.available_versions">
                         <span *ngIf="!installingInProgress" (click)="reinstallLibrary(item, lib)" matTooltip="Retry installation" matTooltipPosition="above">
                           <i class="material-icons">replay</i>
@@ -247,7 +359,7 @@
                         <i class="material-icons">error_outline</i>
                       </div>
                       <div class="lib-error"
-                           *ngIf="item.status === 'invalid version' && item.available_versions?.length" class="lib-error"
+                           *ngIf="item.status.toLowerCase() === 'invalid_version' && item.available_versions?.length" class="lib-error"
                            (click)="openLibInfo(item, 'available');$event.stopPropagation()"
                            matTooltip="Show available version" matTooltipPosition="above"
                       >
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.scss
index fd769f0..86cd434 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.scss
@@ -184,19 +184,28 @@ ul.resources{
       width: 50%;
       padding-bottom: 0;
 
-      .label {
-        width: 20%;
+      &.java-library-search{
+        width: 100%;
+
+        .label{
+          width: 10%;
+        }
+
+        .control{
+          width: 85%;
+        }
       }
-    }
 
-    .other-message{
-      height: 22px;
-      display: flex;
-      align-items: center;
+      .control{
+        width: 70%;
+
+        input{
+          font-size: 14px;
+        }
+      }
 
-      span{
-        font-size: 12px;
-        color: $link-color;
+      .label {
+        width: 20%;
       }
     }
 
@@ -205,6 +214,7 @@ ul.resources{
       padding-bottom: 0;
       flex-direction: column;
       box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .2), 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12);
+      margin-top: 25px;
 
       .mat-form-field-flex {
         padding-left: 15px;
@@ -214,9 +224,13 @@ ul.resources{
         width: 100%;
         overflow-y: auto;
 
-        .mat-form-field {
+
+        &.mat-form-field {
           width: 100%;
-          padding: 5px 20px;
+
+          .mat-form-field-infix{
+            display: flex;
+          }
         }
 
         .mat-input-flex {
@@ -283,7 +297,7 @@ ul.resources{
 }
 
 .list-selected {
-  padding: 0 5px;
+  padding: 10px;
   font-family: 'Open Sans', sans-serif;
   height: 130px;
   overflow-y: auto;
@@ -319,10 +333,6 @@ mat-chip.mat-chip:not(.mat-basic-chip) {
   line-height: 40px;
 }
 
-.list-header+div{
-  padding-left: 5px;
-}
-
 .mat-dialog-container {
   position: relative;
 }
@@ -351,18 +361,17 @@ mat-chip.mat-chip:not(.mat-basic-chip) {
       }
     }
   }
-  .lib-col{
-    padding-left: 4px;
-
-  }
   .lib-name {
     width: 27%;
-    &.lib-input{
 
+    &-col{
+      display: flex;
     }
 
     .lib-name-wrapper{
+      overflow: hidden;
       display: block;
+      text-overflow: ellipsis;
     }
 
     strong {
@@ -547,6 +556,32 @@ mat-chip.mat-chip:not(.mat-basic-chip) {
 .btn{
   line-height: 26px;
 }
+
+.control-relative{
+  position: relative;
+
+  .plus-icon {
+    position: absolute;
+    right: -40px;
+    top: 5px;
+    color: #35afd5;
+    font-size: 27px;
+    cursor: pointer;
+
+    &.not-allow {
+      color: lightgray;
+    }
+  }
+
+  .other-message{
+    position: absolute;
+    font-size: 12px;
+    color: $link-color;
+    top: 40px;
+    left: 12px;
+  }
+}
+
   @media screen and (min-width: 1281px) {
   .libs-info {
     height: 60%;
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.ts
index 2f22fb9..97e94f7 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.ts
@@ -18,7 +18,7 @@
  */
 
 
-import {Component, OnInit, ViewChild, ViewEncapsulation, ChangeDetectorRef, Inject, OnDestroy} from '@angular/core';
+import {Component, OnInit, ViewChild, ViewEncapsulation, ChangeDetectorRef, Inject, OnDestroy, AfterViewInit} from '@angular/core';
 import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
 import { FormControl } from '@angular/forms';
 import { ToastrService } from 'ngx-toastr';
@@ -45,7 +45,7 @@ export class InstallLibrariesComponent implements OnInit, OnDestroy {
 
   public model: InstallLibrariesModel;
   public notebook: any;
-  public filteredList: any;
+  public filteredList: any = [];
   public groupsList: Array<string>;
   public notebookLibs: Array<any> = [];
   public notebookFailedLibs: Array<any> = [];
@@ -57,7 +57,6 @@ export class InstallLibrariesComponent implements OnInit, OnDestroy {
   public uploading: boolean = false;
   public libs_uploaded: boolean = false;
   public validity_format: string = '';
-
   public isInstalled: boolean = false;
   public isInSelectedList: boolean = false;
   public installingInProgress: boolean = false;
@@ -84,6 +83,9 @@ export class InstallLibrariesComponent implements OnInit, OnDestroy {
   @ViewChild('trigger', { static: false }) matAutoComplete;
   public isLibInfoOpened = {  };
   private isLibExist: boolean;
+  public lib: Library = {name: '', version: ''};
+  public javaLib: {group, artifact, version} = {group: '', artifact: '', version: ''};
+  private selectedLib: any = null;
 
   constructor(
     @Inject(MAT_DIALOG_DATA) public data: any,
@@ -98,10 +100,13 @@ export class InstallLibrariesComponent implements OnInit, OnDestroy {
 
   ngOnInit() {
     this.open(this.data);
-    this.libSearch.valueChanges.pipe(
+    this.libSearch.disable();
+    this.libSearch.valueChanges
+      .pipe(
       debounceTime(1000))
       .subscribe(newValue => {
-        this.query = newValue || '';
+        this.query = newValue;
+        this.isDuplicated(this.lib);
         this.filterList();
       });
   }
@@ -145,7 +150,7 @@ export class InstallLibrariesComponent implements OnInit, OnDestroy {
 
   public filterList(): void {
     this.validity_format = '';
-    (this.query.length >= 2 && this.group) ? this.getFilteredList() : this.filteredList = null;
+    (this.query && this.query.length >= 2 && this.group && !this.selectedLib) ? this.getFilteredList() : this.filteredList = null;
   }
 
   public filterGroups(groupsList) {
@@ -159,6 +164,7 @@ export class InstallLibrariesComponent implements OnInit, OnDestroy {
 
   public onUpdate($event) {
     if ($event.model.type === 'group_lib') {
+      this.libSearch.enable();
       this.group = $event.model.value;
     } else if ($event.model.type === 'destination') {
       this.resetDialog();
@@ -168,6 +174,7 @@ export class InstallLibrariesComponent implements OnInit, OnDestroy {
         : this.model.computational_name = null;
       this.uploadLibGroups();
       this.getInstalledLibsByResource();
+      this.libSearch.disable();
     }
     this.filterList();
   }
@@ -177,37 +184,50 @@ export class InstallLibrariesComponent implements OnInit, OnDestroy {
   }
 
   public isDuplicated(item) {
-    const select = { group: this.group, name: item.name, version: item.version };
-
-    this.isInSelectedList = this.model.selectedLibs.filter(el => JSON.stringify(el) === JSON.stringify(select)).length > 0;
-
-    if (this.destination && this.destination.libs)
-      this.isInstalled = this.destination.libs.findIndex(libr => {
-        return select.group !== 'java'
-          ? select.name === libr.name && select.group === libr.group && select.version === libr.version
-          : select.name === libr.name && select.group === libr.group;
-      }) >= 0;
+    if (this.filteredList) {
+      if (this.group !== 'java') {
+        this.selectedLib = this.filteredList.find(lib => lib.name === item.name);
+      } else {
+        this.selectedLib = this.filteredList.find(lib => {
+          return lib.name === item.name.substring(0, item.name.lastIndexOf(':'));
+        });
+      }
+    } else {
+      this.selectedLib = null;
+    }
 
-    return this.isInSelectedList || this.isInstalled;
+    if (this.selectedLib) {
+      this.filteredList = null;
+    }
   }
 
   public addLibrary(item): void {
-    const lib = item.split(':').filter(v => !!v);
-    this.model.selectedLibs.push({ group: this.group, name: lib[0], version: lib[1] || 'N/A' });
-    this.query = '';
-    this.libSearch.setValue('');
-    this.filteredList = null;
+    if (this.selectedLib && !this.selectedLib.isInSelectedList) {
+      this.model.selectedLibs.push({ group: this.group, name: item.name, version: item.version || 'N/A' });
+      this.query = '';
+      this.libSearch.setValue('');
+      this.lib = {name: '', version: ''};
+      this.filteredList = null;
+    }
   }
 
   public selectLibrary(item): void {
-    // this.model.selectedLibs.push({ group: this.group, name: item.name, version: item.version });
-    // this.query = '';
-    this.libSearch.setValue(item.name + ':');
-    this.filteredList = null;
+    if (item.isInSelectedList) {
+      return;
+    }
+    if (this.group === 'java') {
+      this.libSearch.setValue(item.name + ':' + item.version);
+      this.lib.name = item.name + ':' + item.version;
+    } else {
+      this.libSearch.setValue(item.name);
+      this.lib.name = item.name;
+    }
+    this.matAutoComplete.closePanel();
   }
 
   public removeSelectedLibrary(item): void {
     this.model.selectedLibs.splice(this.model.selectedLibs.indexOf(item), 1);
+    this.getMatchedLibs();
   }
 
   public open(notebook): void {
@@ -237,7 +257,7 @@ export class InstallLibrariesComponent implements OnInit, OnDestroy {
   public isInstallingInProgress(): void {
     this.installingInProgress = this.notebookLibs.some(lib => lib.filteredStatus.some(status => status.status === 'installing'));
       if (this.installingInProgress) {
-        clearTimeout(this.loadLibsTimer);
+        window.clearTimeout(this.loadLibsTimer);
         this.loadLibsTimer = window.setTimeout(() => this.getInstalledLibrariesList(), 10000);
       }
     }
@@ -306,7 +326,20 @@ export class InstallLibrariesComponent implements OnInit, OnDestroy {
     if (this.group === 'java') {
       this.model.getDependencies(this.query)
         .subscribe(
-          lib => this.filteredList = [lib],
+          libs => {
+            this.filteredList = [libs];
+            this.filteredList.forEach(lib => {
+              lib.isInSelectedList = this.model.selectedLibs.some(el => lib.name === el.name.substring(0, el.name.lastIndexOf(':')));
+              lib.isInstalled = this.notebookLibs.some(libr => {
+              // && lib.version === item.name.substring(item.name.lastIndexOf(':') + 1
+                return  lib.name === libr.name.substring(0, libr.name.lastIndexOf(':')) &&
+                this.group === libr.group &&
+                libr.status.some(res => res.resource === this.destination.name);
+              }
+             );
+            });
+            this.isDuplicated(this.lib);
+          },
           error => {
             if (error.status === HTTP_STATUS_CODES.NOT_FOUND
               || error.status === HTTP_STATUS_CODES.BAD_REQUEST
@@ -316,12 +349,23 @@ export class InstallLibrariesComponent implements OnInit, OnDestroy {
             }
           });
     } else {
+       this.getMatchedLibs();
+    }
+  }
+
+  private getMatchedLibs() {
+    if (this.query.length > 1) {
       this.model.getLibrariesList(this.group, this.query)
         .subscribe((libs: Library[]) => {
-          console.log('libs', libs);
-          console.log(this.query.slice(0, this.query.indexOf(':')));
-          this.isLibExist = libs.some(v => v.name === this.query.slice(0, this.query.indexOf(':')));
+          this.isLibExist = libs.some(v => v.name === this.query);
           this.filteredList = libs;
+          this.filteredList.forEach(lib => {
+            lib.isInSelectedList = this.model.selectedLibs.some(el => el.name === lib.name);
+            lib.isInstalled = this.notebookLibs.some(libr => lib.name === libr.name &&
+              this.group === libr.group &&
+              libr.status.some(res => res.resource === this.destination.name));
+          });
+          this.isDuplicated(this.lib);
         });
     }
   }
@@ -340,7 +384,7 @@ export class InstallLibrariesComponent implements OnInit, OnDestroy {
     this.isInSelectedList = false;
     this.uploading = false;
     this.model.selectedLibs = [];
-    this.filteredList = null;
+    this.filteredList = [];
     this.groupsList = [];
 
     clearTimeout(this.clear);
@@ -417,7 +461,7 @@ export class ErrorLibMessageDialogComponent {
   template: `
   <div class="dialog-header">
     <h4 class="modal-title" *ngIf="data.type === 'added'">Installed dependency</h4>
-    <h4 class="modal-title" *ngIf="data.type === 'available'">Library installation error</h4>
+    <h4 class="modal-title" *ngIf="data.type === 'available'">Version is not available</h4>
     <button type="button" class="close" (click)="dialogRef.close()">&times;</button>
   </div>
 <!--  <mat-list class="resources">-->
@@ -440,54 +484,16 @@ export class ErrorLibMessageDialogComponent {
 <!--  </mat-list>-->
 
   <div class="lib-list" *ngIf="data.type === 'added'">
-    <span class="strong">Dependency: </span>{{data.lib.add_pkgs.join(', ')}}
+    <span class="strong dependency-title">Dependency: </span><span class="packeges" *ngFor="let pack of data.lib.add_pkgs">{{pack+', '}}</span>
   </div>
   <div class="lib-list" *ngIf="data.type === 'available'">
-    <p class="terminated">Version is not available</p>
     <span class="strong">Available versions: </span>{{data.lib.available_versions.join(', ')}}
   </div>
-<!--  <div class="text-center">-->
-<!--    <button type="button" class="butt" mat-raised-button (click)="dialogRef.close()">Close</button>-->
-<!--  </div>-->
   `,
   styles: [    `
     .lib-list { max-height: 200px; overflow-x: auto; word-break: break-all; padding: 20px 30px !important; margin: 20px 0; color: #577289;}
-    .terminated{padding-bottom: 15px;}
-
-    .mat-list-base {
-      padding: 40px 30px;
-    }
-
-    .object {
-      width: 70%;
-      display: flex;
-      align-items: center;
-      padding-right: 10px;
-    }
-
-    .size {
-      width: 30%;
-    }
-    .scrolling-content.delete-list {
-      max-height: 200px;
-      overflow-y: auto;
-      padding-top: 11px;
-    }
-
-    .empty-list {
-      display: flex;
-      width: 100%;
-      justify-content: center;
-      color: #35afd5;
-      padding: 15px;
-    }
-
-    .list-header {
-      border-top: 1px solid #edf1f5;
-      border-bottom: 1px solid #edf1f5;
-      color: #577289;
-      width: 100%;
-    }
+    .packeges { padding-left: 7px; line-height: 23px;}
+    .dependency-title{ line-height: 23px; }
   `
   ]
 })
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 cc18983..459f495 100644
--- a/services/self-service/src/main/resources/webapp/src/styles.scss
+++ b/services/self-service/src/main/resources/webapp/src/styles.scss
@@ -140,7 +140,8 @@ mat-chip.mat-chip strong {
 .terminating,
 .failed,
 .deleting,
-.deleted {
+.deleted,
+.invalid_version{
   color: #f1696e;
 }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@dlab.apache.org
For additional commands, e-mail: commits-help@dlab.apache.org