Browse Source

[Feature][UI Next]add subprocess task (#8439)

* Improve modal component, add link function

* add subprocess task

* Resolve the conflict
labbomb 3 years ago
parent
commit
ced01169ea

+ 1 - 0
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'

+ 142 - 0
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
+  }
+}

+ 86 - 0
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
+  }
+}

+ 9 - 0
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,