[Improvement-15603][API] When removing or modifying a workflow the system can check if there any tasks depend on it. (#15681)
* modify the function of queryTaskSubProcessDepOnProcess * add a function to query downstream dependent tasks * confirm to make the workflow offline * query dependent tasks * check dependencies * done * done * done * done * improve the test case * improve the test case * improve codes * prettier the codes * prettier the codes
This commit is contained in:
parent
e3fdb1a3ff
commit
c61b81e0c6
|
|
@ -68,7 +68,7 @@ public class ProjectWorkerGroupController extends BaseController {
|
|||
@ @RequestParam(value = "workerGroups", required = false) String workerGroups
|
||||
* @return create result code
|
||||
*/
|
||||
@Operation(summary = "assignWorkerGroups", description = "CREATE_PROCESS_DEFINITION_NOTES")
|
||||
@Operation(summary = "assignWorkerGroups", description = "ASSIGN_WORKER_GROUPS_NOTES")
|
||||
@Parameters({
|
||||
@Parameter(name = "projectCode", description = "PROJECT_CODE", schema = @Schema(implementation = long.class, example = "123456")),
|
||||
@Parameter(name = "workerGroups", description = "WORKER_GROUP_LIST", schema = @Schema(implementation = List.class))
|
||||
|
|
|
|||
|
|
@ -135,4 +135,20 @@ public class WorkFlowLineageController extends BaseController {
|
|||
putMsg(result, Status.SUCCESS);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Operation(summary = "queryDownstreamDependentTaskList", description = "QUERY_DOWNSTREAM_DEPENDENT_TASK_NOTES")
|
||||
@Parameters({
|
||||
@Parameter(name = "workFlowCode", description = "PROCESS_DEFINITION_CODE", required = true, schema = @Schema(implementation = Long.class)),
|
||||
@Parameter(name = "taskCode", description = "TASK_DEFINITION_CODE", required = false, schema = @Schema(implementation = Long.class, example = "123456789")),
|
||||
})
|
||||
@GetMapping(value = "/query-dependent-tasks")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
@ApiException(QUERY_WORKFLOW_LINEAGE_ERROR)
|
||||
public Result<Map<String, Object>> queryDownstreamDependentTaskList(@Parameter(hidden = true) @RequestAttribute(value = SESSION_USER) User loginUser,
|
||||
@RequestParam(value = "workFlowCode") Long workFlowCode,
|
||||
@RequestParam(value = "taskCode", required = false, defaultValue = "0") Long taskCode) {
|
||||
Map<String, Object> result =
|
||||
workFlowLineageService.queryDownstreamDependentTasks(workFlowCode, taskCode);
|
||||
return returnDataList(result);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,15 @@ public interface WorkFlowLineageService {
|
|||
*/
|
||||
Set<TaskMainInfo> queryTaskDepOnProcess(long projectCode, long processDefinitionCode);
|
||||
|
||||
/**
|
||||
* Query downstream tasks depend on a process definition or a task
|
||||
*
|
||||
* @param processDefinitionCode Process definition code want to query tasks dependence
|
||||
* @param taskCode Task code want to query tasks dependence
|
||||
* @return downstream dependent tasks
|
||||
*/
|
||||
Map<String, Object> queryDownstreamDependentTasks(Long processDefinitionCode, Long taskCode);
|
||||
|
||||
/**
|
||||
* Query and return tasks dependence with string format, is a wrapper of queryTaskDepOnTask and task query method.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -2537,6 +2537,7 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro
|
|||
// do nothing if the workflow is already offline
|
||||
return;
|
||||
}
|
||||
|
||||
workflowDefinition.setReleaseState(ReleaseState.OFFLINE);
|
||||
processDefinitionDao.updateById(workflowDefinition);
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
|
@ -278,11 +279,29 @@ public class WorkFlowLineageServiceImpl extends BaseServiceImpl implements WorkF
|
|||
public Set<TaskMainInfo> queryTaskDepOnProcess(long projectCode, long processDefinitionCode) {
|
||||
Set<TaskMainInfo> taskMainInfos = new HashSet<>();
|
||||
List<TaskMainInfo> taskDependents =
|
||||
workFlowLineageMapper.queryTaskDependentDepOnProcess(projectCode, processDefinitionCode);
|
||||
workFlowLineageMapper.queryTaskDependentOnProcess(processDefinitionCode, 0);
|
||||
List<TaskMainInfo> taskSubProcess =
|
||||
workFlowLineageMapper.queryTaskSubProcessDepOnProcess(projectCode, processDefinitionCode);
|
||||
taskMainInfos.addAll(taskDependents);
|
||||
taskMainInfos.addAll(taskSubProcess);
|
||||
return taskMainInfos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query downstream tasks depend on a process definition or a task
|
||||
*
|
||||
* @param processDefinitionCode Process definition code want to query tasks dependence
|
||||
* @param taskCode Task code want to query tasks dependence
|
||||
* @return downstream dependent tasks
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> queryDownstreamDependentTasks(Long processDefinitionCode, Long taskCode) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
List<TaskMainInfo> taskDependents =
|
||||
workFlowLineageMapper.queryTaskDependentOnProcess(processDefinitionCode,
|
||||
Objects.isNull(taskCode) ? 0 : taskCode.longValue());
|
||||
result.put(Constants.DATA_LIST, taskDependents);
|
||||
putMsg(result, Status.SUCCESS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,4 +86,17 @@ public class WorkFlowLineageControllerTest {
|
|||
Mockito.when(workFlowLineageService.queryWorkFlowLineageByCode(projectCode, code)).thenReturn(new HashMap<>());
|
||||
assertDoesNotThrow(() -> workFlowLineageController.queryWorkFlowLineageByCode(user, projectCode, code));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryDownstreamDependentTaskList() {
|
||||
long code = 1L;
|
||||
long taskCode = 1L;
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put(Constants.STATUS, Status.SUCCESS);
|
||||
Mockito.when(workFlowLineageService.queryDownstreamDependentTasks(code, taskCode))
|
||||
.thenReturn(result);
|
||||
|
||||
assertDoesNotThrow(
|
||||
() -> workFlowLineageController.queryDownstreamDependentTaskList(user, code, taskCode));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,11 @@ public class TaskMainInfo {
|
|||
*/
|
||||
private Date taskUpdateTime;
|
||||
|
||||
/**
|
||||
* projectCode
|
||||
*/
|
||||
private long projectCode;
|
||||
|
||||
/**
|
||||
* processDefinitionCode
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -124,12 +124,12 @@ public interface WorkFlowLineageMapper {
|
|||
* current method `queryTaskDepOnProcess`. Which mean with the same parameter processDefinitionCode, all tasks in
|
||||
* `queryTaskDepOnTask` are in the result of method `queryTaskDepOnProcess`.
|
||||
*
|
||||
* @param projectCode Project code want to query tasks dependence
|
||||
* @param processDefinitionCode Process definition code want to query tasks dependence
|
||||
* @param taskCode Task code want to query tasks dependence
|
||||
* @return List of TaskMainInfo
|
||||
*/
|
||||
List<TaskMainInfo> queryTaskDependentDepOnProcess(@Param("projectCode") long projectCode,
|
||||
@Param("processDefinitionCode") long processDefinitionCode);
|
||||
List<TaskMainInfo> queryTaskDependentOnProcess(@Param("processDefinitionCode") long processDefinitionCode,
|
||||
@Param("taskCode") long taskCode);
|
||||
|
||||
/**
|
||||
* Query all tasks depend on task, only downstream task support currently(from dependent task type).
|
||||
|
|
|
|||
|
|
@ -191,12 +191,13 @@
|
|||
</where>
|
||||
</select>
|
||||
|
||||
<select id="queryTaskDependentDepOnProcess" resultType="org.apache.dolphinscheduler.dao.entity.TaskMainInfo">
|
||||
<select id="queryTaskDependentOnProcess" resultType="org.apache.dolphinscheduler.dao.entity.TaskMainInfo">
|
||||
select td.id
|
||||
, td.name as taskName
|
||||
, td.code as taskCode
|
||||
, td.version as taskVersion
|
||||
, td.task_type as taskType
|
||||
, pd.project_code as projectCode
|
||||
, ptr.process_definition_code as processDefinitionCode
|
||||
, pd.name as processDefinitionName
|
||||
, pd.version as processDefinitionVersion
|
||||
|
|
@ -205,9 +206,6 @@
|
|||
join t_ds_process_task_relation ptr on ptr.post_task_code = td.code and td.version = ptr.post_task_version
|
||||
join t_ds_process_definition pd on pd.code = ptr.process_definition_code and pd.version = ptr.process_definition_version
|
||||
<where>
|
||||
<if test="projectCode != 0">
|
||||
and ptr.project_code = #{projectCode}
|
||||
</if>
|
||||
<!-- ptr.process_definition_code != #{processDefinitionCode} query task not in current workflow -->
|
||||
<!-- For dependnet task type, using `like concat('%"definitionCode":', #{processDefinitionCode}, '%')` -->
|
||||
<if test="processDefinitionCode != 0">
|
||||
|
|
@ -215,6 +213,9 @@
|
|||
and ptr.process_definition_code != #{processDefinitionCode}
|
||||
and td.task_params like concat('%"definitionCode":', #{processDefinitionCode}, '%')
|
||||
</if>
|
||||
<if test="taskCode != 0">
|
||||
and (td.task_params like concat('%"depTaskCode":', #{taskCode}, '%') or td.task_params like concat('%"depTaskCode":-1%'))
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
|
|
|
|||
|
|
@ -238,6 +238,13 @@ export default {
|
|||
confirm_to_offline: 'Confirm to make the workflow offline?',
|
||||
time_to_online: 'Confirm to make the Scheduler online?',
|
||||
time_to_offline: 'Confirm to make the Scheduler offline?',
|
||||
warning_dependent_tasks_title: 'Warning',
|
||||
warning_dependent_tasks_desc: 'The downstream dependent tasks exists. Are you sure to make the workflow offline?',
|
||||
warning_dependencies: 'Dependencies:',
|
||||
delete_validate_dependent_tasks_desc: 'The downstream dependent tasks exists. You can not delete the workflow.',
|
||||
warning_offline_scheduler_dependent_tasks_desc: 'The downstream dependent tasks exists. Are you sure to make the scheduler offline?',
|
||||
delete_task_validate_dependent_tasks_desc: 'The downstream dependent tasks exists. You can not delete the task.',
|
||||
warning_delete_scheduler_dependent_tasks_desc: 'The downstream dependent tasks exists. Are you sure to delete the scheduler?',
|
||||
},
|
||||
task: {
|
||||
on_line: 'Online',
|
||||
|
|
@ -306,7 +313,8 @@ export default {
|
|||
startup_parameter: 'Startup Parameter',
|
||||
whether_dry_run: 'Whether Dry-Run',
|
||||
please_choose: 'Please Choose',
|
||||
remove_task_cache: 'Clear cache'
|
||||
remove_task_cache: 'Clear cache',
|
||||
delete_validate_dependent_tasks_desc: 'The downstream dependent tasks exists. You can not delete the task.',
|
||||
},
|
||||
dag: {
|
||||
create: 'Create Workflow',
|
||||
|
|
|
|||
|
|
@ -236,6 +236,13 @@ export default {
|
|||
confirm_to_offline: '是否确定下线该工作流?',
|
||||
time_to_online: '是否确定上线该定时?',
|
||||
time_to_offline: '是否确定下线该定时?',
|
||||
warning_dependent_tasks_title: '警告',
|
||||
warning_dependent_tasks_desc: '下游存在依赖, 下线操作可能会对下游任务产生影响. 你确定要下线该工作流嘛?',
|
||||
warning_dependencies: '依赖如下:',
|
||||
delete_validate_dependent_tasks_desc: '下游存在依赖,你不能删除该工作流',
|
||||
warning_offline_scheduler_dependent_tasks_desc: '下游存在依赖, 下线操作可能会对下游任务产生影响. 你确定要下线该定时嘛?',
|
||||
delete_task_validate_dependent_tasks_desc: '下游存在依赖,你不能删除该任务.',
|
||||
warning_delete_scheduler_dependent_tasks_desc: '下游存在依赖, 删除定时可能会对下游任务产生影响. 你确定要删除该定时嘛?',
|
||||
},
|
||||
task: {
|
||||
on_line: '线上',
|
||||
|
|
@ -304,7 +311,8 @@ export default {
|
|||
startup_parameter: '启动参数',
|
||||
whether_dry_run: '是否空跑',
|
||||
please_choose: '请选择',
|
||||
remove_task_cache: '清除缓存'
|
||||
remove_task_cache: '清除缓存',
|
||||
delete_validate_dependent_tasks_desc: '下游存在依赖,你不能删除该任务定义',
|
||||
},
|
||||
dag: {
|
||||
create: '创建工作流',
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
|
||||
import { axios } from '@/service/service'
|
||||
import { ProjectCodeReq, WorkflowCodeReq } from './types'
|
||||
import {DependentTaskReq, ProjectCodeReq, WorkflowCodeReq} from './types'
|
||||
|
||||
export function queryWorkFlowList(projectCode: ProjectCodeReq): any {
|
||||
return axios({
|
||||
|
|
@ -41,3 +41,11 @@ export function queryLineageByWorkFlowCode(
|
|||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function queryDependentTasks(projectCode: number, params: DependentTaskReq): any {
|
||||
return axios({
|
||||
url: `/projects/${projectCode}/lineages/query-dependent-tasks`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
|
@ -47,10 +47,15 @@ interface WorkflowRes {
|
|||
workFlowRelationList: WorkFlowRelationList[]
|
||||
}
|
||||
|
||||
interface DependentTaskReq extends WorkflowCodeReq {
|
||||
taskCode?: number
|
||||
}
|
||||
|
||||
export {
|
||||
ProjectCodeReq,
|
||||
WorkflowCodeReq,
|
||||
WorkFlowNameReq,
|
||||
DependentTaskReq,
|
||||
WorkflowRes,
|
||||
WorkFlowListRes
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* 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,
|
||||
PropType,
|
||||
h,
|
||||
ref, watch
|
||||
} from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import {NEllipsis, NModal, NSpace} from 'naive-ui'
|
||||
import {IDefinitionData} from "@/views/projects/workflow/definition/types";
|
||||
import ButtonLink from "@/components/button-link";
|
||||
|
||||
const props = {
|
||||
row: {
|
||||
type: Object as PropType<IDefinitionData>,
|
||||
default: {},
|
||||
required: false
|
||||
},
|
||||
show: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false
|
||||
},
|
||||
required: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: true
|
||||
},
|
||||
taskLinks: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'dependenciesConfirm',
|
||||
props,
|
||||
emits: ['update:show', 'update:row', 'confirm'],
|
||||
setup(props, ctx) {
|
||||
const { t } = useI18n()
|
||||
|
||||
const showRef = ref(props.show)
|
||||
|
||||
const confirmToHandle = () => {
|
||||
ctx.emit('confirm')
|
||||
}
|
||||
|
||||
const cancelToHandle = () => {
|
||||
ctx.emit('update:show', showRef)
|
||||
}
|
||||
|
||||
const renderDownstreamDependencies = () => {
|
||||
return h(
|
||||
<NSpace vertical>
|
||||
<div>{props.content}</div>
|
||||
<div>{t('project.workflow.warning_dependencies')}</div>
|
||||
{props.taskLinks.map((item: any) => {
|
||||
return (
|
||||
<ButtonLink
|
||||
onClick={item.action}
|
||||
disabled={false}
|
||||
>
|
||||
{{
|
||||
default: () =>
|
||||
h(NEllipsis,
|
||||
{
|
||||
style: 'max-width: 350px;line-height: 1.5'
|
||||
},
|
||||
() => item.text
|
||||
)
|
||||
}}
|
||||
</ButtonLink>
|
||||
)
|
||||
})}
|
||||
</NSpace>
|
||||
)
|
||||
}
|
||||
|
||||
watch(()=> props.show,
|
||||
() => {
|
||||
showRef.value = props.show
|
||||
})
|
||||
|
||||
return {renderDownstreamDependencies, confirmToHandle, cancelToHandle, showRef}
|
||||
},
|
||||
|
||||
render() {
|
||||
const { t } = useI18n()
|
||||
|
||||
return (
|
||||
<NModal
|
||||
v-model:show={this.showRef}
|
||||
preset={'dialog'}
|
||||
type={this.$props.required? 'error':'warning'}
|
||||
title={t('project.workflow.warning_dependent_tasks_title')}
|
||||
positiveText={this.$props.required? '':t('project.workflow.confirm')}
|
||||
negativeText={t('project.workflow.cancel')}
|
||||
maskClosable={false}
|
||||
onNegativeClick={this.cancelToHandle}
|
||||
onPositiveClick={this.confirmToHandle}
|
||||
onClose={this.cancelToHandle}
|
||||
>
|
||||
{{
|
||||
default: () => (
|
||||
this.renderDownstreamDependencies()
|
||||
)
|
||||
}}
|
||||
</NModal>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* 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 {DependentTaskReq} from "@/service/modules/lineages/types";
|
||||
import {queryDependentTasks} from "@/service/modules/lineages";
|
||||
import {TASK_TYPES_MAP} from "@/store/project";
|
||||
|
||||
export function useDependencies() {
|
||||
|
||||
const getDependentTasksBySingleTask = async (projectCode: any, workflowCode: any, taskCode: any) => {
|
||||
let tasks = [] as any
|
||||
if (workflowCode && taskCode) {
|
||||
let dependentTaskReq = {workFlowCode: workflowCode, taskCode: taskCode} as DependentTaskReq
|
||||
const res = await queryDependentTasks(projectCode, dependentTaskReq)
|
||||
res.filter((item: any) => item.processDefinitionCode !== workflowCode && item.taskType === TASK_TYPES_MAP.DEPENDENT.alias)
|
||||
.forEach((item: any) => {
|
||||
tasks.push(item.processDefinitionName + '->' + item.taskName)
|
||||
})
|
||||
}
|
||||
return tasks
|
||||
}
|
||||
|
||||
const getDependentTasksByWorkflow = async (projectCode: any, workflowCode: any) => {
|
||||
let tasks = [] as any
|
||||
if (workflowCode) {
|
||||
let dependentTaskReq = {workFlowCode: workflowCode} as DependentTaskReq
|
||||
const res = await queryDependentTasks(projectCode, dependentTaskReq)
|
||||
res.filter((item: any) => item.processDefinitionCode !== workflowCode && item.taskType === TASK_TYPES_MAP.DEPENDENT.alias)
|
||||
.forEach((item: any) => {
|
||||
tasks.push(item.processDefinitionName + '->' + item.taskName)
|
||||
})
|
||||
}
|
||||
return tasks
|
||||
}
|
||||
|
||||
const getDependentTasksByMultipleTasks = async (projectCode: any, workflowCode: any, taskCodes: any[]) => {
|
||||
let tasks = [] as any
|
||||
if (workflowCode && taskCodes?.length>0) {
|
||||
for(const taskCode of taskCodes) {
|
||||
const res = await getDependentTasksBySingleTask(projectCode, workflowCode, taskCode)
|
||||
if (res?.length >0) {
|
||||
tasks = tasks.concat(res)
|
||||
}
|
||||
}
|
||||
}
|
||||
return tasks
|
||||
}
|
||||
|
||||
const getDependentTaskLinksByMultipleTasks = async (projectCode: any, workflowCode: any, taskCodes: any[]) => {
|
||||
let dependentTaskLinks = [] as any
|
||||
if (workflowCode && projectCode) {
|
||||
for (const taskCode of taskCodes) {
|
||||
await getDependentTaskLinksByTask(projectCode, workflowCode, taskCode).then((res: any) => {
|
||||
dependentTaskLinks = dependentTaskLinks.concat(res)
|
||||
})
|
||||
}
|
||||
}
|
||||
return dependentTaskLinks
|
||||
}
|
||||
|
||||
const getDependentTaskLinks = async (projectCode: any, workflowCode: any) => {
|
||||
let dependentTaskReq = {workFlowCode: workflowCode} as DependentTaskReq
|
||||
let dependentTaskLinks = [] as any
|
||||
if (workflowCode && projectCode) {
|
||||
await queryDependentTasks(projectCode, dependentTaskReq).then((res: any) => {
|
||||
res.filter((item: any) => item.processDefinitionCode !== workflowCode && item.taskType === TASK_TYPES_MAP.DEPENDENT.alias)
|
||||
.forEach((item: any) => {
|
||||
dependentTaskLinks.push(
|
||||
{
|
||||
text: item.processDefinitionName + '->' + item.taskName,
|
||||
show: true,
|
||||
action: () => {
|
||||
const url = `/projects/${item.projectCode}/workflow/definitions/${item.processDefinitionCode}`
|
||||
window.open(url, '_blank')
|
||||
},
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
return dependentTaskLinks
|
||||
}
|
||||
|
||||
const getDependentTaskLinksByTask = async (projectCode: any, workflowCode: any, taskCode: any) => {
|
||||
let dependentTaskReq = {workFlowCode: workflowCode, taskCode: taskCode} as DependentTaskReq
|
||||
let dependentTaskLinks = [] as any
|
||||
if (workflowCode && projectCode) {
|
||||
await queryDependentTasks(projectCode, dependentTaskReq).then((res: any) => {
|
||||
res.filter((item: any) => item.processDefinitionCode !== workflowCode && item.taskType === TASK_TYPES_MAP.DEPENDENT.alias)
|
||||
.forEach((item: any) => {
|
||||
dependentTaskLinks.push(
|
||||
{
|
||||
text: item.processDefinitionName + '->' + item.taskName,
|
||||
show: true,
|
||||
action: () => {
|
||||
const url = `/projects/${item.projectCode}/workflow/definitions/${item.processDefinitionCode}`
|
||||
window.open(url, '_blank')
|
||||
},
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
return dependentTaskLinks
|
||||
}
|
||||
|
||||
return { getDependentTasksBySingleTask, getDependentTasksByMultipleTasks, getDependentTaskLinks, getDependentTasksByWorkflow, getDependentTaskLinksByTask, getDependentTaskLinksByMultipleTasks }
|
||||
}
|
||||
|
|
@ -41,6 +41,7 @@ import Card from '@/components/card'
|
|||
import VersionModal from './components/version-modal'
|
||||
import TaskModal from '@/views/projects/task/components/node/detail-modal'
|
||||
import type { INodeData } from './types'
|
||||
import DependenciesModal from "@/views/projects/components/dependencies/dependencies-modal";
|
||||
|
||||
const BatchTaskDefinition = defineComponent({
|
||||
name: 'batch-task-definition',
|
||||
|
|
@ -213,6 +214,13 @@ const BatchTaskDefinition = defineComponent({
|
|||
readonly={this.taskReadonly}
|
||||
saving={this.taskSaving}
|
||||
/>
|
||||
<DependenciesModal
|
||||
v-model:show={this.dependenciesData.showRef}
|
||||
v-model:taskLinks={this.dependenciesData.taskLinks}
|
||||
required={this.dependenciesData.required}
|
||||
content={this.dependenciesData.tip}
|
||||
onConfirm={this.dependenciesData.action}
|
||||
/>
|
||||
</NSpace>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,11 +49,15 @@ import type {
|
|||
} from '@/service/modules/task-definition/types'
|
||||
import type { IRecord } from './types'
|
||||
|
||||
import { useDependencies } from '../../components/dependencies/use-dependencies'
|
||||
|
||||
export function useTable(onEdit: Function) {
|
||||
const { t } = useI18n()
|
||||
const route = useRoute()
|
||||
const projectCode = Number(route.params.projectCode)
|
||||
|
||||
const {getDependentTaskLinksByTask} = useDependencies()
|
||||
|
||||
const createColumns = (variables: any) => {
|
||||
variables.columns = [
|
||||
{
|
||||
|
|
@ -260,22 +264,38 @@ export function useTable(onEdit: Function) {
|
|||
totalPage: ref(1),
|
||||
taskType: ref(null),
|
||||
showVersionModalRef: ref(false),
|
||||
dependentTasksShowRef: ref(false),
|
||||
dependentTaskLinksRef: ref([]),
|
||||
row: {},
|
||||
loadingRef: ref(false)
|
||||
loadingRef: ref(false),
|
||||
dependenciesData: ref({showRef: ref(false), taskLinks: ref([]), required: ref(false), tip: ref(''), action:() => {}}),
|
||||
})
|
||||
|
||||
const handleDelete = (row: any) => {
|
||||
deleteTaskDefinition({ code: row.taskCode }, { projectCode }).then(() => {
|
||||
getTableData({
|
||||
pageSize: variables.pageSize,
|
||||
pageNo:
|
||||
variables.tableData.length === 1 && variables.page > 1
|
||||
? variables.page - 1
|
||||
: variables.page,
|
||||
searchTaskName: variables.searchTaskName,
|
||||
searchWorkflowName: variables.searchWorkflowName,
|
||||
taskType: variables.taskType
|
||||
})
|
||||
variables.row = row
|
||||
getDependentTaskLinksByTask(projectCode, row.processDefinitionCode, row.taskCode).then((res: any) =>{
|
||||
if (res && res.length > 0) {
|
||||
variables.dependenciesData = {
|
||||
showRef: true,
|
||||
taskLinks: res,
|
||||
tip: t('project.workflow.delete_validate_dependent_tasks_desc'),
|
||||
required: true,
|
||||
action: () => {}
|
||||
}
|
||||
} else {
|
||||
deleteTaskDefinition({ code: row.taskCode }, { projectCode }).then(() => {
|
||||
getTableData({
|
||||
pageSize: variables.pageSize,
|
||||
pageNo:
|
||||
variables.tableData.length === 1 && variables.page > 1
|
||||
? variables.page - 1
|
||||
: variables.page,
|
||||
searchTaskName: variables.searchTaskName,
|
||||
searchWorkflowName: variables.searchWorkflowName,
|
||||
taskType: variables.taskType
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ import { useRoute } from 'vue-router'
|
|||
import styles from './menu.module.scss'
|
||||
import { uuid } from '@/common/common'
|
||||
import { IWorkflowTaskInstance } from './types'
|
||||
import { NButton } from 'naive-ui'
|
||||
import {NButton} from 'naive-ui'
|
||||
import {useDependencies} from "@/views/projects/components/dependencies/use-dependencies"
|
||||
|
||||
const props = {
|
||||
startDisplay: {
|
||||
|
|
@ -57,6 +58,10 @@ const props = {
|
|||
top: {
|
||||
type: Number as PropType<number>,
|
||||
default: 0
|
||||
},
|
||||
dependenciesData: {
|
||||
type: Object as PropType<any>,
|
||||
require: false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -77,6 +82,12 @@ export default defineComponent({
|
|||
const graph = inject('graph', ref())
|
||||
const route = useRoute()
|
||||
const projectCode = Number(route.params.projectCode)
|
||||
const workflowCode = Number(route.params.code)
|
||||
const { t } = useI18n()
|
||||
|
||||
const { getDependentTaskLinksByTask } = useDependencies()
|
||||
|
||||
const dependenciesData = props.dependenciesData
|
||||
|
||||
const hide = () => {
|
||||
ctx.emit('hide', false)
|
||||
|
|
@ -134,9 +145,19 @@ export default defineComponent({
|
|||
})
|
||||
}
|
||||
|
||||
const handleDelete = () => {
|
||||
graph.value?.removeCell(props.cell)
|
||||
ctx.emit('removeTasks', [Number(props.cell?.id)])
|
||||
const handleDelete = async () => {
|
||||
let taskCode = props.cell?.id
|
||||
let res = await getDependentTaskLinksByTask(projectCode, workflowCode, taskCode)
|
||||
dependenciesData.showRef = false
|
||||
if (res.length > 0) {
|
||||
dependenciesData.showRef = true
|
||||
dependenciesData.taskLinks = res
|
||||
dependenciesData.tip = t('project.task.delete_validate_dependent_tasks_desc')
|
||||
dependenciesData.required = true
|
||||
} else {
|
||||
graph.value?.removeCell(props.cell)
|
||||
ctx.emit('removeTasks', [Number(props.cell?.id)])
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
|
@ -189,8 +210,8 @@ export default defineComponent({
|
|||
{t('project.node.copy')}
|
||||
</NButton>
|
||||
<NButton
|
||||
class={`${styles['menu-item']}`}
|
||||
onClick={this.handleDelete}
|
||||
class={`${styles['menu-item']}`}
|
||||
onClick={this.handleDelete}
|
||||
>
|
||||
{t('project.node.delete')}
|
||||
</NButton>
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ import type { Graph } from '@antv/x6'
|
|||
import StartupParam from './dag-startup-param'
|
||||
import VariablesView from '@/views/projects/workflow/instance/components/variables-view'
|
||||
import { WorkflowDefinition, WorkflowInstance } from './types'
|
||||
import { useDependencies } from "@/views/projects/components/dependencies/use-dependencies"
|
||||
|
||||
const props = {
|
||||
layoutToggle: {
|
||||
|
|
@ -64,6 +65,10 @@ const props = {
|
|||
// The same as the structure responsed by the queryProcessDefinitionByCode api
|
||||
type: Object as PropType<WorkflowDefinition>,
|
||||
default: null
|
||||
},
|
||||
dependenciesData: {
|
||||
type: Object as PropType<any>,
|
||||
require: false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -79,6 +84,11 @@ export default defineComponent({
|
|||
const graph = inject<Ref<Graph | undefined>>('graph', ref())
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const projectCode = Number(route.params.projectCode)
|
||||
const workflowCode = Number(route.params.code)
|
||||
const { getDependentTaskLinksByMultipleTasks } = useDependencies()
|
||||
|
||||
const dependenciesData = props.dependenciesData
|
||||
|
||||
/**
|
||||
* Node search and navigate
|
||||
|
|
@ -164,15 +174,23 @@ export default defineComponent({
|
|||
/**
|
||||
* Delete selected edges and nodes
|
||||
*/
|
||||
const removeCells = () => {
|
||||
const removeCells = async () => {
|
||||
if (graph.value) {
|
||||
const cells = graph.value.getSelectedCells()
|
||||
if (cells) {
|
||||
const codes = cells
|
||||
.filter((cell) => cell.isNode())
|
||||
.map((cell) => +cell.id)
|
||||
context.emit('removeTasks', codes, cells)
|
||||
graph.value?.removeCells(cells)
|
||||
const res = await getDependentTaskLinksByMultipleTasks(projectCode, workflowCode, codes)
|
||||
if (res.length > 0) {
|
||||
dependenciesData.showRef = true
|
||||
dependenciesData.taskLinks = res
|
||||
dependenciesData.tip = t('project.task.delete_validate_dependent_tasks_desc')
|
||||
dependenciesData.required = true
|
||||
} else {
|
||||
context.emit('removeTasks', codes, cells)
|
||||
graph.value?.removeCells(cells)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import {
|
|||
toRef,
|
||||
watch,
|
||||
onBeforeUnmount,
|
||||
computed
|
||||
computed, reactive
|
||||
} from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
|
@ -57,6 +57,7 @@ import utils from '@/utils'
|
|||
import { useUISettingStore } from '@/store/ui-setting/ui-setting'
|
||||
import { executeTask } from '@/service/modules/executors'
|
||||
import { removeTaskInstanceCache } from '@/service/modules/task-instances'
|
||||
import DependenciesModal from "@/views/projects/components/dependencies/dependencies-modal";
|
||||
|
||||
const props = {
|
||||
// If this prop is passed, it means from definition detail
|
||||
|
|
@ -333,6 +334,13 @@ export default defineComponent({
|
|||
}
|
||||
}
|
||||
|
||||
const dependenciesData = reactive({
|
||||
showRef: ref(false),
|
||||
taskLinks: ref([]),
|
||||
required: ref(false),
|
||||
tip: ref(''), action: () => {}
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.definition,
|
||||
() => {
|
||||
|
|
@ -373,6 +381,7 @@ export default defineComponent({
|
|||
onSaveModelToggle={saveModelToggle}
|
||||
onRemoveTasks={removeTasks}
|
||||
onRefresh={refreshTaskStatus}
|
||||
v-model:dependenciesData={dependenciesData}
|
||||
/>
|
||||
<div class={Styles.content}>
|
||||
<DagSidebar onDragStart={onDragStart} />
|
||||
|
|
@ -428,6 +437,14 @@ export default defineComponent({
|
|||
onViewLog={handleViewLog}
|
||||
onExecuteTask={handleExecuteTask}
|
||||
onRemoveTaskInstanceCache={handleRemoveTaskInstanceCache}
|
||||
v-model:dependenciesData={dependenciesData}
|
||||
/>
|
||||
<DependenciesModal
|
||||
v-model:show={dependenciesData.showRef}
|
||||
v-model:taskLinks={dependenciesData.taskLinks}
|
||||
required={dependenciesData.required}
|
||||
content={dependenciesData.tip}
|
||||
onConfirm={dependenciesData.action}
|
||||
/>
|
||||
{!!props.definition && (
|
||||
<StartModal
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import {
|
|||
} from '@vicons/antd'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { IDefinitionData } from '../types'
|
||||
|
||||
const props = {
|
||||
row: {
|
||||
type: Object as PropType<IDefinitionData>
|
||||
|
|
@ -95,6 +96,7 @@ export default defineComponent({
|
|||
const handleReleaseScheduler = () => {
|
||||
ctx.emit('releaseScheduler')
|
||||
}
|
||||
|
||||
return {
|
||||
handleEditWorkflow,
|
||||
handleStartWorkflow,
|
||||
|
|
@ -114,6 +116,7 @@ export default defineComponent({
|
|||
const releaseState = this.row?.releaseState
|
||||
const scheduleReleaseState = this.row?.scheduleReleaseState
|
||||
const schedule = this.row?.schedule
|
||||
|
||||
return (
|
||||
<NSpace>
|
||||
<NTooltip trigger={'hover'}>
|
||||
|
|
@ -166,10 +169,7 @@ export default defineComponent({
|
|||
trigger: () => (
|
||||
<NPopconfirm onPositiveClick={this.handleReleaseWorkflow}>
|
||||
{{
|
||||
default: () =>
|
||||
releaseState === 'ONLINE'
|
||||
? t('project.workflow.confirm_to_offline')
|
||||
: t('project.workflow.confirm_to_online'),
|
||||
default: () => releaseState === 'OFFLINE' ? t('project.workflow.confirm_to_online'):t('project.workflow.confirm_to_offline'),
|
||||
trigger: () => (
|
||||
<NButton
|
||||
size='small'
|
||||
|
|
@ -220,9 +220,7 @@ export default defineComponent({
|
|||
<NPopconfirm onPositiveClick={this.handleReleaseScheduler}>
|
||||
{{
|
||||
default: () =>
|
||||
scheduleReleaseState === 'ONLINE'
|
||||
? t('project.workflow.time_to_offline')
|
||||
: t('project.workflow.time_to_online'),
|
||||
scheduleReleaseState === 'OFFLINE' ? t('project.workflow.time_to_online'):t('project.workflow.time_to_offline'),
|
||||
trigger: () => (
|
||||
<NButton
|
||||
size='small'
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import {
|
|||
NSpace,
|
||||
NTooltip,
|
||||
NPopconfirm,
|
||||
NModal
|
||||
NModal,
|
||||
} from 'naive-ui'
|
||||
import {
|
||||
defineComponent,
|
||||
|
|
@ -45,6 +45,7 @@ import VersionModal from './components/version-modal'
|
|||
import CopyModal from './components/copy-modal'
|
||||
import type { Router } from 'vue-router'
|
||||
import Search from '@/components/input-search'
|
||||
import DependenciesModal from '@/views/projects/components/dependencies/dependencies-modal'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'WorkflowDefinitionList',
|
||||
|
|
@ -318,6 +319,14 @@ export default defineComponent({
|
|||
maskClosable={false}
|
||||
onPositiveClick={this.confirmToSetWorkflowTiming}
|
||||
/>
|
||||
<DependenciesModal
|
||||
v-model:row={this.row}
|
||||
v-model:show={this.dependenciesData.showRef}
|
||||
v-model:taskLinks={this.dependenciesData.taskLinks}
|
||||
required={this.dependenciesData.required}
|
||||
content={this.dependenciesData.tip}
|
||||
onConfirm={this.dependenciesData.action}
|
||||
/>
|
||||
</NSpace>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import { useTable } from './use-table'
|
|||
import Card from '@/components/card'
|
||||
import TimingModal from '../components/timing-modal'
|
||||
import type { Router } from 'vue-router'
|
||||
import DependenciesModal from "@/views/projects/components/dependencies/dependencies-modal";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'WorkflowDefinitionTiming',
|
||||
|
|
@ -115,6 +116,13 @@ export default defineComponent({
|
|||
v-model:show={this.showRef}
|
||||
onUpdateList={this.handleUpdateList}
|
||||
/>
|
||||
<DependenciesModal
|
||||
v-model:show={this.dependenciesData.showRef}
|
||||
v-model:taskLinks={this.dependenciesData.taskLinks}
|
||||
required={this.dependenciesData.required}
|
||||
content={this.dependenciesData.tip}
|
||||
onConfirm={this.dependenciesData.action}
|
||||
/>
|
||||
</NSpace>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,15 +39,18 @@ import {
|
|||
import { format } from 'date-fns-tz'
|
||||
import { ISearchParam } from './types'
|
||||
import type { Router } from 'vue-router'
|
||||
import { useDependencies } from "@/views/projects/components/dependencies/use-dependencies"
|
||||
|
||||
export function useTable() {
|
||||
const { t } = useI18n()
|
||||
const router: Router = useRouter()
|
||||
|
||||
const {getDependentTaskLinks} = useDependencies()
|
||||
|
||||
const variables = reactive({
|
||||
columns: [],
|
||||
tableWidth: DefaultTableWidth,
|
||||
row: {},
|
||||
row: {} as any,
|
||||
tableData: [],
|
||||
projectCode: ref(Number(router.currentRoute.value.params.projectCode)),
|
||||
page: ref(1),
|
||||
|
|
@ -58,7 +61,8 @@ export function useTable() {
|
|||
loadingRef: ref(false),
|
||||
processDefinitionCode: router.currentRoute.value.params.definitionCode
|
||||
? ref(Number(router.currentRoute.value.params.definitionCode))
|
||||
: ref()
|
||||
: ref(),
|
||||
dependenciesData: ref({showRef: false, taskLinks: ref([]), required: ref(false), tip: ref(''), action:() => {}}),
|
||||
})
|
||||
|
||||
const renderTime = (time: string, timeZone: string) => {
|
||||
|
|
@ -329,7 +333,7 @@ export function useTable() {
|
|||
NPopconfirm,
|
||||
{
|
||||
onPositiveClick: () => {
|
||||
handleDelete(row.id)
|
||||
handleDelete(row)
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -344,7 +348,8 @@ export function useTable() {
|
|||
{
|
||||
circle: true,
|
||||
type: 'error',
|
||||
size: 'small'
|
||||
size: 'small',
|
||||
disabled: row.releaseState === 'ONLINE'
|
||||
},
|
||||
{
|
||||
icon: () => h(DeleteOutlined)
|
||||
|
|
@ -387,12 +392,43 @@ export function useTable() {
|
|||
}
|
||||
|
||||
const handleReleaseState = (row: any) => {
|
||||
let handle = online
|
||||
if (row.releaseState === 'ONLINE') {
|
||||
handle = offline
|
||||
variables.row = row
|
||||
getDependentTaskLinks(variables.projectCode, row.processDefinitionCode).then((res: any) =>{
|
||||
if (res && res.length > 0) {
|
||||
variables.dependenciesData.showRef = true
|
||||
variables.dependenciesData.taskLinks = res
|
||||
variables.dependenciesData.tip = t('project.workflow.warning_delete_scheduler_dependent_tasks_desc')
|
||||
variables.dependenciesData.required = false
|
||||
variables.dependenciesData.action = confirmToOfflineSchedule
|
||||
} else {
|
||||
offline(variables.projectCode, row.id).then(() => {
|
||||
window.$message.success(t('project.workflow.success'))
|
||||
getTableData({
|
||||
pageSize: variables.pageSize,
|
||||
pageNo: variables.page,
|
||||
searchVal: variables.searchVal,
|
||||
projectCode: variables.projectCode,
|
||||
processDefinitionCode: variables.processDefinitionCode
|
||||
})
|
||||
})
|
||||
}})
|
||||
} else {
|
||||
online(variables.projectCode, row.id).then(() => {
|
||||
window.$message.success(t('project.workflow.success'))
|
||||
getTableData({
|
||||
pageSize: variables.pageSize,
|
||||
pageNo: variables.page,
|
||||
searchVal: variables.searchVal,
|
||||
projectCode: variables.projectCode,
|
||||
processDefinitionCode: variables.processDefinitionCode
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
handle(variables.projectCode, row.id).then(() => {
|
||||
const confirmToOfflineSchedule = () => {
|
||||
offline(variables.projectCode, variables.row.id).then(() => {
|
||||
window.$message.success(t('project.workflow.success'))
|
||||
getTableData({
|
||||
pageSize: variables.pageSize,
|
||||
|
|
@ -402,14 +438,11 @@ export function useTable() {
|
|||
processDefinitionCode: variables.processDefinitionCode
|
||||
})
|
||||
})
|
||||
variables.dependenciesData.showRef = false
|
||||
}
|
||||
|
||||
const handleDelete = (id: number) => {
|
||||
/* after deleting data from the current page, you need to jump forward when the page is empty. */
|
||||
if (variables.tableData.length === 1 && variables.page > 1) {
|
||||
variables.page -= 1
|
||||
}
|
||||
deleteScheduleById(id, variables.projectCode).then(() => {
|
||||
const confirmToDeleteSchedule = () => {
|
||||
deleteScheduleById(variables.row.id, variables.projectCode).then(() => {
|
||||
window.$message.success(t('project.workflow.success'))
|
||||
getTableData({
|
||||
pageSize: variables.pageSize,
|
||||
|
|
@ -419,6 +452,35 @@ export function useTable() {
|
|||
processDefinitionCode: variables.processDefinitionCode
|
||||
})
|
||||
})
|
||||
variables.dependenciesData.showRef = false
|
||||
}
|
||||
|
||||
const handleDelete = (row: any) => {
|
||||
/* after deleting data from the current page, you need to jump forward when the page is empty. */
|
||||
if (variables.tableData.length === 1 && variables.page > 1) {
|
||||
variables.page -= 1
|
||||
}
|
||||
variables.row = row
|
||||
getDependentTaskLinks(variables.projectCode, row.processDefinitionCode).then((res: any) =>{
|
||||
if (res && res.length > 0) {
|
||||
variables.dependenciesData.showRef = true
|
||||
variables.dependenciesData.taskLinks = res
|
||||
variables.dependenciesData.tip = t('project.workflow.warning_delete_scheduler_dependent_tasks_desc')
|
||||
variables.dependenciesData.required = false
|
||||
variables.dependenciesData.action = confirmToDeleteSchedule
|
||||
} else {
|
||||
deleteScheduleById(row.id, variables.projectCode).then(() => {
|
||||
window.$message.success(t('project.workflow.success'))
|
||||
getTableData({
|
||||
pageSize: variables.pageSize,
|
||||
pageNo: variables.page,
|
||||
searchVal: variables.searchVal,
|
||||
projectCode: variables.projectCode,
|
||||
processDefinitionCode: variables.processDefinitionCode
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -43,11 +43,14 @@ import {
|
|||
import type { IDefinitionParam } from './types'
|
||||
import type { Router } from 'vue-router'
|
||||
import type { TableColumns, RowKey } from 'naive-ui/es/data-table/src/interface'
|
||||
import {useDependencies} from '../../components/dependencies/use-dependencies'
|
||||
|
||||
export function useTable() {
|
||||
const { t } = useI18n()
|
||||
const router: Router = useRouter()
|
||||
const { copy } = useTextCopy()
|
||||
const { getDependentTaskLinks } = useDependencies()
|
||||
|
||||
const variables = reactive({
|
||||
columns: [],
|
||||
tableWidth: DefaultTableWidth,
|
||||
|
|
@ -67,7 +70,8 @@ export function useTable() {
|
|||
versionShowRef: ref(false),
|
||||
copyShowRef: ref(false),
|
||||
loadingRef: ref(false),
|
||||
setTimingDialogShowRef: ref(false)
|
||||
setTimingDialogShowRef: ref(false),
|
||||
dependenciesData: ref({showRef: false, taskLinks: ref([]), required: ref(false), tip: ref(''), action:() => {}}),
|
||||
})
|
||||
|
||||
const createColumns = (variables: any) => {
|
||||
|
|
@ -304,17 +308,6 @@ export function useTable() {
|
|||
variables.row = row
|
||||
}
|
||||
|
||||
const deleteWorkflow = (row: any) => {
|
||||
deleteByCode(variables.projectCode, row.code).then(() => {
|
||||
window.$message.success(t('project.workflow.success'))
|
||||
getTableData({
|
||||
pageSize: variables.pageSize,
|
||||
pageNo: variables.page,
|
||||
searchVal: variables.searchVal
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const batchDeleteWorkflow = () => {
|
||||
const data = {
|
||||
codes: _.join(variables.checkedRowKeys, ',')
|
||||
|
|
@ -354,48 +347,142 @@ export function useTable() {
|
|||
|
||||
const batchCopyWorkflow = () => {}
|
||||
|
||||
const releaseWorkflow = (row: any) => {
|
||||
const confirmToOfflineWorkflow = () => {
|
||||
const row: any = variables.row
|
||||
const data = {
|
||||
name: row.name,
|
||||
releaseState: (row.releaseState === 'ONLINE' ? 'OFFLINE' : 'ONLINE') as
|
||||
| 'OFFLINE'
|
||||
| 'ONLINE'
|
||||
| 'OFFLINE'
|
||||
| 'ONLINE'
|
||||
}
|
||||
|
||||
release(data, variables.projectCode, row.code).then(() => {
|
||||
if (data.releaseState === 'ONLINE') {
|
||||
variables.setTimingDialogShowRef = true
|
||||
variables.row = row
|
||||
if (row?.schedule) {
|
||||
variables.row = row.schedule
|
||||
variables.timingType = 'update'
|
||||
variables.timingState = row.scheduleReleaseState
|
||||
}
|
||||
} else {
|
||||
if (data.releaseState === 'OFFLINE') {
|
||||
release(data, variables.projectCode, row.code).then(() => {
|
||||
getTableData({
|
||||
pageSize: variables.pageSize,
|
||||
pageNo: variables.page,
|
||||
searchVal: variables.searchVal
|
||||
})
|
||||
window.$message.success(t('project.workflow.success'))
|
||||
}
|
||||
})
|
||||
}
|
||||
variables.dependenciesData.showRef = false
|
||||
}
|
||||
|
||||
const confirmToOfflineScheduler = () => {
|
||||
const row: any = variables.row
|
||||
offline(variables.projectCode, row.schedule.id).then(() => {
|
||||
window.$message.success(t('project.workflow.success'))
|
||||
getTableData({
|
||||
pageSize: variables.pageSize,
|
||||
pageNo: variables.page,
|
||||
searchVal: variables.searchVal
|
||||
})
|
||||
})
|
||||
variables.dependenciesData.showRef = false
|
||||
}
|
||||
|
||||
const releaseScheduler = (row: any) => {
|
||||
if (row.schedule) {
|
||||
let handle = online
|
||||
if (row.schedule.releaseState === 'ONLINE') {
|
||||
handle = offline
|
||||
}
|
||||
handle(variables.projectCode, row.schedule.id).then(() => {
|
||||
window.$message.success(t('project.workflow.success'))
|
||||
const releaseWorkflow = (row: any) => {
|
||||
const data = {
|
||||
name: row.name,
|
||||
releaseState: (row.releaseState === 'ONLINE' ? 'OFFLINE' : 'ONLINE') as
|
||||
| 'OFFLINE'
|
||||
| 'ONLINE'
|
||||
}
|
||||
variables.row = row
|
||||
if (data.releaseState === 'ONLINE') {
|
||||
release(data, variables.projectCode, row.code).then(() => {
|
||||
variables.setTimingDialogShowRef = true
|
||||
if (row?.schedule) {
|
||||
variables.row = row.schedule
|
||||
variables.timingType = 'update'
|
||||
variables.timingState = row.scheduleReleaseState
|
||||
}
|
||||
getTableData({
|
||||
pageSize: variables.pageSize,
|
||||
pageNo: variables.page,
|
||||
searchVal: variables.searchVal
|
||||
})
|
||||
})
|
||||
} else {
|
||||
getDependentTaskLinks(variables.projectCode, row.code).then((res: any) => {
|
||||
if (res && res.length > 0) {
|
||||
variables.dependenciesData = {
|
||||
showRef: true,
|
||||
taskLinks: res,
|
||||
tip: t('project.workflow.warning_dependent_tasks_desc'),
|
||||
required: false,
|
||||
action: confirmToOfflineWorkflow
|
||||
}
|
||||
} else {
|
||||
release(data, variables.projectCode, row.code).then(() => {
|
||||
window.$message.success(t('project.workflow.success'))
|
||||
getTableData({
|
||||
pageSize: variables.pageSize,
|
||||
pageNo: variables.page,
|
||||
searchVal: variables.searchVal
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const deleteWorkflow = (row: any) => {
|
||||
getDependentTaskLinks(variables.projectCode, row.code).then((res: any) => {
|
||||
if (res && res.length > 0) {
|
||||
variables.dependenciesData = {
|
||||
showRef: true,
|
||||
taskLinks: res,
|
||||
tip: t('project.workflow.delete_validate_dependent_tasks_desc'),
|
||||
required: true,
|
||||
action: () => {}
|
||||
}
|
||||
} else {
|
||||
deleteByCode(variables.projectCode, row.code).then(() => {
|
||||
window.$message.success(t('project.workflow.success'))
|
||||
getTableData({
|
||||
pageSize: variables.pageSize,
|
||||
pageNo: variables.page,
|
||||
searchVal: variables.searchVal
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const releaseScheduler = (row: any) => {
|
||||
variables.row = row
|
||||
if (row.schedule) {
|
||||
if (row.schedule.releaseState === 'ONLINE') {
|
||||
getDependentTaskLinks(variables.projectCode, row.code).then((res: any) => {
|
||||
if (res && res.length > 0) {
|
||||
variables.dependenciesData = {
|
||||
showRef: true,
|
||||
taskLinks: res,
|
||||
tip: t('project.workflow.warning_offline_scheduler_dependent_tasks_desc'),
|
||||
required: false,
|
||||
action: confirmToOfflineScheduler
|
||||
}
|
||||
} else {
|
||||
offline(variables.projectCode, row.schedule.id).then(() => {
|
||||
window.$message.success(t('project.workflow.success'))
|
||||
getTableData({
|
||||
pageSize: variables.pageSize,
|
||||
pageNo: variables.page,
|
||||
searchVal: variables.searchVal
|
||||
})
|
||||
})
|
||||
}})
|
||||
} else {
|
||||
online(variables.projectCode, row.schedule.id).then(() => {
|
||||
window.$message.success(t('project.workflow.success'))
|
||||
getTableData({
|
||||
pageSize: variables.pageSize,
|
||||
pageNo: variables.page,
|
||||
searchVal: variables.searchVal
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -479,6 +566,6 @@ export function useTable() {
|
|||
getTableData,
|
||||
batchDeleteWorkflow,
|
||||
batchExportWorkflow,
|
||||
batchCopyWorkflow
|
||||
batchCopyWorkflow,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,14 +15,15 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { NDataTable, NPagination, NSpace } from 'naive-ui'
|
||||
import { defineComponent, onMounted, toRefs, watch } from 'vue'
|
||||
import {NDataTable, NPagination, NSpace} from 'naive-ui'
|
||||
import {defineComponent, onMounted, toRefs, watch} from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useTable } from '../definition/timing/use-table'
|
||||
import Card from '@/components/card'
|
||||
import TimingModal from '../definition/components/timing-modal'
|
||||
import TimingCondition from '@/views/projects/workflow/timing/components/timing-condition'
|
||||
import { ITimingSearch } from '@/views/projects/workflow/timing/types'
|
||||
import DependenciesModal from "@/views/projects/components/dependencies/dependencies-modal";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'WorkflowTimingList',
|
||||
|
|
@ -110,6 +111,13 @@ export default defineComponent({
|
|||
v-model:show={this.showRef}
|
||||
onUpdateList={this.handleUpdateList}
|
||||
/>
|
||||
<DependenciesModal
|
||||
v-model:show={this.dependenciesData.showRef}
|
||||
v-model:taskLinks={this.dependenciesData.taskLinks}
|
||||
required={this.dependenciesData.required}
|
||||
content={this.dependenciesData.tip}
|
||||
onConfirm={this.dependenciesData.action}
|
||||
/>
|
||||
</NSpace>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue