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

pingsutw 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 7f95da6  SUBMARINE-1178. Upgrade tag components for model management UI
7f95da6 is described below

commit 7f95da6b6bcd763ac9b088b41502465f7b986b3e
Author: andybi7676 <[email protected]>
AuthorDate: Fri Jan 7 22:16:43 2022 +0800

    SUBMARINE-1178. Upgrade tag components for model management UI
    
    ### What is this PR for?
    <!-- A few sentences describing the overall goals of the pull request's 
commits.
    First time? Check out the contributing guide - 
https://submarine.apache.org/contribution/contributions.html
    -->
    Upgrades model management tags UI and allows users to create or delete tags 
through the frontend.
    
    ### What type of PR is it?
    [Bug Fix | Improvement | Feature | Documentation | Hot Fix | Refactoring]
    Improvement
    
    ### Todos
    * [x] - separate UI looking for registered model tags and model version 
tags.
    * [x] - enable tags deletion.
    * [x] - enable tags creation.
    
    ### 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/projects/SUBMARINE/issues/SUBMARINE-1178
    ### 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.
    -->
    Checkout model management page.
    ### Screenshots (if appropriate)
    
    
https://user-images.githubusercontent.com/59821107/148557952-2e8e838f-12d9-4705-a9aa-997269be4697.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: Kevin <[email protected]>
    
    Closes #863 from andybi7676/SUBMARINE-1178 and squashes the following 
commits:
    
    3c069eda [andybi7676] SUBMARINE-1178. upgrade model tags UI and allow 
create&delete through frontend
---
 .../model-card/model-card.component.html           |  2 +-
 .../model/model-home/model-home.component.html     |  4 +-
 .../model/model-info/model-info.component.html     |  4 +-
 .../model/model-info/model-info.component.ts       |  2 -
 .../model-tag/model-tag.component.html             |  7 +-
 .../model-tag/model-tag.component.scss             | 20 ++++-
 .../model-tag/model-tag.component.ts               | 18 ++++-
 .../model/model-tags/model-tags.component.html     | 58 ++++++++++++++
 .../model-tags.component.scss}                     | 25 +++---
 .../model/model-tags/model-tags.component.ts       | 91 ++++++++++++++++++++++
 .../model-version-tag.component.html}              |  9 ++-
 .../model-version-tag.component.scss}              | 22 +++++-
 .../model-version-tag.component.ts}                | 24 ++++--
 .../model-version/model-version.component.html     |  2 +-
 .../src/app/pages/workbench/model/model.module.ts  |  6 +-
 .../src/app/services/model-version.service.ts      | 28 +++++++
 .../src/app/services/model.service.ts              | 28 +++++++
 17 files changed, 310 insertions(+), 40 deletions(-)

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 fcc0f92..4ea2327 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
@@ -22,7 +22,7 @@
     <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>
+      <submarine-model-tag *ngFor="let tag of card.tags" [tag]="tag" 
[type]="'default'"></submarine-model-tag>
     </p>
     <p>Description: {{description}}</p>
     </nz-card>
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 7ea4439..7ae9f46 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
@@ -30,11 +30,11 @@
     <div nz-col [nzSpan]="6">
       <nz-select nzMode="multiple" [nzCustomTemplate]="multipleTemplate" 
style="width: 100%;" nzPlaceHolder="Filter by tags" 
[(ngModel)]="listOfChosenTags" (ngModelChange)="filterByTags()">
         <nz-option *ngFor="let option of listOfTagsOption" 
[nzLabel]="option.label" [nzValue]="option.value" nzCustomContent>
-          <submarine-model-tag [tag]="option.label" 
[cssType]="'default'"></submarine-model-tag>
+          <submarine-model-tag [tag]="option.label" 
[type]="'default'"></submarine-model-tag>
         </nz-option>
       </nz-select>
       <ng-template #multipleTemplate let-selected nzBorderless 
[ngClass]="'noPadding'">
-        <submarine-model-tag [tag]="selected.nzLabel" 
[cssType]="'selection'"></submarine-model-tag>
+        <submarine-model-tag [tag]="selected.nzLabel" 
[type]="'selection'"></submarine-model-tag>
       </ng-template>
     </div>
   </div>
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-info/model-info.component.html
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-info/model-info.component.html
index 8ad2d4a..a8b51b3 100644
--- 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-info/model-info.component.html
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-info/model-info.component.html
@@ -31,7 +31,7 @@
       <p nz-typography>
         <span><strong>Tags: </strong></span>
         <span *ngIf="!isModelInfoLoading">
