You are viewing a plain text version of this content. The canonical link for it is here.
Posted to submarine-dev@hadoop.apache.org by li...@apache.org on 2019/10/12 02:17:00 UTC
[hadoop-submarine] branch master updated: SUBMARINE-216. Integrated
workbench add project web & server
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/hadoop-submarine.git
The following commit(s) were added to refs/heads/master by this push:
new 36d8c78 SUBMARINE-216. Integrated workbench add project web & server
36d8c78 is described below
commit 36d8c78383bf953849e4dd0062085dd3de420253
Author: Xun Liu <li...@apache.org>
AuthorDate: Fri Oct 4 17:09:33 2019 +0800
SUBMARINE-216. Integrated workbench add project web & server
### What is this PR for?
The submarine project manager is independently developed.
Integration of front-end pages and back-end services is required.
### What type of PR is it?
[Improvement]
### Todos
* [ ] - Task
### What is the Jira issue?
* https://issues.apache.org/jira/browse/SUBMARINE-216
### How should this be tested?
* [CI pass](https://travis-ci.org/liuxunorg/hadoop-submarine/builds/596424390)
### Screenshots (if appropriate)
![project-add](https://user-images.githubusercontent.com/3677382/66627864-8aee4580-ec2f-11e9-82b1-9fe1cf1ff602.gif)
### Questions:
* Does the licenses files need update? Yes/No
* Is there breaking changes for older versions? Yes/No
* Does this needs documentation? Yes/No
Author: Xun Liu <li...@apache.org>
Closes #42 from liuxunorg/SUBMARINE-216 and squashes the following commits:
022f86e [Xun Liu] [SUBMARINE-216] Integrated workbench add project web & server
---
docs/database/submarine-data.sql | 15 ++
docs/database/submarine.sql | 14 +-
.../apache/submarine/database/entity/Project.java | 99 +++++++++---
.../org/apache/submarine/rest/ProjectRestApi.java | 60 +++++++-
.../submarine/database/mappers/ProjectMapper.xml | 70 ++++++---
.../database/service/ProjectServiceTest.java | 26 ++--
.../workbench-web/public/assets/notebook_logo.png | Bin 0 -> 8354 bytes
.../workbench-web/public/assets/python_logo.png | Bin 0 -> 10836 bytes
.../workbench-web/public/assets/r_logo.png | Bin 0 -> 8793 bytes
.../workbench-web/public/assets/scala_logo.png | Bin 0 -> 10055 bytes
.../workbench-web/src/api/system.js | 14 +-
.../src/components/Dict/DictSelectTag.vue | 47 +++++-
.../workbench/workspace/project/NewProject.vue | 117 +++++++-------
.../workspace/project/NewProjectStep1.vue | 105 +++++++++++--
.../workspace/project/NewProjectStep2.vue | 139 +++++++++++++----
.../workspace/project/NewProjectStep3.vue | 36 +++--
.../workbench/workspace/project/ProjectList.vue | 168 +++++++--------------
17 files changed, 623 insertions(+), 287 deletions(-)
diff --git a/docs/database/submarine-data.sql b/docs/database/submarine-data.sql
index 4f37838..644a15e 100644
--- a/docs/database/submarine-data.sql
+++ b/docs/database/submarine-data.sql
@@ -16,6 +16,9 @@
-- ----------------------------
INSERT INTO `sys_dict` VALUES ('ca2dd544ca4c11e9a71e0242ac110002','SYS_USER_SEX','Sys user sex','submarine system dict, Do not modify.',0,0,NULL,'2019-08-29 11:04:36',NULL,'2019-09-01 01:08:12');
INSERT INTO `sys_dict` VALUES ('f405a7b1cc5411e9af810242ac110002','SYS_USER_STATUS','Sys user status','submarine system dict, Do not modify.',0,0,NULL,'2019-09-01 01:08:05',NULL,'2019-09-01 01:08:05');
+INSERT INTO `sys_dict` VALUES ('3a1ed33ae83611e9ab840242ac110002','PROJECT_TYPE','Project machine learning type','submarine system dict, Do not modify.',0,0,NULL,'2019-09-01 01:08:05',NULL,'2019-09-01 01:08:05');
+INSERT INTO `sys_dict` VALUES ('8a101495e84011e9ab840242ac110002','PROJECT_VISIBILITY','Project visibility type','submarine system dict, Do not modify.',0,0,NULL,'2019-09-01 01:08:05',NULL,'2019-09-01 01:08:05');
+INSERT INTO `sys_dict` VALUES ('8f0439c9e84011e9ab840242ac110002','PROJECT_PERMISSION','Project permission type','submarine system dict, Do not modify.',0,0,NULL,'2019-09-01 01:08:05',NULL,'2019-09-01 01:08:05');
-- ----------------------------
-- Records of sys_dict_item
@@ -25,6 +28,18 @@ INSERT INTO `sys_dict_item` VALUES ('4c5d736acc5511e9af810242ac110002','SYS_USER
INSERT INTO `sys_dict_item` VALUES ('6d5ae3b2cc5511e9af810242ac110002','SYS_USER_STATUS_REGISTERED','New Registered','SYS_USER_STATUS','submarine system dict, Do not modify.',3,0,NULL,'2019-09-01 01:11:29',NULL,'2019-09-01 01:12:47');
INSERT INTO `sys_dict_item` VALUES ('d018e2b0ca4c11e9a71e0242ac110002','SYS_USER_SEX_MALE','Male','SYS_USER_SEX','submarine system dict, Do not modify.',1,0,NULL,'2019-08-29 11:04:46',NULL,'2019-09-01 00:53:54');
INSERT INTO `sys_dict_item` VALUES ('d94410adca4c11e9a71e0242ac110002','SYS_USER_SEX_FEMALE','Female','SYS_USER_SEX','submarine system dict, Do not modify.',2,0,NULL,'2019-08-29 11:05:02',NULL,'2019-09-01 00:54:00');
+INSERT INTO `sys_dict_item` VALUES ('7b9aafa0e83611e9ab840242ac110002','PROJECT_TYPE_NOTEBOOK','notebook','PROJECT_TYPE','submarine system dict, Do not modify.',1,0,NULL,'2019-08-29 11:05:02',NULL,'2019-09-01 00:54:00');
+INSERT INTO `sys_dict_item` VALUES ('8229a76be83611e9ab840242ac110002','PROJECT_TYPE_PYTHON','python','PROJECT_TYPE','submarine system dict, Do not modify.',2,0,NULL,'2019-08-29 11:05:02',NULL,'2019-09-01 00:54:00');
+INSERT INTO `sys_dict_item` VALUES ('ac80ab12e83611e9ab840242ac110002','PROJECT_TYPE_R','R','PROJECT_TYPE','submarine system dict, Do not modify.',3,0,NULL,'2019-08-29 11:05:02',NULL,'2019-09-01 00:54:00');
+INSERT INTO `sys_dict_item` VALUES ('b1070158e83611e9ab840242ac110002','PROJECT_TYPE_SCALA','scala','PROJECT_TYPE','submarine system dict, Do not modify.',4,0,NULL,'2019-08-29 11:05:02',NULL,'2019-09-01 00:54:00');
+INSERT INTO `sys_dict_item` VALUES ('8c53870be83611e9ab840242ac110002','PROJECT_TYPE_TENSORFLOW','tensorflow','PROJECT_TYPE','submarine system dict, Do not modify.',5,0,NULL,'2019-08-29 11:05:02',NULL,'2019-09-01 00:54:00');
+INSERT INTO `sys_dict_item` VALUES ('90ca63dfe83611e9ab840242ac110002','PROJECT_TYPE_PYTORCH','pytorch','PROJECT_TYPE','submarine system dict, Do not modify.',6,0,NULL,'2019-08-29 11:05:02',NULL,'2019-09-01 00:54:00');
+INSERT INTO `sys_dict_item` VALUES ('2ed844fae84111e9ab840242ac110002','PROJECT_VISIBILITY_PRIVATE','private','PROJECT_VISIBILITY','submarine system dict, Do not modify.',1,0,NULL,'2019-09-01 01:09:32',NULL,'2019-09-01 01:13:19');
+INSERT INTO `sys_dict_item` VALUES ('341d5a35e84111e9ab840242ac110002','PROJECT_VISIBILITY_TEAM','team','PROJECT_VISIBILITY','submarine system dict, Do not modify.',2,0,NULL,'2019-09-01 01:10:33',NULL,'2019-09-01 01:12:53');
+INSERT INTO `sys_dict_item` VALUES ('3866b369e84111e9ab840242ac110002','PROJECT_VISIBILITY_PUBLIC','public','PROJECT_VISIBILITY','submarine system dict, Do not modify.',3,0,NULL,'2019-09-01 01:11:29',NULL,'2019-09-01 01:12:47');
+INSERT INTO `sys_dict_item` VALUES ('3cc1a373e84111e9ab840242ac110002','PROJECT_PERMISSION_VIEW','can view','PROJECT_PERMISSION','submarine system dict, Do not modify.',1,0,NULL,'2019-09-01 01:09:32',NULL,'2019-09-01 01:13:19');
+INSERT INTO `sys_dict_item` VALUES ('44e90f6ce84111e9ab840242ac110002','PROJECT_PERMISSION_EDIT','can edit','PROJECT_PERMISSION','submarine system dict, Do not modify.',2,0,NULL,'2019-09-01 01:11:29',NULL,'2019-09-01 01:12:47');
+INSERT INTO `sys_dict_item` VALUES ('40dbb5ece84111e9ab840242ac110002','PROJECT_PERMISSION_EXECUTE','can execute','PROJECT_PERMISSION','submarine system dict, Do not modify.',3,0,NULL,'2019-09-01 01:10:33',NULL,'2019-09-01 01:12:53');
-- ----------------------------
-- Records of sys_department
diff --git a/docs/database/submarine.sql b/docs/database/submarine.sql
index a8b2482..38ebe7c 100644
--- a/docs/database/submarine.sql
+++ b/docs/database/submarine.sql
@@ -162,16 +162,24 @@ CREATE TABLE `team_member` (
DROP TABLE IF EXISTS `project`;
CREATE TABLE `project` (
`id` varchar(32) NOT NULL,
- `project_name` varchar(100) NOT NULL COMMENT 'project name',
- `visibility` int(1) default 0 COMMENT '0:Private, 1:Team, 2:Public',
- `type` int(1) default 0 COMMENT 'machine learning type (0:notebook, 1:python, 2:spark, 3:R, 4:tensorflow, 5:pytorch)',
+ `name` varchar(100) NOT NULL COMMENT 'project name',
+ `visibility` varchar(32) default NULL COMMENT 'dict_code:PROJECT_VISIBILITY',
+ `permission` varchar(32) default NULL COMMENT 'dict_code:PROJECT_PERMISSION',
+ `type` varchar(32) default NULL COMMENT 'dict_code:PROJECT_TYPE',
`description` varchar(255) COMMENT 'description',
`user_name` varchar(32) NOT NULL COMMENT 'owner user id',
+ `team_name` varchar(32) default NULL COMMENT 'team name',
+ `tags` varchar(128) default NULL COMMENT 'Comma separated tag',
+ `star_num` int(8) default 0 COMMENT 'star number',
+ `like_num` int(8) default 0 COMMENT 'like number',
+ `message_num` int(8) default 0 COMMENT 'message number',
`create_by` varchar(32) default NULL COMMENT 'create user',
`create_time` datetime default NULL COMMENT 'create time',
`update_by` varchar(32) default NULL COMMENT 'last update user',
`update_time` datetime default NULL COMMENT 'last update time',
PRIMARY KEY (`id`)/*,
+ CONSTRAINT `FK_PROJECT_TYPE` FOREIGN KEY (`type`) REFERENCES `sys_dict_item` (`item_code`),
+ CONSTRAINT `FK_PROJECT_TEAM_NAME` FOREIGN KEY (`team_name`) REFERENCES `team` (`team_name`),
CONSTRAINT `FK_PROJECT_USER_NAME` FOREIGN KEY (`user_name`) REFERENCES `sys_user` (`user_name`)*/
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
diff --git a/submarine-workbench/workbench-server/src/main/java/org/apache/submarine/database/entity/Project.java b/submarine-workbench/workbench-server/src/main/java/org/apache/submarine/database/entity/Project.java
index 98066f1..848ab22 100644
--- a/submarine-workbench/workbench-server/src/main/java/org/apache/submarine/database/entity/Project.java
+++ b/submarine-workbench/workbench-server/src/main/java/org/apache/submarine/database/entity/Project.java
@@ -18,45 +18,65 @@
*/
package org.apache.submarine.database.entity;
+import org.apache.submarine.annotation.Dict;
+
import java.util.ArrayList;
import java.util.List;
public class Project extends BaseEntity {
- private String projectName;
+ private String name;
+
+ @Dict(Code = "PROJECT_VISIBILITY")
+ private String visibility;
+
+ @Dict(Code = "PROJECT_TYPE")
+ private String type;
+
+ @Dict(Code = "PROJECT_PERMISSION")
+ private String permission;
- // 0:Private, 1:Team, 2:Public
- private Integer visibility;
+ // Comma separated tag
+ private String tags;
- // 0:notebook, 1:python, 2:spark, 3:R, 4:tensorflow, 5:pytorch
- private Integer type;
+ // number of star
+ private Integer starNum = 0;
+
+ // number of like
+ private Integer likeNum = 0;
+
+ // number of message
+ private Integer messageNum = 0;
+
+ // Team.teamName
+ private String teamName;
private String description;
private String userName;
- private List<ProjectFiles> projectFilesList;
+ private List<ProjectFiles> projectFilesList = new ArrayList<>();
- public String getProjectName() {
- return projectName;
+ public String getName() {
+ return name;
}
- public void setProjectName(String projectName) {
- this.projectName = projectName == null ? null : projectName.trim();
+ public void setName(String name) {
+ this.name = name == null ? null : name.trim();
}
- public Integer getVisibility() {
+ public String getVisibility() {
return visibility;
}
- public void setVisibility(Integer visibility) {
+ public void setVisibility(String visibility) {
this.visibility = visibility;
}
- public Integer getType() {
+ public String getType() {
return type;
}
- public void setType(Integer type) {
+ public void setType(String type) {
this.type = type;
}
@@ -85,9 +105,54 @@ public class Project extends BaseEntity {
}
public void addProjectFilesList(ProjectFiles projectFiles) {
- if (projectFilesList == null) {
- projectFilesList = new ArrayList<>();
- }
this.projectFilesList.add(projectFiles);
}
+
+ public String getTags() {
+ return tags;
+ }
+
+ public void setTags(String tags) {
+ this.tags = tags;
+ }
+
+ public Integer getStarNum() {
+ return starNum;
+ }
+
+ public void setStarNum(Integer starNum) {
+ this.starNum = starNum;
+ }
+
+ public Integer getLikeNum() {
+ return likeNum;
+ }
+
+ public void setLikeNum(Integer likeNum) {
+ this.likeNum = likeNum;
+ }
+
+ public Integer getMessageNum() {
+ return messageNum;
+ }
+
+ public void setMessageNum(Integer messageNum) {
+ this.messageNum = messageNum;
+ }
+
+ public String getTeamName() {
+ return teamName;
+ }
+
+ public void setTeamName(String teamName) {
+ this.teamName = teamName;
+ }
+
+ public String getPermission() {
+ return permission;
+ }
+
+ public void setPermission(String permission) {
+ this.permission = permission;
+ }
}
diff --git a/submarine-workbench/workbench-server/src/main/java/org/apache/submarine/rest/ProjectRestApi.java b/submarine-workbench/workbench-server/src/main/java/org/apache/submarine/rest/ProjectRestApi.java
index 275fe15..8d98b08 100644
--- a/submarine-workbench/workbench-server/src/main/java/org/apache/submarine/rest/ProjectRestApi.java
+++ b/submarine-workbench/workbench-server/src/main/java/org/apache/submarine/rest/ProjectRestApi.java
@@ -29,7 +29,10 @@ import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Singleton;
+import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
@@ -61,7 +64,7 @@ public class ProjectRestApi {
List<Project> projectList = new ArrayList<>();
try {
- projectList = projectService.queryPageList("liuxun", column, order, pageNo, pageSize);
+ projectList = projectService.queryPageList(userName, column, order, pageNo, pageSize);
} catch (Exception e) {
LOG.error(e.getMessage(), e);
return new JsonResponse.Builder<>(Response.Status.OK).success(false).build();
@@ -72,4 +75,59 @@ public class ProjectRestApi {
.success(true).result(listResult).build();
}
+ @POST
+ @Path("/add")
+ @SubmarineApi
+ public Response add(Project project) {
+ LOG.info("add project:{}", project.toString());
+
+ // insert into database, return id
+ try {
+ projectService.add(project);
+ } catch (Exception e) {
+ LOG.error(e.getMessage(), e);
+ return new JsonResponse.Builder<>(Response.Status.OK).success(false)
+ .message("Save project failed!").build();
+ }
+
+ return new JsonResponse.Builder<Project>(Response.Status.OK)
+ .message("Save project successfully!").result(project).success(true).build();
+ }
+
+ @PUT
+ @Path("/edit")
+ @SubmarineApi
+ public Response edit(Project project) {
+ LOG.info("edit project:{}", project.toString());
+
+ try {
+ // update project
+ projectService.updateByPrimaryKeySelective(project);
+ } catch (Exception e) {
+ return new JsonResponse.Builder<>(Response.Status.OK).success(false)
+ .message("Update project failed!").build();
+ }
+
+ return new JsonResponse.Builder<>(Response.Status.OK)
+ .message("Update project successfully!").success(true).build();
+ }
+
+ @DELETE
+ @Path("/delete")
+ @SubmarineApi
+ public Response delete(@QueryParam("id") String id) {
+ // TODO(zhulinhao): At the front desk need to id
+ LOG.info("delete project:{}", id);
+
+ try {
+ projectService.delete(id);
+ } catch (Exception e) {
+ LOG.error(e.getMessage(), e);
+ return new JsonResponse.Builder<>(Response.Status.OK).success(false)
+ .message("Delete project failed!").build();
+ }
+
+ return new JsonResponse.Builder<>(Response.Status.OK)
+ .message("Delete project successfully!").success(true).build();
+ }
}
diff --git a/submarine-workbench/workbench-server/src/main/resources/org/apache/submarine/database/mappers/ProjectMapper.xml b/submarine-workbench/workbench-server/src/main/resources/org/apache/submarine/database/mappers/ProjectMapper.xml
index 3911db4..b70f04e 100644
--- a/submarine-workbench/workbench-server/src/main/resources/org/apache/submarine/database/mappers/ProjectMapper.xml
+++ b/submarine-workbench/workbench-server/src/main/resources/org/apache/submarine/database/mappers/ProjectMapper.xml
@@ -28,16 +28,18 @@
</resultMap>
<resultMap id="resultMap" type="org.apache.submarine.database.entity.Project" extends="BaseEntityResultMap">
- <result column="project_name" jdbcType="VARCHAR" property="projectName" />
- <result column="visibility" jdbcType="INTEGER" property="visibility" />
- <result column="type" jdbcType="INTEGER" property="type" />
+ <result column="name" jdbcType="VARCHAR" property="name" />
+ <result column="visibility" jdbcType="VARCHAR" property="visibility" />
+ <result column="permission" jdbcType="VARCHAR" property="permission" />
+ <result column="type" jdbcType="VARCHAR" property="type" />
<result column="description" jdbcType="VARCHAR" property="description" />
<result column="user_name" jdbcType="VARCHAR" property="userName" />
+ <result column="team_name" jdbcType="VARCHAR" property="teamName" />
</resultMap>
<sql id="Base_Column_List">
- id, project_name, visibility, type, description, user_name, create_by, create_time,
- update_by, update_time
+ id, name, visibility, permission, type, description, user_name, team_name,
+ create_by, create_time, update_by, update_time
</sql>
<select id="selectAll" parameterType="java.util.Map" resultMap="resultMap">
@@ -50,7 +52,7 @@
</select>
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="resultMap">
- select
+ select
<include refid="Base_Column_List" />
from project
where id = #{id,jdbcType=VARCHAR}
@@ -65,11 +67,13 @@
<selectKey keyProperty="id" resultType="java.lang.String" order="BEFORE">
SELECT REPLACE(UUID(),"-","")
</selectKey>
- insert into project (id, project_name, visibility,
- type, description, user_name,
+ insert into project (id, name, visibility,
+ permission, type, description,
+ user_name, team_name,
create_by, create_time, update_by, update_time)
- values (#{id,jdbcType=VARCHAR}, #{projectName,jdbcType=VARCHAR}, #{visibility,jdbcType=INTEGER},
- #{type,jdbcType=INTEGER}, #{description,jdbcType=VARCHAR}, #{userName,jdbcType=VARCHAR},
+ values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{visibility,jdbcType=VARCHAR},
+ #{permission,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR}, #{description,jdbcType=VARCHAR},
+ #{userName,jdbcType=VARCHAR}, #{teamName,jdbcType=VARCHAR},
#{createBy,jdbcType=VARCHAR}, now(), #{updateBy,jdbcType=VARCHAR}, now())
</insert>
@@ -79,12 +83,15 @@
<if test="id != null">
id,
</if>
- <if test="projectName != null">
- project_name,
+ <if test="name != null">
+ name,
</if>
<if test="visibility != null">
visibility,
</if>
+ <if test="permission != null">
+ permission,
+ </if>
<if test="type != null">
type,
</if>
@@ -94,6 +101,9 @@
<if test="userName != null">
user_name,
</if>
+ <if test="teamName != null">
+ team_name,
+ </if>
<if test="createBy != null">
create_by,
</if>
@@ -111,14 +121,17 @@
<if test="id != null">
#{id,jdbcType=VARCHAR},
</if>
- <if test="projectName != null">
- #{projectName,jdbcType=VARCHAR},
+ <if test="name != null">
+ #{name,jdbcType=VARCHAR},
</if>
<if test="visibility != null">
- #{visibility,jdbcType=INTEGER},
+ #{visibility,jdbcType=VARCHAR},
+ </if>
+ <if test="permission != null">
+ #{permission,jdbcType=VARCHAR},
</if>
<if test="type != null">
- #{type,jdbcType=INTEGER},
+ #{type,jdbcType=VARCHAR},
</if>
<if test="description != null">
#{description,jdbcType=VARCHAR},
@@ -126,6 +139,9 @@
<if test="userName != null">
#{userName,jdbcType=VARCHAR},
</if>
+ <if test="teamName != null">
+ #{teamName,jdbcType=VARCHAR},
+ </if>
<if test="createBy != null">
#{createBy,jdbcType=VARCHAR},
</if>
@@ -144,14 +160,17 @@
<update id="updateByPrimaryKeySelective" parameterType="org.apache.submarine.database.entity.Project">
update project
<set>
- <if test="projectName != null">
- project_name = #{projectName,jdbcType=VARCHAR},
+ <if test="name != null">
+ name = #{name,jdbcType=VARCHAR},
</if>
<if test="visibility != null">
- visibility = #{visibility,jdbcType=INTEGER},
+ visibility = #{visibility,jdbcType=VARCHAR},
+ </if>
+ <if test="permission != null">
+ permission = #{permission,jdbcType=VARCHAR},
</if>
<if test="type != null">
- type = #{type,jdbcType=INTEGER},
+ type = #{type,jdbcType=VARCHAR},
</if>
<if test="description != null">
description = #{description,jdbcType=VARCHAR},
@@ -159,6 +178,9 @@
<if test="userName != null">
user_name = #{userName,jdbcType=VARCHAR},
</if>
+ <if test="teamName != null">
+ team_name = #{teamName,jdbcType=VARCHAR},
+ </if>
<if test="updateBy != null">
update_by = #{updateBy,jdbcType=VARCHAR},
</if>
@@ -169,11 +191,13 @@
<update id="updateByPrimaryKey" parameterType="org.apache.submarine.database.entity.Project">
update project
- set project_name = #{projectName,jdbcType=VARCHAR},
- visibility = #{visibility,jdbcType=INTEGER},
- type = #{type,jdbcType=INTEGER},
+ set name = #{name,jdbcType=VARCHAR},
+ visibility = #{visibility,jdbcType=VARCHAR},
+ permission = #{permission,jdbcType=VARCHAR},
+ type = #{type,jdbcType=VARCHAR},
description = #{description,jdbcType=VARCHAR},
user_name = #{userName,jdbcType=VARCHAR},
+ team_name = #{teamName,jdbcType=VARCHAR},
update_by = #{updateBy,jdbcType=VARCHAR},
update_time = #{updateTime,jdbcType=TIMESTAMP}
where id = #{id,jdbcType=VARCHAR}
diff --git a/submarine-workbench/workbench-server/src/test/java/org/apache/submarine/database/service/ProjectServiceTest.java b/submarine-workbench/workbench-server/src/test/java/org/apache/submarine/database/service/ProjectServiceTest.java
index 180d891..c2536be 100644
--- a/submarine-workbench/workbench-server/src/test/java/org/apache/submarine/database/service/ProjectServiceTest.java
+++ b/submarine-workbench/workbench-server/src/test/java/org/apache/submarine/database/service/ProjectServiceTest.java
@@ -53,10 +53,10 @@ public class ProjectServiceTest {
Project project = new Project();
project.setDescription("ProjectServiceTest-Description");
- project.setProjectName("ProjectServiceTest-ProjectName");
- project.setType(1);
+ project.setName("ProjectServiceTest-ProjectName");
+ project.setType("PROJECT_TYPE_NOTEBOOK");
project.setUserName("ProjectServiceTest-UserName");
- project.setVisibility(1);
+ project.setVisibility("PROJECT_VISIBILITY_PRIVATE");
project.setCreateBy("ProjectServiceTest-UserName");
List list = new ArrayList<ProjectFiles>();
list.add(projectFiles);
@@ -71,7 +71,7 @@ public class ProjectServiceTest {
Project projectDb = projectList.get(0);
assertEquals(project.getDescription(), projectDb.getDescription());
- assertEquals(project.getProjectName(), projectDb.getProjectName());
+ assertEquals(project.getName(), projectDb.getName());
assertEquals(project.getType(), projectDb.getType());
assertEquals(project.getUserName(), projectDb.getUserName());
assertEquals(project.getVisibility(), projectDb.getVisibility());
@@ -95,10 +95,10 @@ public class ProjectServiceTest {
Project project = new Project();
project.setDescription("ProjectServiceTest-Description");
- project.setProjectName("ProjectServiceTest-ProjectName");
- project.setType(1);
+ project.setName("ProjectServiceTest-ProjectName");
+ project.setType("PROJECT_TYPE_NOTEBOOK");
project.setUserName("ProjectServiceTest-UserName");
- project.setVisibility(1);
+ project.setVisibility("PROJECT_VISIBILITY_PRIVATE");
project.setCreateBy("ProjectServiceTest-UserName");
List list = new ArrayList<ProjectFiles>();
list.add(projectFiles);
@@ -107,9 +107,9 @@ public class ProjectServiceTest {
Boolean ret = projectService.add(project);
assertTrue(ret);
- project.setProjectName("update_projectName");
+ project.setName("update_projectName");
project.setDescription("update_description");
- project.setVisibility(2);
+ project.setVisibility("PROJECT_VISIBILITY_PUBLIC");
project.setUpdateBy("project_updateBy");
ProjectFiles projectFilesUpdate = new ProjectFiles();
projectFilesUpdate.setFileContent("ProjectServiceTest-FileContent2");
@@ -126,7 +126,7 @@ public class ProjectServiceTest {
assertEquals(projectList.size(), 1);
Project projectDb = projectList.get(0);
- assertEquals(project.getProjectName(), projectDb.getProjectName());
+ assertEquals(project.getName(), projectDb.getName());
assertEquals(project.getDescription(), projectDb.getDescription());
assertEquals(project.getVisibility(), projectDb.getVisibility());
assertEquals(project.getUpdateBy(), projectDb.getUpdateBy());
@@ -152,10 +152,10 @@ public class ProjectServiceTest {
Project project = new Project();
project.setDescription("ProjectServiceTest-Description");
- project.setProjectName("ProjectServiceTest-ProjectName");
- project.setType(1);
+ project.setName("ProjectServiceTest-ProjectName");
+ project.setType("PROJECT_TYPE_NOTEBOOK");
project.setUserName("ProjectServiceTest-UserName");
- project.setVisibility(1);
+ project.setVisibility("PROJECT_VISIBILITY_PRIVATE");
project.setCreateBy("ProjectServiceTest-UserName");
List list = new ArrayList<ProjectFiles>();
list.add(projectFiles);
diff --git a/submarine-workbench/workbench-web/public/assets/notebook_logo.png b/submarine-workbench/workbench-web/public/assets/notebook_logo.png
new file mode 100644
index 0000000..430455b
Binary files /dev/null and b/submarine-workbench/workbench-web/public/assets/notebook_logo.png differ
diff --git a/submarine-workbench/workbench-web/public/assets/python_logo.png b/submarine-workbench/workbench-web/public/assets/python_logo.png
new file mode 100644
index 0000000..24d3c09
Binary files /dev/null and b/submarine-workbench/workbench-web/public/assets/python_logo.png differ
diff --git a/submarine-workbench/workbench-web/public/assets/r_logo.png b/submarine-workbench/workbench-web/public/assets/r_logo.png
new file mode 100644
index 0000000..bcbbcfb
Binary files /dev/null and b/submarine-workbench/workbench-web/public/assets/r_logo.png differ
diff --git a/submarine-workbench/workbench-web/public/assets/scala_logo.png b/submarine-workbench/workbench-web/public/assets/scala_logo.png
new file mode 100644
index 0000000..3117e79
Binary files /dev/null and b/submarine-workbench/workbench-web/public/assets/scala_logo.png differ
diff --git a/submarine-workbench/workbench-web/src/api/system.js b/submarine-workbench/workbench-web/src/api/system.js
index 93b3111..b2b6ddb 100644
--- a/submarine-workbench/workbench-web/src/api/system.js
+++ b/submarine-workbench/workbench-web/src/api/system.js
@@ -34,10 +34,17 @@ const resetParentDept = (params) => putAction('/sys/dept/resetParentDept', param
const ajaxGetDictItems = (code, params) => getAction(`/sys/dictItem/getDictItems/${code}`, params)
// team
+const queryTeam = (params) => getAction('/team/list', params)
const addTeam = (params) => postAction('/team/add', params)
const editTeam = (params) => putAction('/team/edit', params)
const deleteTeam = (params) => deleteAction('/team/delete', params)
+// project
+const queryProject = (params) => getAction('/project/list', params)
+const addProject = (params) => postAction('/project/add', params)
+const editProject = (params) => putAction('/project/edit', params)
+const deleteProject = (params) => deleteAction('/project/delete', params)
+
export {
ajaxGetDictItems,
addUser,
@@ -61,7 +68,12 @@ export {
deleteByDepartId,
queryIdTree,
resetParentDept,
+ queryTeam,
addTeam,
editTeam,
- deleteTeam
+ deleteTeam,
+ queryProject,
+ addProject,
+ editProject,
+ deleteProject
}
diff --git a/submarine-workbench/workbench-web/src/components/Dict/DictSelectTag.vue b/submarine-workbench/workbench-web/src/components/Dict/DictSelectTag.vue
index a9f768d..61f8172 100644
--- a/submarine-workbench/workbench-web/src/components/Dict/DictSelectTag.vue
+++ b/submarine-workbench/workbench-web/src/components/Dict/DictSelectTag.vue
@@ -3,7 +3,12 @@
<a-radio v-for="(item, key) in dictOptions" :key="key" :value="item.itemName">{{ item.itemCode }}</a-radio>
</a-radio-group>
- <a-select v-else-if="tagType=='select'" :placeholder="placeholder" :disabled="disabled" :value="value" @change="handleInput">
+ <a-select
+ v-else-if="tagType=='select'"
+ :placeholder="placeholder"
+ :disabled="disabled"
+ :value="value"
+ @change="handleInput">
<a-select-option value="">Please Select</a-select-option>
<a-select-option v-for="(item, key) in dictOptions" :key="key" :value="item.itemCode">
<span style="display: inline-block;width: 100%" :title=" item.itemName ">
@@ -14,11 +19,16 @@
</template>
<script>
-import { ajaxGetDictItems } from '@/api/system'
+import { ajaxGetDictItems, queryTeam } from '@/api/system'
export default {
name: 'DictSelectTag',
props: {
+ tableName: {
+ type: String,
+ default: '',
+ required: true
+ },
dictCode: {
type: String,
default: '',
@@ -57,14 +67,18 @@ export default {
}
},
created () {
- console.log(this.dictCode)
+ // console.log(this.dictCode)
if (!this.type || this.type === 'list') {
this.tagType = 'select'
} else {
this.tagType = this.type
}
// Get dictionary data
- this.initDictData()
+ if (this.tableName === 'team') {
+ this.initTeamData()
+ } else {
+ this.initDictData()
+ }
},
methods: {
initDictData () {
@@ -76,6 +90,31 @@ export default {
}
})
},
+ initTeamData () {
+ // Initialize the dictionary array according to the dictionary Code
+ var params = {}
+ params.owner = this.$store.getters.userInfo.name
+ params.column = 'createTime'
+ params.order = 'desc'
+ params.pageNo = 0
+ params.pageSize = 100
+ queryTeam(params).then((res) => {
+ if (res.success) {
+ console.log(res.result.records)
+ if (res.result.records) {
+ var dictItems = []
+ res.result.records.forEach(function (team) {
+ console.log('team=', team)
+ var item = {}
+ item.itemCode = team.teamName
+ item.itemName = team.teamName
+ dictItems = [...dictItems, item]
+ })
+ this.dictOptions = dictItems
+ }
+ }
+ })
+ },
handleInput (e) {
let val
if (this.tagType === 'radio') {
diff --git a/submarine-workbench/workbench-web/src/views/workbench/workspace/project/NewProject.vue b/submarine-workbench/workbench-web/src/views/workbench/workspace/project/NewProject.vue
index ea76779..d432f48 100644
--- a/submarine-workbench/workbench-web/src/views/workbench/workspace/project/NewProject.vue
+++ b/submarine-workbench/workbench-web/src/views/workbench/workspace/project/NewProject.vue
@@ -11,19 +11,19 @@ limitations under the License.
-->
<template>
<a-card title="Create New Project">
- <a-button shape="circle" icon="close" slot="extra" @click="showProjectList"/>
+ <a-button type="primary" shape="circle" icon="close" slot="extra" @click="showProjectList"/>
<a-spin :spinning="confirmLoading">
<a-steps :current="currentStep" class="steps">
<a-step title="Basic Information" />
- <a-step title="Initial Setup" />
+ <a-step title="Initial Project" />
<a-step title="Preview Project" />
</a-steps>
<a-divider type="horizontal" style="width: 100%"/>
<div class="content">
- <step1 v-if="currentStep === 0" @nextStep="nextStep" />
- <step2 v-if="currentStep === 1" @nextStep="nextStep" @prevStep="prevStep"/>
- <step3 v-if="currentStep === 2" @prevStep="prevStep" @finish="finish"/>
+ <step1 v-if="currentStep === 0" v-model="project" @nextStep="nextStep" @updateProject="updateProject"/>
+ <step2 v-if="currentStep === 1" v-model="project" @nextStep="nextStep" @prevStep="prevStep" @updateProject="updateProject"/>
+ <step3 v-if="currentStep === 2" v-model="project" @prevStep="prevStep" @finish="finish" @updateProject="updateProject"/>
</div>
</a-spin>
</a-card>
@@ -34,12 +34,7 @@ import pick from 'lodash.pick'
import Step1 from './NewProjectStep1'
import Step2 from './NewProjectStep2'
import Step3 from './NewProjectStep3'
-
-const stepForms = [
- ['name', 'desc'],
- ['target', 'template', 'type'],
- ['time', 'frequency']
-]
+import { addProject } from '@/api/system'
export default {
name: 'StepByStepModal',
@@ -61,32 +56,74 @@ export default {
visible: false,
confirmLoading: false,
currentStep: 0,
- mdl: {},
+ project: {
+ name: '',
+ userName: '',
+ description: '',
+ type: 'PROJECT_TYPE_NOTEBOOK',
+ teamName: '',
+ visibility: 'PROJECT_VISIBILITY_PRIVATE',
+ permission: 'PROJECT_PERMISSION_VIEW',
+ starNum: 0,
+ likeNum: 0,
+ messageNum: 0
+ },
radioStyle: {
display: 'block',
height: '30px',
lineHeight: '30px'
},
+ login_user: {},
form: this.$form.createForm(this)
}
},
+ computed: {
+ userInfo () {
+ return this.$store.getters.userInfo
+ }
+ },
+ created () {
+ this.login_user = this.userInfo
+ },
methods: {
showProjectList () {
this.$emit('showProjectList')
},
- nextStep () {
+ updateProject: function (childProject) {
+ console.log('updateProject=', childProject)
+ this.project = Object.assign(this.project, childProject)
+ },
+ nextStep: function (childModel) {
+ console.log('childModel=', childModel)
+ this.project = Object.assign(this.project, childModel)
+ console.log('project = ', this.project)
if (this.currentStep < 2) {
this.currentStep += 1
}
},
- prevStep () {
+ prevStep: function (childModel) {
+ console.log('childModel=', childModel)
+ this.project = Object.assign(this.project, childModel)
+ console.log('project = ', this.project)
if (this.currentStep > 0) {
this.currentStep -= 1
}
},
- finish () {
- this.$emit('showProjectList')
- this.currentStep = 0
+ finish: function (childModel) {
+ this.project = Object.assign(this.project, childModel)
+ this.project.userName = this.login_user.name
+ this.project.createBy = this.login_user.name
+ this.project.updateBy = this.login_user.name
+
+ addProject(this.project).then((res) => {
+ if (res.success) {
+ this.$message.info(res.message)
+ this.$emit('showProjectList')
+ this.currentStep = 0
+ } else {
+ this.$message.warning(res.message)
+ }
+ })
},
edit (record) {
this.visible = true
@@ -94,52 +131,6 @@ export default {
this.$nextTick(() => {
setFieldsValue(pick(record, []))
})
- },
- handleNext (step) {
- const { form: { validateFields } } = this
- const currentStep = step + 1
- if (currentStep <= 2) {
- // stepForms
- validateFields(stepForms[ this.currentStep ], (errors, values) => {
- if (!errors) {
- this.currentStep = currentStep
- }
- })
- return
- }
- // last step
- this.confirmLoading = true
- validateFields((errors, values) => {
- console.log('errors:', errors, 'val:', values)
- if (!errors) {
- console.log('values:', values)
- setTimeout(() => {
- this.confirmLoading = false
- this.$emit('ok', values)
- }, 1500)
- } else {
- this.confirmLoading = false
- }
- })
- },
- backward () {
- this.currentStep--
- },
- handleCancel () {
- // clear form & currentStep
- this.visible = false
- this.currentStep = 0
- },
- handleChange (info) {
- const status = info.file.status
- if (status !== 'uploading') {
- console.log(info.file, info.fileList)
- }
- if (status === 'done') {
- this.$message.success(`${info.file.name} file uploaded successfully.`)
- } else if (status === 'error') {
- this.$message.error(`${info.file.name} file upload failed.`)
- }
}
}
}
diff --git a/submarine-workbench/workbench-web/src/views/workbench/workspace/project/NewProjectStep1.vue b/submarine-workbench/workbench-web/src/views/workbench/workspace/project/NewProjectStep1.vue
index 10379a1..1a1be3b 100644
--- a/submarine-workbench/workbench-web/src/views/workbench/workspace/project/NewProjectStep1.vue
+++ b/submarine-workbench/workbench-web/src/views/workbench/workspace/project/NewProjectStep1.vue
@@ -14,18 +14,33 @@ limitations under the License.
<a-form :form="form" style="max-width: 650px; margin: 10px auto 0;">
<a-form-item label="Project Name" :labelCol="labelCol" :wrapperCol="wrapperCol">
- <a-input v-decorator="['name', {rules: [{required: true}]}]" />
+ <a-input v-model="project.name" v-decorator="[ 'name', validatorRules.name]" />
</a-form-item>
<a-form-item label="Description" :labelCol="labelCol" :wrapperCol="wrapperCol">
- <a-textarea :rows="4" v-decorator="['desc', {rules: [{required: true}]}]"></a-textarea>
+ <a-textarea :rows="4" v-model="project.description" v-decorator="['desc', validatorRules.description]" />
</a-form-item>
<a-form-item label="Visibility" :labelCol="labelCol" :wrapperCol="wrapperCol">
- <a-radio-group v-decorator="['type', {initialValue: 0, rules: [{required: true}]}]" style="width: 100%">
- <a-radio class="radioStyle" :value="0"><a class="a-radio_a">Private</a> - Only project collaborators can view or edit the project. </a-radio>
- <a-radio class="radioStyle" :value="1"><a class="a-radio_a">Team</a> - All members of the team can view the project.</a-radio>
- <a-radio class="radioStyle" :value="2"><a class="a-radio_a">Public</a> - All authenticated users can view the project.</a-radio>
+ <a-radio-group v-model="project.visibility" @change="visibilityOnChange" style="width: 100%">
+ <a-radio class="radioStyle" :value="'PROJECT_VISIBILITY_PRIVATE'"><a class="a-radio_a">Private</a> - Only project collaborators can view or edit the project. </a-radio>
+ <a-radio class="radioStyle" :value="'PROJECT_VISIBILITY_TEAM'"><a class="a-radio_a">Team</a> - All members of the team can view the project.</a-radio>
+ <dict-select-tag
+ v-if="project.visibility==='PROJECT_VISIBILITY_TEAM'"
+ tableName="team"
+ triggerChange="true"
+ @change="teamNameOnChange"
+ v-model="project.teamName"
+ v-decorator="['teamName', validatorRules.teamName]"/>
+ <a-radio class="radioStyle" :value="'PROJECT_VISIBILITY_PUBLIC'"><a class="a-radio_a">Public</a> - All authenticated users can view the project.</a-radio>
+ </a-radio-group>
+ </a-form-item>
+
+ <a-form-item label="Permission" :labelCol="labelCol" :wrapperCol="wrapperCol" v-if="project.visibility!=='PROJECT_VISIBILITY_PRIVATE'">
+ <a-radio-group v-model="project.permission" @change="permissionOnChange" style="width: 100%">
+ <a-radio class="radioStyle" :value="'PROJECT_PERMISSION_VIEW'"><a class="a-radio_a">Can View</a>{{ permissionCanView }}</a-radio>
+ <a-radio class="radioStyle" :value="'PROJECT_PERMISSION_EDIT'"><a class="a-radio_a">Can Edit</a>{{ permissionCanEdit }}</a-radio>
+ <a-radio class="radioStyle" :value="'PROJECT_PERMISSION_EXECUTE'"><a class="a-radio_a">Can Execute</a>{{ permissionCanExecute }}</a-radio>
</a-radio-group>
</a-form-item>
@@ -38,28 +53,92 @@ limitations under the License.
</template>
<script>
+import pick from 'lodash.pick'
+import DictSelectTag from '@/components/Dict/DictSelectTag.vue'
export default {
- name: 'Step1',
+ name: 'NewProjectStep1',
+ components: { DictSelectTag },
+
+ props: {
+ project: {
+ type: Object,
+ // Object or array defaults must be obtained from a factory function
+ default: function () {
+ return { }
+ },
+ required: true
+ }
+ },
+
+ model: {
+ // Pass the variable value to the child component when the parent component sets the v-model
+ prop: 'project'
+ },
+ mounted () {
+ console.log('projectaaa', this.project)
+ const that = this
+ that.form.resetFields()
+ that.$nextTick(() => {
+ that.form.setFieldsValue(pick(this.project, 'name', 'description', 'visibility', 'teamName', 'permission'))
+ })
+ that.setPermissionDesc()
+ },
+
data () {
return {
labelCol: { lg: { span: 5 }, sm: { span: 5 } },
wrapperCol: { lg: { span: 19 }, sm: { span: 19 } },
- form: this.$form.createForm(this),
- fileList: [],
- uploading: false,
- dataSourceType: 'file'
+ validatorRules: {
+ name: { rules: [{ required: true, message: 'Please enter project name!' }] },
+ description: { rules: [{ required: true, message: 'Please enter project description!' }] },
+ teamName: { rules: [{ required: true, message: 'Please select team name!' }] }
+ },
+ permissionCanView: '',
+ permissionCanEdit: '',
+ permissionCanExecute: '',
+ form: this.$form.createForm(this)
}
},
+
methods: {
nextStep () {
const { form: { validateFields } } = this
- // 先校验,通过表单校验后,才进入下一步
+ // Check the form, then go to the next step.
validateFields((err, values) => {
if (!err) {
- this.$emit('nextStep')
+ console.log('project=', this.project)
+ this.$emit('nextStep', this.project)
}
})
+ },
+ visibilityOnChange (e) {
+ this.project.visibility = e.target.value
+ console.log('project.visibility=', this.project.visibility)
+ if (this.project.visibility !== 'PROJECT_VISIBILITY_TEAM') {
+ this.project.teamName = ''
+ }
+ this.setPermissionDesc()
+ this.$emit('updateProject', this.project)
+ },
+ setPermissionDesc () {
+ if (this.project.visibility !== 1) {
+ this.permissionCanView = ' - All members can view the project.'
+ this.permissionCanEdit = ' - All members can edit the project.'
+ this.permissionCanExecute = ' - All members can execute the project.'
+ } else {
+ this.permissionCanView = ' - All members of the team can view the project.'
+ this.permissionCanEdit = ' - All members of the team can edit the project.'
+ this.permissionCanExecute = ' - All members of the team can execute the project.'
+ }
+ },
+ permissionOnChange (e) {
+ this.project.permission = e.target.value
+ this.$emit('updateProject', this.project)
+ },
+ teamNameOnChange (val) {
+ this.project.teamName = val
+ this.$emit('updateProject', this.project)
}
}
}
diff --git a/submarine-workbench/workbench-web/src/views/workbench/workspace/project/NewProjectStep2.vue b/submarine-workbench/workbench-web/src/views/workbench/workspace/project/NewProjectStep2.vue
index 8180a06..ea7771f 100644
--- a/submarine-workbench/workbench-web/src/views/workbench/workspace/project/NewProjectStep2.vue
+++ b/submarine-workbench/workbench-web/src/views/workbench/workspace/project/NewProjectStep2.vue
@@ -11,33 +11,49 @@ limitations under the License.
-->
<template>
<div style="margin: 20px auto 0;">
- <a-tabs defaultActiveKey="1" tab-position="top" type="card">
- <a-tab-pane key="1">
- <span slot="tab">
- <a-icon type="file" />
- Blank
- </span>
- <div class="tab-content"><p>You can either create a blank project.</p></div>
- </a-tab-pane>
+ <a-tabs defaultActiveKey="2" tab-position="top" type="card">
- <a-tab-pane key="2">
+ <a-tab-pane key="1" disabled>
<span slot="tab">
- <a-icon type="database" />
- Template
+ <a-tooltip placement="top" >
+ <template slot="title">
+ <span>Future is under development</span>
+ </template>
+ <a-icon type="database" />
+ Template
+ </a-tooltip>
</span>
<a-table
+ bordered
+ rowKey="id"
:columns="templateColumns"
:dataSource="templateDataSource"
:pagination="false"
+ :locale="{emptyText: 'No data record'}"
:scroll="{ y: 300 }"
- bordered
+ :customRow="templateCustomRow"
+ :rowSelection="{type:'radio', onChange:onTemplateSelectChange, selectedRowKeys:templateSelectedRowKeys}"
>
</a-table>
</a-tab-pane>
- <a-tab-pane key="3">
+
+ <a-tab-pane key="2">
+ <span slot="tab">
+ <a-icon type="file" />
+ Blank
+ </span>
+ <div class="tab-content"><p>You can either create a blank project.</p></div>
+ </a-tab-pane>
+
+ <a-tab-pane key="3" disabled>
<span slot="tab">
- <a-icon type="upload" />
- Upload
+ <a-tooltip placement="top" >
+ <template slot="title">
+ <span>Future is under development</span>
+ </template>
+ <a-icon type="upload" />
+ Upload
+ </a-tooltip>
</span>
<a-upload-dragger name="file" :multiple="true" action="https://www.mocky.io/v2/5cc8019d300000980a055e76">
<p class="ant-upload-drag-icon">
@@ -47,17 +63,28 @@ limitations under the License.
<p class="ant-upload-hint">Support for a single or bulk upload. Strictly prohibit from uploading company data or other band files</p>
</a-upload-dragger>
</a-tab-pane>
- <a-tab-pane key="4">
+
+ <a-tab-pane key="4" disabled>
<span slot="tab">
- <a-icon type="github" />
- Git Repo
+ <a-tooltip placement="top" >
+ <template slot="title">
+ <span>Future is under development</span>
+ </template>
+ <a-icon type="github" />
+ Git Repo
+ </a-tooltip>
</span>
<a-table
+ style="height: 325px"
+ bordered
+ rowKey="id"
:columns="gitColumns"
:dataSource="gitDataSource"
:pagination="false"
+ :locale="{emptyText: 'No data record'}"
:scroll="{ y: 300 }"
- bordered
+ :customRow="gitCustomRow"
+ :rowSelection="{type:'radio', onChange:onGitSelectChange, selectedRowKeys:gitSelectedRowKeys}"
>
</a-table>
</a-tab-pane>
@@ -73,7 +100,22 @@ limitations under the License.
<script>
export default {
- name: 'Step1',
+ name: 'NewProjectStep2',
+ props: {
+ project: {
+ type: Object,
+ // Object or array defaults must be obtained from a factory function
+ default: function () {
+ return { }
+ },
+ required: true
+ }
+ },
+
+ model: {
+ // Pass the variable value to the child component when the parent component sets the v-model
+ prop: 'project'
+ },
data () {
return {
labelCol: { lg: { span: 5 }, sm: { span: 5 } },
@@ -184,21 +226,66 @@ export default {
name: 'PyTorch test',
description: 'Apache {Submarine} is the latest machine learning framework'
}
- ]
+ ],
+ templateSelectedRowKeys: [],
+ templateSelectedRows: [],
+ gitSelectedRowKeys: [],
+ gitSelectedRows: []
}
},
+
methods: {
nextStep () {
const { form: { validateFields } } = this
// 先校验,通过表单校验后,才进入下一步
validateFields((err, values) => {
if (!err) {
- this.$emit('nextStep')
+ console.log('project21=', this.project)
+ this.$emit('nextStep', this.project)
}
})
},
prevStep () {
- this.$emit('prevStep')
+ console.log('project22=', this.project)
+ this.$emit('prevStep', this.project)
+ },
+ cleanSelect () {
+ this.templateSelectedRowKeys = []
+ this.templateSelectedRows = []
+ this.gitSelectedRowKeys = []
+ this.gitSelectedRows = []
+ },
+ onTemplateSelectChange (selectedRowKeys, selectedRows) {
+ this.cleanSelect()
+ this.templateSelectedRowKeys = selectedRowKeys
+ this.templateSelectedRows = selectedRows
+ },
+ onGitSelectChange (selectedRowKeys, selectedRows) {
+ this.cleanSelect()
+ this.gitSelectedRowKeys = selectedRowKeys
+ this.gitSelectedRows = selectedRows
+ },
+ templateCustomRow (record, index) {
+ return {
+ on: {
+ click: () => {
+ this.cleanSelect()
+ this.templateSelectedRowKeys.push(index)
+ this.templateSelectedRows.push(record)
+ }
+ }
+ }
+ },
+ gitCustomRow (record, index) {
+ return {
+ on: {
+ click: () => {
+ this.cleanSelect()
+ this.gitSelectedRowKeys.push(index)
+ this.gitSelectedRows.push(record)
+ }
+ }
+ }
}
}
}
@@ -210,13 +297,13 @@ export default {
border: 1px dashed #e9e9e9;
border-radius: 6px;
background-color: #fafafa;
- min-height: 200px;
+ min-height: 325px;
text-align: center;
// padding-top: 30px;
p {
- padding-top: 80px;
- font-size: 20px;
+ padding-top: 145px;
+ font-size: 24px;
}
}
diff --git a/submarine-workbench/workbench-web/src/views/workbench/workspace/project/NewProjectStep3.vue b/submarine-workbench/workbench-web/src/views/workbench/workspace/project/NewProjectStep3.vue
index ac33c74..f0f3814 100644
--- a/submarine-workbench/workbench-web/src/views/workbench/workspace/project/NewProjectStep3.vue
+++ b/submarine-workbench/workbench-web/src/views/workbench/workspace/project/NewProjectStep3.vue
@@ -12,29 +12,30 @@ limitations under the License.
<template>
<div>
<a-row style="margin-bottom: 8px; margin-left: 8px; margin-right: 8px;">
- <a-col :span="6"><span style="font-size: 18px; font-weight: bold">Files</span></a-col>
+ <a-col :span="6"><span style="font-size: 18px; font-weight: bold">Project Files</span></a-col>
<a-col :span="12"></a-col>
<a-col :span="6" style="text-align: right">
</a-col>
</a-row>
<a-table
+ style="height: 300px"
:columns="projectColumns"
- :dataSource="projectDataSource"
:pagination="false"
:scroll="{ y: 300 }"
+ :locale="{emptyText: 'No data record'}"
bordered
>
<template slot="footer">
- Total: 35 files
+ Total: 0 files
</template>
</a-table>
- <div style="text-align: center; margin-top: 40px;">
+ <div style="text-align: center; margin-top: 100px;">
<a-button @click="prevStep"><a-icon type="left" />Previous Step</a-button>
- <a-button style="margin-left: 8px" type="primary" @click="finish" icon="check">Submit</a-button>
- <a-button style="margin-left: 8px" type="primary" icon="form">Open Workbench</a-button>
+ <a-button style="margin-left: 8px" type="primary" @click="finish" icon="save">Save</a-button>
+ <a-button style="margin-left: 8px" type="primary" icon="form">Open In Notebook</a-button>
</div>
</div>
</template>
@@ -43,10 +44,25 @@ limitations under the License.
import { STable } from '@/components'
export default {
- name: 'DataPage',
+ name: 'NewProjectStep3',
components: {
STable
},
+ props: {
+ project: {
+ type: Object,
+ // Object or array defaults must be obtained from a factory function
+ default: function () {
+ return { }
+ },
+ required: true
+ }
+ },
+
+ model: {
+ // Object or array defaults must be obtained from a factory function
+ prop: 'project'
+ },
data () {
return {
labelCol: { lg: { span: 5 }, sm: { span: 5 } },
@@ -139,10 +155,12 @@ export default {
},
methods: {
prevStep () {
- this.$emit('prevStep')
+ console.log('project31=', this.project)
+ this.$emit('prevStep', this.project)
},
finish () {
- this.$emit('finish')
+ console.log('project32=', this.project)
+ this.$emit('finish', this.project)
}
}
}
diff --git a/submarine-workbench/workbench-web/src/views/workbench/workspace/project/ProjectList.vue b/submarine-workbench/workbench-web/src/views/workbench/workspace/project/ProjectList.vue
index dce670d..7ad6e11 100644
--- a/submarine-workbench/workbench-web/src/views/workbench/workspace/project/ProjectList.vue
+++ b/submarine-workbench/workbench-web/src/views/workbench/workspace/project/ProjectList.vue
@@ -20,16 +20,21 @@ limitations under the License.
<a-list
:grid="{gutter: 24, lg: 3, md: 2, sm: 1, xs: 1}"
:dataSource="data"
+ :pagination="pagination"
>
<a-list-item slot="renderItem" slot-scope="item">
<template>
<a-card :hoverable="true">
<a-card-meta style="min-height: 148px">
- <div style="margin-bottom: 3px;" slot="title">{{ item.title }}
+ <div style="margin-bottom: 3px;" slot="title">{{ item.name }}
</div>
- <a-avatar class="card-avatar" slot="avatar" size="large" v-if="item.mlType === 'tensorflow'" :src="'assets/tensorflow_logo.png'"/>
- <a-avatar class="card-avatar" slot="avatar" size="large" v-if="item.mlType === 'pytorch'" :src="'assets/pytorch_logo.png'"/>
+ <a-avatar class="card-avatar" slot="avatar" size="large" v-if="item.type === 'PROJECT_TYPE_NOTEBOOK'" :src="'assets/notebook_logo.png'"/>
+ <a-avatar class="card-avatar" slot="avatar" size="large" v-if="item.type === 'PROJECT_TYPE_PYTHON'" :src="'assets/python_logo.png'"/>
+ <a-avatar class="card-avatar" slot="avatar" size="large" v-if="item.type === 'PROJECT_TYPE_R'" :src="'assets/r_logo.png'"/>
+ <a-avatar class="card-avatar" slot="avatar" size="large" v-if="item.type === 'PROJECT_TYPE_SCALA'" :src="'assets/scala_logo.png'"/>
+ <a-avatar class="card-avatar" slot="avatar" size="large" v-if="item.type === 'PROJECT_TYPE_TENSORFLOW'" :src="'assets/tensorflow_logo.png'"/>
+ <a-avatar class="card-avatar" slot="avatar" size="large" v-if="item.type === 'PROJECT_TYPE_PYTORCH'" :src="'assets/pytorch_logo.png'"/>
<div slot="title">
<template v-for="(tag, index) in tags">
@@ -64,35 +69,18 @@ limitations under the License.
</div>
<div class="meta-content" slot="description"><ellipsis :length="140">{{ item.description }}</ellipsis><br/>
- <a slot="description" class="list-content-item_icon"><a-icon type="star-o"/>{{ item.star }}</a>
+ <a slot="description" class="list-content-item_icon"><a-icon type="star-o"/>{{ item.starNum }}</a>
<a-divider slot="title" type="vertical" class="list-content-item_divider"/>
- <a slot="description" class="list-content-item_icon"><a-icon type="like-o"/>{{ item.like }}</a>
+ <a slot="description" class="list-content-item_icon"><a-icon type="like-o"/>{{ item.likeNum }}</a>
<a-divider slot="title" type="vertical" class="list-content-item_divider"/>
- <a slot="description" class="list-content-item_icon"><a-icon type="message"/>{{ item.message }}</a>
+ <a slot="description" class="list-content-item_icon"><a-icon type="message"/>{{ item.messageNum }}</a>
</div>
</a-card-meta>
<template class="ant-card-actions" slot="actions">
<a><a-icon type="edit"/> Edit</a>
<a><a-icon type="download"/> Download</a>
<a><a-icon type="setting"/> Setting</a>
- <a>
- <a-dropdown>
- <a class="ant-dropdown-link" href="javascript:;">
- <a-icon type="ellipsis"/>
- </a>
- <a-menu slot="overlay">
- <a-menu-item>
- <a href="javascript:;">1st menu item</a>
- </a-menu-item>
- <a-menu-item>
- <a href="javascript:;">2nd menu item</a>
- </a-menu-item>
- <a-menu-item>
- <a href="javascript:;">3rd menu item</a>
- </a-menu-item>
- </a-menu>
- </a-dropdown>
- </a>
+ <a><a-icon type="delete"/> Delete</a>
</template>
</a-card>
</template>
@@ -106,94 +94,9 @@ limitations under the License.
import HeadInfo from '@/components/tools/HeadInfo'
import Ellipsis from '@/components/Ellipsis'
import NewProject from './NewProject'
-
-const dataSource = []
-dataSource.push(null)
-for (let i = 0; i < 11; i++) {
- dataSource.push({
- title: 'Alipay',
- avatar: 'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png',
- description: ''
- })
-}
+import { queryProject } from '@/api/system'
const data = []
-data.push({
- mlType: 'tensorflow',
- title: 'Tensorflow-test1',
- description: 'Basic Operations on multi-GPU (notebook) (code). A simple example to introduce multi-GPU in TensorFlow. Basic Operations on multi-GPU (notebook) (code). A simple example to introduce multi-GPU in TensorFlow. A simple example to introduce multi-GPU in TensorFlow. Train a Neural Network on multi-GPU (notebook) (code)',
- owner: 'Frank',
- star: 10,
- like: 24,
- message: 2,
- visibility: 'Private',
- runTimes: 2,
- lastRunTime: '2018-07-26 22:44',
- progress: {
- value: 90
- }
-})
-data.push({
- mlType: 'pytorch',
- title: 'Tensorflow-test1',
- description: 'Basic Operations on multi-GPU (notebook) (code). ',
- owner: 'Frank',
- star: 10,
- like: 24,
- message: 2,
- visibility: 'Private',
- runTimes: 2,
- lastRunTime: '2018-07-26 22:44',
- progress: {
- value: 54
- }
-})
-data.push({
- mlType: 'tensorflow',
- title: 'Tensorflow-test1',
- description: 'Basic Operations on multi-GPU (notebook) (code). A simple example to introduce multi-GPU in TensorFlow. Train a Neural Network on multi-GPU (notebook) (code)',
- owner: 'Frank',
- star: 10,
- like: 24,
- message: 2,
- visibility: 'Public',
- runTimes: 2,
- lastRunTime: '2018-07-26 22:44',
- progress: {
- value: 66
- }
-})
-data.push({
- mlType: 'pytorch',
- title: 'Tensorflow-test1',
- description: 'Basic Operations on multi-GPU (notebook) (code). A simple example to introduce multi-GPU in TensorFlow. Train a Neural Network on multi-GPU (notebook) (code)',
- owner: 'Frank',
- star: 10,
- like: 24,
- message: 2,
- visibility: 'Public',
- runTimes: 2,
- lastRunTime: '2018-07-26 22:44',
- progress: {
- value: 30
- }
-})
-data.push({
- mlType: 'tensorflow',
- title: 'Tensorflow-test1',
- description: 'Basic Operations on multi-GPU (notebook) (code). A simple example to introduce multi-GPU in TensorFlow. Train a Neural Network on multi-GPU (notebook) (code)',
- owner: 'Frank',
- star: 10,
- like: 24,
- message: 2,
- visibility: 'Public',
- runTimes: 2,
- lastRunTime: '2018-07-26 22:44',
- progress: {
- status: 'exception',
- value: 100
- }
-})
export default {
name: 'StandardList',
@@ -207,14 +110,51 @@ export default {
tags: ['python', 'test', 'mnist'],
tagInputVisible: false,
tagInputValue: '',
-
- dataSource,
data,
- activeTabKey: '1'
+ activeTabKey: '1',
+ login_user: {},
+ pagination: {
+ pageSize: 9,
+ onChange: (page) => {
+ this.pagination.current = page
+ this.loadProjectData()
+ }
+ }
}
},
-
+ computed: {
+ userInfo () {
+ return this.$store.getters.userInfo
+ }
+ },
+ created () {
+ this.login_user = this.userInfo
+ this.loadProjectData(1)
+ },
methods: {
+ loadProjectData () {
+ var params = {
+ userName: this.login_user.name,
+ column: 'update_time',
+ order: 'desc',
+ pageNo: this.pagination.current,
+ pageSize: this.pagination.pageSize
+ }
+
+ queryProject(params).then((res) => {
+ console.log('res=', res)
+ if (res.success) {
+ this.data = res.result.records
+ this.pagination.total = res.result.total
+ } else {
+ this.$message.error(res.message)
+ }
+ })
+ },
+ changePage (page, pageSize) {
+ console.log('page=', page)
+ console.log('pageSize=', pageSize)
+ },
onShowNewProject () {
this.$emit('showNewProject')
},