You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datalab.apache.org by yt...@apache.org on 2021/08/10 07:59:14 UTC

[incubator-datalab] 04/09: [DATALAB-2347] refactored Project list component

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

ytykhun pushed a commit to branch DATALAB-2347
in repository https://gitbox.apache.org/repos/asf/incubator-datalab.git

commit 62374eab25f04cc30874348a1152ed4cbab7d300
Author: Yurii Tykhun <ty...@gmail.com>
AuthorDate: Fri Jul 30 18:12:36 2021 +0300

    [DATALAB-2347] refactored Project list component
---
 .../project-list/project-list.component.html       | 193 ++++++++++-----------
 .../project-list/project-list.component.scss       |  68 ++++----
 .../project/project-list/project-list.component.ts |  88 +++++-----
 3 files changed, 176 insertions(+), 173 deletions(-)

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 e407d30..27e2ba4 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
@@ -18,107 +18,106 @@
   -->
 <div class="table-wrapper scrolling">
   <table mat-table [dataSource]="dataSource" class="projects-table mat-elevation-z6 selection">
-  <ng-container matColumnDef="name">
-    <th mat-header-cell *matHeaderCellDef class="name"> Project name </th>
-    <td mat-cell *matCellDef="let element" class="name project-name"> {{element.name}} </td>
-  </ng-container>
+    <ng-container matColumnDef="name">
+      <th mat-header-cell *matHeaderCellDef class="name"> Project name </th>
+      <td mat-cell *matCellDef="let element" class="name project-name"> {{element.name}} </td>
+    </ng-container>
 
-  <ng-container matColumnDef="groups">
-    <th mat-header-cell *matHeaderCellDef class="groups"> Group </th>
-    <td mat-cell *matCellDef="let element" class="groups">
-      <div class="mat-chip-list-wrap scrolling">
-        <mat-chip-list>
-          <mat-chip *ngFor="let group of element.groups"
-                    [matTooltip]="group"
-                    matTooltipPosition="above"
-                    class="ellipsis"
-          >
-            {{ group }}
-          </mat-chip>
-        </mat-chip-list>
-      </div>
-    </td>
-  </ng-container>
-
-  <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">
-      <div *ngIf="!element.endpoints?.length; else list">
-        <span *ngIf="!element.endpoints.length" class="no-details">no details</span>
-      </div>
-      <ng-template #list>
-        <div *ngFor="let endpoint of element.endpoints" class="resource-wrap">
-          <div class="resource-name">
-            <a class="project-endpoint-name">
-              {{ endpoint.name }}
-            </a>
-          </div>
-          <div class="resource-status">
-            <span [ngClass]="{'active' : endpoint.endpointStatus === 'ACTIVE', 'failed': endpoint.endpointStatus === 'INACTIVE'}">
-              {{ (endpoint.endpointStatus | titlecase) || 'N/A'}}
-            </span>
-          </div>
-
-          <span class="status resource-status"
-            [ngClass]="endpoint?.status.toLowerCase() || ''">{{ endpoint?.status.toLowerCase() }}</span>
+    <ng-container matColumnDef="groups">
+      <th mat-header-cell *matHeaderCellDef class="groups"> Group </th>
+      <td mat-cell *matCellDef="let element" class="groups">
+        <div class="mat-chip-list-wrap scrolling">
+          <mat-chip-list>
+            <mat-chip 
+              *ngFor="let group of element.groups"
+              [matTooltip]="group"
+              matTooltipPosition="above"
+              class="ellipsis"
+            >
+              {{ group }}
+            </mat-chip>
+          </mat-chip-list>
         </div>
-      </ng-template>
-    </td>
-  </ng-container>
+      </td>
+    </ng-container>
 
