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 2019/12/27 12:14:49 UTC

[incubator-dlab] branch develop updated: [DLAB-1390] Added Endpoint Status on project page (#511)

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 8421369  [DLAB-1390] Added Endpoint Status on project page (#511)
8421369 is described below

commit 84213692e79e8ca015af86847e36a5c3c35294e9
Author: Dmytro Gnatyshyn <42...@users.noreply.github.com>
AuthorDate: Fri Dec 27 14:14:42 2019 +0200

    [DLAB-1390] Added Endpoint Status on project page (#511)
    
    [DLAB-1390, DLAB-1391]: Added Endpoint Status on project page and all actions collect in action menu for every project
---
 .../dlab/backendapi/resources/ProjectResource.java | 16 ++---
 .../resources/dto/ProjectActionFormDTO.java        |  7 +-
 .../dlab/backendapi/service/ProjectService.java    |  6 ++
 .../service/impl/ProjectServiceImpl.java           | 15 +++++
 .../webapp/src/app/administration/project/index.ts |  6 +-
 .../project-list/project-list.component.html       | 76 ++++++++++++++--------
 .../project-list/project-list.component.scss       | 60 +++++++++++++++--
 .../project/project-list/project-list.component.ts | 53 +++++++++++++--
 .../administration/project/project.component.ts    | 17 +----
 .../src/app/core/services/endpoint.service.ts      |  5 +-
 .../detail-dialog/detail-dialog.component.html     |  2 +-
 .../install-libraries.component.html               |  2 +-
 .../install-libraries.component.scss               |  6 +-
 .../src/app/shared/bubble/bubble.component.css     |  2 +-
 .../webapp/src/app/shared/material.module.ts       |  1 -
 .../edge-action-dialog.component.ts                | 72 ++++++++++++++++++++
 .../edge-action-dialog}/index.ts                   | 27 +++-----
 .../webapp/src/app/shared/navbar/index.ts          |  4 +-
 18 files changed, 286 insertions(+), 91 deletions(-)

diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java
index 966a4aa..a93224c 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java
@@ -19,6 +19,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses;
 
 import javax.annotation.security.RolesAllowed;
 import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
 import javax.ws.rs.*;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
@@ -83,8 +84,8 @@ public class ProjectResource {
 	@Consumes(MediaType.APPLICATION_JSON)
 	@RolesAllowed("/api/project")
 	public Response startProject(@Parameter(hidden = true) @Auth UserInfo userInfo,
-								 @Valid ProjectActionFormDTO startProjectDto) {
-		projectService.start(userInfo, startProjectDto.getEndpoint(), startProjectDto.getProjectName());
+								 @NotNull @Valid ProjectActionFormDTO startProjectDto) {
+		projectService.start(userInfo, startProjectDto.getEndpoints(), startProjectDto.getProjectName());
 		return Response
 				.accepted()
 				.build();
@@ -102,8 +103,8 @@ public class ProjectResource {
 	@Consumes(MediaType.APPLICATION_JSON)
 	@RolesAllowed("/api/project")
 	public Response stopProject(@Parameter(hidden = true) @Auth UserInfo userInfo,
-								@Valid ProjectActionFormDTO stopProjectDTO) {
-		projectService.stop(userInfo, stopProjectDTO.getEndpoint(), stopProjectDTO.getProjectName());
+								@NotNull @Valid ProjectActionFormDTO stopProjectDTO) {
+		projectService.stop(userInfo, stopProjectDTO.getEndpoints(), stopProjectDTO.getProjectName());
 		return Response
 				.accepted()
 				.build();
@@ -227,10 +228,9 @@ public class ProjectResource {
 	@POST
 	@Path("terminate")
 	@RolesAllowed("/api/project")
-	public Response removeProjectEndpoint(
-			@Parameter(hidden = true) @Auth UserInfo userInfo,
-			ProjectActionFormDTO projectActionDTO) {
-		projectService.terminateEndpoint(userInfo, projectActionDTO.getEndpoint(), projectActionDTO.getProjectName());
+	public Response removeProjectEndpoint(@Parameter(hidden = true) @Auth UserInfo userInfo,
+										  @NotNull @Valid ProjectActionFormDTO projectActionDTO) {
+		projectService.terminateEndpoint(userInfo, projectActionDTO.getEndpoints(), projectActionDTO.getProjectName());
 		return Response.ok().build();
 	}
 
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/ProjectActionFormDTO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/ProjectActionFormDTO.java
index e82f8f6..24d8342 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/ProjectActionFormDTO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/ProjectActionFormDTO.java
@@ -3,10 +3,15 @@ package com.epam.dlab.backendapi.resources.dto;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import lombok.Data;
 
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
 @Data
 public class ProjectActionFormDTO {
+	@NotNull
 	@JsonProperty("project_name")
 	private final String projectName;
+	@NotNull
 	@JsonProperty("endpoint")
-	private final String endpoint;
+	private final List<String> endpoints;
 }
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java
index e01280c..738fbdb 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java
@@ -24,12 +24,18 @@ public interface ProjectService {
 
 	void terminateEndpoint(UserInfo userInfo, String endpoint, String name);
 
+	void terminateEndpoint(UserInfo userInfo, List<String> endpoints, String name);
+
 	void terminateProject(UserInfo userInfo, String name);
 
 	void start(UserInfo userInfo, String endpoint, String name);
 
+	void start(UserInfo userInfo, List<String> endpoints, String name);
+
 	void stop(UserInfo userInfo, String endpoint, String name);
 
+	void stop(UserInfo userInfo, List<String> endpoints, String name);
+
 	void stopWithResources(UserInfo userInfo, String projectName);
 
 	void update(UserInfo userInfo, UpdateProjectDTO projectDTO);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java
index 5697d2e..bdafb26 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java
@@ -125,6 +125,11 @@ public class ProjectServiceImpl implements ProjectService {
 	}
 
 	@Override
+	public void terminateEndpoint(UserInfo userInfo, List<String> endpoints, String name) {
+		endpoints.forEach(endpoint -> terminateEndpoint(userInfo, endpoint, name));
+	}
+
+	@Override
 	public void terminateProject(UserInfo userInfo, String name) {
 		List<ProjectEndpointDTO> endpoints = get(name).getEndpoints();
 		checkProjectRelatedResourcesInProgress(name, endpoints, TERMINATE_ACTION);
@@ -142,12 +147,22 @@ public class ProjectServiceImpl implements ProjectService {
 	}
 
 	@Override
+	public void start(UserInfo userInfo, List<String> endpoints, String name) {
+		endpoints.forEach(endpoint -> start(userInfo, endpoint, name));
+	}
+
+	@Override
 	public void stop(UserInfo userInfo, String endpoint, String name) {
 		projectActionOnCloud(userInfo, name, STOP_PRJ_API, endpoint);
 		projectDAO.updateEdgeStatus(name, endpoint, UserInstanceStatus.STOPPING);
 	}
 
 	@Override
+	public void stop(UserInfo userInfo, List<String> endpoints, String name) {
+		endpoints.forEach(endpoint -> stop(userInfo, endpoint, name));
+	}
+
+	@Override
 	public void stopWithResources(UserInfo userInfo, String projectName) {
 		List<ProjectEndpointDTO> endpoints = get(projectName).getEndpoints();
 		checkProjectRelatedResourcesInProgress(projectName, endpoints, STOP_ACTION);
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/project/index.ts b/services/self-service/src/main/resources/webapp/src/app/administration/project/index.ts
index f03b47e..609ea59 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/project/index.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/project/index.ts
@@ -30,6 +30,7 @@ import { ProjectListComponent } from './project-list/project-list.component';
 
 import { ProjectComponent, EditProjectComponent } from './project.component';
 import { ProjectDataService } from './project-data.service';
+import {BubbleModule} from "../../shared/bubble";
 
 @NgModule({
   imports: [
@@ -38,11 +39,12 @@ import { ProjectDataService } from './project-data.service';
     ReactiveFormsModule,
     MaterialModule,
     FormControlsModule,
-    UnderscorelessPipeModule
+    UnderscorelessPipeModule,
+    BubbleModule
   ],
   declarations: [ProjectComponent, EditProjectComponent, ProjectFormComponent, ProjectListComponent],
   entryComponents: [EditProjectComponent],
   providers: [ProjectDataService],
   exports: [ProjectComponent]
 })
-export class ProjectModule { }
\ No newline at end of file
+export class ProjectModule { }
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/project/project-list/project-list.component.html b/services/self-service/src/main/resources/webapp/src/app/administration/project/project-list/project-list.component.html
index de8741a..06246d4 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/project/project-list/project-list.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/project/project-list/project-list.component.html
@@ -35,6 +35,7 @@
   <ng-container matColumnDef="endpoints">
     <th mat-header-cell *matHeaderCellDef class="endpoints">
       <span class="label-endpoint"> Endpoint </span>
+      <span class="label-endpoint-status"> Endpoint status </span>
       <span class="label-status"> Edge node status </span>
     </th>
     <td mat-cell *matCellDef="let element" class="source endpoints">
@@ -48,24 +49,14 @@
               {{ endpoint.name }}
             </a>
           </div>
+          <div class="resource-status">
+            <span [ngClass]="{'active' : endpoint.endpointStatus === 'ACTIVE', 'failed': endpoint.endpointStatus === 'INACTIVE'}">
+              {{ endpoint.endpointStatus | titlecase }}
+            </span>
+          </div>
+
           <span class="status resource-status"
             ngClass="{{endpoint.status.toLowerCase() || ''}}">{{ endpoint.status.toLowerCase() }}</span>
-          <div class="resource-actions">
-            <a class="start-stop-action">
-              <i class="material-icons" (click)="toggleEndpointAction(element, 'stop', endpoint)"
-                *ngIf="endpoint.status === 'RUNNING' || endpoint.status === 'STOPPING'"
-                [ngClass]="{'not-active' : endpoint.status === 'STOPPING'}">pause_circle_outline</i>
-            </a>
-            <a class="start-stop-action">
-              <i class="material-icons" (click)="toggleEndpointAction(element, 'start', endpoint)"
-                *ngIf="endpoint.status === 'STOPPED'">play_circle_outline</i>
-            </a>
-
-            <a class="remove_butt" (click)="toggleEndpointAction(element, 'terminate', endpoint)"
-              [ngClass]="{ 'disabled' : endpoint.status !== 'RUNNING' && endpoint.status !== 'STOPPED' }">
-              <i class="material-icons">highlight_off</i>
-            </a>
-          </div>
         </div>
       </ng-template>
     </td>
@@ -73,18 +64,47 @@
 
   <ng-container matColumnDef="actions">
     <th mat-header-cell *matHeaderCellDef class="project-actions"></th>
-    <td mat-cell *matCellDef="let element" class="project-actions">
-      <span>
-        <a (click)="editProject(element)">
-          <mat-icon>mode_edit</mat-icon>
-        </a>
-      </span>
-      <span>
-        <a (click)="deleteProject(element)" class="action"
-          [ngClass]="{'not-allowed' : isInProgress(element) || !isActiveEndpoint(element) }">
-          <mat-icon>delete_forever</mat-icon>
-        </a>
-      </span>
+    <td mat-cell *matCellDef="let element" class="settings">
+      <span #settings (click)="actions.toggle($event, settings)" class="actions"></span>
+      <bubble-up #actions class="list-menu" position="bottom-left" alternative="top-left">
+        <ul class="list-unstyled">
+          <div class="active-items"></div>
+          <li class="project-seting-item" *ngIf="areStoppedEndpoints(element)">
+            <i class="material-icons">play_circle_outline</i>
+            <a class="action" (click)="openEdgeDialog('start', element)">
+              Start edge node
+            </a>
+          </li>
+          <li class="project-seting-item" *ngIf="areStartedEndpoints(element)">
+            <i class="material-icons">pause_circle_outline</i>
+            <a class="action" (click)="openEdgeDialog('stop', element )">
+              Stop edge node
+            </a>
+          </li>
+          <li class="project-seting-item " *ngIf="areStoppedEndpoints(element) || areStartedEndpoints(element)">
+            <i class="material-icons">highlight_off</i>
+            <a class="action" (click)="openEdgeDialog('terminate', element)">
+              Terminate edge node
+            </a>
+          </li>
+          <li class="project-seting-item">
+            <i class="material-icons">mode_edit</i>
+            <a (click)="editProject(element)">
+              Edit {{element.name }}
+            </a>
+          </li>
+          <li class="project-seting-item" *ngIf="!isInProgress(element) && isActiveEndpoint(element)">
+            <i class="material-icons">delete_forever</i>
+            <a (click)="deleteProject(element)" class="action"
+               [ngClass]="{'not-allowed' : isInProgress(element) || !isActiveEndpoint(element) }">
+              Delete {{element.name }}
+            </a>
+          </li>
+        </ul>
+      </bubble-up>
+    </td>
+    <td class="settings">
+
     </td>
 
   </ng-container>
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/project/project-list/project-list.component.scss b/services/self-service/src/main/resources/webapp/src/app/administration/project/project-list/project-list.component.scss
index c37e628..a877e95 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/project/project-list/project-list.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/project/project-list/project-list.component.scss
@@ -30,26 +30,33 @@ table {
   }
 
   .endpoints {
-    width: 25%;
+    width: 45%;
     padding: 15px 0;
 
     .resource-wrap {
       .resource-name {
-        width: 50%;
+        width: 30%;
+        padding-left: 0;
+      }
+      resource-name, resource-status{
+        width: 30%;
         padding-left: 0;
       }
     }
 
-    .label-endpoint {
+    .label-endpoint, .label-endpoint-status {
       display: inline-block;
-      width: 50%;
+      width: 30%;
     }
 
     .label-status {
-      padding-left: 5px;
+      width: 30%;
     }
 
     &.source {
+      &.endpoints .resource-wrap{
+        justify-content: flex-start;
+      }
       .no-details {
         padding-left: 0;
       }
@@ -57,7 +64,7 @@ table {
   }
 
   .groups {
-    width: 25%;
+    width: 20%;
     padding: 10px 0;
   }
 
@@ -87,3 +94,44 @@ table {
     }
   }
 }
+
+td.settings {
+  position: relative;
+  vertical-align: middle !important;
+  text-align: right;
+  .actions {
+    background-image: url(../../../../assets/svg/settings_icon.svg);
+    width: 16px;
+    height: 16px;
+    display: inline-block;
+    text-align: center;
+    cursor: pointer;
+  }
+}
+.project-seting-item{
+  display: flex;
+  padding: 10px;
+  align-items: center;
+  border-bottom: 1px solid #edf1f5;
+  cursor: pointer;
+  color: #577289;
+  &:hover{
+    color: #36afd5;
+    transition: all .45s ease-in-out;
+  }
+  a{
+    padding-left: 5px;
+  }
+}
+.material-icons {
+  font-size: 18px;
+  padding-top: 1px;
+}
+
+.list-menu{
+  min-width: 190px;
+}
+
+
+
+
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/project/project-list/project-list.component.ts b/services/self-service/src/main/resources/webapp/src/app/administration/project/project-list/project-list.component.ts
index 1e2d3a8..5256d77 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/project/project-list/project-list.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/project/project-list/project-list.component.ts
@@ -17,15 +17,18 @@
  * under the License.
  */
 
-import { Component, OnInit, Output, EventEmitter, OnDestroy } from '@angular/core';
+import {Component, OnInit, Output, EventEmitter, OnDestroy, Inject} from '@angular/core';
 import { ToastrService } from 'ngx-toastr';
 import { MatTableDataSource } from '@angular/material/table';
 import { Subscription } from 'rxjs';
+import { MatDialogRef, MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog';
 
 import { ProjectDataService } from '../project-data.service';
 import { Project, Endpoint } from '../project.component';
 import { CheckUtils } from '../../../core/util';
 import {ProgressBarService} from "../../../core/services/progress-bar.service";
+import {EdgeActionDialogComponent} from "../../../shared/modal-dialog/edge-action-dialog";
+import {EndpointService} from "../../../core/services";
 
 @Component({
   selector: 'project-list',
@@ -41,14 +44,18 @@ export class ProjectListComponent implements OnInit, OnDestroy {
   @Output() editItem: EventEmitter<{}> = new EventEmitter();
   @Output() deleteItem: EventEmitter<{}> = new EventEmitter();
   @Output() toggleStatus: EventEmitter<{}> = new EventEmitter();
-
   private subscriptions: Subscription = new Subscription();
 
   constructor(
     public toastr: ToastrService,
     private projectDataService: ProjectDataService,
     private progressBarService: ProgressBarService,
-  ) { }
+    private endpointService: EndpointService,
+    @Inject(MAT_DIALOG_DATA) public data: any,
+    public dialogRef: MatDialogRef<ProjectListComponent>,
+    public dialog: MatDialog,
+  ) {
+  }
 
 
   ngOnInit() {
@@ -63,6 +70,13 @@ export class ProjectListComponent implements OnInit, OnDestroy {
     setTimeout(() => {this.progressBarService.startProgressBar()} , 0);
     this.subscriptions.add(this.projectDataService._projects.subscribe((value: Project[]) => {
       this.projectList = value;
+      this.endpointService.getEndpointsData().subscribe((endpoints: any) => {
+        if(this.projectList){
+          this.projectList.forEach(project => project.endpoints.forEach(endpoint => {
+            endpoint.endpointStatus = endpoints.filter(v => v.name === endpoint.name)[0].status;
+          }))
+        }
+       });
       if (value) this.dataSource = new MatTableDataSource(value);
       this.progressBarService.stopProgressBar();
     }, () => this.progressBarService.stopProgressBar()));
@@ -70,7 +84,7 @@ export class ProjectListComponent implements OnInit, OnDestroy {
 
   public showActiveInstances(): void {
     const filteredList = this.projectList.map(project => {
-      project.endpoints = project.endpoints.filter((endpoint: Endpoint) => endpoint.status !== 'TERMINATED' && endpoint.status !== 'TERMINATING' && endpoint.status !== 'FAILED')
+      project.endpoints = project.endpoints.filter((endpoint: Endpoint) => endpoint.status !== 'TERMINATED' && endpoint.status !== 'TERMINATING' && endpoint.status !== 'FAILED');
       return project;
     });
 
@@ -78,7 +92,7 @@ export class ProjectListComponent implements OnInit, OnDestroy {
   }
 
   public toggleEndpointAction(project, action, endpoint) {
-    this.toggleStatus.emit({ project, endpoint, action });
+    this.toggleStatus.emit({project, endpoint, action});
   }
 
   public editProject(item: Project[]) {
@@ -102,4 +116,33 @@ export class ProjectListComponent implements OnInit, OnDestroy {
   public toEndpointStatus(status) {
     return CheckUtils.endpointStatus[status] || status;
   }
+
+  public openEdgeDialog(action, project) {
+      const endpoints = project.endpoints.filter(endpoint => {
+        if(action === "stop"){
+          return endpoint.status == 'RUNNING'
+        }
+        if(action === "start"){
+          return endpoint.status == 'STOPPED'
+        }
+        if(action === "terminate"){
+          return endpoint.status == 'RUNNING' || endpoint.status == 'STOPPED'
+        }
+      });
+      this.dialog.open(EdgeActionDialogComponent, {data: {type: action, item: endpoints}, panelClass: 'modal-sm'})
+        .afterClosed().subscribe(endpoint => {
+        if(endpoint && endpoint.length){
+        this.toggleStatus.emit({project, endpoint, action});
+        }
+      }, error => this.toastr.error(error.message || `Endpoint ${action} failed!`, 'Oops!')
+      );
+    }
+
+  public areStartedEndpoints(project) {
+    return project.endpoints.filter(endpoint => endpoint.status == 'RUNNING').length > 0;
+  }
+
+  public areStoppedEndpoints(project) {
+    return project.endpoints.filter(endpoint => endpoint.status == 'STOPPED').length > 0;
+  }
 }
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/project/project.component.ts b/services/self-service/src/main/resources/webapp/src/app/administration/project/project.component.ts
index da7c986..382cd17 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/project/project.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/project/project.component.ts
@@ -35,7 +35,7 @@ export interface Endpoint {
 
 export interface Project {
   name: string;
-  endpoints: Endpoint[];
+  endpoints: any;
   tag: string;
   groups: string[];
   shared_image_enabled?: boolean;
@@ -114,21 +114,8 @@ export class ProjectComponent implements OnInit, OnDestroy {
   }
 
   public toggleStatus($event) {
-    const data = { 'project_name': $event.project.name, endpoint: $event.endpoint.name };
-    if ($event.action === 'stop' || $event.action === 'terminate') {
-      this.dialog.open(NotificationDialogComponent, {
-        data: {
-          type: 'confirmation',
-          template: `Edge node in endpoint <span class="strong">${$event.endpoint.name}</span> will be ${$event.action === 'stop' ? 'stopped' : 'terminated'} for <span class="strong">${$event.project.name}</span>`,
-          item: $event.endpoint, action: $event.action === 'stop' ? 'stopped' : 'terminated'
-        }, panelClass: 'modal-sm'
-      })
-        .afterClosed().subscribe(result => {
-          result && this.toggleStatusRequest(data, $event.action);
-        }, error => this.toastr.error(error.message, 'Oops!'));
-    } else {
+    const data = { 'project_name': $event.project.name, endpoint: $event.endpoint.map(endpoint => endpoint.name)};
       this.toggleStatusRequest(data, $event.action);
-    }
   }
 
   private toggleStatusRequest(data, action) {
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/services/endpoint.service.ts b/services/self-service/src/main/resources/webapp/src/app/core/services/endpoint.service.ts
index aa94418..2abe823 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/services/endpoint.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/services/endpoint.service.ts
@@ -35,7 +35,10 @@ export class EndpointService {
     return this.applicationServiceFacade
       .buildGetEndpointsData()
       .pipe(
-        map(response => response),
+        map(response => {
+          console.log(response);
+          return response
+        }),
         catchError(ErrorUtils.handleServiceError));
   }
 
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 2aaa4b5..22802ae 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
@@ -121,7 +121,7 @@
           </ng-template>
           <div [scrollTo]="configuration?.nativeElement['checked'] || false" class="text-center m-top-20 m-bott-10"
             *ngIf="(configuration?.nativeElement['checked'] || false) && notebook.status === 'running'">
-            <button mat-raised-button type="button" (click)="bindDialog.close()" class="butt action">Cancel</button>
+            <button mat-raised-button type="button" (click)="dialogRef.close()" class="butt action">Cancel</button>
             <button mat-raised-button type="submit" [disabled]="!configurationForm.valid"
               class="butt butt-success action" [ngClass]="{'not-allowed': !configurationForm.valid}"
               (click)="editClusterConfiguration(configurationForm.value)">Update</button>
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 29101a2..2948e4a 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
@@ -179,7 +179,7 @@
           </th>
            <ng-container matColumnDef="action-filter" stickyEnd>
              <th mat-header-cell>
-               <div class="actions">
+               <div class="filter-actions">
                  <button mat-icon-button class="btn reset" (click)="resetFilterConfigurations()">
                    <i class="material-icons">close</i>
                  </button>
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 3559e9d..bc55374 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
@@ -380,7 +380,8 @@ mat-chip.mat-chip:not(.mat-basic-chip) {
     padding: 0;
     border: none;
   }
-  .actions {
+
+  .filter-actions {
     display: flex;
 
     .btn {
@@ -405,8 +406,9 @@ mat-chip.mat-chip:not(.mat-basic-chip) {
   }
 }
 
-.filter-row .actions {
+.filter-row .filter-actions {
   margin-left: 6px;
+
   .reset{
       &:hover {
       border-color: #f1696e;
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/bubble/bubble.component.css b/services/self-service/src/main/resources/webapp/src/app/shared/bubble/bubble.component.css
index 90c88aa..331f715 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/bubble/bubble.component.css
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/bubble/bubble.component.css
@@ -18,7 +18,7 @@
  */
 
 .bubble-up {
-  width: 100%;  
+  width: 100%;
   background: #fff;
   border: none;
   display: none;
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/material.module.ts b/services/self-service/src/main/resources/webapp/src/app/shared/material.module.ts
index ef81fe5..44f2ca3 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/material.module.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/material.module.ts
@@ -51,7 +51,6 @@ import { MatTableModule } from '@angular/material/table';
 import { MatTabsModule } from '@angular/material/tabs';
 import { MatToolbarModule } from '@angular/material/toolbar';
 import { MatTooltipModule } from '@angular/material/tooltip';
-import { DateAdapter } from '@angular/material/core';
 
 @NgModule({
   exports: [
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/edge-action-dialog/edge-action-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/edge-action-dialog/edge-action-dialog.component.ts
new file mode 100644
index 0000000..0152c3d
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/edge-action-dialog/edge-action-dialog.component.ts
@@ -0,0 +1,72 @@
+import { Component, Inject } from '@angular/core';
+import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
+
+
+@Component({
+  selector: 'edge-action-dialog',
+  template: `
+  <div id="dialog-box">
+    <header class="dialog-header">
+      <h4 class="modal-title"><span class="action">{{data.type | titlecase}}</span> endpoints</h4>
+      <button type="button" class="close" (click)="dialogRef.close()">&times;</button>
+    </header>
+      <div mat-dialog-content class="content message">
+          <h3 class="strong">Select the items you want to {{data.type}}</h3>
+          <ul class="endpoint-list scrolling-content">
+              <li *ngFor="let endpoint of data.item" class="endpoint-list-item">
+                  <label class="strong">
+                      <input type="checkbox" [(ngModel)]="endpoint.checked" (change)="endpointAction()">
+                      {{endpoint.name}}
+                  </label>
+              </li>
+          </ul>
+      </div>
+      <p class="m-top-20 action-text"><span class="strong">Do you want to proceed?</span></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)="dialogRef.close(endpointsNewStatus)">Yes</button>
+      </div>
+  </div>
+  `,
+  styles: [`
+    .content { color: #718ba6; padding: 20px 50px; font-size: 14px; font-weight: 400; margin: 0; }
+    .info { color: #35afd5; }
+    .info .confirm-dialog { color: #607D8B; }
+    header { display: flex; justify-content: space-between; color: #607D8B; }
+    header h4 i { vertical-align: bottom; }
+    header a i { font-size: 20px; }
+    header a:hover i { color: #35afd5; cursor: pointer; }
+    .endpoint-list{text-align: left; margin-top: 30px}
+    .endpoint-list-item{padding: 5px 0}
+    .action{text-transform: capitalize}
+    .action-text { text-align: center; }
+    .label-name { display: inline-block; width: 100% }
+    .scrolling-content{overflow-y: auto; max-height: 200px; }
+    .endpoint { width: 70%; text-align: left; color: #577289;}
+    .status { width: 30%;text-align: right;}
+    label { font-size: 15px; font-weight: 500; font-family: "Open Sans",sans-serif; cursor: pointer; display: flex; align-items: center;}
+    label input {margin-top: 2px; margin-right: 5px;}
+
+    .node { font-weight: 300;}
+    .label-name { display: inline-block; width: 100%}
+    .scrolling-content{overflow-y: auto; max-height: 200px;}
+    .endpoint { width: 280px;text-align: left;}
+    .status { text-align: left;}
+  `]
+})
+
+export class EdgeActionDialogComponent {
+  public endpointsNewStatus: Array<object>;
+  constructor(
+    public dialogRef: MatDialogRef<EdgeActionDialogComponent>,
+    @Inject(MAT_DIALOG_DATA) public data: any) {
+  }
+
+  ngOnInit() {
+  }
+
+  public endpointAction() {
+    this.endpointsNewStatus = this.data.item.filter(endpoint => endpoint.checked);
+  }
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/index.ts b/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/edge-action-dialog/index.ts
similarity index 60%
copy from services/self-service/src/main/resources/webapp/src/app/shared/navbar/index.ts
copy to services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/edge-action-dialog/index.ts
index c5f19a4..fd6e98a 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/index.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/edge-action-dialog/index.ts
@@ -19,25 +19,16 @@
 
 import { NgModule } from '@angular/core';
 import { CommonModule } from '@angular/common';
-import { RouterModule } from '@angular/router';
-import { MaterialModule } from '../material.module';
-import { ProgressDialogModule, BubbleModule } from '../index';
+import { EdgeActionDialogComponent } from './edge-action-dialog.component';
+import { MaterialModule } from '../../material.module';
+import {FormsModule} from "@angular/forms";
 
-import { NavbarComponent } from './navbar.component';
-import { NotificationDialogModule } from '../modal-dialog/notification-dialog';
-
-export * from './navbar.component';
+export * from './edge-action-dialog.component';
 
 @NgModule({
-  imports: [
-    CommonModule,
-    RouterModule,
-    MaterialModule,
-    NotificationDialogModule,
-    ProgressDialogModule,
-    BubbleModule
-  ],
-  declarations: [NavbarComponent],
-  exports: [NavbarComponent, RouterModule]
+  imports: [CommonModule, MaterialModule, FormsModule],
+  declarations: [EdgeActionDialogComponent],
+  entryComponents: [EdgeActionDialogComponent],
+  exports: [EdgeActionDialogComponent]
 })
-export class NavbarModule { }
+export class EdgeActionDialogModule {}
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/index.ts b/services/self-service/src/main/resources/webapp/src/app/shared/navbar/index.ts
index c5f19a4..7a6f2d4 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/index.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/navbar/index.ts
@@ -25,6 +25,7 @@ import { ProgressDialogModule, BubbleModule } from '../index';
 
 import { NavbarComponent } from './navbar.component';
 import { NotificationDialogModule } from '../modal-dialog/notification-dialog';
+import {EdgeActionDialogModule} from "../modal-dialog/edge-action-dialog";
 
 export * from './navbar.component';
 
@@ -34,8 +35,9 @@ export * from './navbar.component';
     RouterModule,
     MaterialModule,
     NotificationDialogModule,
+    EdgeActionDialogModule,
     ProgressDialogModule,
-    BubbleModule
+    BubbleModule,
   ],
   declarations: [NavbarComponent],
   exports: [NavbarComponent, RouterModule]


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