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

kuanhsun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/submarine.git


The following commit(s) were added to refs/heads/master by this push:
     new 695755b  SUBMARINE-1092. Use Model Management REST API in Model 
Management Page
695755b is described below

commit 695755b896fb28c7c2ac58e031cba162df9c7216
Author: andybi7676 <[email protected]>
AuthorDate: Wed Dec 1 23:07:57 2021 +0800

    SUBMARINE-1092. Use Model Management REST API in Model Management Page
    
    ### What is this PR for?
    remove the static part in the model main page and use REST API to fetch 
data from the database.
    
    ### What type of PR is it?
    Improvement
    ### Todos
    * [x] - model main page fetching
    * [x] - loading icon when fetching
    
    ### What is the Jira issue?
    <!-- * Open an issue on Jira 
https://issues.apache.org/jira/browse/SUBMARINE/
    * Put link here, and add [SUBMARINE-*Jira number*] in PR title, eg. 
`SUBMARINE-23. PR title`
    -->
    https://issues.apache.org/jira/browse/SUBMARINE-1092
    
    ### How should this be tested?
    <!--
    * First time? Setup Travis CI as described on 
https://submarine.apache.org/contribution/contributions.html#continuous-integration
    * Strongly recommended: add automated unit tests for any new or changed 
behavior
    * Outline any manual steps to test the PR here.
    -->
    ### Screenshots (if appropriate)
    
    
https://user-images.githubusercontent.com/59821107/143672967-1bd64dfc-24fb-4363-942b-44bf651bb4db.mp4
    
    ### Questions:
    * Do the license files need updating? No
    * Are there breaking changes for older versions? No
    * Does this need new documentation? No
    
    Author: andybi7676 <[email protected]>
    
    Signed-off-by: kuanhsun <[email protected]>
    
    Closes #812 from andybi7676/SUBMARINE-1092 and squashes the following 
commits:
    
    54d9eaaf [andybi7676] SUBMARINE-1092. resolve tags_set
    68e0914c [andybi7676] SUBMARINE-1092. add loading icon when data not coming
    64b4339c [andybi7676] SUBMARINE-1092. add fetching registered model
---
 .../workbench-web/src/app/interfaces/model-info.ts |  4 +-
 .../model-card/model-card.component.html           |  4 +-
 .../model-cards/model-card/model-card.component.ts |  2 +-
 .../model-cards/model-cards.component.html         |  2 +-
 .../model-cards/model-cards.component.ts           |  1 +
 .../model/model-home/model-home.component.html     |  2 +-
 .../model/model-home/model-home.component.ts       | 93 ++++-----------------
 .../pages/workbench/model/model-routing.module.ts  |  8 +-
 .../app/pages/workbench/model/model.component.ts   |  6 +-
 .../pages/workbench/workbench-routing.module.ts    |  8 +-
 .../src/app/services/model.service.ts              | 95 ++++++++++++++++++++++
 11 files changed, 132 insertions(+), 93 deletions(-)

diff --git a/submarine-workbench/workbench-web/src/app/interfaces/model-info.ts 
b/submarine-workbench/workbench-web/src/app/interfaces/model-info.ts
index 01b9f59..7fe01b9 100644
--- a/submarine-workbench/workbench-web/src/app/interfaces/model-info.ts
+++ b/submarine-workbench/workbench-web/src/app/interfaces/model-info.ts
@@ -19,8 +19,8 @@
 
 export interface ModelInfo {
   name: string;
-  createTime: string,
-  updatedTime: string, 
+  creationTime: string,
+  lastUpdatedTime: string, 
   tags: string[],
   description: string,
 }
\ No newline at end of file
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-cards/model-card/model-card.component.html
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-cards/model-card/model-card.component.html
index c79ca16..fcc0f92 100644
--- 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-cards/model-card/model-card.component.html
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-cards/model-card/model-card.component.html
@@ -19,8 +19,8 @@
 <a [routerLink]="[card.name]">
   <nz-list-item >
     <nz-card style="width:100%;" nzTitle={{card.name}} 
