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:13 UTC

[incubator-datalab] 03/09: [DATALAB-2347] refactored Project creation 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 c9bb91ab91e74b33808ef5252dd75a5a0b85c18c
Author: Yurii Tykhun <ty...@gmail.com>
AuthorDate: Thu Jul 29 17:16:52 2021 +0300

    [DATALAB-2347] refactored Project creation component
---
 .../administration/project/project-data.service.ts |   7 -
 .../project-form/project-form.component.html       | 155 ++++++++++++++++-----
 .../project-form/project-form.component.scss       |   8 +-
 .../project/project-form/project-form.component.ts |  15 +-
 .../administration/project/project.component.html  |  27 +++-
 .../administration/project/project.component.ts    |  55 ++++----
 6 files changed, 184 insertions(+), 83 deletions(-)

diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/project/project-data.service.ts b/services/self-service/src/main/resources/webapp/src/app/administration/project/project-data.service.ts
index a461686..0cb20d2 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/project/project-data.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/project/project-data.service.ts
@@ -46,17 +46,10 @@ export class ProjectDataService {
         mergeMap ((response: Project[]) => {
             if (response && this.endpointsList.length) {
               response.forEach(project => project.endpoints.forEach(endpoint => {
-                const filtredEndpoints =  this.endpointsList.filter(v => v.name === endpoint.name);
                 const idx = this.endpointsList.findIndex(v => v.name === endpoint.name);
-                // console.log('IDX ', idx);
-                // if (filtredEndpoints.length) {
                 if (idx >= 0) {
                   endpoint.endpointStatus = this.endpointsList[idx].status;
                 }
-
-                // } else {
-                //   endpoint.endpointStatus = 'N/A';
-                // }
               }));
             }
           return of(response);
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/project/project-form/project-form.component.html b/services/self-service/src/main/resources/webapp/src/app/administration/project/project-form/project-form.component.html
index 463c344..cd76e97 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/project/project-form/project-form.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/project/project-form/project-form.component.html
@@ -31,7 +31,8 @@
               <div>
                 <a href="#/help/publickeyguide" target="_blank">
                   <small class="helper_instruction">
-                    <i class="material-icons">help_outline</i>Where can I get public key?</small>
+                    <i class="material-icons">help_outline</i>Where can I get public key?
+                  </small>
                 </a>
               </div>
             </div>
@@ -40,40 +41,69 @@
                 <span class="upload-icon"></span> Upload
                 <input (change)="onFileChange($event)" type="file" name="file" accept=".pub" />
               </span>
-              <button mat-raised-button type="button" class="butt butt-generate" [ngClass]="{ 'not-allowed' : item }"
-                (click)="generateUserAccessKey()">
+              <button 
+                mat-raised-button 
+                type="button" 
+                class="butt butt-generate" 
+                [ngClass]="{ 'not-allowed' : item }"
+                (click)="generateUserAccessKey()"
+              >
                 <i class="material-icons">move_to_inbox</i> Generate
               </button>
 
               <div *ngIf="keyLabel" class="m-bott-10 m-top-10 ellipsis" [class.danger_color]="!accessKeyValid">
-                {{ keyLabel }}</div>
+                {{ keyLabel }}
+              </div>
             </div>
           </div>
           <div class="text-center m-bott-10">
-            <button mat-raised-button type="button" class="butt" [disabled]="item" (click)="reset()">Clear</button>
-            <button mat-raised-button type="button" class="butt next" matStepperNext>Next
-              <i class="material-icons arrow-icon">keyboard_arrow_right</i></button>
+            <button 
+              mat-raised-button 
+              type="button" 
+              class="butt" 
+              [disabled]="item" 
+              (click)="reset()"
+            >
+              Clear
+            </button>
+            <button 
+              mat-raised-button 
+              type="button" 
+              class="butt next" 
+              matStepperNext
+            >
+              Next
+              <i class="material-icons arrow-icon">keyboard_arrow_right</i>
+            </button>
           </div>
         </div>
       </section>
     </mat-step>
+
     <mat-step [completed]='false'>
       <ng-template matStepLabel>Project</ng-template>
       <section class="inner-step mat-reset">
-
         <div class="form-block">
           <div>
             <div class="control-group m-bott-10">
               <label class="label">Project name</label>
               <div class="control">
-                <input type="text" formControlName="name" placeholder="Enter project name"
-                  (blur)="generateProjectTag($event)" [ngClass]="{ 'not-allowed' : item }">
-                <span class="error" *ngIf="projectForm?.controls.name.hasError('duplication')">This project name already
-                  exists.</span>
-                <span class="error" *ngIf="!projectForm?.controls.name.valid
-                  && !projectForm?.controls.name.hasError('duplication')
-                  && !projectForm?.controls.name.hasError('limit')
-                  && projectForm?.controls.name.dirty">
+                <input 
+                  type="text" 
+                  formControlName="name" 
+                  placeholder="Enter project name"
+                  (blur)="generateProjectTag($event)" 
+                  [ngClass]="{ 'not-allowed' : item }"
+                />
+                <span class="error" *ngIf="projectForm?.controls.name.hasError('duplication')">
+                  This project name already exists.
+                </span>
+                <span 
+                  class="error" 
+                  *ngIf="!projectForm?.controls.name.valid
+                      && !projectForm?.controls.name.hasError('duplication')
+                      && !projectForm?.controls.name.hasError('limit')
+                      && projectForm?.controls.name.dirty">
                   Project name can only contain letters and numbers.
                 </span>
                 <span class="error" *ngIf="projectForm?.controls.name.hasError('limit')">
@@ -84,8 +114,13 @@
             <div class="control-group m-bott-10">
               <label class="label">Project tag</label>
               <div class="control">
-                <input readonly type="text" formControlName="tag" placeholder="< equal to project name >"
-                  class="not-allowed">
+                <input 
+                  readonly 
+                  type="text" 
+                  formControlName="tag" 
+                  placeholder="< equal to project name >"
+                  class="not-allowed"
+                />
               </div>
             </div>
             <div class="control-group m-bott-10">
@@ -97,7 +132,8 @@
                     disableOptionCentering 
                     formControlName="endpoints" 
                     placeholder="Select endpoints"
-                    panelClass="crete-project-dialog scrolling">
+                    panelClass="crete-project-dialog scrolling"
+                  >
                     <mat-option class="multiple-select" disabled>
                       <a class="select ani" (click)="selectOptions(endpointsList, 'endpoints', 'all')">
                         <i class="material-icons">playlist_add_check</i>&nbsp;All
@@ -107,12 +143,20 @@
                         <i class="material-icons">clear</i>&nbsp;None
                       </a>
                     </mat-option>
-                    <mat-option *ngFor="let endpoint of endpointsList" [value]="endpoint.name"
-                      [disabled]="isDisabled(endpoint.name) || endpoint.status !== 'ACTIVE'">
+                    <mat-option 
+                      *ngFor="let endpoint of endpointsList" 
+                      [value]="endpoint.name"
+                      [disabled]="isDisabled(endpoint.name) || endpoint.status !== 'ACTIVE'"
+                    >
                       {{ endpoint.name === 'local' ? endpoint.name : endpoint.name + (endpoint.status !== 'ACTIVE' ? ' (inactive)' : '')}}
                     </mat-option>
-                    <mat-option *ngIf="!endpointsList.length" class="multiple-select empty ml-10" disabled>
-                      Endpoints list is empty</mat-option>
+                    <mat-option 
+                      *ngIf="!endpointsList.length" 
+                      class="multiple-select empty ml-10" 
+                      disabled
+                    >
+                      Endpoints list is empty
+                    </mat-option>
                   </mat-select>
                   <button class="caret">
                     <i class="material-icons">keyboard_arrow_down</i>
@@ -123,16 +167,35 @@
           </div>
 
           <div class="text-center m-bott-10">
-            <button mat-raised-button type="button" class="butt" [disabled]="item" (click)="reset()">Clear</button>
-            <button mat-raised-button matStepperPrevious class="butt"><i
-                class="material-icons arrow-icon">keyboard_arrow_left</i>Back</button>
-            <button mat-raised-button type="button" class="butt next" matStepperNext>Next<i
-                class="material-icons arrow-icon">keyboard_arrow_right</i></button>
+            <button 
+              mat-raised-button 
+              type="button" 
+              class="butt" 
+              [disabled]="item" 
+              (click)="reset()"
+            >
+              Clear
+            </button>
+            <button 
+              mat-raised-button 
+              matStepperPrevious 
+              class="butt"
+            >
+              <i class="material-icons arrow-icon">keyboard_arrow_left</i>Back
+            </button>
+            <button 
+              mat-raised-button 
+              type="button" 
+              class="butt next" 
+              matStepperNext
+            >
+              Next<i class="material-icons arrow-icon">keyboard_arrow_right</i>
+            </button>
           </div>
         </div>
-
       </section>
     </mat-step>
+
     <mat-step [completed]='false'>
       <ng-template matStepLabel>Groups</ng-template>
       <div class="inner-step mat-reset">
@@ -146,7 +209,8 @@
                   disableOptionCentering 
                   formControlName="groups" 
                   placeholder="Select user groups"
-                  panelClass="crete-project-dialog scrolling">
+                  panelClass="crete-project-dialog scrolling"
+                >
                   <mat-option class="multiple-select" disabled>
                     <a class="select ani" (click)="selectOptions(groupsList, 'groups', 'all')">
                       <i class="material-icons">playlist_add_check</i>&nbsp;All
@@ -158,7 +222,8 @@
                   <mat-option *ngFor="let group of groupsList" [value]="group">
                     {{ group }}
                   </mat-option>
-                  <mat-option *ngIf="!groupsList.length" class="multiple-select ml-10" disabled>Groups list is empty
+                  <mat-option *ngIf="!groupsList.length" class="multiple-select ml-10" disabled>
+                    Groups list is empty
                   </mat-option>
                 </mat-select>
                 <button class="caret">
@@ -173,11 +238,29 @@
 <!--                <span class="hold-label">Use shared image</span>-->
 <!--              </mat-slide-toggle>-->
 <!--            </div>-->
-            <button mat-raised-button type="button" class="butt" [disabled]="item" (click)="reset()">Clear</button>
-            <button mat-raised-button matStepperPrevious class="butt"><i
-                class="material-icons arrow-icon">keyboard_arrow_left</i>Back</button>
-            <button mat-raised-button type="button" class="butt butt-success" [disabled]="!projectForm.valid"
-              (click)="confirm(projectForm.value)">
+            <button 
+              mat-raised-button 
+              type="button" 
+              class="butt" 
+              [disabled]="item" 
+              (click)="reset()"
+            >
+              Clear
+            </button>
+            <button 
+              mat-raised-button 
+              matStepperPrevious 
+              class="butt"
+            >
+              <i class="material-icons arrow-icon">keyboard_arrow_left</i>Back
+            </button>
+            <button 
+              mat-raised-button 
+              type="button" 
+              class="butt butt-success" 
+              [disabled]="!projectForm.valid"
+              (click)="confirm(projectForm.value)"
+            >
               <span *ngIf="item; else update">Update</span>
               <ng-template #update>Create</ng-template>
             </button>
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/project/project-form/project-form.component.scss b/services/self-service/src/main/resources/webapp/src/app/administration/project/project-form/project-form.component.scss
index 54a9244..3e11ea2 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/project/project-form/project-form.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/project/project-form/project-form.component.scss
@@ -32,16 +32,16 @@
 
         .ellipsis {
           position: absolute;
-          width: 100%;
           right: 0;
+          width: 100%;
         }
       }
     }
   }
 
   &.split {
-    flex-direction: column;
     display: flex;
+    flex-direction: column;
     justify-content: space-between;
     height: 240px;
   }