-  <ng-container matColumnDef="actions">
-    <th mat-header-cell *matHeaderCellDef class="project-actions">
-      <span class="label"> Actions </span>
-    </th>
-    <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 actions-list">
-          <div class="active-items"></div>
-          <li class="project-seting-item" *ngIf="element.areStoppedNode" (click)="openEdgeDialog('start', element)">
-            <i class="material-icons">play_circle_outline</i>
-            <a class="action">
-              Start edge node
-            </a>
-          </li>
-          <li class="project-seting-item" *ngIf="element.areRunningNode" (click)="openEdgeDialog('stop', element )">
-            <i class="material-icons">pause_circle_outline</i>
-            <a class="action" >
-              Stop edge node
-            </a>
-          </li>
-          <!-- <li class="project-seting-item " *ngIf="element.areTerminatedNode" (click)="openEdgeDialog('recreate', element)">
-            <i class="material-icons">refresh</i>
-            <a class="action">
-              Recreate edge node
-            </a>
-          </li> -->
-          <li class="project-seting-item " *ngIf="element.areStoppedNode || element.areRunningNode" (click)="openEdgeDialog('terminate', element)">
-            <i class="material-icons">phonelink_off</i>
-            <a class="action">
-              Terminate edge node
-            </a>
-          </li>
-          <li class="project-seting-item" (click)="editProject(element)" *ngIf="!isProjectAdmin">
-            <i class="material-icons">mode_edit</i>
-            <a >
-              Edit project
-            </a>
-          </li>
-        </ul>
-      </bubble-up>
-    </td>
-    <td class="settings">
+    <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">
+        <div *ngIf="!element.endpoints?.length; else list">
+          <span *ngIf="!element.endpoints.length" class="no-details">no details</span>
+        </div>
+        <ng-template #list>
+          <div *ngFor="let endpoint of element.endpoints" class="resource-wrap">
+            <div class="resource-name">
+              <a class="project-endpoint-name">
+                {{ endpoint.name }}
+              </a>
+            </div>
+            <div class="resource-status">
+              <span [ngClass]="{'active' : endpoint.endpointStatus === 'ACTIVE', 'failed': endpoint.endpointStatus === 'INACTIVE'}">
+                {{ (endpoint.endpointStatus | titlecase) || 'N/A'}}
+              </span>
+            </div>
 
-    </td>
+            <span class="status resource-status" [ngClass]="endpoint?.status.toLowerCase() || ''">
+              {{ endpoint?.status.toLowerCase() }}
+            </span>
+          </div>
+        </ng-template>
+      </td>
+    </ng-container>
 
-  </ng-container>
+    <ng-container matColumnDef="actions">
+      <th mat-header-cell *matHeaderCellDef class="project-actions">
+        <span class="label"> Actions </span>
+      </th>
+      <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 actions-list">
+            <div class="active-items"></div>
+            <li class="project-seting-item" *ngIf="element.areStoppedNode" (click)="openEdgeDialog('start', element)">
+              <i class="material-icons">play_circle_outline</i>
+              <a class="action">
+                Start edge node
+              </a>
+            </li>
+            <li class="project-seting-item" *ngIf="element.areRunningNode" (click)="openEdgeDialog('stop', element )">
+              <i class="material-icons">pause_circle_outline</i>
+              <a class="action" >
+                Stop edge node
+              </a>
+            </li>
+            <!-- <li class="project-seting-item " *ngIf="element.areTerminatedNode" (click)="openEdgeDialog('recreate', element)">
+              <i class="material-icons">refresh</i>
+              <a class="action">
+                Recreate edge node
+              </a>
+            </li> -->
+            <li class="project-seting-item " *ngIf="element.areStoppedNode || element.areRunningNode" (click)="openEdgeDialog('terminate', element)">
+              <i class="material-icons">phonelink_off</i>
+              <a class="action">
+                Terminate edge node
+              </a>
+            </li>
+            <li class="project-seting-item" (click)="editProject(element)" *ngIf="!isProjectAdmin">
+              <i class="material-icons">mode_edit</i>
+              <a >
+                Edit project
+              </a>
+            </li>
+          </ul>
+        </bubble-up>
+      </td>
+      <td class="settings"></td>
+    </ng-container>
 
-  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
-  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
-</table>
+    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
+    <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
+  </table>
 </div>
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 140feb4..836b822 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
@@ -17,13 +17,12 @@
  * under the License.
  */
 