-          <submarine-model-tag *ngFor="let tag of selectedModelInfo.tags" 
[tag]="tag" [cssType]="'default'"></submarine-model-tag>
+          <submarine-model-tags [modelName]="modelName" 
[tags]="selectedModelInfo.tags" [useVersionTags]="false" 
></submarine-model-tags>
         </span>
       </p>
       <p nz-typography>
@@ -71,7 +71,7 @@
         <td>{{ data.creationTime | date: 'M/d/yyyy, h:mm a' }}</td>
         <td>{{ data.lastUpdatedTime | date: 'M/d/yyyy, h:mm a' }}</td>
         <td>
-          <submarine-model-tag *ngFor="let tag of data.tags" [tag]="tag" 
[cssType]="'default'"></submarine-model-tag>
+          <submarine-model-version-tag *ngFor="let tag of data.tags" 
[tag]="tag" [type]="'default'"></submarine-model-version-tag>
         </td>
         <td>{{ data.description }}</td>
       </tr>
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-info/model-info.component.ts
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-info/model-info.component.ts
index f4f884e..b38fc87 100644
--- 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-info/model-info.component.ts
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-info/model-info.component.ts
@@ -54,7 +54,6 @@ export class ModelInfoComponent implements OnInit {
     this.modelService.querySpecificModel(this.modelName).subscribe(
       (res) => {
         this.selectedModelInfo = res;
-        console.log(this.selectedModelInfo);
         this.isModelInfoLoading = false;
       }
     )
@@ -63,7 +62,6 @@ export class ModelInfoComponent implements OnInit {
   fetchModelAllVersions = () => {
     this.modelVersionService.queryModelAllVersions(this.modelName).subscribe(
       (res) => {
-        console.log(res);
         this.modelVersions = res;
         this.isModelVersionsLoading = false;
       }
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.html
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-tag/model-tag.component.html
similarity index 68%
copy from 
submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.html
copy to 
submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-tag/model-tag.component.html
index 14d2603..c3e9543 100644
--- 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.html
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-tag/model-tag.component.html
@@ -16,8 +16,11 @@
   ~ specific language governing permissions and limitations
   ~ under the License.
   -->
-<span [style.color]="textColor" [style.background-color]="backgroundColor" 
[style.border-color]="borderColor" [style.margin]="margin">
+<span class="body" [style.color]="textColor" 
[style.background-color]="backgroundColor" [style.border-color]="borderColor" 
[style.margin]="margin">
   {{tag}}
-  <i *ngIf="closable" nz-icon nzType="close" style.color="'textColor'"></i>
+  <i class="expand" *ngIf="type==='selection'" nz-icon nzType="close" 
style.color="'textColor'"></i>
+  <span class="delete" *ngIf="type==='editable'" >
+    <i class="icon" (click)="onDeleteTag(tag)" nz-icon nzType="close"></i>
+  </span>
 </span>
   
\ No newline at end of file
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.scss
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-tag/model-tag.component.scss
similarity index 76%
copy from 
submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.scss
copy to 
submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-tag/model-tag.component.scss
index 6f80022..d9f015b 100644
--- 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.scss
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-tag/model-tag.component.scss
@@ -16,17 +16,33 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-span {
+.body {
   border: 0.1em solid;
   border-radius: 0.2em;
   background-color: #fafafa;
   padding: 0em 0.3em 0.1em 0.4em;
 }
 
-i {
+.expand {
   color: rgba($color: #000000, $alpha: 0.0);
 }
 
+.delete {
+  color: rgba($color: #000000, $alpha: 0.6);
+  .icon {
+    &:hover{
+      color: rgba($color: #000000, $alpha: 0.9);
+    }
+    font-size: 0.8em;
+    cursor: pointer;
+    transition: all 0.3s;
+      transition-property: all;
+      transition-duration: 0.3s;
+      transition-timing-function: ease;
+      transition-delay: 0s;
+  }
+}
+
 ::ng-deep .ant-select-selection--multiple .ant-select-selection__choice {
   margin-right: 0.1em;
   padding: 0 0.9em 0 0.8em;
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.ts
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-tag/model-tag.component.ts
similarity index 80%
copy from 
submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.ts
copy to 
submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-tag/model-tag.component.ts
index b862fd1..50dc7ea 100644
--- 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.ts
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-tag/model-tag.component.ts
@@ -18,6 +18,8 @@
  */
 
 import { Component, Input, OnInit } from '@angular/core';
+import { ModelService } from '@submarine/services/model.service';
+import { ModelVersionService } from 
'@submarine/services/model-version.service';
 
 @Component({
   selector: 'submarine-model-tag',
@@ -26,7 +28,8 @@ import { Component, Input, OnInit } from '@angular/core';
 })
 export class ModelTagComponent implements OnInit {
   @Input() tag: string;
-  @Input() cssType: string;
+  @Input() type: string;
+  @Input() deleteTag: Function = null;
   textColor: string;
   backgroundColor: string;
   borderColor: string;
@@ -39,8 +42,8 @@ export class ModelTagComponent implements OnInit {
     this.textColor = this.stringToColour(this.tag, "text");
     this.backgroundColor = this.stringToColour(this.tag, "background");
     this.borderColor = this.stringToColour(this.tag, "border");
-    this.margin = this.cssType == "selection" ? "0em -0.8em 0em -0.7em" : "0em 
0.15em 0em 0.15em";
-    this.closable = this.cssType == "selection";
+    this.margin = this.type == "selection" ? "0em -0.8em 0em -0.7em" : "0em 
0.15em 0em 0.15em";
+    this.closable = this.type == "selection";
   }
 
   stringToColour = (str: string, type: string) => {
@@ -64,4 +67,13 @@ export class ModelTagComponent implements OnInit {
     const rgb = "rgba(" + `${r},${g},${b}` + "," + opacity + ")";
     return rgb;
   }
+
+  onDeleteTag = (tag: string) => {
+    if (this.deleteTag !== null) {
+      this.deleteTag(tag);
+    }
+    else {
+      console.warn(`Can not handle tag deletion!`);
+    }
+  }
 }
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-tags.component.html
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-tags.component.html
new file mode 100644
index 0000000..501ef9b
--- /dev/null
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-tags.component.html
@@ -0,0 +1,58 @@
+<!--
+  ~ 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.
+  -->
+<span *ngIf="useVersionTags">
+  <submarine-model-version-tag *ngFor="let tag of tags" [tag]="tag" 
[type]="'editable'" 
[deleteTag]="deleteVersionTag"></submarine-model-version-tag>
+  <span class="addVersionTag" *ngIf="!inputVisible" (click)="showInput()">
+    <i nz-icon nzType="plus"></i>
+    add tag
+  </span>
+  <span class="addTagInput">
+    <input
+      #inputElement
+      nz-input
+      nzSize="small"
+      *ngIf="inputVisible"
+      type="text"
+      [(ngModel)]="inputValue"
+      style="width: 5em;"
+      (blur)="handleInputConfirm()"
+      (keydown.enter)="handleInputConfirm()"
+    />
+  </span>
+</span>
+<span *ngIf="!useVersionTags">
+  <submarine-model-tag *ngFor="let tag of tags" [tag]="tag" 
[type]="'editable'" [deleteTag]="deleteInfoTag"></submarine-model-tag>
+  <span class="addTag" *ngIf="!inputVisible" (click)="showInput()">
+    <i nz-icon nzType="plus"></i>
+    add tag
+  </span>
+  <span class="addTagInput">
+    <input
+      #inputElement
+      nz-input
+      nzSize="small"
+      *ngIf="inputVisible"
+      type="text"
+      [(ngModel)]="inputValue"
+      style="width: 5em;"
+      (blur)="handleInputConfirm()"
+      (keydown.enter)="handleInputConfirm()"
+    />
+  </span>
+</span>
\ No newline at end of file
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.scss
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-tags.component.scss
similarity index 70%
copy from 
submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.scss
copy to 
submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-tags.component.scss
index 6f80022..f8a1d82 100644
--- 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.scss
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-tags.component.scss
@@ -16,20 +16,23 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-span {
-  border: 0.1em solid;
+.addTag {
+  border: 0.1em dashed;
   border-radius: 0.2em;
-  background-color: #fafafa;
-  padding: 0em 0.3em 0.1em 0.4em;
+  border-color: #cccccc;
+  padding: 0em 0.5em 0.1em 0.5em;
+  margin:  0em 0.15em 0em 0.15em;
 }
 
-i {
-  color: rgba($color: #000000, $alpha: 0.0);
+.addVersionTag {
+  border: 0.1em dashed;
+  border-radius: 1em;
+  border-color: #cccccc;
+  padding: 0em 0.5em 0.1em 0.5em;
+  margin:  0em 0.15em 0em 0.15em;
 }
 
-::ng-deep .ant-select-selection--multiple .ant-select-selection__choice {
-  margin-right: 0.1em;
-  padding: 0 0.9em 0 0.8em;
-  background-color: #ffffff;
-  border: 0em solid #e8e8e8;
+.addTagInput {
+  border: none;
+  margin:  0em 0.15em 0em 0.15em;
 }
\ No newline at end of file
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-tags.component.ts
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-tags.component.ts
new file mode 100644
index 0000000..fd1fc0b
--- /dev/null
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-tags.component.ts
@@ -0,0 +1,91 @@
+/*
+ * 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 { Component, Input, OnInit, ElementRef, ViewChild } from 
'@angular/core';
+import { ModelService } from '@submarine/services/model.service';
+import { ModelVersionService } from 
'@submarine/services/model-version.service';
+
+@Component({
+  selector: 'submarine-model-tags',
+  templateUrl: './model-tags.component.html',
+  styleUrls: ['./model-tags.component.scss'],
+})
+export class ModelTagsComponent implements OnInit {
+  @Input() modelName: string = null;
+  @Input() modelVersion: string = null;
+  @Input() useVersionTags: boolean; // if true, use submarine model version 
tag, otherwise use submarine model tag.
+  @Input() tags: Array<string>;
+  @ViewChild('inputElement', { static: false }) inputElement?: ElementRef;
+  inputVisible: boolean = false;
+  inputValue: string = "";
+
+  constructor(
+    private modelVersionService: ModelVersionService,
+    private modelService: ModelService,
+  ) {}
+  
+  ngOnInit() {
+     
+  }
+
+  deleteVersionTag = (tag: string) => {
+    this.modelVersionService.deleteModelVersionTag(this.modelName, 
this.modelVersion, tag).subscribe(
+      (res) => {
+        this.tags = this.tags.filter(t => t !== tag);
+      }
+    );
+  }
+
+  deleteInfoTag = (tag: string) => {
+    this.modelService.deleteModelTag(this.modelName, tag).subscribe(
+      (res) => {
+        this.tags = this.tags.filter(t => t !== tag);
+      }
+    );
+  }
+
+  showInput = () => {
+    this.inputVisible = true;
+    setTimeout(() => {
+      this.inputElement.nativeElement.focus();
+    }, 10);
+  }
+
+  handleInputConfirm = () => {
+    if (this.inputValue) {
+      const newTag = this.inputValue;
+      if (!this.useVersionTags) {
+        this.modelService.createModelTag(this.modelName, newTag).subscribe(
+          (res) => {
+            this.tags.push(newTag);
+          }
+        );
+      }
+      else {
+        this.modelVersionService.createModelVersionTag(this.modelName, 
this.modelVersion, newTag).subscribe(
+          (res) => {
+            this.tags.push(newTag);
+          }
+        );
+      }
+    }
+    this.inputValue = "";
+    this.inputVisible = false;
+  }
+}
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.html
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-version-tag/model-version-tag.component.html
similarity index 68%
rename from 
submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.html
rename to 
submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-version-tag/model-version-tag.component.html
index 14d2603..57620bc 100644
--- 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.html
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-version-tag/model-version-tag.component.html
@@ -16,8 +16,11 @@
   ~ specific language governing permissions and limitations
   ~ under the License.
   -->
-<span [style.color]="textColor" [style.background-color]="backgroundColor" 
[style.border-color]="borderColor" [style.margin]="margin">
+<span class="body" [style.color]="textColor" 
[style.background-color]="backgroundColor" [style.border-color]="borderColor" 
[style.margin]="margin">
   {{tag}}
-  <i *ngIf="closable" nz-icon nzType="close" style.color="'textColor'"></i>
+  <i class="expand" *ngIf="type==='selection'" nz-icon nzType="close" 
style.color="'textColor'"></i>
+  <span class="delete" *ngIf="type==='editable'" >
+    <i class="icon" (click)="onDeleteTag(tag)" nz-icon nzType="close"></i>
+  </span>
 </span>
-  
\ No newline at end of file
+    
\ No newline at end of file
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.scss
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-version-tag/model-version-tag.component.scss
similarity index 74%
rename from 
submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.scss
rename to 
submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-version-tag/model-version-tag.component.scss
index 6f80022..a258c21 100644
--- 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.scss
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-version-tag/model-version-tag.component.scss
@@ -16,17 +16,33 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-span {
+.body {
   border: 0.1em solid;
-  border-radius: 0.2em;
+  border-radius: 1em;
   background-color: #fafafa;
   padding: 0em 0.3em 0.1em 0.4em;
 }
 
-i {
+.expand {
   color: rgba($color: #000000, $alpha: 0.0);
 }
 
+.delete {
+  color: rgba($color: #000000, $alpha: 0.6);
+  .icon {
+    &:hover{
+      color: rgba($color: #000000, $alpha: 0.9);
+    }
+    font-size: 0.8em;
+    cursor: pointer;
+    transition: all 0.3s;
+      transition-property: all;
+      transition-duration: 0.3s;
+      transition-timing-function: ease;
+      transition-delay: 0s;
+  }
+}
+
 ::ng-deep .ant-select-selection--multiple .ant-select-selection__choice {
   margin-right: 0.1em;
   padding: 0 0.9em 0 0.8em;
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.ts
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-version-tag/model-version-tag.component.ts
similarity index 77%
rename from 
submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.ts
rename to 
submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-version-tag/model-version-tag.component.ts
index b862fd1..0bf05fa 100644
--- 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tag/model-tag.component.ts
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-tags/model-version-tag/model-version-tag.component.ts
@@ -20,13 +20,14 @@
 import { Component, Input, OnInit } from '@angular/core';
 
 @Component({
-  selector: 'submarine-model-tag',
-  templateUrl: './model-tag.component.html',
-  styleUrls: ['./model-tag.component.scss'],
+  selector: 'submarine-model-version-tag',
+  templateUrl: './model-version-tag.component.html',
+  styleUrls: ['./model-version-tag.component.scss'],
 })
-export class ModelTagComponent implements OnInit {
+export class ModelVersionTagComponent implements OnInit {
   @Input() tag: string;
-  @Input() cssType: string;
+  @Input() type: string;
+  @Input() deleteTag: Function = null;
   textColor: string;
   backgroundColor: string;
   borderColor: string;
@@ -39,8 +40,8 @@ export class ModelTagComponent implements OnInit {
     this.textColor = this.stringToColour(this.tag, "text");
     this.backgroundColor = this.stringToColour(this.tag, "background");
     this.borderColor = this.stringToColour(this.tag, "border");
-    this.margin = this.cssType == "selection" ? "0em -0.8em 0em -0.7em" : "0em 
0.15em 0em 0.15em";
-    this.closable = this.cssType == "selection";
+    this.margin = this.type == "selection" ? "0em -0.8em 0em -0.7em" : "0em 
0.15em 0em 0.15em";
+    this.closable = this.type == "selection";
   }
 
   stringToColour = (str: string, type: string) => {
@@ -64,4 +65,13 @@ export class ModelTagComponent implements OnInit {
     const rgb = "rgba(" + `${r},${g},${b}` + "," + opacity + ")";
     return rgb;
   }
+
+  onDeleteTag = (tag: string) => {
+    if (this.deleteTag !== null) {
+      this.deleteTag(tag);
+    }
+    else {
+      console.warn(`Can not handle tag deletion!`);
+    }
+  }
 }
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-version/model-version.component.html
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-version/model-version.component.html
index fd3cd01..82bc4ba 100644
--- 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-version/model-version.component.html
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model-version/model-version.component.html
@@ -53,7 +53,7 @@
       <p nz-typography>
         <span><strong>Tags: </strong></span>
         <span  *ngIf="!isLoading">
-          <submarine-model-tag *ngFor="let tag of modelVersionInfo.tags" 
[tag]="tag" [cssType]="'default'"></submarine-model-tag>
+          <submarine-model-tags [modelName]="modelName" 
[modelVersion]="modelVersion" [tags]="modelVersionInfo.tags" 
[useVersionTags]="true"></submarine-model-tags>
         </span>
       </p>
       <p nz-typography>
diff --git 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model.module.ts
 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model.module.ts
index 736482e..007db1a 100644
--- 
a/submarine-workbench/workbench-web/src/app/pages/workbench/model/model.module.ts
+++ 
b/submarine-workbench/workbench-web/src/app/pages/workbench/model/model.module.ts
@@ -29,7 +29,9 @@ import { PipeSharedModule } from 
'@submarine/pipe/pipe-shared.module';
 import { ModelHomeComponent } from './model-home/model-home.component';
 import { ModelCardsComponent } from 
'./model-home/model-cards/model-cards.component';
 import { ModelCardComponent } from 
'./model-home/model-cards/model-card/model-card.component';
-import { ModelTagComponent } from './model-tag/model-tag.component';
+import { ModelTagComponent } from './model-tags/model-tag/model-tag.component';
+import { ModelVersionTagComponent } from 
'./model-tags/model-version-tag/model-version-tag.component';
+import { ModelTagsComponent } from './model-tags/model-tags.component';
 import { ModelInfoComponent } from './model-info/model-info.component';
 
 @NgModule({
@@ -40,6 +42,8 @@ import { ModelInfoComponent } from 
'./model-info/model-info.component';
     ModelCardsComponent,
     ModelCardComponent,
     ModelTagComponent,
+    ModelVersionTagComponent,
+    ModelTagsComponent,
     ModelInfoComponent,
   ],
   imports: [
diff --git 
a/submarine-workbench/workbench-web/src/app/services/model-version.service.ts 
b/submarine-workbench/workbench-web/src/app/services/model-version.service.ts
index 9c1dbc5..821ee53 100644
--- 
a/submarine-workbench/workbench-web/src/app/services/model-version.service.ts
+++ 
b/submarine-workbench/workbench-web/src/app/services/model-version.service.ts
@@ -65,4 +65,32 @@ export class ModelVersionService {
       })
     );
   }
+
+  deleteModelVersionTag(modelName: string, modelVersion: string, tag: string) 
: Observable<string> {
+    const apiUrl = 
this.baseApi.getRestApi(`/v1/model-version/tag?name=${modelName}&version=${modelVersion}&tag=${tag}`);
+    return this.httpClient.delete<Rest<any>>(apiUrl).pipe(
+      switchMap((res) => {
+        if (res.success) {
+          return of(res.message);
+        }
+        else {
+          throw this.baseApi.createRequestError(res.message, res.code, apiUrl, 
'delete');
+        }
+      })
+    )
+  }
+
+  createModelVersionTag(modelName: string, modelVersion: string, tag: string) 
: Observable<string> {
+    const apiUrl = 
this.baseApi.getRestApi(`/v1/model-version/tag?name=${modelName}&version=${modelVersion}&tag=${tag}`);
+    return this.httpClient.post<Rest<any>>(apiUrl, {}).pipe(
+      switchMap((res) => {
+        if (res.success) {
+          return of(res.message);
+        }
+        else {
+          throw this.baseApi.createRequestError(res.message, res.code, apiUrl, 
'post');
+        }
+      })
+    )
+  }
 }
\ No newline at end of file
diff --git 
a/submarine-workbench/workbench-web/src/app/services/model.service.ts 
b/submarine-workbench/workbench-web/src/app/services/model.service.ts
index cd1e9a5..491c68a 100644
--- a/submarine-workbench/workbench-web/src/app/services/model.service.ts
+++ b/submarine-workbench/workbench-web/src/app/services/model.service.ts
@@ -68,6 +68,34 @@ export class ModelService {
     );
   }
 
+  deleteModelTag(modelName: string, tag: string): Observable<string> {
+    const apiUrl = 
this.baseApi.getRestApi(`/v1/registered-model/tag?name=${modelName}&tag=${tag}`);
+    return this.httpClient.delete<Rest<any>>(apiUrl).pipe(
+      switchMap((res) => {
+        if (res.success) {
+          return of(res.message);
+        }
+        else {
+          throw this.baseApi.createRequestError(res.message, res.code, apiUrl, 
'delete');
+        }
+      })
+    )
+  }
+
+  createModelTag(modelName: string, tag: string) : Observable<string> {
+    const apiUrl = 
this.baseApi.getRestApi(`/v1/registered-model/tag?name=${modelName}&tag=${tag}`);
+    return this.httpClient.post<Rest<any>>(apiUrl, {}).pipe(
+      switchMap((res) => {
+        if (res.success) {
+          return of(res.message);
+        }
+        else {
+          throw this.baseApi.createRequestError(res.message, res.code, apiUrl, 
'post');
+        }
+      })
+    )
+  }
+
   durationHandle(secs: number) {
     const hr = Math.floor(secs / 3600);
     const min = Math.floor((secs - hr * 3600) / 60);

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

Reply via email to