@@ -58,7 +58,7 @@
     position: absolute;
     right: 0;
     bottom: -2px;
-    font-family: 'Open Sans', sans-serif;
+    font-family: "Open Sans", sans-serif;
     font-weight: 300;
   }
 }
@@ -76,6 +76,6 @@
 
 .mat-form-field {
   .mat-select {
-    font-family: 'Open Sans', sans-serif;
+    font-family: "Open Sans", sans-serif;
   }
 }
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/project/project-form/project-form.component.ts b/services/self-service/src/main/resources/webapp/src/app/administration/project/project-form/project-form.component.ts
index 69c709d..b5cd1b8 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/project/project-form/project-form.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/project/project-form/project-form.component.ts
@@ -20,6 +20,7 @@
 import { Component, OnInit, Input, Output, EventEmitter, ViewChild, ChangeDetectorRef } from '@angular/core';
 import { FormGroup, FormBuilder, Validators } from '@angular/forms';
 import { MatStepper } from '@angular/material/stepper';
+import {MatDialog} from '@angular/material/dialog';
 import { ToastrService } from 'ngx-toastr';
 import { Subscription } from 'rxjs';
 
@@ -29,7 +30,6 @@ import { CheckUtils, FileUtils, PATTERNS } from '../../../core/util';
 import { Project } from '../project.component';
 import { DICTIONARY } from '../../../../dictionary/global.dictionary';
 import {ConfirmationDialogComponent} from '../../../shared/modal-dialog/confirmation-dialog';