[nzExtra]="extraTemplate">
-    <p>Created: {{card.createTime}}</p>
-    <p>Updated: {{card.updatedTime}}</p>
+    <p>Created: {{card.creationTime}}</p>
+    <p>Last Updated: {{card.lastUpdatedTime}}</p>
     <p>Tags: 
       <submarine-model-tag *ngFor="let tag of card.tags" [tag]="tag" 
[cssType]="'default'"></submarine-model-tag>
     </p>
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-cards/model-card/model-card.component.ts
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-cards/model-card/model-card.component.ts
index 8a23c81..a2320ef 100644
--- 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-cards/model-card/model-card.component.ts
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-cards/model-card/model-card.component.ts
@@ -32,7 +32,7 @@ export class ModelCardComponent implements OnInit {
 
   ngOnInit() {
     if (this.card.description.length > 15) {
-      this.description = this.card.description.substring(0,15) + "...";
+      this.description = this.card.description.substring(0,50) + "...";
     }
     else {
       this.description = this.card.description;
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-cards/model-cards.component.html
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-cards/model-cards.component.html
index b513a66..0293b5e 100644
--- 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-cards/model-cards.component.html
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-cards/model-cards.component.html
@@ -17,7 +17,7 @@
   ~ under the License.
   -->
 
-<nz-list nzGrid [nzPagination]="pagination">
+<nz-list nzGrid [nzPagination]="pagination" [nzLoading]="isLoading">
   <div nz-row [nzGutter]="16">
     <div nz-col [nzSpan]="6" *ngFor="let card of onPageModelCards; let i = 
index">
       <submarine-model-card [card]="card"></submarine-model-card>
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-cards/model-cards.component.ts
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-cards/model-cards.component.ts
index 87829e1..ec901f3 100644
--- 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-cards/model-cards.component.ts
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-cards/model-cards.component.ts
@@ -26,6 +26,7 @@ import { ModelInfo } from '@submarine/interfaces/model-info';
 })
 export class ModelCardsComponent implements OnInit {
   @Input() modelCards: ModelInfo[];
+  @Input() isLoading: boolean;
   nowPage: number;
   totalPages: number;
   onPageModelCards: ModelInfo[];
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-home.component.html
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-home.component.html
index 95ab91e..7ea4439 100644
--- 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-home.component.html
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-home.component.html
@@ -39,6 +39,6 @@
     </div>
   </div>
   <nz-divider></nz-divider>
-  <submarine-model-cards 
[modelCards]="onDisplayModelCards"></submarine-model-cards>
+  <submarine-model-cards [modelCards]="onDisplayModelCards" 
[isLoading]="isModelCardsLoading"></submarine-model-cards>
 </div>
   
\ No newline at end of file
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-home.component.ts
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-home.component.ts
index 9e6643d..01c2f62 100644
--- 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-home.component.ts
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-home/model-home.component.ts
@@ -19,7 +19,7 @@
 
 import { Component, OnInit } from '@angular/core';
 import { ModelInfo } from '@submarine/interfaces/model-info';
-import { ExperimentService } from '@submarine/services/experiment.service';
+import { ModelService } from '@submarine/services/model.service';
 
 @Component({
   selector: 'submarine-model-home',
@@ -27,8 +27,9 @@ import { ExperimentService } from 
'@submarine/services/experiment.service';
   styleUrls: ['./model-home.component.scss'],
 })
 export class ModelHomeComponent implements OnInit {
-  constructor(private experimentService: ExperimentService) {}
+  constructor(private modelService: ModelService) {}
 
+  isModelCardsLoading: boolean = true;
   modelCards: ModelInfo[];
 
   onDisplayModelCards = [];
@@ -38,80 +39,22 @@ export class ModelHomeComponent implements OnInit {
   listOfChosenTags = [];
 
   ngOnInit() {
-    this.modelCards = [
-      {
-        'name': "Model One",
-        'createTime': "2021-10-12",
-        'updatedTime': "2021-10-13", 
-        'tags': ["image", 'text'],
-        'description': "first model",
-      }, 
-      {
-        'name': "Model Two",
-        'createTime': "2021-10-12",
-        'updatedTime': "2021-10-13", 
-        'tags': ["speech"],
-        'description': "second model",
-      },
-      {
-        'name': "Model Three",
-        'createTime': "2021-10-12",
-        'updatedTime': "2021-10-13", 
-        'tags': ["speech"],
-        'description': "The third model has very long description for 
description shorten testing, 1234567890 A recurrent neural network (RNN) is a 
class of artificial neural networks where connections between nodes form a 
directed graph along a temporal sequence. This allows it to exhibit temporal 
dynamic behavior. Derived from feedforward neural networks, RNNs can use their 
internal state (memory) to process variable length sequences of inputs",
-      },
-      {
-        'name': "ModelFour",
-        'createTime': "2021-10-18",
-        'updatedTime': "2021-10-19", 
-        'tags': ["nlp", 'ssl'],
-        'description': "BERT, a famous ssl model in NLP.",
-      },
-      {
-        'name': "ModelFive",
-        'createTime': "2021-10-18",
-        'updatedTime': "2021-10-19", 
-        'tags': ["speech", 'ssl'],
-        'description': "huBERT, a famous ssl model in SP.",
-      },
-      {
-        'name': "ModelSix",
-        'createTime': "2021-10-18",
-        'updatedTime': "2021-10-19", 
-        'tags': ["CV", 'ssl'],
-        'description': "SimCLR, a famous ssl model in CV.",
-      },
-      {
-        'name': "ModelFour",
-        'createTime': "2021-10-18",
-        'updatedTime': "2021-10-19", 
-        'tags': ["nlp", 'ssl'],
-        'description': "BERT, a famous ssl model in NLP.",
-      },
-      {
-        'name': "ModelFive",
-        'createTime': "2021-10-18",
-        'updatedTime': "2021-10-19", 
-        'tags': ["speech", 'ssl'],
-        'description': "huBERT, a famous ssl model in SP.",
-      },
-      {
-        'name': "ModelSix",
-        'createTime': "2021-10-18",
-        'updatedTime': "2021-10-19", 
-        'tags': ["CV", 'ssl'],
-        'description': "SimCLR, a famous ssl model in CV.",
-      },
-    ];
-    
-    this.onDisplayModelCards = this.modelCards.map(card => card);
-    let tags = [];
-    this.modelCards.map((card) => {
-      Array.prototype.push.apply(tags, card.tags);
+    this.fetchModelCards();
+    this.modelService.emitInfo(null);
+  }
+  
+  fetchModelCards = () => {
+    this.modelService.fetchModelList().subscribe((res) => {
+      this.modelCards = res;
+      this.onDisplayModelCards = this.modelCards.map(card => card);
+      let tags_set = new Set();
+      this.modelCards.map((card) => {
+        card.tags.forEach(tags_set.add, tags_set);
+      });
+      let tags = Array.from(tags_set);
+      this.listOfTagsOption = tags.map((tag) => ({ "label": String(tag), 
"value": String(tag)}));
+      this.isModelCardsLoading = false;
     });
-    let tags_set = new Set(tags);
-    tags = Array.from(tags_set);
-    this.listOfTagsOption = tags.map((tag) => ({ "label": String(tag), 
"value": String(tag)}));
   }
 
   searchModel(event: any) {
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-routing.module.ts
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-routing.module.ts
index 6b0ff8e..419e16f 100644
--- 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-routing.module.ts
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-routing.module.ts
@@ -35,13 +35,13 @@ const routes: Routes = [
         component: ModelHomeComponent,
       },
       {
-        path: ':name/:version',
-        component: ModelVersionComponent,
-      },
-      {
         path: ':name',
         component: RegisteredModelComponent,
       },
+      {
+        path: ':name/:version',
+        component: ModelVersionComponent,
+      },
     ],
   },
 ];
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model.component.ts
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model.component.ts
index a6cbfa5..78d15cb 100644
--- 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model.component.ts
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model.component.ts
@@ -18,7 +18,7 @@
  */
 
 import { Component, OnInit } from '@angular/core';
-import { ExperimentService } from '@submarine/services/experiment.service';
+import { ModelService } from '@submarine/services/model.service';
 import { delay } from 'rxjs/operators';
 
 @Component({
@@ -29,9 +29,9 @@ import { delay } from 'rxjs/operators';
 export class ModelComponent implements OnInit {
   modelName: string = null;
 
-  constructor(private experimentService: ExperimentService) {}
+  constructor(private modelService: ModelService) {}
 
   ngOnInit() {
-    this.experimentService.infoEmitted$.pipe(delay(0)).subscribe((name) => 
(this.modelName = name));
+    this.modelService.infoEmitted$.pipe(delay(0)).subscribe((name) => 
(this.modelName = name));
   }
 }
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/workbench-routing.module.ts
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/workbench-routing.module.ts
index 17ac75c..e872c1c 100644
--- 
a/submarine-workbench/workbench-web/src/app/pages/workbench/workbench-routing.module.ts
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/workbench-routing.module.ts
@@ -66,13 +66,13 @@ const routes: Routes = [
         canActivate: ['canActivatePage'],
       },
       {
-        path: 'data',
-        component: DataComponent,
+        path: 'model',
+        loadChildren: () => import('./model/model.module').then((m) => 
m.ModelModule),
         canActivate: ['canActivatePage'],
       },
       {
-        path: 'model',
-        loadChildren: () => import('./model/model.module').then((m) => 
m.ModelModule),
+        path: 'data',
+        component: DataComponent,
         canActivate: ['canActivatePage'],
       },
       {
diff --git 
a/submarine-workbench/workbench-web/src/app/services/model.service.ts 
b/submarine-workbench/workbench-web/src/app/services/model.service.ts
new file mode 100644
index 0000000..58ab99c
--- /dev/null
+++ b/submarine-workbench/workbench-web/src/app/services/model.service.ts
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { Rest } from '@submarine/interfaces';
+import { ModelInfo } from '@submarine/interfaces/model-info';
+import { BaseApiService } from '@submarine/services/base-api.service';
+import { of, throwError, Observable, Subject } from 'rxjs';
+import { catchError, map, switchMap } from 'rxjs/operators';
+
+@Injectable({
+  providedIn: 'root',
+})
+export class ModelService {
+  /*
+    communicate between route-outlet and parent
+    send experiment-id from ExperimentInfo to ExperimentHome
+  */
+  private emitInfoSource = new Subject<string>();
+  infoEmitted$ = this.emitInfoSource.asObservable();
+
+  constructor(private baseApi: BaseApiService, private httpClient: HttpClient) 
{}
+
+  emitInfo(name: string) {
+    this.emitInfoSource.next(name);
+  }
+
+  fetchModelList(): Observable<ModelInfo[]> {
+    const apiUrl = this.baseApi.getRestApi('/v1/registered-model');
+    return this.httpClient.get<Rest<ModelInfo[]>>(apiUrl).pipe(
+      switchMap((res) => {
+        if (res.success) {
+          return of(res.result);
+        } else {
+          throw this.baseApi.createRequestError(res.message, res.code, apiUrl, 
'get');
+        }
+      })
+    );
+  }
+
+  querySpecificModel(name: string): Observable<ModelInfo> {
+    const apiUrl = this.baseApi.getRestApi(`/v1/regitstered-model/${name}`);
+    return this.httpClient.get<Rest<ModelInfo>>(apiUrl).pipe(
+      switchMap((res) => {
+        if (res.success) {
+          return of(res.result);
+        } else {
+          throw this.baseApi.createRequestError(res.message, res.code, apiUrl, 
'get');
+        }
+      })
+    );
+  }
+
+  durationHandle(secs: number) {
+    const hr = Math.floor(secs / 3600);
+    const min = Math.floor((secs - hr * 3600) / 60);
+    const sec = Math.round(secs) - hr * 3600 - min * 60;
+    let showHr;
+    let showMin;
+    let showSec;
+    if (hr < 10) {
+      showHr = '0' + hr;
+    } else {
+      showHr = hr.toString();
+    }
+    if (min < 10) {
+      showMin = '0' + min;
+    } else {
+      showMin = min.toString();
+    }
+    if (sec < 10) {
+      showSec = '0' + sec;
+    } else {
+      showSec = sec.toString();
+    }
+    return `${showHr}:${showMin}:${showSec}`;
+  }
+}

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to