diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/index.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/index.ts index 2ab1b9f288..71c299ced7 100644 --- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/index.ts +++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/index.ts @@ -28,5 +28,6 @@ export { useTimeoutAlarm } from './use-timeout-alarm' export { usePreTasks } from './use-pre-tasks' export { useTaskType } from './use-task-type' export { useProcessName } from './use-process-name' +export { useChildNode } from './use-child-node' export { useShell } from './use-shell' diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-child-node.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-child-node.ts new file mode 100644 index 0000000000..e580b47258 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-child-node.ts @@ -0,0 +1,142 @@ +/* + * 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 { uniqBy } from 'lodash' +import { + querySimpleList, + queryProcessDefinitionByCode +} from '@/service/modules/process-definition' +import type { IJsonItem } from '../types' +import { number } from 'echarts' + +export function useChildNode({ + model, + projectCode, + isCreate, + from, + processName, + code +}: { + model: { [field: string]: any } + projectCode: number + isCreate: boolean + from?: number + processName?: number + code?: number +}): IJsonItem { + const { t } = useI18n() + + const options = ref([] as { label: string; value: string }[]) + const loading = ref(false) + + const getProcessList = async () => { + if (loading.value) return + loading.value = true + try { + const res = await querySimpleList(projectCode) + options.value = res.map((option: { name: string; code: number }) => ({ + label: option.name, + value: option.code + })) + loading.value = false + } catch (err) { + loading.value = false + } + } + const getProcessListByCode = async (processCode: number) => { + if (!processCode) return + try { + const res = await queryProcessDefinitionByCode(processCode, projectCode) + getTaskOptions(res) + } catch (err) {} + } + const getTaskOptions = (processDefinition: { + processTaskRelationList: [] + taskDefinitionList: [] + }) => { + const { processTaskRelationList = [], taskDefinitionList = [] } = + processDefinition + + const preTaskOptions: { code: number; name: string }[] = [] + const tasks: { [field: number]: string } = {} + taskDefinitionList.forEach( + (task: { code: number; taskType: string; name: string }) => { + tasks[task.code] = task.name + if (task.code === code) return + if ( + task.taskType === 'CONDITIONS' && + processTaskRelationList.filter( + (relation: { preTaskCode: number }) => + relation.preTaskCode === task.code + ).length >= 2 + ) { + return + } + preTaskOptions.push({ + code: task.code, + name: task.name + }) + } + ) + model.preTaskOptions = uniqBy(preTaskOptions, 'code') + + if (!code) return + const preTasks: number[] = [] + const postTaskOptions: { code: number; name: string }[] = [] + processTaskRelationList.forEach( + (relation: { preTaskCode: number; postTaskCode: number }) => { + if (relation.preTaskCode === code) { + postTaskOptions.push({ + code: relation.postTaskCode, + name: tasks[relation.postTaskCode] + }) + } + if (relation.postTaskCode === code && relation.preTaskCode !== 0) { + preTasks.push(relation.preTaskCode) + } + } + ) + model.preTasks = preTasks + model.postTaskOptions = postTaskOptions + } + + const onChange = (code: number) => { + getProcessListByCode(code) + } + + onMounted(() => { + if (from === 1 && processName) { + getProcessListByCode(processName) + } + getProcessList() + }) + + return { + type: 'select', + field: 'processName', + span: 24, + name: t('project.node.child_node'), + props: { + loading: loading, + disabled: !isCreate, + 'on-update:value': onChange + }, + options: options + } +} diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-sub-process.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-sub-process.ts new file mode 100644 index 0000000000..4d968d30bc --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-sub-process.ts @@ -0,0 +1,86 @@ +/* + * 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 { reactive } from 'vue' +import * as Fields from '../fields/index' +import type { IJsonItem, INodeData, ITaskData } from '../types' + +export function useSubProcess({ + projectCode, + from = 0, + readonly, + data +}: { + projectCode: number + from?: number + readonly?: boolean + data?: ITaskData +}) { + const model = reactive({ + name: '', + flag: 'YES', + description: '', + timeoutFlag: false, + localParams: [], + environmentCode: null, + failRetryInterval: 1, + failRetryTimes: 0, + workerGroup: 'default', + delayTime: 0, + timeout: 30, + rawScript: '' + } as INodeData) + + let extra: IJsonItem[] = [] + if (from === 1) { + extra = [ + Fields.useTaskType(model, readonly), + Fields.useProcessName({ + model, + projectCode, + isCreate: !data?.id, + from, + processName: data?.processName, + code: data?.code + }) + ] + } + + return { + json: [ + Fields.useName(), + ...extra, + Fields.useRunFlag(), + Fields.useDescription(), + Fields.useTaskPriority(), + Fields.useWorkerGroup(), + Fields.useEnvironmentName(model, !data?.id), + ...Fields.useTaskGroup(model, projectCode), + ...Fields.useTimeoutAlarm(model), + Fields.useChildNode({ + model, + projectCode, + isCreate: !data?.id, + from, + processName: data?.processName, + code: data?.code + }), + Fields.usePreTasks(model) + ] as IJsonItem[], + model + } +} diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/use-task.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/use-task.ts index 258988c148..b56ddb52c9 100644 --- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/use-task.ts +++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/use-task.ts @@ -16,6 +16,7 @@ */ import { useShell } from './tasks/use-shell' +import { useSubProcess } from './tasks/use-sub-process' import { usePython } from './tasks/use-python' import { IJsonItem, INodeData, ITaskData } from './types' @@ -40,6 +41,14 @@ export function useTask({ data }) } + if (taskType === 'SUB_PROCESS') { + node = useSubProcess({ + projectCode, + from, + readonly, + data + }) + } if (taskType === 'PYTHON') { node = usePython({ projectCode,