-import {MatDialog} from '@angular/material/dialog';
 
 export interface GenerateKey { privateKey: string; publicKey: string; }
 
@@ -83,15 +83,20 @@ export class ProjectFormComponent implements OnInit {
   }
 
   private updateProject(data: any) {
-    this.projectService.updateProject(data).subscribe(() => {
-      this.toastr.success('Project updated successfully!', 'Success!');
-      this.update.emit();
-    }, error => this.toastr.error(error.message || 'Project update failed!', 'Oops!'));
+    this.projectService.updateProject(data)
+      .subscribe(
+        () => {
+          this.toastr.success('Project updated successfully!', 'Success!');
+          this.update.emit();
+        }, 
+        error => this.toastr.error(error.message || 'Project update failed!', 'Oops!')
+      );
   }
 
   public confirm(data) {
     if (this.item) {
       const deletedGroups = this.item.groups.filter((v) => !(this.projectForm.value.groups.includes(v)));
+      
       if (deletedGroups.length) {
         this.dialog.open(ConfirmationDialogComponent, {
           data: {notebook: deletedGroups, type: 5, manageAction: true}, panelClass: 'modal-md'
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/project/project.component.html b/services/self-service/src/main/resources/webapp/src/app/administration/project/project.component.html
index 76f0be1..22c759d 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/project/project.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/project/project.component.html
@@ -25,12 +25,21 @@
       matTooltipPosition="above"
       [matTooltipDisabled]="healthStatus?.admin"
     >
-      <button mat-raised-button class="butt butt-create" (click)="createProject()" [disabled]="!projectList.length || !healthStatus?.admin && healthStatus?.projectAdmin">
+      <button 
+        mat-raised-button 
+        class="butt butt-create" 
+        (click)="createProject()" 
+        [disabled]="!projectList.length || !healthStatus?.admin && healthStatus?.projectAdmin"
+      >
         <i class="material-icons">add</i>Create new
       </button>
     </div>
     <div>
-      <button mat-raised-button class="butt butt-tool mr-10" (click)="toggleFiltering()">
+      <button 
+        mat-raised-button 
+        class="butt butt-tool mr-10" 
+        (click)="toggleFiltering()"
+      >
         <span *ngIf="!activeFiltering">
           <i class="material-icons">visibility_off</i> Show active
         </span>
@@ -38,7 +47,12 @@
           <i class="material-icons">visibility</i> Show all
         </span>
       </button>
-      <button mat-raised-button class="butt" (click)="refreshGrid()" [hidden]="!projectList.length">
+      <button 
+        mat-raised-button 
+        class="butt" 
+        (click)="refreshGrid()" 
+        [hidden]="!projectList.length"
+      >
         <i class="material-icons refresh-icon">autorenew</i>Refresh
       </button>
     </div>
@@ -51,8 +65,11 @@
   </mat-card>
 
   <div [hidden]="!projectList.length">
-    <project-list (editItem)="editProject($event)" (toggleStatus)="toggleStatus($event)" [isProjectAdmin]="!healthStatus?.admin && healthStatus?.projectAdmin">
-    </project-list>
+    <project-list 
+      (editItem)="editProject($event)" 
+      (toggleStatus)="toggleStatus($event)" 
+      [isProjectAdmin]="!healthStatus?.admin && healthStatus?.projectAdmin"
+    ></project-list>
   </div>
 
   <inform-message [message]="noPermissionMessage" *ngIf="!healthStatus?.admin && healthStatus?.projectAdmin && !projectList.length"></inform-message>
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 2e28831..329c5f5 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
@@ -23,7 +23,7 @@ import { Subscription } from 'rxjs';
 import { ToastrService } from 'ngx-toastr';
 
 import { ProjectDataService } from './project-data.service';
-import {HealthStatusService, ProjectService, UserResourceService} from '../../core/services';
+import {HealthStatusService, ProjectService } from '../../core/services';
 import { NotificationDialogComponent } from '../../shared/modal-dialog/notification-dialog';
 import { ProjectListComponent } from './project-list/project-list.component';
 import { EnvironmentsDataService } from '../management/management-data.service';
@@ -72,10 +72,11 @@ export class ProjectComponent implements OnInit, OnDestroy {
 
   ngOnInit() {
     this.getEnvironmentHealthStatus();
-    this.subscriptions.add(this.projectDataService._projects.subscribe(
-      (value: Project[]) => {
+    this.subscriptions.add(this.projectDataService._projects
+      .subscribe((value: Project[]) => {
         if (value) this.projectList = value;
-      }));
+      })
+    );
     this.refreshGrid();
     this.getResources();
   }
@@ -85,9 +86,10 @@ export class ProjectComponent implements OnInit, OnDestroy {
   }
 
   private getResources() {
-    this.environmentsDataService.getEnvironmentDataDirect().subscribe((data: any) => {
-      this.resources = data;
-    });
+    this.environmentsDataService.getEnvironmentDataDirect()
+      .subscribe((data: any) => {
+        this.resources = data;
+      });
   }
 
   refreshGrid() {
@@ -105,9 +107,7 @@ export class ProjectComponent implements OnInit, OnDestroy {
 
   public toggleFiltering(): void {
     this.activeFiltering = !this.activeFiltering;
-
     this.activeFiltering ? this.list.showActiveInstances() : this.projectDataService.updateProjects();
-
   }
 
   public editProject($event) {
@@ -118,7 +118,10 @@ export class ProjectComponent implements OnInit, OnDestroy {
   }
 
   public toggleStatus($event) {
-    const data = { 'project_name': $event.project.name, endpoint: $event.endpoint.map(endpoint => endpoint.name)};
+    const data = { 
+      'project_name': $event.project.name, 
+      endpoint: $event.endpoint.map(endpoint => endpoint.name)
+    };
     this.toggleStatusRequest(data, $event.action, $event.oneEdge);
   }
 
@@ -139,7 +142,8 @@ export class ProjectComponent implements OnInit, OnDestroy {
         this.edgeNodeAction(data, action);
       } else {
         this.dialog.open(NotificationDialogComponent, { data: {
-            type: 'terminateNode', item: {action: data, resources: termResources}
+            type: 'terminateNode', 
+            item: {action: data, resources: termResources}
           }, panelClass: 'modal-sm' })
           .afterClosed().subscribe(result => {
           result && this.edgeNodeAction(data, action);
@@ -151,12 +155,16 @@ export class ProjectComponent implements OnInit, OnDestroy {
   }
 
   private edgeNodeAction(data, action) {
-    this.projectService.toggleProjectStatus(data, action).subscribe(() => {
-      this.refreshGrid();
-      this.toastr.success(`Edge node ${this.toEndpointAction(action)} is in progress!`, 'Processing!');
-    }, error => {
-      this.toastr.error(error.message, 'Oops!');
-    });
+    this.projectService.toggleProjectStatus(data, action)
+      .subscribe(
+        () => {
+          this.refreshGrid();
+          this.toastr.success(`Edge node ${this.toEndpointAction(action)} is in progress!`, 'Processing!');
+        }, 
+        error => {
+          this.toastr.error(error.message, 'Oops!');
+        }
+      );
   }
 
   private getEnvironmentHealthStatus() {
@@ -165,15 +173,10 @@ export class ProjectComponent implements OnInit, OnDestroy {
   }
 
   private toEndpointAction(action) {
-    if (action === 'start') {
-      return 'starting';
-    } else if (action === 'stop') {
-      return 'stopping';
-    } else if (action === 'terminate') {
-      return 'terminating';
-    } else {
-      return action;
-    }
+    if (action === 'start') return 'starting';
+    else if (action === 'stop') return 'stopping';
+    else if (action === 'terminate') return 'terminating';
+    else return action;
   }
 }
 

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