-
-.table-wrapper{
-  height: calc(100vh - 120px);
-  overflow: auto;
+.table-wrapper {
   position: relative;
-  margin:  0 -15px -15px -15px;
+  margin: 0 -15px -15px -15px;
   padding: 0 15px 15px 15px;
+  height: calc(100vh - 120px);
+  overflow: auto;
   .mat-header-cell {
     position: sticky;
     top: 0;
@@ -31,6 +30,7 @@
     background: white;
   }
 }
+
 table {
   width: 100%;
 
@@ -41,16 +41,16 @@ table {
   .name {
     width: 25%;
     padding: 20px 0 10px 24px;
-    &.project-name{
+    &.project-name {
       padding-top: 10px;
     }
   }
 
-  th.name{
+  th.name {
     padding-top: 10px;
   }
 
-  .mat-header-row{
+  .mat-header-row {
     padding-top: 12px;
   }
 
@@ -59,13 +59,15 @@ table {
     padding: 15px 0;
 
     .resource-wrap {
-      .resource-name, .resource-status {
+      .resource-name,
+      .resource-status {
         width: 30%;
         padding-left: 0;
       }
     }
 
-    .label-endpoint, .label-endpoint-status {
+    .label-endpoint,
+    .label-endpoint-status {
       display: inline-block;
       width: 30%;
     }
@@ -75,7 +77,7 @@ table {
     }
 
     &.source {
-      &.endpoints .resource-wrap{
+      &.endpoints .resource-wrap {
         justify-content: flex-start;
       }
       .no-details {
@@ -94,19 +96,19 @@ table {
   }
 
   .project-actions {
-    color: #607d8b;
     width: 10%;
+    padding: 10px 24px;
+    color: #607d8b;
     text-align: right;
     vertical-align: top;
-    padding: 10px 24px;
 
-    &.mat-header-cell{
+    &.mat-header-cell {
       padding-top: 19px;
-      color: rgba(0,0,0,.54);
+      color: rgba(0, 0, 0, 0.54);
     }
 
     span:not(.mat-header-cell span) {
-      transition: all .5s ease-in-out;
+      transition: all 0.5s ease-in-out;
       cursor: pointer;
 
       .mat-icon {
@@ -126,47 +128,49 @@ td.settings {
   vertical-align: middle !important;
   text-align: right;
   .actions {
-    margin-top: 3px;
-    background-image: url(../../../../assets/svg/settings_icon.svg);
+    display: inline-block;
     width: 16px;
     height: 16px;
-    display: inline-block;
+    margin-top: 3px;
+    background-image: url(../../../../assets/svg/settings_icon.svg);
     text-align: center;
     cursor: pointer;
   }
 }
-.project-seting-item{
+
+.project-seting-item {
   display: flex;
-  padding: 10px;
   align-items: center;
+  padding: 10px;
   border-bottom: 1px solid #edf1f5;
   cursor: pointer;
   color: #577289;
-  &:last-child{
+  &:last-child {
     border-bottom: none;
   }
-  &:hover{
+  &:hover {
     color: #36afd5;
-    transition: all .45s ease-in-out;
+    transition: all 0.45s ease-in-out;
   }
-  a{
+  a {
     padding-left: 5px;
   }
 }
+
 .material-icons {
   font-size: 18px;
   padding-top: 1px;
 }
 
-.list-menu{
+.list-menu {
   min-width: 205px;
 }
 
-.project-endpoint-name{
-   color: #577289;
+.project-endpoint-name {
+  color: #577289;
 }
 
-.actions-list{
+.actions-list {
   padding: 10px 15px;
 }
 
@@ -174,8 +178,4 @@ td.settings {
   max-width: 200px !important;
   white-space: nowrap;
   display: inline-block;
-}
-
-
-
-
+}
\ No newline at end of file
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 6ee2f2a..41a2127 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,7 +17,7 @@
  * under the License.
  */
 
-import {Component, OnInit, Output, EventEmitter, OnDestroy, Inject, Input} from '@angular/core';
+import { Component, OnInit, Output, EventEmitter, OnDestroy, Inject, Input } from '@angular/core';
 import { ToastrService } from 'ngx-toastr';
 import { MatTableDataSource } from '@angular/material/table';
 import { Subscription } from 'rxjs';
@@ -25,11 +25,8 @@ import { MatDialogRef, MAT_DIALOG_DATA, MatDialog } from '@angular/material/dial
 
 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',
@@ -47,16 +44,14 @@ export class ProjectListComponent implements OnInit, OnDestroy {
   @Output() toggleStatus: EventEmitter<{}> = new EventEmitter();
   private subscriptions: Subscription = new Subscription();
 
-  constructor(
+  constructor (
     public toastr: ToastrService,
     private projectDataService: ProjectDataService,
     private progressBarService: ProgressBarService,
     @Inject(MAT_DIALOG_DATA) public data: any,
     public dialogRef: MatDialogRef<ProjectListComponent>,
     public dialog: MatDialog,
-  ) {
-  }
-
+  ) { }
 
   ngOnInit() {
     this.getProjectList();
@@ -68,23 +63,30 @@ export class ProjectListComponent implements OnInit, OnDestroy {
 
   private getProjectList() {
     this.progressBarService.startProgressBar();
-    this.subscriptions.add(this.projectDataService._projects.subscribe((value: Project[]) => {
-      this.projectList = value;
-      if (this.projectList) {
-        this.projectList.forEach(project => {
-          project.areRunningNode = this.areResoursesInStatuses(project.endpoints, ['RUNNING']);
-          project.areStoppedNode = this.areResoursesInStatuses(project.endpoints, ['STOPPED']);
-          project.areTerminatedNode = this.areResoursesInStatuses(project.endpoints, ['TERMINATED', 'FAILED']);
-        });
-      }
-      if (value) this.dataSource = new MatTableDataSource(value);
-      this.progressBarService.stopProgressBar();
-    }, () => this.progressBarService.stopProgressBar()));
+    this.subscriptions.add(this.projectDataService._projects
+      .subscribe(
+        (value: Project[]) => {
+          this.projectList = value;
+          if (this.projectList) {
+            this.projectList.forEach(project => {
+              project.areRunningNode = this.areResoursesInStatuses(project.endpoints, ['RUNNING']);
+              project.areStoppedNode = this.areResoursesInStatuses(project.endpoints, ['STOPPED']);
+              project.areTerminatedNode = this.areResoursesInStatuses(project.endpoints, ['TERMINATED', 'FAILED']);
+            });
+          }
+          if (value) this.dataSource = new MatTableDataSource(value);
+          this.progressBarService.stopProgressBar();
+        }, 
+        () => this.progressBarService.stopProgressBar()
+      )
+    );
   }
 
   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) => {
+        return endpoint.status !== 'TERMINATED' && endpoint.status !== 'TERMINATING' && endpoint.status !== 'FAILED'
+      });
       return project;
     });
 
@@ -96,32 +98,34 @@ export class ProjectListComponent implements OnInit, OnDestroy {
   }
 
   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';
-        }
-        if (action === 'recreate') {
-          return endpoint.status === 'TERMINATED' || endpoint.status === 'FAILED';
-        }
-      });
-      if (action === 'terminate' && endpoints.length === 1) {
-        this.toggleStatus.emit({project, endpoint: endpoints, action, oneEdge: true});
-      } else {
-        this.dialog.open(EdgeActionDialogComponent, {data: {type: action, item: endpoints}, panelClass: 'modal-sm'})
-          .afterClosed().subscribe(endpoint => {
+    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';
+      }
+      if (action === 'recreate') {
+        return endpoint.status === 'TERMINATED' || endpoint.status === 'FAILED';
+      }
+    });
+    if (action === 'terminate' && endpoints.length === 1) {
+      this.toggleStatus.emit({ project, endpoint: endpoints, action, oneEdge: true });
+    } else {
+      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!')
+          }, 
+          error => this.toastr.error(error.message || `Endpoint ${action} failed!`, 'Oops!')
         );
-      }
     }
+  }
 
   public areResoursesInStatuses(resources, statuses: Array<string>) {
     return resources.some(resource => statuses.some(status => resource.status === status));

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