You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@submarine.apache.org by li...@apache.org on 2020/09/18 01:51:28 UTC
[submarine] branch master updated: SUBMARINE-608. [WEB] Create
environment through UI
This is an automated email from the ASF dual-hosted git repository.
liuxun 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 329fec8 SUBMARINE-608. [WEB] Create environment through UI
329fec8 is described below
commit 329fec8e53355b9d3465b044c9e7c75b96c31e80
Author: kobe860219 <ko...@gmail.com>
AuthorDate: Thu Sep 17 11:14:59 2020 +0800
SUBMARINE-608. [WEB] Create environment through UI
### What is this PR for?
Complete creation environment through UI.
### What type of PR is it?
[Feature]
### Todos
### What is the Jira issue?
https://issues.apache.org/jira/browse/SUBMARINE-608
### How should this be tested?
https://travis-ci.org/github/kobe860219/submarine/builds/727321947
### Screenshots (if appropriate)
![螢幕錄製 2020-09-15 下午4](https://user-images.githubusercontent.com/48027290/93199002-5a3c5780-f780-11ea-939f-bb31c6d4069b.gif)
### Questions:
* Does the licenses files need update? No
* Is there breaking changes for older versions? No
* Does this needs documentation? No
Author: kobe860219 <ko...@gmail.com>
Closes #402 from kobe860219/SUBMARINE-608 and squashes the following commits:
207f0ef [kobe860219] SUBMARINE-608. [WEB] Create environment through UI
5a457f4 [kobe860219] SUBMARINE-608. [WEB] Create environment through UI
---
.../src/app/interfaces/environment-spec.ts | 2 -
.../environment/environment.component.html | 104 +++++++++++++++++++
.../workbench/environment/environment.component.ts | 112 +++++++++++++++++++--
.../workbench/notebook/notebook.component.html | 2 +-
.../src/app/services/environment.service.ts | 15 ++-
5 files changed, 224 insertions(+), 11 deletions(-)
diff --git a/submarine-workbench/workbench-web-ng/src/app/interfaces/environment-spec.ts b/submarine-workbench/workbench-web-ng/src/app/interfaces/environment-spec.ts
index ffc32e8..90cd3b6 100644
--- a/submarine-workbench/workbench-web-ng/src/app/interfaces/environment-spec.ts
+++ b/submarine-workbench/workbench-web-ng/src/app/interfaces/environment-spec.ts
@@ -24,8 +24,6 @@ export interface KernelSpec {
export interface EnvironmentSpec {
name: string;
- description: string;
dockerImage: string;
- image: string;
kernelSpec: KernelSpec;
}
diff --git a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/environment/environment.component.html b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/environment/environment.component.html
index 10de4d5..8fcdd17 100644
--- a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/environment/environment.component.html
+++ b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/environment/environment.component.html
@@ -58,6 +58,7 @@
id="createEnvironment"
nzType="primary"
style="margin-right: 5px; margin-bottom: 15px; margin-top: 15px;"
+ (click)="initEnvForm()"
>
<i nz-icon nzType="plus"></i>
New Environment
@@ -115,3 +116,106 @@
<router-outlet></router-outlet>
</div>
</nz-layout>
+
+<nz-modal [(nzVisible)]="isVisible" nzTitle="Create Environment" [nzWidth]="700">
+ <div *nzModalFooter>
+ <button nz-button nzType="default" (click)="closeModal()">Cancel</button>
+ <button id="go" nz-button nzType="primary" [disabled]="checkStatus()" (click)="createEnvironment()">
+ Create
+ </button>
+ </div>
+ <div>
+ <form [formGroup]="environmentForm">
+ <h2>Meta</h2>
+ <div class="single-field-group">
+ <label for="environmentName">
+ <span class="red-star">*</span>
+ Environment Name
+ </label>
+ <input
+ required
+ nz-input
+ type="text"
+ name="environmentName"
+ id="environmentName"
+ formControlName="environmentName"
+ />
+ </div>
+ <div class="single-field-group">
+ <label for="dockerImage">
+ <span class="red-star">*</span>
+ Docker Image
+ </label>
+ <input required nz-input type="text" name="dockerImage" id="dockerImage" formControlName="dockerImage" />
+ </div>
+ <h2>Kernel Spec</h2>
+ <div class="single-field-group">
+ <label for="name">
+ <span class="red-star">*</span>
+ Name
+ </label>
+ <input required nz-input type="text" name="name" id="name" formControlName="name" />
+ </div>
+ <div formArrayName="channels">
+ <div *ngFor="let channel of channels.controls; let i = index">
+ <div class="single-field-group">
+ <label>Channel {{ i + 1 }}:</label>
+ <input required nz-input type="text" name="channel{{ i }}" id="channel{{ i }}" [formControlName]="i" />
+ <i
+ nz-icon
+ style="margin-left: 5px;"
+ nzType="close-circle"
+ nzTheme="fill"
+ (click)="deleteItem(channels, i)"
+ ></i>
+ </div>
+ </div>
+ </div>
+ <div style="margin: 10px;">
+ <button
+ nz-button
+ style="display: block; margin: auto;"
+ id="addChannel-btn"
+ type="default"
+ (click)="addChannel()"
+ >
+ New Channel
+ </button>
+ </div>
+ <div formArrayName="dependencies">
+ <div *ngFor="let channel of dependencies.controls; let i = index">
+ <div class="single-field-group">
+ <label>Dependency {{ i + 1 }}:</label>
+ <input
+ required
+ nz-input
+ type="text"
+ name="dependencies{{ i }}"
+ id="dependencies{{ i }}"
+ [formControlName]="i"
+ />
+ <i
+ nz-icon
+ style="margin-left: 5px;"
+ nzType="close-circle"
+ nzTheme="fill"
+ (click)="deleteItem(dependencies, i)"
+ ></i>
+ </div>
+ </div>
+ </div>
+ <div style="margin: 10px;">
+ <button
+ style="margin-top: 10px;"
+ nz-button
+ style="display: block; margin: auto;"
+ id="addDep-btn"
+ type="default"
+ (click)="addDependencies()"
+ >
+ New Dependency
+ </button>
+ </div>
+ </form>
+ </div>
+</nz-modal>
diff --git a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/environment/environment.component.ts b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/environment/environment.component.ts
index dbef9ec..023769c 100644
--- a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/environment/environment.component.ts
+++ b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/environment/environment.component.ts
@@ -18,6 +18,7 @@
*/
import { Component, OnInit } from '@angular/core';
+import { FormArray, FormControl, FormGroup, Validators } from '@angular/forms';
import { Environment } from '@submarine/interfaces/environment-info';
import { EnvironmentService } from '@submarine/services/environment.service';
import { NzMessageService } from 'ng-zorro-antd';
@@ -28,15 +29,23 @@ import { NzMessageService } from 'ng-zorro-antd';
styleUrls: ['./environment.component.scss']
})
export class EnvironmentComponent implements OnInit {
- constructor(
- private environmentService: EnvironmentService,
- private nzMessageService: NzMessageService) {}
+ constructor(private environmentService: EnvironmentService, private nzMessageService: NzMessageService) {}
environmentList: Environment[] = [];
checkedList: boolean[] = [];
selectAllChecked: boolean = false;
+ isVisible = false;
+ environmentForm;
+
ngOnInit() {
+ this.environmentForm = new FormGroup({
+ environmentName: new FormControl(null, Validators.required),
+ dockerImage: new FormControl(null, Validators.required),
+ name: new FormControl(null, Validators.required),
+ channels: new FormArray([]),
+ dependencies: new FormArray([])
+ });
this.fetchEnvironmentList();
}
@@ -50,8 +59,99 @@ export class EnvironmentComponent implements OnInit {
});
}
- // TODO(kobe860219): Create new environment
- createEnvironment(data) {}
+ get environmentName() {
+ return this.environmentForm.get('environmentName');
+ }
+
+ get dockerImage() {
+ return this.environmentForm.get('dockerImage');
+ }
+
+ get name() {
+ return this.environmentForm.get('name');
+ }
+
+ get channels() {
+ return this.environmentForm.get('channels') as FormArray;
+ }
+
+ get dependencies() {
+ return this.environmentForm.get('dependencies') as FormArray;
+ }
+
+ initEnvForm() {
+ this.isVisible = true;
+ this.environmentName.reset();
+ this.dockerImage.reset();
+ this.name.reset();
+ this.channels.clear();
+ this.dependencies.clear();
+ }
+
+ checkStatus() {
+ return (
+ this.environmentName.invalid ||
+ this.dockerImage.invalid ||
+ this.name.invalid ||
+ this.channels.invalid ||
+ this.dependencies.invalid
+ );
+ }
+
+ closeModal() {
+ this.isVisible = false;
+ }
+
+ addChannel() {
+ this.channels.push(new FormControl('', Validators.required));
+ }
+
+ addDependencies() {
+ this.dependencies.push(new FormControl('', Validators.required));
+ }
+
+ deleteItem(arr: FormArray, index: number) {
+ arr.removeAt(index);
+ }
+
+ createEnvironment() {
+ this.isVisible = false;
+ const newEnvironmentSpec = this.createEnvironmentSpec();
+ console.log(newEnvironmentSpec);
+ this.environmentService.createEnvironment(newEnvironmentSpec).subscribe(
+ () => {
+ this.nzMessageService.success('Create Environment Success!');
+ this.fetchEnvironmentList();
+ },
+ (err) => {
+ this.nzMessageService.error(`${err}, please try again`, {
+ nzPauseOnHover: true
+ });
+ }
+ );
+ }
+
+ createEnvironmentSpec() {
+ const environmentSpec = {
+ name: this.environmentForm.get('environmentName').value,
+ dockerImage: this.environmentForm.get('dockerImage').value,
+ kernelSpec: {
+ name: this.environmentForm.get('name').value,
+ channels: [],
+ dependencies: []
+ }
+ };
+
+ for (const channel of this.channels.controls) {
+ environmentSpec.kernelSpec.channels.push(channel.value);
+ }
+
+ for (const dependency of this.dependencies.controls) {
+ environmentSpec.kernelSpec.dependencies.push(dependency.value);
+ }
+
+ return environmentSpec;
+ }
// TODO(kobe860219): Update an environment
updateEnvironment(id: string, data) {}
@@ -74,7 +174,7 @@ export class EnvironmentComponent implements OnInit {
deleteEnvironments() {
for (let i = this.checkedList.length - 1; i >= 0; i--) {
- console.log(this.environmentList[i].environmentSpec.name)
+ console.log(this.environmentList[i].environmentSpec.name);
if (this.checkedList[i] === true) {
this.onDeleteEnvironment(this.environmentList[i].environmentSpec.name, false);
}
diff --git a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/notebook/notebook.component.html b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/notebook/notebook.component.html
index cdd0ed9..e1c4f7e 100644
--- a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/notebook/notebook.component.html
+++ b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/notebook/notebook.component.html
@@ -190,7 +190,7 @@
</div>
</div>
<button nz-button style="display: block; margin: auto;" id="envVar-btn" type="default" (click)="onCreateEnvVar()">
- Add new env
+ Add New EnvVar
</button>
</form>
</nz-modal>
diff --git a/submarine-workbench/workbench-web-ng/src/app/services/environment.service.ts b/submarine-workbench/workbench-web-ng/src/app/services/environment.service.ts
index 7f28365..9a14d3d 100644
--- a/submarine-workbench/workbench-web-ng/src/app/services/environment.service.ts
+++ b/submarine-workbench/workbench-web-ng/src/app/services/environment.service.ts
@@ -24,6 +24,7 @@ import { Environment } from '@submarine/interfaces/environment-info';
import { BaseApiService } from '@submarine/services/base-api.service';
import { of, throwError, Observable } from 'rxjs';
import { catchError, map, switchMap } from 'rxjs/operators';
+import { EnvironmentSpec } from '@submarine/interfaces/environment-spec';
@Injectable({
providedIn: 'root'
@@ -48,8 +49,18 @@ export class EnvironmentService {
// TODO(kobe860219): Query environment
querySpecificEnvironment(id: string) {}
- // TODO(kobe860219): Create new environment
- createEnvironment(createData) {}
+ createEnvironment(spec: object): Observable<Environment> {
+ const apiUrl = this.baseApi.getRestApi(`/v1/environment/`);
+ return this.httpClient.post<Rest<Environment>>(apiUrl, spec).pipe(
+ switchMap((res) => {
+ if (res.success) {
+ return of(res.result);
+ } else {
+ throw this.baseApi.createRequestError(res.message, res.code, apiUrl, 'post', spec);
+ }
+ })
+ );
+ }
// TODO(kobe860219): Update an environment
updateEnvironment(updateData) {}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@submarine.apache.org
For additional commands, e-mail: dev-help@submarine.apache.org