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 1b44e27 SUBMARINE-430. [WEB] Implement Interpreter page with Angular
1b44e27 is described below
commit 1b44e27d167b626aceac7d8df7b2715f4e295547
Author: kevin85421 <[email protected]>
AuthorDate: Tue Mar 17 13:51:42 2020 +0800
SUBMARINE-430. [WEB] Implement Interpreter page with Angular
### What is this PR for?
Implement frontend of Interpreter page in workbench with Angular
### What type of PR is it?
[Feature]
### Todos
### What is the Jira issue?
https://issues.apache.org/jira/browse/SUBMARINE-430
### How should this be tested?
https://travis-ci.org/github/apache/submarine/builds/663381988?utm_source=github_status&utm_medium=notification
### Screenshots (if appropriate)


### Questions:
* Does the licenses files need an update? No
* Are there breaking changes for older versions? No
* Does this needs documentation? No
Author: kevin85421 <[email protected]>
Closes #229 from kevin85421/SUBMARINE-430 and squashes the following
commits:
7e2ba55 [kevin85421] SUBMARINE-430. [WEB] Implement frontend of Interpreter
page in workbench with Angular
---
.../submarine/integration/interpreterIT.java | 66 +++++++++++++
.../interpreter-add-modal.component.html} | 22 ++++-
.../interpreter-add-modal.component.scss} | 0
.../interpreter-add-modal.component.ts | 67 +++++++++++++
.../interpreter/interpreter.component.html | 110 ++++++++++++++++++++-
.../interpreter/interpreter.component.scss | 14 +++
.../workbench/interpreter/interpreter.component.ts | 92 ++++++++++++++++-
...erpreter.component.ts => interpreter.module.ts} | 27 +++--
.../src/app/pages/workbench/job/job.module.ts | 8 +-
.../src/app/pages/workbench/workbench.module.ts | 14 ++-
.../pages/workbench/workspace/workspace.module.ts | 10 +-
11 files changed, 396 insertions(+), 34 deletions(-)
diff --git
a/submarine-test/test-e2e/src/test/java/org/apache/submarine/integration/interpreterIT.java
b/submarine-test/test-e2e/src/test/java/org/apache/submarine/integration/interpreterIT.java
new file mode 100644
index 0000000..99c385c
--- /dev/null
+++
b/submarine-test/test-e2e/src/test/java/org/apache/submarine/integration/interpreterIT.java
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+package org.apache.submarine.integration;
+
+import org.apache.submarine.AbstractSubmarineIT;
+import org.apache.submarine.WebDriverManager;
+import org.apache.submarine.SubmarineITUtils;
+import org.openqa.selenium.By;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import org.testng.Assert;
+
+public class interpreterIT extends AbstractSubmarineIT {
+
+ public final static Logger LOG =
LoggerFactory.getLogger(interpreterIT.class);
+
+ @BeforeClass
+ public static void startUp(){
+ LOG.info("[Testcase]: interpreterIT");
+ driver = WebDriverManager.getWebDriver();
+ }
+
+ @AfterClass
+ public static void tearDown(){
+ driver.quit();
+ }
+
+ @Test
+ public void workspaceNavigation() throws Exception {
+ // Login
+ LOG.info("Login");
+ pollingWait(By.cssSelector("input[ng-reflect-name='userName']"),
MAX_BROWSER_TIMEOUT_SEC).sendKeys("admin");
+ pollingWait(By.cssSelector("input[ng-reflect-name='password']"),
MAX_BROWSER_TIMEOUT_SEC).sendKeys("admin");
+ clickAndWait(By.cssSelector("button[class='login-form-button ant-btn
ant-btn-primary']"));
+ pollingWait(By.cssSelector("a[routerlink='/workbench/dashboard']"),
MAX_BROWSER_TIMEOUT_SEC);
+
+ // Routing to Interpreter
+ pollingWait(By.xpath("//span[contains(text(), \"Interpreter\")]"),
MAX_BROWSER_TIMEOUT_SEC).click();
+ Assert.assertEquals(driver.getCurrentUrl(),
"http://localhost:8080/workbench/interpreter");
+
+ // Test create new Interpreter
+ pollingWait(By.xpath("//button[@id='interpreterAddButton']"),
MAX_BROWSER_TIMEOUT_SEC).click();
+ pollingWait(By.xpath("//input[@id='inputNewInterpreterName']"),
MAX_BROWSER_TIMEOUT_SEC).sendKeys("Python Interpreter 2");
+ pollingWait(By.xpath("//input[@id='inputNewInterpreterType']"),
MAX_BROWSER_TIMEOUT_SEC).sendKeys("Python");
+ pollingWait(By.cssSelector("button[class='ant-btn ng-star-inserted
ant-btn-primary']"), MAX_BROWSER_TIMEOUT_SEC).click();
+ Assert.assertEquals(
driver.findElements(By.xpath("//td[@id='interpreterNamePython Interpreter
2']")).size(), 1);
+ }
+}
diff --git
a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.component.html
b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter-add-modal/interpreter-add-modal.component.html
similarity index 52%
copy from
submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.component.html
copy to
submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter-add-modal/interpreter-add-modal.component.html
index 598b5fa..db18911 100644
---
a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.component.html
+++
b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter-add-modal/interpreter-add-modal.component.html
@@ -17,4 +17,24 @@
~ under the License.
-->
-<p>interpreter works!</p>
+<nz-modal [nzVisible]="visible" [nzTitle]="modalTitle" nzCancelText="Close"
nzOkText="Ok" (nzOnCancel)="hideModal()"
+ (nzOnOk)="submitForm()">
+ <form nz-form nzLayout="horizontal" [formGroup]="form">
+ <nz-form-item>
+ <nz-form-label nzRequired>
+ Name
+ </nz-form-label>
+ <nz-form-control>
+ <input id="inputNewInterpreterName" type="text" nz-input
formControlName="interpreterName"/>
+ </nz-form-control>
+ </nz-form-item>
+ <nz-form-item>
+ <nz-form-label nzRequired>
+ Type
+ </nz-form-label>
+ <nz-form-control>
+ <input id="inputNewInterpreterType" nz-input
formControlName="interpreterType"/>
+ </nz-form-control>
+ </nz-form-item>
+ </form>
+</nz-modal>
diff --git
a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.component.scss
b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter-add-modal/interpreter-add-modal.component.scss
similarity index 100%
copy from
submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.component.scss
copy to
submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter-add-modal/interpreter-add-modal.component.scss
diff --git
a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter-add-modal/interpreter-add-modal.component.ts
b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter-add-modal/interpreter-add-modal.component.ts
new file mode 100644
index 0000000..52704a3
--- /dev/null
+++
b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter-add-modal/interpreter-add-modal.component.ts
@@ -0,0 +1,67 @@
+/*
+ * 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, EventEmitter, Input, OnChanges, Output, SimpleChanges }
from '@angular/core';
+import { FormBuilder, FormControl, FormGroup, Validators } from
'@angular/forms';
+
+@Component({
+ selector: 'submarine-interpreter-add-modal',
+ templateUrl: './interpreter-add-modal.component.html',
+ styleUrls: ['./interpreter-add-modal.component.scss']
+})
+export class InterpreterAddModalComponent implements OnChanges {
+ @Input() modalTitle: string;
+ @Input() interpreterName: string;
+ @Input() interpreterType: string;
+ @Input() visible: boolean;
+ @Output() readonly close: EventEmitter<any> = new EventEmitter();
+ @Output() readonly ok: EventEmitter<any> = new EventEmitter();
+ form: FormGroup;
+
+ constructor(private fb: FormBuilder) {
+ this.form = this.fb.group({
+ interpreterName: ['', Validators.required],
+ interpreterType: ['', Validators.required]
+ });
+ }
+
+ ngOnChanges (changes: SimpleChanges) {
+ this.form.reset({
+ interpreterName: this.interpreterName,
+ interpreterType: this.interpreterType
+ });
+ }
+
+ hideModal() {
+ this.close.emit();
+ }
+
+ submitForm() {
+ for (const key in this.form.controls) {
+ this.form.controls[key].markAsDirty();
+ this.form.controls[key].updateValueAndValidity();
+ }
+
+ if (!this.form.valid) {
+ return;
+ }
+
+ this.ok.emit(this.form.value);
+ }
+}
diff --git
a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.component.html
b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.component.html
index 598b5fa..1ec7654 100644
---
a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.component.html
+++
b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.component.html
@@ -17,4 +17,112 @@
~ under the License.
-->
-<p>interpreter works!</p>
+<nz-layout style="margin: -24px -24px 16px;">
+ <nz-layout class="inner-layout">
+ <div id="interpreterOuter">
+ <nz-breadcrumb>
+ <nz-breadcrumb-item>
+ <a [routerLink]="['/', 'workbench', 'home']">Home</a>
+ </nz-breadcrumb-item>
+ <nz-breadcrumb-item>Interpreter</nz-breadcrumb-item>
+ </nz-breadcrumb>
+ <br/>
+ <h2>Interpreter</h2>
+ <nz-content>Users can manage their Interpreters.</nz-content>
+ <br/>
+ </div>
+ </nz-layout>
+</nz-layout>
+
+<nz-card>
+ <div class="interpreter-table-operate">
+ <form nz-row nz-form [nzLayout]="'inline'"
[formGroup]="interpreterQueryForm">
+ <nz-form-item nz-col nzSpan="8">
+ <nz-form-label nz-col nzSpan="4">Name</nz-form-label>
+ <nz-form-control nz-col nzSpan="20">
+ <input nz-input formControlName="interpreterName" placeholder="Enter
Interpreter Name"/>
+ </nz-form-control>
+ </nz-form-item>
+ <nz-form-item nz-col nzSpan="8">
+ <nz-form-label nz-col nzSpan="4">Status</nz-form-label>
+ <nz-form-control nz-col nzSpan="20">
+ <nz-cascader [nzOptions]="statusOptions"
formControlName="interpreterStatus" nzPlaceHolder="Enter Interpreter
Status"></nz-cascader>
+ </nz-form-control>
+ </nz-form-item>
+ <nz-form-item nz-col nzSpan="8">
+ <nz-form-control>
+ <button nz-button style="margin-left: 8px" nzType="primary"
(click)="queryInterpreter()">
+ <i nz-icon nzType="search"></i>
+ Query
+ </button>
+ <button nz-button style="margin-left: 8px"
(click)="onShowAddInterpreterModal()" id="interpreterAddButton">
+ <i nz-icon nzType="plus"></i>
+ Add
+ </button>
+ </nz-form-control>
+ </nz-form-item>
+ </form>
+ </div>
+ <div>
+ <nz-table #table [nzData]="interpreterInfoList" [nzScroll]="{ x: '1100px'
}" nzNoResult="No result" nzBordered>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Type</th>
+ <th>Status</th>
+ <th>Progress</th>
+ <th>Last Updated</th>
+ <th nzRight="0px">Action</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr *ngFor="let data of table.data">
+ <td id="{{ 'interpreterName' + data.name }}">{{ data.name }}</td>
+ <td>{{ data.type }}</td>
+ <td>
+ <nz-tag [nzColor]="statusColor[data.status]">{{ data.status
}}</nz-tag>
+ </td>
+ <td>
+ <nz-progress nzStrokeLinecap="round"
[nzPercent]="data.progress"></nz-progress>
+ </td>
+ <td>{{ data.lastUpdated | date: 'medium'}}</td>
+ <td class="td-action" nzRight="0px">
+ <a>
+ <i nz-icon nzType="edit" nzTheme="outline"></i>
+ Start
+ </a>
+ <a nz-dropdown [nzDropdownMenu]="more">
+ More
+ <i nz-icon nzType="down"></i>
+ </a>
+ <nz-dropdown-menu #more="nzDropdownMenu">
+ <ul nz-menu nzSelectable>
+ <li
+ nz-menu-item
+ nz-popconfirm
+ nzTitle="Are you certain you want to kill the interpreter?"
+ nzOkText="Ok"
+ nzCancelText="Cancel"
+ (nzOnConfirm)="killInterpreter()"
+ >
+ Kill
+ </li>
+ <li nz-menu-item>Terminal</li>
+ <li nz-menu-item>Log</li>
+ </ul>
+ </nz-dropdown-menu>
+ </td>
+ </tr>
+ </tbody>
+ </nz-table>
+ </div>
+</nz-card>
+
+<submarine-interpreter-add-modal
+ [modalTitle]="addModalTitle"
+ [visible]="addModalVisible"
+ [interpreterName]="newInterpreterName"
+ [interpreterType]="newInterpreterType"
+ (close)="onHideAddInterpreterModal()"
+ (ok)="updateNewInterpreter($event)"
+></submarine-interpreter-add-modal>
diff --git
a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.component.scss
b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.component.scss
index 3d56d22..3dc1e6e 100644
---
a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.component.scss
+++
b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.component.scss
@@ -16,3 +16,17 @@
* specific language governing permissions and limitations
* under the License.
*/
+
+#interpreterOuter{
+ background-color: white;
+ padding-left: 30px;
+ padding-top: 20px;
+}
+
+.interpreter-table-operate {
+ margin-bottom: 16px;
+}
+
+.td-action a + a {
+ margin-left: 8px;
+}
diff --git
a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.component.ts
b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.component.ts
index 4a3ab30..f170552 100644
---
a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.component.ts
+++
b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.component.ts
@@ -18,6 +18,16 @@
*/
import { Component, OnInit } from '@angular/core';
+import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
+import { CascaderOption } from 'ng-zorro-antd/cascader';
+
+interface InterpreterInfo {
+ name: string;
+ type: string;
+ status: string;
+ progress: number;
+ lastUpdated: number;
+}
@Component({
selector: 'submarine-interpreter',
@@ -25,10 +35,90 @@ import { Component, OnInit } from '@angular/core';
styleUrls: ['./interpreter.component.scss']
})
export class InterpreterComponent implements OnInit {
+ // Add Modal
+ addModalTitle: string;
+ addModalVisible: boolean;
+ newInterpreterName: string = '';
+ newInterpreterType: string = '';
+
+ constructor(private fb: FormBuilder) {
+ this.interpreterQueryForm = this.fb.group({
+ interpreterName: [''],
+ interpreterStatus: ['']
+ });
+ }
+
+ statusOptions: CascaderOption[] = [
+ {
+ value: 'Running',
+ label: 'Running',
+ isLeaf: true
+ },
+ {
+ value: 'Idle',
+ label: 'Idle',
+ isLeaf: true
+ }
+ ];
+
+ statusColor: {[key: string]: string} = {
+ Running: 'blue',
+ Idle: 'green'
+ }
+ interpreterQueryForm: FormGroup
+ // TODO(kevin85421)
+ lastUpdatedTime: number = Date.now();
+ interpreterInfoList: InterpreterInfo[] = [
+ {
+ name: 'Spark Interpreter 1',
+ type: 'Spark',
+ status: 'Running',
+ progress: 50,
+ lastUpdated: this.lastUpdatedTime
+ },
+ {
+ name: 'Python Interpreter 1',
+ type: 'Python',
+ status: 'Idle',
+ progress: 65,
+ lastUpdated: this.lastUpdatedTime
+ }
+ ]
- constructor() { }
+ // TODO(kevin85421)
+ queryInterpreter() {
+ for (const key in this.interpreterQueryForm.controls) {
+ console.log(key);
+ console.log(this.interpreterQueryForm.controls[key].value);
+ }
+ }
+
+ // TODO(kevin85421)
+ killInterpreter() {}
ngOnInit() {
}
+ onShowAddInterpreterModal() {
+ this.addModalTitle = "Add";
+ this.addModalVisible = true;
+ }
+
+ onHideAddInterpreterModal() {
+ this.addModalVisible = false;
+ }
+
+ updateNewInterpreter(newInterpreter: {interpreterName: string,
interpreterType: string}) {
+ this.interpreterInfoList = [
+ ...this.interpreterInfoList,
+ {
+ name: newInterpreter.interpreterName,
+ type: newInterpreter.interpreterType,
+ status: 'Idle',
+ progress: 0,
+ lastUpdated: this.lastUpdatedTime
+ }
+ ]
+ this.onHideAddInterpreterModal();
+ }
}
diff --git
a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.component.ts
b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.module.ts
similarity index 52%
copy from
submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.component.ts
copy to
submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.module.ts
index 4a3ab30..ed0a2e9 100644
---
a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.component.ts
+++
b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/interpreter/interpreter.module.ts
@@ -1,4 +1,4 @@
-/*!
+/*
* 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
@@ -16,19 +16,18 @@
* specific language governing permissions and limitations
* under the License.
*/
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { RouterModule } from '@angular/router';
+import { ComponentsModule } from '@submarine/components/components.module';
+import { NgZorroAntdModule } from 'ng-zorro-antd';
-import { Component, OnInit } from '@angular/core';
+import { InterpreterAddModalComponent } from
'./interpreter-add-modal/interpreter-add-modal.component';
+import { InterpreterComponent } from './interpreter.component';
-@Component({
- selector: 'submarine-interpreter',
- templateUrl: './interpreter.component.html',
- styleUrls: ['./interpreter.component.scss']
+@NgModule({
+ declarations: [InterpreterComponent, InterpreterAddModalComponent],
+ imports: [CommonModule, NgZorroAntdModule, ComponentsModule, FormsModule,
ReactiveFormsModule, RouterModule]
})
-export class InterpreterComponent implements OnInit {
-
- constructor() { }
-
- ngOnInit() {
- }
-
-}
+export class InterpreterModule {}
diff --git
a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/job/job.module.ts
b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/job/job.module.ts
index 01a9df3..256726e 100644
---
a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/job/job.module.ts
+++
b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/job/job.module.ts
@@ -20,7 +20,7 @@ import { ReactiveFormsModule } from '@angular/forms';
* under the License.
*/
- @NgModule({
- exports: [ReactiveFormsModule]
- })
- export class jobModule {}
+@NgModule({
+ exports: [ReactiveFormsModule]
+})
+export class JobModule {}
diff --git
a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/workbench.module.ts
b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/workbench.module.ts
index 6346b80..3d85b23 100644
---
a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/workbench.module.ts
+++
b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/workbench.module.ts
@@ -19,31 +19,28 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
+import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { WorkbenchRoutingModule } from
'@submarine/pages/workbench/workbench-routing.module';
import { NgZorroAntdModule } from 'ng-zorro-antd';
import { DataComponent } from './data/data.component';
import { HomeComponent } from './home/home.component';
-import { InterpreterComponent } from './interpreter/interpreter.component';
+import { InterpreterModule } from './interpreter/interpreter.module';
import { JobComponent } from './job/job.component';
+import { JobModule } from './job/job.module';
import { ModelComponent } from './model/model.component';
import { WorkbenchComponent } from './workbench.component';
import { WorkspaceComponent } from './workspace/workspace.component';
-import { FormsModule } from '@angular/forms';
import { WorkspaceModule } from './workspace/workspace.module';
-import { jobModule } from './job/job.module';
-
-
@NgModule({
declarations: [
WorkbenchComponent,
HomeComponent,
WorkspaceComponent,
- InterpreterComponent,
JobComponent,
DataComponent,
- ModelComponent,
+ ModelComponent
],
imports: [
CommonModule,
@@ -52,7 +49,8 @@ import { jobModule } from './job/job.module';
RouterModule,
FormsModule,
WorkspaceModule,
- jobModule
+ JobModule,
+ InterpreterModule
]
})
export class WorkbenchModule {
diff --git
a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/workspace/workspace.module.ts
b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/workspace/workspace.module.ts
index 3ee851b..df74d79 100644
---
a/submarine-workbench/workbench-web-ng/src/app/pages/workbench/workspace/workspace.module.ts
+++
b/submarine-workbench/workbench-web-ng/src/app/pages/workbench/workspace/workspace.module.ts
@@ -17,17 +17,17 @@
* under the License.
*/
-import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { FormsModule } from '@angular/forms';
import { ComponentsModule } from '@submarine/components/components.module';
import { NgZorroAntdModule } from 'ng-zorro-antd';
+import { NewProjectPageComponent } from
'./project/new-project-page/new-project-page.component';
import { ProjectComponent } from './project/project.component';
import { ReleaseComponent } from './release/release.component';
-import { TrainingComponent } from './training/training.component';
-import { TeamComponent } from './team/team.component';
import { SharedComponent } from './shared/shared.component';
-import { FormsModule } from '@angular/forms';
-import { NewProjectPageComponent } from
'./project/new-project-page/new-project-page.component';
+import { TeamComponent } from './team/team.component';
+import { TrainingComponent } from './training/training.component';
@NgModule({
declarations: [
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]