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]