[Feature-14505][UI] Support to set project-level preferences (#14573)
* add a few codes about the project preferences
(cherry picked from commit 20cf4ad4e6)
This commit is contained in:
parent
436c8e251e
commit
9057762ccb
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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.dolphinscheduler.api.controller;
|
||||
|
||||
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_PROJECT_PREFERENCE_ERROR;
|
||||
import static org.apache.dolphinscheduler.api.enums.Status.UPDATE_PROJECT_PREFERENCE_ERROR;
|
||||
|
||||
import org.apache.dolphinscheduler.api.aspect.AccessLogAnnotation;
|
||||
import org.apache.dolphinscheduler.api.exceptions.ApiException;
|
||||
import org.apache.dolphinscheduler.api.service.ProjectPreferenceService;
|
||||
import org.apache.dolphinscheduler.api.utils.Result;
|
||||
import org.apache.dolphinscheduler.common.constants.Constants;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestAttribute;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@Tag(name = "PROJECT_PREFERENCE_TAG")
|
||||
@RestController
|
||||
@RequestMapping("projects/{projectCode}/project-preference")
|
||||
@Slf4j
|
||||
public class ProjectPreferenceController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private ProjectPreferenceService projectPreferenceService;
|
||||
|
||||
@Operation(summary = "updateProjectPreference", description = "UPDATE_PROJECT_PREFERENCE_NOTES")
|
||||
@Parameters({
|
||||
@Parameter(name = "projectPreferences", description = "PROJECT_PREFERENCES", schema = @Schema(implementation = String.class)),
|
||||
})
|
||||
@PutMapping
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
@ApiException(UPDATE_PROJECT_PREFERENCE_ERROR)
|
||||
@AccessLogAnnotation(ignoreRequestArgs = "loginUser")
|
||||
public Result updateProjectPreference(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
|
||||
@Parameter(name = "projectCode", description = "PROJECT_CODE", required = true) @PathVariable long projectCode,
|
||||
@RequestParam(value = "projectPreferences", required = true) String projectPreferences) {
|
||||
return projectPreferenceService.updateProjectPreference(loginUser, projectCode, projectPreferences);
|
||||
}
|
||||
|
||||
@Operation(summary = "queryProjectPreferenceByProjectCode", description = "QUERY_PROJECT_PREFERENCE_NOTES")
|
||||
@GetMapping()
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
@ApiException(QUERY_PROJECT_PREFERENCE_ERROR)
|
||||
@AccessLogAnnotation(ignoreRequestArgs = "loginUser")
|
||||
public Result queryProjectPreferenceByProjectCode(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
|
||||
@Parameter(name = "projectCode", description = "PROJECT_CODE", required = true) @PathVariable long projectCode) {
|
||||
return projectPreferenceService.queryProjectPreferenceByProjectCode(loginUser, projectCode);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -287,6 +287,11 @@ public enum Status {
|
|||
|
||||
PROJECT_PARAMETER_CODE_EMPTY(10220, "project parameter code empty", "项目参数code为空"),
|
||||
|
||||
CREATE_PROJECT_PREFERENCE_ERROR(10300, "create project preference error", "创建项目偏好设置错误"),
|
||||
|
||||
UPDATE_PROJECT_PREFERENCE_ERROR(10301, "update project preference error", "更新项目偏好设置错误"),
|
||||
QUERY_PROJECT_PREFERENCE_ERROR(10302, "query project preference error", "查询项目偏好设置错误"),
|
||||
|
||||
UDF_FUNCTION_NOT_EXIST(20001, "UDF function not found", "UDF函数不存在"),
|
||||
UDF_FUNCTION_EXISTS(20002, "UDF function already exists", "UDF函数已存在"),
|
||||
RESOURCE_NOT_EXIST(20004, "resource not exist", "资源不存在"),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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.dolphinscheduler.api.service;
|
||||
|
||||
import org.apache.dolphinscheduler.api.utils.Result;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
|
||||
public interface ProjectPreferenceService {
|
||||
|
||||
Result updateProjectPreference(User loginUser, long projectCode, String preferences);
|
||||
|
||||
Result queryProjectPreferenceByProjectCode(User loginUser, long projectCode);
|
||||
}
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* 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.dolphinscheduler.api.service.impl;
|
||||
|
||||
import static org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.PROJECT;
|
||||
|
||||
import org.apache.dolphinscheduler.api.enums.Status;
|
||||
import org.apache.dolphinscheduler.api.service.ProjectPreferenceService;
|
||||
import org.apache.dolphinscheduler.api.service.ProjectService;
|
||||
import org.apache.dolphinscheduler.api.utils.Result;
|
||||
import org.apache.dolphinscheduler.common.utils.CodeGenerateUtils;
|
||||
import org.apache.dolphinscheduler.dao.entity.Project;
|
||||
import org.apache.dolphinscheduler.dao.entity.ProjectPreference;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
import org.apache.dolphinscheduler.dao.mapper.ProjectMapper;
|
||||
import org.apache.dolphinscheduler.dao.mapper.ProjectPreferenceMapper;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class ProjectPreferenceServiceImpl extends BaseServiceImpl
|
||||
implements
|
||||
ProjectPreferenceService {
|
||||
|
||||
@Autowired
|
||||
private ProjectPreferenceMapper projectPreferenceMapper;
|
||||
|
||||
@Autowired
|
||||
private ProjectService projectService;
|
||||
|
||||
@Autowired
|
||||
private ProjectMapper projectMapper;
|
||||
|
||||
@Override
|
||||
public Result updateProjectPreference(User loginUser, long projectCode, String preferences) {
|
||||
Result result = new Result();
|
||||
|
||||
// check if the user has the writing permission for project
|
||||
Project project = projectMapper.queryByCode(projectCode);
|
||||
boolean hasProjectAndWritePerm = projectService.hasProjectAndWritePerm(loginUser, project, result);
|
||||
if (!hasProjectAndWritePerm) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ProjectPreference projectPreference = projectPreferenceMapper
|
||||
.selectOne(new QueryWrapper<ProjectPreference>().lambda().eq(ProjectPreference::getProjectCode,
|
||||
projectCode));
|
||||
|
||||
Date now = new Date();
|
||||
if (Objects.isNull(projectPreference)) {
|
||||
projectPreference = new ProjectPreference();
|
||||
projectPreference.setProjectCode(projectCode);
|
||||
projectPreference.setPreferences(preferences);
|
||||
projectPreference.setUserId(loginUser.getId());
|
||||
projectPreference.setCode(CodeGenerateUtils.getInstance().genCode());
|
||||
projectPreference.setCreateTime(now);
|
||||
projectPreference.setUpdateTime(now);
|
||||
if (projectPreferenceMapper.insert(projectPreference) > 0) {
|
||||
log.info("Project preference is created and id is :{}", projectPreference.getId());
|
||||
result.setData(projectPreference);
|
||||
putMsg(result, Status.SUCCESS);
|
||||
} else {
|
||||
log.error("Project preference create error, projectCode:{}.", projectPreference.getProjectCode());
|
||||
putMsg(result, Status.CREATE_PROJECT_PREFERENCE_ERROR);
|
||||
}
|
||||
} else {
|
||||
projectPreference.setPreferences(preferences);
|
||||
projectPreference.setUserId(loginUser.getId());
|
||||
projectPreference.setUpdateTime(now);
|
||||
|
||||
if (projectPreferenceMapper.updateById(projectPreference) > 0) {
|
||||
log.info("Project preference is updated and id is :{}", projectPreference.getId());
|
||||
result.setData(projectPreference);
|
||||
putMsg(result, Status.SUCCESS);
|
||||
} else {
|
||||
log.error("Project preference update error, projectCode:{}.", projectPreference.getProjectCode());
|
||||
putMsg(result, Status.UPDATE_PROJECT_PREFERENCE_ERROR);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result queryProjectPreferenceByProjectCode(User loginUser, long projectCode) {
|
||||
Result result = new Result();
|
||||
|
||||
Project project = projectMapper.queryByCode(projectCode);
|
||||
boolean hasProjectAndPerm = projectService.hasProjectAndPerm(loginUser, project, result, PROJECT);
|
||||
if (!hasProjectAndPerm) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ProjectPreference projectPreference = projectPreferenceMapper
|
||||
.selectOne(new QueryWrapper<ProjectPreference>().lambda().eq(ProjectPreference::getProjectCode,
|
||||
projectCode));
|
||||
|
||||
result.setData(projectPreference);
|
||||
|
||||
putMsg(result, Status.SUCCESS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -447,4 +447,9 @@ UPDATE_PROJECT_PARAMETER_NOTES=update project parameter
|
|||
PROJECT_PARAMETER_CODE=project parameter code
|
||||
DELETE_PROJECT_PARAMETER_NOTES=delete project parameter
|
||||
QUERY_PROJECT_PARAMETER_LIST_PAGING_NOTES=query project parameter list paging
|
||||
QUERY_PROJECT_PARAMETER_NOTES=query project parameter
|
||||
QUERY_PROJECT_PARAMETER_NOTES=query project parameter
|
||||
|
||||
PROJECT_PREFERENCE_TAG=project preference related operation
|
||||
UPDATE_PROJECT_PREFERENCE_NOTES=update project preference
|
||||
PROJECT_PREFERENCES=project preferences
|
||||
QUERY_PROJECT_PREFERENCE_NOTES=query project preference
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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.dolphinscheduler.api.controller;
|
||||
|
||||
import org.apache.dolphinscheduler.api.enums.Status;
|
||||
import org.apache.dolphinscheduler.api.service.impl.ProjectPreferenceServiceImpl;
|
||||
import org.apache.dolphinscheduler.api.utils.Result;
|
||||
import org.apache.dolphinscheduler.common.enums.UserType;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||
public class ProjectPreferenceControllerTest {
|
||||
|
||||
@InjectMocks
|
||||
private ProjectPreferenceController projectPreferenceController;
|
||||
|
||||
@Mock
|
||||
private ProjectPreferenceServiceImpl projectPreferenceService;
|
||||
|
||||
@Test
|
||||
public void testUpdateProjectPreference() {
|
||||
User loginUser = getGeneralUser();
|
||||
|
||||
Mockito.when(projectPreferenceService.updateProjectPreference(Mockito.any(), Mockito.anyLong(),
|
||||
Mockito.anyString())).thenReturn(getSuccessResult());
|
||||
|
||||
Result result = projectPreferenceController.updateProjectPreference(loginUser, 1, "value");
|
||||
Assertions.assertEquals(Status.SUCCESS.getCode(), result.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryProjectPreferenceByProjectCode() {
|
||||
User loginUser = getGeneralUser();
|
||||
|
||||
Mockito.when(projectPreferenceService.queryProjectPreferenceByProjectCode(Mockito.any(), Mockito.anyLong()))
|
||||
.thenReturn(getSuccessResult());
|
||||
Result result = projectPreferenceController.queryProjectPreferenceByProjectCode(loginUser, 1);
|
||||
Assertions.assertEquals(Status.SUCCESS.getCode(), result.getCode());
|
||||
}
|
||||
|
||||
private User getGeneralUser() {
|
||||
User loginUser = new User();
|
||||
loginUser.setUserType(UserType.GENERAL_USER);
|
||||
loginUser.setUserName("userName");
|
||||
loginUser.setId(1);
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
private Result getSuccessResult() {
|
||||
Result result = new Result();
|
||||
result.setCode(Status.SUCCESS.getCode());
|
||||
result.setMsg(Status.SUCCESS.getMsg());
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* 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.dolphinscheduler.api.service;
|
||||
|
||||
import org.apache.dolphinscheduler.api.enums.Status;
|
||||
import org.apache.dolphinscheduler.api.service.impl.ProjectPreferenceServiceImpl;
|
||||
import org.apache.dolphinscheduler.api.service.impl.ProjectServiceImpl;
|
||||
import org.apache.dolphinscheduler.api.utils.Result;
|
||||
import org.apache.dolphinscheduler.common.enums.UserType;
|
||||
import org.apache.dolphinscheduler.dao.entity.Project;
|
||||
import org.apache.dolphinscheduler.dao.entity.ProjectPreference;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
import org.apache.dolphinscheduler.dao.mapper.ProjectMapper;
|
||||
import org.apache.dolphinscheduler.dao.mapper.ProjectPreferenceMapper;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||
public class ProjectPreferenceServiceTest {
|
||||
|
||||
@InjectMocks
|
||||
private ProjectPreferenceServiceImpl projectPreferenceService;
|
||||
|
||||
@Mock
|
||||
private ProjectMapper projectMapper;
|
||||
|
||||
@Mock
|
||||
private ProjectPreferenceMapper projectPreferenceMapper;
|
||||
|
||||
@Mock
|
||||
private ProjectServiceImpl projectService;
|
||||
|
||||
protected final static long projectCode = 1L;
|
||||
|
||||
@Test
|
||||
public void testUpdateProjectPreference() {
|
||||
User loginUser = getGeneralUser();
|
||||
|
||||
Mockito.when(projectMapper.queryByCode(projectCode)).thenReturn(getProject(projectCode));
|
||||
Mockito.when(projectService.hasProjectAndWritePerm(Mockito.any(), Mockito.any(), Mockito.any(Result.class)))
|
||||
.thenReturn(true);
|
||||
|
||||
Mockito.when(projectPreferenceMapper.selectOne(Mockito.any())).thenReturn(null);
|
||||
Mockito.when(projectPreferenceMapper.insert(Mockito.any())).thenReturn(1);
|
||||
|
||||
Result result = projectPreferenceService.updateProjectPreference(loginUser, projectCode, "value");
|
||||
Assertions.assertEquals(Status.SUCCESS.getCode(), result.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryProjectPreferenceByProjectCode() {
|
||||
User loginUser = getGeneralUser();
|
||||
|
||||
// PROJECT_PARAMETER_NOT_EXISTS
|
||||
Mockito.when(projectMapper.queryByCode(projectCode)).thenReturn(getProject(projectCode));
|
||||
Mockito.when(projectService.hasProjectAndPerm(Mockito.any(), Mockito.any(), Mockito.any(Result.class),
|
||||
Mockito.any())).thenReturn(true);
|
||||
|
||||
Mockito.when(projectPreferenceMapper.selectOne(Mockito.any())).thenReturn(null);
|
||||
Result result = projectPreferenceService.queryProjectPreferenceByProjectCode(loginUser, projectCode);
|
||||
Assertions.assertEquals(Status.SUCCESS.getCode(), result.getCode());
|
||||
|
||||
// SUCCESS
|
||||
Mockito.when(projectPreferenceMapper.selectOne(Mockito.any())).thenReturn(getProjectPreference());
|
||||
result = projectPreferenceService.queryProjectPreferenceByProjectCode(loginUser, projectCode);
|
||||
Assertions.assertEquals(Status.SUCCESS.getCode(), result.getCode());
|
||||
}
|
||||
|
||||
private User getGeneralUser() {
|
||||
User loginUser = new User();
|
||||
loginUser.setUserType(UserType.GENERAL_USER);
|
||||
loginUser.setUserName("userName");
|
||||
loginUser.setId(1);
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
private Project getProject(long projectCode) {
|
||||
Project project = new Project();
|
||||
project.setCode(projectCode);
|
||||
project.setId(1);
|
||||
project.setName("test");
|
||||
project.setUserId(1);
|
||||
return project;
|
||||
}
|
||||
|
||||
private ProjectPreference getProjectPreference() {
|
||||
ProjectPreference projectPreference = new ProjectPreference();
|
||||
projectPreference.setId(1);
|
||||
projectPreference.setCode(1);
|
||||
projectPreference.setProjectCode(projectCode);
|
||||
projectPreference.setPreferences("value");
|
||||
return projectPreference;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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.dolphinscheduler.dao.entity;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@TableName("t_ds_project_preference")
|
||||
public class ProjectPreference {
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
private long code;
|
||||
|
||||
@TableField("project_code")
|
||||
private long projectCode;
|
||||
|
||||
@TableField("preferences")
|
||||
private String preferences;
|
||||
|
||||
@TableField("user_id")
|
||||
private Integer userId;
|
||||
|
||||
private Date createTime;
|
||||
|
||||
private Date updateTime;
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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.dolphinscheduler.dao.mapper;
|
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.ProjectPreference;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
public interface ProjectPreferenceMapper extends BaseMapper<ProjectPreference> {
|
||||
|
||||
}
|
||||
|
|
@ -681,6 +681,28 @@ CREATE TABLE t_ds_project_parameter
|
|||
-- Records of t_ds_project_parameter
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for t_ds_project_preference
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS t_ds_project_preference CASCADE;
|
||||
CREATE TABLE t_ds_project_preference
|
||||
(
|
||||
id int(11) NOT NULL AUTO_INCREMENT,
|
||||
code bigint(20) NOT NULL,
|
||||
project_code bigint(20) NOT NULL,
|
||||
preferences varchar(512) NOT NULL,
|
||||
user_id int(11) DEFAULT NULL,
|
||||
create_time datetime NOT NULL,
|
||||
update_time datetime DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY unique_project_preference_project_code (project_code),
|
||||
UNIQUE KEY unique_project_preference_code (code)
|
||||
);
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of t_ds_project_preference
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for t_ds_queue
|
||||
-- ----------------------------
|
||||
|
|
|
|||
|
|
@ -684,6 +684,27 @@ CREATE TABLE `t_ds_project_parameter` (
|
|||
-- Records of t_ds_project_parameter
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for t_ds_project_preference
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `t_ds_project_preference`;
|
||||
CREATE TABLE `t_ds_project_preference` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'key',
|
||||
`code` bigint(20) NOT NULL COMMENT 'encoding',
|
||||
`project_code` bigint(20) NOT NULL COMMENT 'project code',
|
||||
`preferences` varchar(512) NOT NULL COMMENT 'project preferences',
|
||||
`user_id` int(11) DEFAULT NULL COMMENT 'creator id',
|
||||
`create_time` datetime NOT NULL COMMENT 'create time',
|
||||
`update_time` datetime DEFAULT NULL COMMENT 'update time',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `unique_project_preference_project_code`(`project_code`),
|
||||
UNIQUE KEY `unique_project_preference_code`(`code`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE = utf8_bin;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of t_ds_project_preference
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for t_ds_queue
|
||||
-- ----------------------------
|
||||
|
|
|
|||
|
|
@ -606,6 +606,27 @@ CREATE TABLE t_ds_project_parameter (
|
|||
CREATE UNIQUE INDEX unique_project_parameter_name on t_ds_project_parameter (project_code, param_name);
|
||||
CREATE UNIQUE INDEX unique_project_parameter_code on t_ds_project_parameter (code);
|
||||
|
||||
|
||||
--
|
||||
-- Table structure for table t_ds_project_preference
|
||||
--
|
||||
DROP TABLE IF EXISTS t_ds_project_preference;
|
||||
CREATE TABLE t_ds_project_preference
|
||||
(
|
||||
id int NOT NULL ,
|
||||
code bigint NOT NULL,
|
||||
project_code bigint NOT NULL,
|
||||
preferences varchar(512) NOT NULL,
|
||||
user_id int DEFAULT NULL ,
|
||||
create_time timestamp DEFAULT CURRENT_TIMESTAMP ,
|
||||
update_time timestamp DEFAULT CURRENT_TIMESTAMP ,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX unique_project_preference_project_code on t_ds_project_preference (project_code);
|
||||
CREATE UNIQUE INDEX unique_project_preference_code on t_ds_project_preference (code);
|
||||
|
||||
|
||||
--
|
||||
-- Table structure for table t_ds_queue
|
||||
--
|
||||
|
|
@ -998,6 +1019,10 @@ DROP SEQUENCE IF EXISTS t_ds_project_parameter_id_sequence;
|
|||
CREATE SEQUENCE t_ds_project_parameter_id_sequence;
|
||||
ALTER TABLE t_ds_project_parameter ALTER COLUMN id SET DEFAULT NEXTVAL('t_ds_project_parameter_id_sequence');
|
||||
|
||||
DROP SEQUENCE IF EXISTS t_ds_project_preference_id_sequence;
|
||||
CREATE SEQUENCE t_ds_project_preference_id_sequence;
|
||||
ALTER TABLE t_ds_project_preference ALTER COLUMN id SET DEFAULT NEXTVAL('t_ds_project_preference_id_sequence');
|
||||
|
||||
-- Records of t_ds_user?user : admin , password : dolphinscheduler123
|
||||
INSERT INTO t_ds_user(user_name, user_password, user_type, email, phone, tenant_id, state, create_time, update_time, time_zone)
|
||||
VALUES ('admin', '7ad2410b2f4c074479a8937a28a22b8f', '0', 'xxx@qq.com', '', '-1', 1, '2018-03-27 15:48:50', '2018-10-24 17:40:22', null);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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.dolphinscheduler.dao.mapper;
|
||||
|
||||
import org.apache.dolphinscheduler.dao.BaseDaoTest;
|
||||
import org.apache.dolphinscheduler.dao.entity.ProjectPreference;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
public class ProjectPreferenceMapperTest extends BaseDaoTest {
|
||||
|
||||
@Autowired
|
||||
private ProjectPreferenceMapper projectPreferenceMapper;
|
||||
|
||||
private ProjectPreference insertOne(long code, long projectCode) {
|
||||
ProjectPreference projectPreference = new ProjectPreference();
|
||||
projectPreference.setCode(code);
|
||||
projectPreference.setProjectCode(projectCode);
|
||||
projectPreference.setPreferences("{workerGroup:{availableOptions:[],default:1}}");
|
||||
projectPreference.setCreateTime(new Date());
|
||||
projectPreference.setUpdateTime(new Date());
|
||||
projectPreference.setUserId(1);
|
||||
projectPreferenceMapper.insert(projectPreference);
|
||||
return projectPreference;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdate() {
|
||||
ProjectPreference projectPreference = insertOne(1, 1);
|
||||
projectPreference.setUpdateTime(new Date());
|
||||
|
||||
int update = projectPreferenceMapper.updateById(projectPreference);
|
||||
Assertions.assertEquals(1, update);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryByProjectCode() {
|
||||
long projectCode = 2;
|
||||
ProjectPreference expectedProjectPreference = insertOne(2, projectCode);
|
||||
|
||||
ProjectPreference projectPreference = projectPreferenceMapper
|
||||
.selectOne(new QueryWrapper<ProjectPreference>().lambda().eq(ProjectPreference::getProjectCode,
|
||||
projectCode));
|
||||
Assertions.assertEquals(expectedProjectPreference, projectPreference);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -33,7 +33,6 @@ export function useForm() {
|
|||
delete state.formRef.model[key]
|
||||
}
|
||||
}
|
||||
|
||||
setValues(initialValues)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -117,6 +117,11 @@ export function useDataList() {
|
|||
key: `/projects/${projectCode}/parameter`,
|
||||
payload: { projectName: projectName },
|
||||
},
|
||||
{
|
||||
label: t('menu.project_preferences'),
|
||||
key: `/projects/${projectCode}/preferences`,
|
||||
payload: { projectName: projectName },
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ export default {
|
|||
security: 'Security',
|
||||
project_overview: 'Project Overview',
|
||||
project_parameter: 'Project Parameter',
|
||||
project_preferences: 'Project Preferences',
|
||||
workflow_relation: 'Workflow Relation',
|
||||
workflow: 'Workflow',
|
||||
workflow_definition: 'Workflow Definition',
|
||||
|
|
|
|||
|
|
@ -904,4 +904,11 @@ export default {
|
|||
delete_confirm: 'Delete?',
|
||||
success: 'Success',
|
||||
},
|
||||
preference: {
|
||||
edit_preference: 'Edit Preference',
|
||||
preference_manage: 'Project Preference Management',
|
||||
instruction_tips: 'The settings below will affect all workflows and tasks under this project.When creating the workflow or task, these preferences will be the default value of their components.',
|
||||
success: 'Success',
|
||||
submit: 'Submit'
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ export default {
|
|||
ui_setting: '界面设置',
|
||||
project_overview: '项目概览',
|
||||
project_parameter: '项目级别参数',
|
||||
project_preferences: '项目偏好设置',
|
||||
workflow_relation: '工作流关系',
|
||||
workflow: '工作流',
|
||||
workflow_definition: '工作流定义',
|
||||
|
|
|
|||
|
|
@ -878,4 +878,11 @@ export default {
|
|||
delete_confirm: '确定删除吗?',
|
||||
success: '成功',
|
||||
},
|
||||
preference: {
|
||||
edit_preference: '修改项目偏好设置',
|
||||
preference_manage: '项目偏好管理',
|
||||
instruction_tips: '下面这些项目偏好配置将影响这个项目下的所有工作流和任务。当创建工作流和任务时,这些配置将影响组件中的默认选项',
|
||||
success: '成功',
|
||||
submit: '提交'
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,17 @@ export default {
|
|||
auth: []
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/projects/:projectCode/preferences',
|
||||
name: 'projects-preference',
|
||||
component: components['projects-preference'],
|
||||
meta: {
|
||||
title: '项目偏好设置',
|
||||
activeMenu: 'projects',
|
||||
showSide: true,
|
||||
auth: []
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/projects/:projectCode/workflow/relation',
|
||||
name: 'workflow-relation',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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 { axios } from '@/service/service'
|
||||
|
||||
import {
|
||||
UpdateProjectPreferenceReq
|
||||
} from './types'
|
||||
|
||||
export function queryProjectPreferenceByProjectCode(
|
||||
projectCode: number
|
||||
): any {
|
||||
return axios({
|
||||
url: `/projects/${projectCode}/project-preference`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function updateProjectPreference(
|
||||
data: UpdateProjectPreferenceReq,
|
||||
projectCode: number
|
||||
): any {
|
||||
return axios({
|
||||
url: `/projects/${projectCode}/project-preference`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
interface ProjectPreferenceReq {
|
||||
projectPreferences: string
|
||||
}
|
||||
|
||||
interface UpdateProjectPreferenceReq extends ProjectPreferenceReq {
|
||||
code: number
|
||||
}
|
||||
|
||||
interface ProjectPreferenceRes {
|
||||
id: number
|
||||
code: number
|
||||
projectCode: number
|
||||
preferences: string
|
||||
createTime: string
|
||||
updateTime: string
|
||||
}
|
||||
|
||||
export {
|
||||
ProjectPreferenceRes,
|
||||
ProjectPreferenceReq,
|
||||
UpdateProjectPreferenceReq
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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 { ref, onMounted } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { IJsonItem } from '../../task/components/node/types'
|
||||
import { listAlertGroupById } from '@/service/modules/alert-group'
|
||||
|
||||
export function useAlertGroup(): IJsonItem {
|
||||
const { t } = useI18n()
|
||||
|
||||
const options = ref([] as { label: string; value: string }[])
|
||||
|
||||
const getAlertGroups = async () => {
|
||||
const res = await listAlertGroupById()
|
||||
options.value = res.map((item: any) => ({
|
||||
label: item.groupName,
|
||||
value: item.id
|
||||
}))
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getAlertGroups()
|
||||
})
|
||||
|
||||
return {
|
||||
type: 'select',
|
||||
field: 'alertGroups',
|
||||
span: 12,
|
||||
name: t('project.workflow.alarm_group'),
|
||||
options: options,
|
||||
value: 'default'
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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 { ref, onMounted } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { IJsonItem } from '../../task/components/node/types'
|
||||
import { queryTenantList } from '@/service/modules/tenants'
|
||||
|
||||
export function useTenant(): IJsonItem {
|
||||
const { t } = useI18n()
|
||||
|
||||
const options = ref([] as { label: string; value: string }[])
|
||||
|
||||
const getTenantList = async () => {
|
||||
const res = await queryTenantList()
|
||||
options.value = res.map((item: any) => ({
|
||||
label: item.tenantCode,
|
||||
value: item.tenantCode
|
||||
}))
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getTenantList()
|
||||
})
|
||||
|
||||
return {
|
||||
type: 'select',
|
||||
field: 'tenant',
|
||||
span: 12,
|
||||
name: t('project.workflow.tenant_code'),
|
||||
options: options,
|
||||
value: 'default'
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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 { useI18n } from 'vue-i18n'
|
||||
import type { IJsonItem } from '../../task/components/node/types'
|
||||
import { warningTypeList } from '@/common/common'
|
||||
|
||||
export function useWarningType(): IJsonItem {
|
||||
const { t } = useI18n()
|
||||
|
||||
const options = [] as any
|
||||
|
||||
const initOptions = () => {
|
||||
warningTypeList.forEach((item) => {
|
||||
options.push({ label: t(item.code), value: item.id })
|
||||
})
|
||||
}
|
||||
|
||||
initOptions()
|
||||
|
||||
return {
|
||||
type: 'select',
|
||||
field: 'warningType',
|
||||
name: t('project.workflow.notification_strategy'),
|
||||
span: 12,
|
||||
options,
|
||||
validate: {
|
||||
required: true
|
||||
},
|
||||
value: 'NONE'
|
||||
}
|
||||
}
|
||||
|
|
@ -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.
|
||||
*/
|
||||
|
||||
import { defineComponent } from 'vue'
|
||||
import Form from '@/components/form'
|
||||
import { useForm } from './use-form'
|
||||
import { NButton, NDivider, NSpace } from 'naive-ui'
|
||||
|
||||
const PreferenceForm = defineComponent({
|
||||
name: 'PreferenceForm',
|
||||
setup() {
|
||||
const {
|
||||
formRef,
|
||||
elementsRef,
|
||||
rulesRef,
|
||||
model,
|
||||
formProps,
|
||||
t,
|
||||
handleUpdate
|
||||
} = useForm()
|
||||
|
||||
return () => (
|
||||
<div>
|
||||
<div style={{ margin: '30px' }}>
|
||||
{t('project.preference.instruction_tips')}
|
||||
</div>
|
||||
<NDivider />
|
||||
<Form
|
||||
ref={formRef}
|
||||
meta={{
|
||||
model,
|
||||
rules: rulesRef.value,
|
||||
elements: elementsRef.value,
|
||||
...formProps.value
|
||||
}}
|
||||
layout={{
|
||||
xGap: 10
|
||||
}}
|
||||
style={{ marginLeft: '150px' }}
|
||||
/>
|
||||
<NDivider />
|
||||
<NSpace justify='end'>
|
||||
<NButton type='info' onClick={handleUpdate}>
|
||||
{t('project.preference.submit')}
|
||||
</NButton>
|
||||
</NSpace>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default PreferenceForm
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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 { NSpace } from 'naive-ui'
|
||||
import { defineComponent, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import Card from '@/components/card'
|
||||
import PreferenceForm from '@/views/projects/preference/detail'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ProjectPreference',
|
||||
setup() {
|
||||
const detailRef = ref()
|
||||
|
||||
return {
|
||||
detailRef
|
||||
}
|
||||
},
|
||||
render() {
|
||||
const { t } = useI18n()
|
||||
const { detailRef } = this
|
||||
|
||||
return (
|
||||
<NSpace vertical>
|
||||
<Card title={t('project.preference.preference_manage')}>
|
||||
<NSpace vertical>
|
||||
<PreferenceForm ref={detailRef} />
|
||||
</NSpace>
|
||||
</Card>
|
||||
</NSpace>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* 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 { onMounted, reactive, ref, Ref } from 'vue'
|
||||
import getElementByJson from '@/components/form/get-elements-by-json'
|
||||
import type {
|
||||
IFormItem,
|
||||
IJsonItem,
|
||||
INodeData
|
||||
} from '../task/components/node/types'
|
||||
import * as Fields from '@/views/projects/task/components/node/fields'
|
||||
import { Router, useRouter } from 'vue-router'
|
||||
import {
|
||||
queryProjectPreferenceByProjectCode,
|
||||
updateProjectPreference
|
||||
} from '@/service/modules/projects-preference'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { UpdateProjectPreferenceReq } from '@/service/modules/projects-preference/types'
|
||||
import { useWarningType } from '@/views/projects/preference/components/use-warning-type'
|
||||
import { useTenant } from '@/views/projects/preference/components/use-tenant'
|
||||
import { useAlertGroup } from '@/views/projects/preference/components/use-alert-group'
|
||||
|
||||
export function useForm() {
|
||||
const router: Router = useRouter()
|
||||
const { t } = useI18n()
|
||||
|
||||
const projectCode = Number(router.currentRoute.value.params.projectCode)
|
||||
|
||||
const formRef = ref()
|
||||
const jsonRef = ref([]) as Ref<IJsonItem[]>
|
||||
const elementsRef = ref([]) as Ref<IFormItem[]>
|
||||
const rulesRef = ref({})
|
||||
const formProps = ref({})
|
||||
|
||||
formProps.value = {
|
||||
labelPlacement: 'left',
|
||||
labelWidth: 'auto',
|
||||
size: 'large'
|
||||
}
|
||||
|
||||
const data = reactive({
|
||||
model: {
|
||||
taskPriority: 'MEDIUM',
|
||||
workerGroup: 'default',
|
||||
environmentCode: null,
|
||||
failRetryTimes: 0,
|
||||
failRetryInterval: 1,
|
||||
cpuQuota: -1,
|
||||
memoryMax: -1,
|
||||
timeoutFlag: false,
|
||||
timeoutNotifyStrategy: ['WARN'],
|
||||
timeout: 30
|
||||
} as INodeData
|
||||
})
|
||||
|
||||
const setValues = (initialValues: { [field: string]: any }) => {
|
||||
Object.assign(data.model, initialValues)
|
||||
}
|
||||
|
||||
const initProjectPreference = async () => {
|
||||
if (projectCode) {
|
||||
const result = await queryProjectPreferenceByProjectCode(projectCode)
|
||||
if (result?.preferences) {
|
||||
setValues(JSON.parse(result.preferences))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
initProjectPreference()
|
||||
})
|
||||
|
||||
const handleUpdate = () => {
|
||||
const requestData = {
|
||||
projectPreferences: JSON.stringify(data.model)
|
||||
} as UpdateProjectPreferenceReq
|
||||
updateProjectPreference(requestData, projectCode).then(() => {
|
||||
window.$message.success(t('project.preference.success'))
|
||||
})
|
||||
}
|
||||
|
||||
const preferencesItems: IJsonItem[] = [
|
||||
Fields.useTaskPriority(),
|
||||
useTenant(),
|
||||
Fields.useWorkerGroup(),
|
||||
Fields.useEnvironmentName(data.model, true),
|
||||
...Fields.useFailed(),
|
||||
useWarningType(),
|
||||
useAlertGroup(),
|
||||
...Fields.useResourceLimit()
|
||||
]
|
||||
|
||||
const restructurePreferencesItems = (preferencesItems: any) => {
|
||||
for (let item of preferencesItems) {
|
||||
if (item.validate?.required) {
|
||||
item.validate.required = false
|
||||
item.span = 12
|
||||
}
|
||||
Object.assign(item, { props: { style: 'width: 250px' } })
|
||||
}
|
||||
return preferencesItems
|
||||
}
|
||||
|
||||
jsonRef.value = restructurePreferencesItems(preferencesItems)
|
||||
|
||||
const getElements = () => {
|
||||
const { rules, elements } = getElementByJson(jsonRef.value, data.model)
|
||||
elementsRef.value = elements
|
||||
rulesRef.value = rules
|
||||
}
|
||||
|
||||
getElements()
|
||||
|
||||
return {
|
||||
formRef,
|
||||
elementsRef,
|
||||
rulesRef,
|
||||
model: data.model,
|
||||
formProps,
|
||||
t,
|
||||
handleUpdate
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,8 @@ import {
|
|||
provide,
|
||||
computed,
|
||||
h,
|
||||
Ref
|
||||
Ref,
|
||||
onMounted
|
||||
} from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import Modal from '@/components/modal'
|
||||
|
|
@ -48,6 +49,8 @@ import type {
|
|||
IWorkflowTaskInstance,
|
||||
WorkflowInstance
|
||||
} from './types'
|
||||
import { queryProjectPreferenceByProjectCode } from '@/service/modules/projects-preference'
|
||||
import { INodeData } from './types'
|
||||
|
||||
const props = {
|
||||
show: {
|
||||
|
|
@ -109,6 +112,7 @@ const NodeDetailModal = defineComponent({
|
|||
}
|
||||
|
||||
const headerLinks = ref([] as any)
|
||||
const projectPreferences = ref({} as any)
|
||||
|
||||
const handleViewLog = () => {
|
||||
if (props.taskInstance) {
|
||||
|
|
@ -116,6 +120,20 @@ const NodeDetailModal = defineComponent({
|
|||
}
|
||||
}
|
||||
|
||||
const initProjectPreferences = (projectCode: number) => {
|
||||
queryProjectPreferenceByProjectCode(projectCode).then((result: any) => {
|
||||
if (result?.preferences) {
|
||||
projectPreferences.value = JSON.parse(result.preferences)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const restructureNodeData = (data: INodeData) => {
|
||||
if (!data?.id) {
|
||||
Object.assign(data, projectPreferences.value)
|
||||
}
|
||||
}
|
||||
|
||||
const initHeaderLinks = (processInstance: any, taskType?: ITaskType) => {
|
||||
headerLinks.value = [
|
||||
{
|
||||
|
|
@ -158,7 +176,9 @@ const NodeDetailModal = defineComponent({
|
|||
},
|
||||
{
|
||||
text: t('project.node.enter_this_child_node'),
|
||||
show: props.data.taskType === 'SUB_PROCESS' || props.data.taskType === 'DYNAMIC',
|
||||
show:
|
||||
props.data.taskType === 'SUB_PROCESS' ||
|
||||
props.data.taskType === 'DYNAMIC',
|
||||
disabled:
|
||||
!props.data.id ||
|
||||
(router.currentRoute.value.name === 'workflow-instance-detail' &&
|
||||
|
|
@ -204,14 +224,20 @@ const NodeDetailModal = defineComponent({
|
|||
}))
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
initProjectPreferences(props.projectCode)
|
||||
})
|
||||
|
||||
watch(
|
||||
() => [props.show, props.data],
|
||||
async () => {
|
||||
if (!props.show) return
|
||||
initHeaderLinks(props.processInstance, props.data.taskType)
|
||||
taskStore.init()
|
||||
const nodeData = formatModel(props.data)
|
||||
await nextTick()
|
||||
detailRef.value.value.setValues(formatModel(props.data))
|
||||
restructureNodeData(nodeData)
|
||||
detailRef.value.value.setValues(nodeData)
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ export function formatParams(data: INodeData): {
|
|||
upstreamCodes: string
|
||||
taskDefinitionJsonObj: object
|
||||
} {
|
||||
|
||||
const taskParams: ITaskParams = {}
|
||||
if (data.taskType === 'SUB_PROCESS' || data.taskType === 'DYNAMIC') {
|
||||
taskParams.processDefinitionCode = data.processDefinitionCode
|
||||
|
|
|
|||
|
|
@ -47,9 +47,11 @@ import {
|
|||
NThing,
|
||||
NPopover
|
||||
} from 'naive-ui'
|
||||
import { Router, useRouter } from 'vue-router'
|
||||
import { ArrowDownOutlined, ArrowUpOutlined } from '@vicons/antd'
|
||||
import { timezoneList } from '@/common/timezone'
|
||||
import Crontab from '@/components/crontab'
|
||||
import { queryProjectPreferenceByProjectCode } from '@/service/modules/projects-preference'
|
||||
|
||||
const props = {
|
||||
row: {
|
||||
|
|
@ -74,6 +76,8 @@ export default defineComponent({
|
|||
const crontabRef = ref()
|
||||
const parallelismRef = ref(false)
|
||||
const { t } = useI18n()
|
||||
const router: Router = useRouter()
|
||||
|
||||
const { timingState } = useForm()
|
||||
const {
|
||||
variables,
|
||||
|
|
@ -86,12 +90,24 @@ export default defineComponent({
|
|||
getPreviewSchedule
|
||||
} = useModal(timingState, ctx)
|
||||
|
||||
const projectCode = Number(router.currentRoute.value.params.projectCode)
|
||||
|
||||
const environmentOptions = computed(() =>
|
||||
variables.environmentList.filter((item: any) =>
|
||||
item.workerGroups?.includes(timingState.timingForm.workerGroup)
|
||||
)
|
||||
)
|
||||
|
||||
const projectPreferences = ref({} as any)
|
||||
|
||||
const initProjectPreferences = (projectCode: number) => {
|
||||
queryProjectPreferenceByProjectCode(projectCode).then((result: any) => {
|
||||
if (result?.preferences) {
|
||||
projectPreferences.value = JSON.parse(result.preferences)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const hideModal = () => {
|
||||
ctx.emit('update:show')
|
||||
}
|
||||
|
|
@ -186,6 +202,71 @@ export default defineComponent({
|
|||
})
|
||||
}
|
||||
|
||||
const containValueInOptions = (
|
||||
options: Array<any>,
|
||||
findingValue: string
|
||||
): boolean => {
|
||||
for (let { value } of options) {
|
||||
if (findingValue === value) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
const restructureTimingForm = (timingForm: any) => {
|
||||
if (projectPreferences.value?.taskPriority) {
|
||||
timingForm.processInstancePriority =
|
||||
projectPreferences.value.taskPriority
|
||||
}
|
||||
if (projectPreferences.value?.warningType) {
|
||||
timingForm.warningType = projectPreferences.value.warningType
|
||||
}
|
||||
if (projectPreferences.value?.workerGroup) {
|
||||
if (
|
||||
containValueInOptions(
|
||||
variables.workerGroups,
|
||||
projectPreferences.value.workerGroup
|
||||
)
|
||||
) {
|
||||
timingForm.workerGroup = projectPreferences.value.workerGroup
|
||||
}
|
||||
}
|
||||
if (projectPreferences.value?.tenant) {
|
||||
if (
|
||||
containValueInOptions(
|
||||
variables.tenantList,
|
||||
projectPreferences.value.tenant
|
||||
)
|
||||
) {
|
||||
timingForm.tenantCode = projectPreferences.value.tenant
|
||||
}
|
||||
}
|
||||
if (
|
||||
projectPreferences.value?.environmentCode &&
|
||||
variables?.environmentList
|
||||
) {
|
||||
if (
|
||||
containValueInOptions(
|
||||
variables.environmentList,
|
||||
projectPreferences.value.environmentCode
|
||||
)
|
||||
) {
|
||||
timingForm.environmentCode = projectPreferences.value.environmentCode
|
||||
}
|
||||
}
|
||||
if (projectPreferences.value?.alertGroup && variables?.alertGroups) {
|
||||
if (
|
||||
containValueInOptions(
|
||||
variables.alertGroups,
|
||||
projectPreferences.value.alertGroup
|
||||
)
|
||||
) {
|
||||
timingForm.warningGroupId = projectPreferences.value.alertGroup
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const trim = getCurrentInstance()?.appContext.config.globalProperties.trim
|
||||
|
||||
onMounted(() => {
|
||||
|
|
@ -193,12 +274,16 @@ export default defineComponent({
|
|||
getTenantList()
|
||||
getAlertGroups()
|
||||
getEnvironmentList()
|
||||
initProjectPreferences(projectCode)
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.row,
|
||||
() => {
|
||||
if (!props.row.crontab) return
|
||||
if (!props.row.crontab) {
|
||||
restructureTimingForm(timingState.timingForm)
|
||||
return
|
||||
}
|
||||
|
||||
timingState.timingForm.startEndTime = [
|
||||
new Date(props.row.startTime),
|
||||
|
|
@ -298,19 +383,22 @@ export default defineComponent({
|
|||
</NFormItem>
|
||||
<NFormItem label=' ' showFeedback={false}>
|
||||
<NList>
|
||||
{this.schedulePreviewList.length > 0 ?
|
||||
<NListItem>
|
||||
<NThing
|
||||
description={t('project.workflow.next_five_execution_times')}
|
||||
>
|
||||
{this.schedulePreviewList.map((item: string) => (
|
||||
<NSpace>
|
||||
{item}
|
||||
<br/>
|
||||
</NSpace>
|
||||
))}
|
||||
</NThing>
|
||||
</NListItem> : null}
|
||||
{this.schedulePreviewList.length > 0 ? (
|
||||
<NListItem>
|
||||
<NThing
|
||||
description={t(
|
||||
'project.workflow.next_five_execution_times'
|
||||
)}
|
||||
>
|
||||
{this.schedulePreviewList.map((item: string) => (
|
||||
<NSpace>
|
||||
{item}
|
||||
<br />
|
||||
</NSpace>
|
||||
))}
|
||||
</NThing>
|
||||
</NListItem>
|
||||
) : null}
|
||||
</NList>
|
||||
</NFormItem>
|
||||
<NFormItem
|
||||
|
|
|
|||
Loading…
Reference in New Issue