This is an automated email from the ASF dual-hosted git repository.

jinyleechina pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git


The following commit(s) were added to refs/heads/dev by this push:
     new 984665a  [Feature-7018][UI] Add list edit view from task definition 
(#7852)
984665a is described below

commit 984665a5efb0676bfb8194971fe1016cc344ffb1
Author: wangyizhi <[email protected]>
AuthorDate: Fri Jan 7 10:38:56 2022 +0800

    [Feature-7018][UI] Add list edit view from task definition (#7852)
    
    * Performance optimization of DEPENDENT task
    
    * fix eslint
    
    * [Feature] Improve task definition list
    
    * feat: Task definition list
    
    * change update interface
---
 .../home/pages/dag/_source/formModel/formModel.vue | 118 ++++++--
 .../dag/_source/formModel/tasks/pre_tasks.vue      |  59 +++-
 .../projects/pages/taskDefinition/_source/list.vue | 200 +++++++++----
 .../taskDefinition/_source/taskDeleteModal.vue     |  91 ++++++
 .../pages/taskDefinition/_source/taskMoveModel.vue | 107 +++++++
 .../pages/taskDefinition/_source/versions.vue      | 253 +++++++++++++++++
 .../pages/projects/pages/taskDefinition/index.vue  | 313 ++++++++++++++++++---
 .../src/js/conf/home/store/dag/actions.js          | 138 ++++++++-
 .../js/module/components/conditions/conditions.vue |  39 +--
 .../components/secondaryMenu/_source/menu.js       |  13 +-
 .../src/js/module/i18n/locale/en_US.js             |  11 +-
 .../src/js/module/i18n/locale/zh_CN.js             |  11 +-
 12 files changed, 1170 insertions(+), 183 deletions(-)

diff --git 
a/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/formModel.vue
 
b/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/formModel.vue
index 24e2640..743f04b 100644
--- 
a/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/formModel.vue
+++ 
b/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/formModel.vue
@@ -17,11 +17,17 @@
 <template>
   <div class="form-model-wrapper" v-clickoutside="_handleClose">
     <div class="title-box">
-      <span class="name">{{ $t("Current node settings") }}
-        <a v-if="helpUrlEnable(nodeData.taskType)" class="helper-link" 
target="_blank"
-           :href="helpUrl(nodeData.taskType)">
+      <span class="name"
+        >{{ $t("Current node settings") }}
+        <a
+          v-if="helpUrlEnable(nodeData.taskType)"
+          class="helper-link"
+          target="_blank"
+          :href="helpUrl(nodeData.taskType)"
+        >
           <i class="el-icon-question" />
-          {{nodeData.taskType}} {{ $t('Instructions') }}</a>
+          {{ nodeData.taskType }} {{ $t("Instructions") }}</a
+        >
       </span>
       <span class="go-subtask">
         <!-- Component can't pop up box to do component processing -->
@@ -94,6 +100,26 @@
           </div>
         </m-list-box>
 
+        <m-list-box v-if="fromTaskDefinition">
+          <div slot="text">{{ $t("Process Name") }}</div>
+          <div slot="content">
+            <el-select
+              @change="changeProcessCode"
+              :value="processCode"
+              size="small"
+              style="width: 100%"
+              :disabled="isDetails || taskDefinition"
+            >
+              <el-option
+                v-for="process in processListS"
+                :key="process.code"
+                :label="process.name"
+                :value="process.code"
+              />
+            </el-select>
+          </div>
+        </m-list-box>
+
         <!-- Running sign -->
         <m-list-box>
           <div slot="text">{{ $t("Run flag") }}</div>
@@ -164,13 +190,14 @@
             </span>
             <span class="text-b">{{ $t("Task group queue priority") }}</span>
             <el-input
-              :disabled="taskGroupId===''"
-              style="width: 166px;"
+              :disabled="taskGroupId === ''"
+              style="width: 166px"
               type="input"
               v-model="taskGroupPriority"
               maxlength="60"
               v-on:input="_onUpdateTaskGroupPriority"
-              size="small">
+              size="small"
+            >
             </el-input>
           </div>
         </m-list-box>
@@ -448,11 +475,7 @@
           </m-waterdrop>
         </div>
         <!-- Pre-tasks in workflow -->
-        <m-pre-tasks
-          ref="preTasks"
-          v-if="!fromTaskDefinition"
-          :code="code"
-        />
+        <m-pre-tasks ref="preTasks" :code="code" 
:fromTaskDefinition="fromTaskDefinition" :prevTasks="prevTasks" 
:processDefinition="processDefinition"/>
       </div>
     </div>
     <div class="bottom-box">
@@ -583,7 +606,10 @@
         backfillRefresh: true,
         // whether this is a new Task
         isNewCreate: true,
-        tasksTypeList: Object.keys(tasksType)
+        tasksTypeList: Object.keys(tasksType),
+        // processCode
+        processCode: undefined,
+        processDefinition: null
       }
     },
     provide () {
@@ -609,7 +635,7 @@
     },
     inject: ['dagChart'],
     methods: {
-      ...mapActions('dag', ['getTaskInstanceList']),
+      ...mapActions('dag', ['getTaskInstanceList', 'getProcessDefinition']),
       helpUrlEnable (typekey) {
         const type = tasksType[typekey]
         if (!type) return false
@@ -850,10 +876,16 @@
         if (!this.$refs[this.nodeData.taskType]._verification()) {
           return
         }
-        // set preTask
-        if (this.$refs.preTasks) {
-          this.$refs.preTasks.setPreNodes()
+        // set dag preTask
+        if (this.dagChart && this.$refs.preTasks) {
+          this.$refs.preTasks.setDagPreNodes()
         }
+
+        // set edge label
+        if (this.dagChart) {
+          this._setEdgeLabel()
+        }
+
         this.successBranch && (this.conditionResult.successNode[0] = 
this.successBranch)
         this.failedBranch && (this.conditionResult.failedNode[0] = 
this.failedBranch)
         this.$emit('addTaskInfo', {
@@ -882,11 +914,12 @@
             taskGroupId: this.taskGroupId,
             taskGroupPriority: this.taskGroupPriority
           },
-          fromThis: this
+          fromThis: this,
+          ...(this.fromTaskDefinition ? {
+            prevTasks: this.$refs.preTasks ? this.$refs.preTasks.preTasks : [],
+            processCode: this.processCode
+          } : {})
         })
-
-        // set edge label
-        this._setEdgeLabel()
       },
       /**
        * Sub-workflow selected node echo name
@@ -1005,6 +1038,44 @@
       },
       changeTaskType (value) {
         this.$emit('changeTaskType', value)
+      },
+      calculateRelatedTasks () {
+        if (this.processDefinition && this.taskDefinition) {
+          const relations = this.processDefinition.processTaskRelationList || 
[]
+          const tasks = this.processDefinition.taskDefinitionList || []
+          const tasksMap = {}
+          tasks.forEach(task => {
+            tasksMap[task.code] = task
+          })
+          const taskCode = this.taskDefinition.code
+          const buildTask = (task) => ({
+            code: task.code,
+            name: task.name,
+            type: task.taskType
+          })
+          // Downstream tasks
+          const postTasks = relations
+            .filter(relation => relation.preTaskCode === taskCode)
+            .map(relation => buildTask(tasksMap[relation.postTaskCode]))
+
+          // Upstream tasks
+          const prevTasks = relations
+            .filter(relation => relation.postTaskCode === taskCode && 
relation.preTaskCode !== 0)
+            .map(relation => buildTask(tasksMap[relation.preTaskCode]))
+
+          this.postTasks = postTasks
+          this.prevTasks = prevTasks
+        }
+      },
+      getProcessDetails () {
+        this.getProcessDefinition(this.processCode).then(res => {
+          this.processDefinition = res
+          this.calculateRelatedTasks()
+        })
+      },
+      changeProcessCode (code) {
+        this.processCode = code
+        this.getProcessDetails()
       }
     },
     created () {
@@ -1046,6 +1117,11 @@
         this.postTasks = postNodes.map(buildTask)
         this.prevTasks = prevNodes.map(buildTask)
       }
+
+      if (this.fromTaskDefinition && this.taskDefinition) {
+        this.processCode = this.taskDefinition.processCode
+        this.getProcessDetails()
+      }
     },
     mounted () {
       let self = this
diff --git 
a/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/pre_tasks.vue
 
b/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/pre_tasks.vue
index cc97696..5ffd2c8 100644
--- 
a/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/pre_tasks.vue
+++ 
b/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/pre_tasks.vue
@@ -53,7 +53,11 @@
       code: {
         type: Number,
         default: 0
-      }
+      },
+      processDefinition: {
+        type: Object
+      },
+      prevTasks: Array
     },
     data () {
       return {
@@ -61,20 +65,45 @@
         preTasks: []
       }
     },
-    mounted () {
-      const canvas = this.getDagCanvasRef()
-      const edges = canvas.getEdges()
-      this.preTasks = canvas.getPrevNodes(this.code).map(node => node.id)
-      this.options = this.tasks.filter((task) => {
-        // The current node cannot be used as the prev node
-        if (task.code === this.code) return false
-        if (this.preTasks.includes(task.code)) return true
-        // The number of edges start with CONDITIONS task cannot be greater 
than 2
-        if (task.taskType === 'CONDITIONS') {
-          return edges.filter((e) => e.sourceId === task.code).length < 2
+    watch: {
+      processDefinition (def) {
+        if (def) {
+          this.preTasks = []
+          const relations = def.processTaskRelationList
+          this.options = def.taskDefinitionList.filter((task) => {
+            // The current node cannot be used as the prev node
+            if (task.code === this.code) return false
+            // The number of edges start with CONDITIONS task cannot be 
greater than 2
+            if (task.taskType === 'CONDITIONS') {
+              return relations.filter((e) => e.preTaskCode === 
task.code).length < 2
+            }
+            return true
+          })
+        }
+      },
+      prevTasks (prevTasks) {
+        if (prevTasks) {
+          this.preTasks = prevTasks.map(task => task.code)
         }
-        return true
-      })
+      }
+    },
+    mounted () {
+      // Called by dag
+      if (this.dagChart) {
+        const canvas = this.getDagCanvasRef()
+        const edges = canvas.getEdges()
+        this.preTasks = canvas.getPrevNodes(this.code).map(node => node.id)
+        this.options = this.tasks.filter((task) => {
+          // The current node cannot be used as the prev node
+          if (task.code === this.code) return false
+          if (this.preTasks.includes(task.code)) return true
+          // The number of edges start with CONDITIONS task cannot be greater 
than 2
+          if (task.taskType === 'CONDITIONS') {
+            return edges.filter((e) => e.sourceId === task.code).length < 2
+          }
+          return true
+        })
+      }
     },
     computed: {
       ...mapState('dag', ['tasks'])
@@ -89,7 +118,7 @@
           return canvas
         }
       },
-      setPreNodes () {
+      setDagPreNodes () {
         const canvas = this.getDagCanvasRef()
         canvas.setPreNodes(this.code, this.preTasks, true)
       }
diff --git 
a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskDefinition/_source/list.vue
 
b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskDefinition/_source/list.vue
index bca4b47..36d2456 100644
--- 
a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskDefinition/_source/list.vue
+++ 
b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskDefinition/_source/list.vue
@@ -23,61 +23,106 @@
         style="width: 100%"
         @selection-change="select"
       >
-        <el-table-column
-          prop="id"
-          :label="$t('#')"
-          min-width="50"
-        ></el-table-column>
         <el-table-column :label="$t('Task Name')" min-width="200">
           <template v-slot="scope">
             <el-popover trigger="hover" placement="top">
-              <p>{{ scope.row.name }}</p>
+              <div>{{ scope.row.taskName }}</div>
               <div slot="reference" class="name-wrapper">
                 <a
                   href="javascript:"
                   class="links"
                   @click="viewTaskDetail(scope.row)"
                 >
-                  {{ scope.row.name }}
+                  <span class="ellipsis name">{{ scope.row.taskName }}</span>
                 </a>
               </div>
             </el-popover>
           </template>
         </el-table-column>
-        <el-table-column :label="$t('Task Type')" prop="taskType" 
min-width="135">
+        <el-table-column
+          :label="$t('Process Name')"
+          prop="processDefinitionName"
+          min-width="135"
+        >
+        </el-table-column>
+        <el-table-column
+          :label="$t('Process State')"
+          prop="processReleaseState"
+          min-width="135"
+        >
         </el-table-column>
         <el-table-column
-          :label="$t('User Name')"
-          prop="userName"
-          width="135"
-        ></el-table-column>
+          :label="$t('Task Type')"
+          prop="taskType"
+          min-width="135"
+        >
+        </el-table-column>
         <el-table-column :label="$t('Version Info')" min-width="135">
           <template v-slot="scope">
             <span>
-              {{ 'V' + scope.row.version }}
+              {{ "V" + scope.row.taskVersion }}
             </span>
           </template>
         </el-table-column>
+        <el-table-column :label="$t('Upstream Tasks')" min-width="300">
+          <template v-slot="scope">
+            <div class="upstream-tasks">
+              <el-popover
+                trigger="hover"
+                placement="top"
+                v-for="task in scope.row.upstreamTasks.slice(0, 3)"
+                :key="task.taskCode"
+              >
+                <div>{{ task.taskName }}</div>
+                <el-tag class="pre-task-tag" size="mini" slot="reference">
+                  {{ task.taskName }}
+                </el-tag>
+              </el-popover>
+              <!-- more popover -->
+              <el-popover
+                v-if="scope.row.upstreamTasks.length > 3"
+                trigger="hover"
+                :title="$t('Upstream Tasks')"
+                placement="top"
+              >
+                <div class="task-definition-upstreams-popover">
+                  <el-tag
+                    size="mini"
+                    slot="reference"
+                    class="popover-tag"
+                    v-for="task in scope.row.upstreamTasks"
+                    :key="task.taskCode"
+                  >
+                    {{ task.taskName }}
+                  </el-tag>
+                </div>
+                <el-tag class="pre-task-tag" size="mini" slot="reference">
+                  {{
+                    $t("and {n} more", {
+                      n: scope.row.upstreamTasks.length - 3,
+                    })
+                  }}
+                </el-tag>
+              </el-popover>
+              <span v-if="scope.row.upstreamTasks.length === 0">-</span>
+            </div>
+          </template>
+        </el-table-column>
         <el-table-column :label="$t('Create Time')" min-width="135">
           <template v-slot="scope">
             <span>
-              {{ scope.row.createTime | formatDate }}
+              {{ scope.row.taskCreateTime | formatDate }}
             </span>
           </template>
         </el-table-column>
         <el-table-column :label="$t('Update Time')" min-width="135">
           <template v-slot="scope">
             <span>
-              {{ scope.row.updateTime | formateDate }}
+              {{ scope.row.taskUpdateTime | formateDate }}
             </span>
           </template>
         </el-table-column>
-        <el-table-column :label="$t('Description')" min-width="100">
-          <template v-slot="scope">
-            <span>{{ scope.row.description | filterNull }} </span>
-          </template>
-        </el-table-column>
-        <el-table-column :label="$t('Operation')" width="100" fixed="right">
+        <el-table-column :label="$t('Operation')" width="150" fixed="right">
           <template v-slot="scope">
             <el-tooltip
               :content="$t('Edit')"
@@ -90,33 +135,68 @@
                   size="mini"
                   icon="el-icon-edit-outline"
                   circle
-                  :disabled="scope.row.taskType === 'CONDITIONS' || 
scope.row.taskType ==='SWITCH' "
+                  :disabled="
+                    ['CONDITIONS', 'SWITCH'].includes(scope.row.taskType) ||
+                    (scope.row.processDefinitionCode &&
+                      scope.row.processReleaseState === 'ONLINE')
+                  "
                   @click="editTask(scope.row)"
                 ></el-button>
               </span>
             </el-tooltip>
             <el-tooltip
+              :content="$t('Move task')"
+              placement="top"
+              :enterable="false"
+            >
+              <span>
+                <el-button
+                  type="primary"
+                  size="mini"
+                  icon="el-icon-rank"
+                  circle
+                  :disabled="
+                    scope.row.processDefinitionCode &&
+                    scope.row.processReleaseState === 'ONLINE'
+                  "
+                  @click="showMoveModal(scope.row)"
+                ></el-button>
+              </span>
+            </el-tooltip>
+            <el-tooltip
               :content="$t('Delete')"
               placement="top"
               :enterable="false"
             >
-              <el-popconfirm
-                :confirmButtonText="$t('Confirm')"
-                :cancelButtonText="$t('Cancel')"
-                icon="el-icon-info"
-                iconColor="red"
-                :title="$t('Delete?')"
-                @onConfirm="deleteTask(scope.row.code, scope.row.projectCode)"
-              >
+              <span>
                 <el-button
                   type="danger"
                   size="mini"
                   icon="el-icon-delete"
                   slot="reference"
                   circle
-                >
-                </el-button>
-              </el-popconfirm>
+                  :disabled="
+                    scope.row.processDefinitionCode &&
+                    scope.row.processReleaseState === 'ONLINE'
+                  "
+                  @click="showDeleteModal(scope.row)"
+                ></el-button>
+              </span>
+            </el-tooltip>
+            <el-tooltip
+              :content="$t('Version Info')"
+              placement="top"
+              :enterable="false"
+            >
+              <span
+                ><el-button
+                  type="primary"
+                  size="mini"
+                  icon="el-icon-info"
+                  @click="viewTaskVersions(scope.row)"
+                  circle
+                ></el-button
+              ></span>
             </el-tooltip>
           </template>
         </el-table-column>
@@ -127,7 +207,6 @@
 
 <script>
   import _ from 'lodash'
-  import { mapActions } from 'vuex'
 
   export default {
     name: 'task-list',
@@ -151,47 +230,48 @@
         deep: true
       }
     },
-    created () {
-    // this.list = this.tasksList
-    },
+    created () {},
     methods: {
-      ...mapActions('dag', ['deleteTaskDefinition']),
       /**
-       * onUpdate
+       * Delete task
        */
-      _onUpdate () {
-        this.$emit('on-update')
+      showDeleteModal (taskRow) {
+        this.$emit('showDeleteModal', taskRow)
       },
       /**
-       * deleteTaskDefinition
+       * View task detail
        */
-      deleteTask (code) {
-        this.deleteTaskDefinition({
-          code: code
-        })
-          .then((res) => {
-            this._onUpdate()
-            this.$message.success(res.msg)
-          })
-          .catch((e) => {
-            this.$message.error(e.msg || '')
-          })
+      viewTaskDetail (taskRow) {
+        this.$emit('viewTaskDetail', taskRow)
       },
       /**
-       * taskdefinition detail
+       * Edit task
        */
-      viewTaskDetail (task) {
-        this.$emit('viewTaskDetail', task)
+      editTask (taskRow) {
+        this.$emit('editTask', taskRow)
       },
       /**
-       * task edit
+       * View task versions
        */
-      editTask (task) {
-        this.$emit('editTask', task)
+      viewTaskVersions (taskRow) {
+        this.$emit('viewTaskVersions', taskRow)
+      },
+      /**
+       * Move Task
+       */
+      showMoveModal (taskRow) {
+        this.$emit('showMoveModal', taskRow)
       }
     }
   }
 </script>
 
-<style>
+<style lang="scss">
+.task-definition-upstreams-popover {
+  max-width: 500px;
+  .popover-tag {
+    margin-right: 10px;
+    margin-bottom: 10px;
+  }
+}
 </style>
diff --git 
a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskDefinition/_source/taskDeleteModal.vue
 
b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskDefinition/_source/taskDeleteModal.vue
new file mode 100644
index 0000000..9d90ad5
--- /dev/null
+++ 
b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskDefinition/_source/taskDeleteModal.vue
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+<template>
+  <div>
+    <el-dialog :title="$t('Delete')" :visible.sync="visible" width="500px">
+      <div class="content" v-if="taskRow">
+        <template v-if="taskRow.processDefinitionCode">
+          <span>{{
+            $t("Delete task {taskName} from process {processName}?", {
+              processName: taskRow.processDefinitionName,
+              taskName: taskRow.taskName,
+            })
+          }}</span>
+          <el-checkbox class="remove-checkbox" v-model="removeCompletely">{{
+            $t("Delete task completely")
+          }}</el-checkbox>
+        </template>
+        <template v-else>
+          <span>{{
+            $t("Delete {taskName}?", {
+              taskName: taskRow.taskName,
+            })
+          }}</span>
+        </template>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button size="small" @click="close">{{ $t("Cancel") }}</el-button>
+        <el-button size="small" type="primary" @click="submit">{{
+          $t("Confirm")
+        }}</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  export default {
+    props: {
+      taskRow: Object
+    },
+    data () {
+      return {
+        visible: false,
+        // Whether to delete the task completely
+        removeCompletely: false
+      }
+    },
+    methods: {
+      show () {
+        this.visible = true
+      },
+      close () {
+        this.visible = false
+      },
+      submit () {
+        this.$emit('deleteTask', {
+          completely: this.taskRow.processDefinitionCode ? 
this.removeCompletely : true,
+          taskCode: this.taskRow.taskCode,
+          processDefinitionCode: this.taskRow.processDefinitionCode
+        })
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+.content {
+  margin: 20px;
+  color: #333;
+  display: flex;
+  flex-direction: column;
+
+  .remove-checkbox {
+    margin-top: 20px;
+  }
+}
+</style>
diff --git 
a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskDefinition/_source/taskMoveModel.vue
 
b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskDefinition/_source/taskMoveModel.vue
new file mode 100644
index 0000000..23c9c2e
--- /dev/null
+++ 
b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskDefinition/_source/taskMoveModel.vue
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+<template>
+  <div>
+    <el-dialog :title="$t('Move task')" :visible.sync="visible" width="500px">
+      <div class="content" v-if="taskRow">
+        <el-form ref="form" :model="form" label-width="100px" size="mini">
+          <el-form-item :label="$t('Process Name')">
+            <el-select v-model="form.processCode">
+              <el-option
+                :label="process.name"
+                :value="process.code"
+                v-for="process in processListS"
+                :key="process.code"
+                >{{ process.name }}</el-option
+              >
+            </el-select>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button size="small" @click="close">{{ $t("Cancel") }}</el-button>
+        <el-button size="small" type="primary" @click="submit">{{
+          $t("Confirm")
+        }}</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  import { mapState } from 'vuex'
+
+  export default {
+    props: {
+      taskRow: Object
+    },
+    data () {
+      return {
+        visible: false,
+        form: {
+          processCode: -1
+        }
+      }
+    },
+    computed: {
+      ...mapState('dag', ['processListS'])
+    },
+    methods: {
+      show () {
+        this.visible = true
+      },
+      close () {
+        this.visible = false
+      },
+      submit () {
+        if (this.taskRow.processDefinitionCode === this.form.processCode) {
+          this.visible = false
+          return
+        }
+        if (!this.form.processCode) {
+          this.$message.error(this.$t('Please select a process (required)'))
+          return
+        }
+        this.$emit('moveTask', {
+          taskCode: this.taskRow.taskCode,
+          processDefinitionCode: this.taskRow.processDefinitionCode,
+          targetProcessDefinitionCode: this.form.processCode
+        })
+      }
+    },
+    watch: {
+      taskRow (val) {
+        if (val) {
+          this.form.processCode = val.processDefinitionCode || ''
+        }
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+.content {
+  margin: 20px;
+  color: #333;
+  display: flex;
+  flex-direction: column;
+
+  .remove-checkbox {
+    margin-top: 20px;
+  }
+}
+</style>
diff --git 
a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskDefinition/_source/versions.vue
 
b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskDefinition/_source/versions.vue
new file mode 100644
index 0000000..9b09741
--- /dev/null
+++ 
b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskDefinition/_source/versions.vue
@@ -0,0 +1,253 @@
+/*
+* 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.
+*/
+<template>
+  <el-drawer
+    :title="$t('Version Info')"
+    :visible.sync="visible"
+    :with-header="false"
+    size=""
+  >
+    <!-- fix the bug that Element-ui(2.13.2) auto focus on the first input -->
+    <div style="width: 0px; height: 0px; overflow: hidden">
+      <el-input type="text" />
+    </div>
+    <div class="container">
+      <div class="versions-header">
+        <span class="name">{{ $t("Version Info") }}</span>
+      </div>
+      <div class="table-box" v-if="taskVersions.length > 0">
+        <el-table :data="taskVersions" size="mini" style="width: 100%">
+          <el-table-column
+            type="index"
+            :label="$t('#')"
+            width="50"
+          ></el-table-column>
+          <el-table-column prop="userName" :label="$t('Version')">
+            <template slot-scope="scope">
+              <span v-if="scope.row.version">
+                <span
+                  v-if="scope.row.version === taskRow.taskVersion"
+                  style="color: green"
+                  ><strong
+                    >V{{ scope.row.version }}
+                    {{ $t("Current Version") }}</strong
+                  ></span
+                >
+                <span v-else>V{{ scope.row.version }}</span>
+              </span>
+              <span v-else>-</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            prop="description"
+            :label="$t('Description')"
+          ></el-table-column>
+          <el-table-column :label="$t('Create Time')" min-width="120">
+            <template slot-scope="scope">
+              <span>{{ scope.row.updateTime | formatDate }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column :label="$t('Operation')" width="100">
+            <template slot-scope="scope">
+              <el-tooltip
+                :content="$t('Switch To This Version')"
+                placement="top"
+              >
+                <el-popconfirm
+                  :confirmButtonText="$t('Confirm')"
+                  :cancelButtonText="$t('Cancel')"
+                  icon="el-icon-info"
+                  iconColor="red"
+                  :title="$t('Confirm Switch To This Version?')"
+                  @onConfirm="swtichVersion(scope.row)"
+                >
+                  <el-button
+                    :disabled="
+                      taskRow.processReleaseState === 'ONLINE' ||
+                      scope.row.version === taskRow.taskVersion
+                    "
+                    type="primary"
+                    size="mini"
+                    icon="el-icon-warning"
+                    circle
+                    slot="reference"
+                  ></el-button>
+                </el-popconfirm>
+              </el-tooltip>
+              <el-tooltip :content="$t('Delete')" placement="top">
+                <el-popconfirm
+                  :confirmButtonText="$t('Confirm')"
+                  :cancelButtonText="$t('Cancel')"
+                  icon="el-icon-info"
+                  iconColor="red"
+                  :title="$t('Delete?')"
+                  @onConfirm="deleteVersion(scope.row)"
+                >
+                  <el-button
+                    :disabled="scope.row.version === taskRow.taskVersion"
+                    type="danger"
+                    size="mini"
+                    icon="el-icon-delete"
+                    circle
+                    slot="reference"
+                  ></el-button>
+                </el-popconfirm>
+              </el-tooltip>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+
+      <div v-if="taskVersions.length === 0">
+        <m-no-data />
+      </div>
+
+      <div v-if="taskVersions.length > 0">
+        <div class="versions-footer">
+          <el-button size="mini" @click="close()">{{ $t("Cancel") 
}}</el-button>
+          <el-pagination
+            background
+            @current-change="changePageNo"
+            layout="prev, pager, next"
+            :total="total"
+            :page-size="pageSize"
+          >
+          </el-pagination>
+        </div>
+      </div>
+    </div>
+  </el-drawer>
+</template>
+
+<script>
+  import mNoData from '@/module/components/noData/noData'
+  import { mapActions } from 'vuex'
+
+  export default {
+    name: 'task-definition-versions',
+    data () {
+      return {
+        visible: false,
+        taskVersions: [],
+        pageNo: 1,
+        pageSize: 10,
+        total: 0
+      }
+    },
+    props: {
+      taskRow: Object
+    },
+    methods: {
+      ...mapActions('dag', [
+        'getTaskVersions',
+        'switchTaskVersion',
+        'deleteTaskVersion'
+      ]),
+      show () {
+        this.visible = true
+      },
+      close () {
+        this.visible = false
+        this.taskVersions = []
+      },
+      changePageNo (val) {
+        this.pageNo = val
+        this.reload()
+      },
+      reload () {
+        this.getTaskVersions({
+          taskCode: this.taskRow.taskCode,
+          pageNo: this.pageNo,
+          pageSize: this.pageSize
+        }).then((res) => {
+          this.taskVersions = res.totalList
+          this.total = res.total
+        })
+      },
+      swtichVersion (row) {
+        this.switchTaskVersion({ taskCode: row.code, version: row.version })
+          .then((res) => {
+            this.$message.success(res.msg)
+            this.$emit('reloadList')
+            this.close()
+          })
+          .catch((err) => {
+            this.$message.error(err.msg || '')
+          })
+      },
+      deleteVersion (row) {
+        this.deleteTaskVersion({ taskCode: row.code, version: row.version })
+          .then((res) => {
+            this.$message.success(res.msg)
+            this.$emit('reloadList')
+            this.close()
+          })
+          .catch((err) => {
+            this.$message.error(err.msg || '')
+          })
+      }
+    },
+    components: { mNoData },
+    watch: {
+      visible (bool, a, b) {
+        if (bool && this.taskRow) {
+          this.reload()
+        }
+      }
+    }
+  }
+</script>
+
+<style lang="scss" rel="stylesheet/scss">
+.container {
+  width: 500px;
+  position: relative;
+
+  .versions-header {
+    height: 60px;
+    position: relative;
+    line-height: 60px;
+
+    .name {
+      font-size: 16px;
+    }
+  }
+
+  .versions-footer {
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    width: 100%;
+    border-top: 1px solid #dcdedc;
+    background: #fff;
+    display: flex;
+    padding: 20px;
+    align-items: center;
+    justify-content: flex-end;
+
+    .ans-page {
+      display: inline-block;
+    }
+  }
+
+  .table-box {
+    overflow-y: scroll;
+    height: calc(100vh - 61px);
+    padding-bottom: 60px;
+  }
+}
+</style>
diff --git 
a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskDefinition/index.vue
 
b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskDefinition/index.vue
index 50a8b0a..a09f16f 100644
--- 
a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskDefinition/index.vue
+++ 
b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskDefinition/index.vue
@@ -18,12 +18,61 @@
   <div class="task-definition" v-if="!isLoading">
     <m-list-construction :title="$t('Task Definition')">
       <template slot="conditions">
-        <m-conditions @on-conditions="_onConditions" :taskTypeShow="true">
+        <m-conditions>
           <template v-slot:button-group>
             <el-button size="mini" @click="createTask">
               {{ $t("Create task") }}
             </el-button>
           </template>
+          <template v-slot:search-group>
+            <div class="list">
+              <el-button
+                size="mini"
+                @click="_ckQuery"
+                icon="el-icon-search"
+              ></el-button>
+            </div>
+            <div class="list">
+              <el-select
+                size="mini"
+                style="width: 140px"
+                :placeholder="$t('type')"
+                :value="tempParams.taskType"
+                @change="_onChangeTaskType"
+                clearable
+              >
+                <el-option
+                  v-for="taskType in tasksTypeList"
+                  :key="taskType"
+                  :value="taskType"
+                  :label="taskType"
+                >
+                </el-option>
+              </el-select>
+            </div>
+            <div class="list">
+              <el-input
+                v-model="tempParams.processName"
+                @keyup.enter.native="_ckQuery"
+                size="mini"
+                :placeholder="$t('Process Name')"
+                type="text"
+                style="width: 180px"
+                clearable
+              />
+            </div>
+            <div class="list">
+              <el-input
+                v-model="tempParams.taskName"
+                @keyup.enter.native="_ckQuery"
+                size="mini"
+                :placeholder="$t('Task Name')"
+                type="text"
+                style="width: 180px"
+                clearable
+              />
+            </div>
+          </template>
         </m-conditions>
       </template>
       <template v-slot:content>
@@ -32,7 +81,10 @@
             :tasksList="tasksList"
             @on-update="_onUpdate"
             @editTask="editTask"
+            @showDeleteModal="showDeleteModal"
+            @showMoveModal="showMoveModal"
             @viewTaskDetail="viewTaskDetail"
+            @viewTaskVersions="viewTaskVersions"
           ></m-list>
           <div class="page-box">
             <el-pagination
@@ -75,6 +127,21 @@
       >
       </m-form-model>
     </el-drawer>
+    <task-delete-modal
+      ref="taskDeleteModal"
+      :taskRow="deletingTaskRow"
+      @deleteTask="deleteTask"
+    />
+    <task-move-modal
+      ref="taskMoveModal"
+      :taskRow="movingTaskRow"
+      @moveTask="moveTask"
+    />
+    <version-drawer
+      ref="versionDrawer"
+      :taskRow="versionTaskRow"
+      @reloadList="_onUpdate"
+    />
   </div>
 </template>
 <script>
@@ -86,10 +153,11 @@
   import { mapActions, mapMutations } from 'vuex'
   import listUrlParamHandle from '@/module/mixin/listUrlParamHandle'
   import mFormModel from 
'@/conf/home/pages/dag/_source/formModel/formModel.vue'
-  /**
-   * tasksType
-   */
   import { tasksType } from '@/conf/home/pages/dag/_source/config.js'
+  import TaskDeleteModal from './_source/taskDeleteModal.vue'
+  import TaskMoveModal from './_source/taskMoveModel.vue'
+  import VersionDrawer from './_source/versions.vue'
+  import _ from 'lodash'
 
   const DEFAULT_NODE_DATA = {
     id: -1,
@@ -108,9 +176,14 @@
         searchParams: {
           pageSize: 10,
           pageNo: 1,
-          searchVal: '',
-          taskType: '',
-          userId: ''
+          processName: '',
+          taskName: '',
+          taskType: ''
+        },
+        tempParams: {
+          processName: '',
+          taskName: '',
+          taskType: ''
         },
         // whether the task config drawer is visible
         taskDrawer: false,
@@ -119,7 +192,14 @@
         // tasksType
         tasksTypeList,
         // editing task definition
-        editingTask: null
+        editingTask: null,
+        editingProcess: null,
+        // task to be deleted
+        deletingTaskRow: null,
+        // task ready to move
+        movingTaskRow: null,
+        // the current browse task
+        versionTaskRow: null
       }
     },
     mixins: [listUrlParamHandle],
@@ -127,8 +207,12 @@
       ...mapActions('dag', [
         'getTaskDefinitionsList',
         'genTaskCodeList',
-        'saveTaskDefinition',
-        'updateTaskDefinition'
+        'saveTaskDefinitionWithUpstreams',
+        'updateTaskDefinition',
+        'deleteTaskDefinition',
+        'getTaskDefinition',
+        'moveTaskToProcess',
+        'deleteRelation'
       ]),
       ...mapActions('dag', [
         'getProcessList',
@@ -142,7 +226,7 @@
         'getAlarmGroupsAll'
       ]),
       /**
-       * Toggle task drawer
+       * Toggle task form-model drawer
        */
       showTaskDrawer () {
         this.taskDrawer = true
@@ -151,10 +235,16 @@
         this.setIsDetails(false)
         this.taskDrawer = false
       },
-      saveTask ({ item }) {
+      /**
+       * Save task
+       */
+      saveTask ({ item: taskDefinition, prevTasks, processCode }) {
         const isEditing = !!this.editingTask
         if (isEditing) {
-          this.updateTaskDefinition(item)
+          this.updateTaskDefinition({
+            prevTasks: prevTasks,
+            taskDefinition: taskDefinition
+          })
             .then((res) => {
               this.$message.success(res.msg)
               this._onUpdate()
@@ -172,13 +262,13 @@
               return code
             })
             .then((code) => {
-              return this.saveTaskDefinition({
-                taskDefinitionJson: [
-                  {
-                    ...item,
-                    code
-                  }
-                ]
+              return this.saveTaskDefinitionWithUpstreams({
+                taskDefinition: {
+                  ...taskDefinition,
+                  code
+                },
+                prevTasks: prevTasks,
+                processDefinitionCode: processCode
               })
             })
             .then((res) => {
@@ -191,20 +281,101 @@
             })
         }
       },
+      /**
+       * Show task creation modal
+       */
       createTask () {
         this.editingTask = null
         this.nodeData.taskType = DEFAULT_NODE_DATA.taskType
         this.showTaskDrawer()
       },
-      editTask (task) {
-        this.editingTask = task
-        this.nodeData.id = task.code
-        this.nodeData.taskType = task.taskType
-        this.showTaskDrawer()
+      /**
+       * Show task edit modal
+       */
+      editTask (taskRow) {
+        this.getTaskDefinition(taskRow.taskCode).then((taskDefinition) => {
+          this.editingTask = {
+            ...taskDefinition,
+            processCode: taskRow.processDefinitionCode
+          }
+          this.nodeData.id = taskDefinition.code
+          this.nodeData.taskType = taskDefinition.taskType
+          this.showTaskDrawer()
+        })
       },
-      viewTaskDetail (task) {
+      /**
+       * Show task detail modal
+       */
+      viewTaskDetail (taskRow) {
         this.setIsDetails(true)
-        this.editTask(task)
+        this.editTask(taskRow)
+      },
+      /**
+       * Show delete task modal
+       */
+      showDeleteModal (taskRow) {
+        this.deletingTaskRow = taskRow
+        if (this.$refs.taskDeleteModal) {
+          this.$refs.taskDeleteModal.show()
+        }
+      },
+      /**
+       * Show Move Modal
+       */
+      showMoveModal (taskRow) {
+        this.movingTaskRow = taskRow
+        if (this.$refs.taskMoveModal) {
+          this.$refs.taskMoveModal.show()
+        }
+      },
+      /**
+       * Delete task
+       * @param {Boolean} completely Whether to delete the task completely
+       */
+      deleteTask ({ completely, taskCode, processDefinitionCode }) {
+        const completelyDelete = this.deleteTaskDefinition
+        const deleteRelation = this.deleteRelation
+        const delRequest = completely ? completelyDelete : deleteRelation
+        const params = completely
+          ? { taskCode }
+          : {
+            taskCode,
+            processDefinitionCode
+          }
+        delRequest(params)
+          .then((res) => {
+            this.$message.success(res.msg)
+            this.$refs.taskDeleteModal.close()
+            this.deletingTaskRow = null
+            this._onUpdate()
+          })
+          .catch((err) => {
+            this.$message.error(err.msg || '')
+          })
+      },
+      /**
+       * Move task to another workflow
+       */
+      moveTask (params) {
+        this.moveTaskToProcess(params)
+          .then((res) => {
+            this.$message.success(res.msg)
+            this.$refs.taskMoveModal.close()
+            this.movingTaskRow = null
+            this._onUpdate()
+          })
+          .catch((err) => {
+            this.$message.error(err.msg || '')
+          })
+      },
+      /**
+       * ViewTaskVersion
+       */
+      viewTaskVersions (taskRow) {
+        if (this.$refs.versionDrawer) {
+          this.versionTaskRow = taskRow
+          this.$refs.versionDrawer.show()
+        }
       },
       /**
        * pageNo
@@ -216,25 +387,52 @@
         this.searchParams.pageSize = val
       },
       /**
-       * conditions
+       * query tasks
        */
-      _onConditions (o) {
-        this.searchParams.searchVal = o.searchVal
-        this.searchParams.taskType = o.taskType
+      _ckQuery (o) {
+        this.searchParams.processName = this.tempParams.processName
+        this.searchParams.taskType = this.tempParams.taskType
+        this.searchParams.taskName = this.tempParams.taskName
         this.searchParams.pageNo = 1
       },
       /**
+       * filter tasks by taskType
+       */
+      _onChangeTaskType (val) {
+        this.tempParams.taskType = val
+      },
+      /**
        * get task definition list
        */
       _getList (flag) {
         this.isLoading = !flag
-        this.getTaskDefinitionsList(this.searchParams)
+        this.getTaskDefinitionsList({
+          pageNo: this.searchParams.pageNo,
+          pageSize: this.searchParams.pageSize,
+          taskType: this.searchParams.taskType,
+          searchTaskName: this.searchParams.taskName,
+          searchWorkflowName: this.searchParams.processName
+        })
           .then((res) => {
             if (this.searchParams.pageNo > 1 && res.totalList.length === 0) {
               this.searchParams.pageNo = this.searchParams.pageNo - 1
             } else {
-              this.tasksList = []
-              this.tasksList = res.totalList
+              this.tasksList = res.totalList.map((task) => {
+                const upstreamTaskMap = task.upstreamTaskMap || {}
+                const upstreamTasks = Object.keys(upstreamTaskMap).map((code) 
=> {
+                  return {
+                    taskCode: code,
+                    taskName: upstreamTaskMap[code]
+                  }
+                })
+                return {
+                  ...task,
+                  upstreamTasks,
+                  upstreamTaskNames: upstreamTasks
+                    .map((u) => u.taskName)
+                    .join(',')
+                }
+              })
               this.total = res.total
               this.isLoading = false
             }
@@ -280,15 +478,23 @@
         .catch(() => {
           this.isLoading = false
         })
+      // Routing parameter merging
+      if (!_.isEmpty(this.$route.query)) {
+        this.tempParams.processName = this.$route.query.processName || ''
+        this.tempParams.taskType = this.$route.query.taskType || ''
+        this.tempParams.taskName = this.$route.query.taskName || ''
+      }
     },
-    mounted () {},
     components: {
       mListConstruction,
       mConditions,
       mList,
       mNoData,
       mSpin,
-      mFormModel
+      mFormModel,
+      TaskMoveModal,
+      TaskDeleteModal,
+      VersionDrawer
     }
   }
 </script>
@@ -297,5 +503,40 @@
   .taskGroupBtn {
     width: 300px;
   }
+
+  ::v-deep .table-box {
+    table {
+      tr {
+        th:first-child,
+        td:first-child {
+          text-align: left;
+          padding-left: 20px;
+        }
+        td:first-child span {
+          text-align: left;
+        }
+      }
+      td,
+      th.is-leaf {
+        padding-left: 10px;
+      }
+    }
+    .pre-task-tag {
+      margin-right: 10px;
+      max-width: 100px;
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
+    .upstream-tasks {
+      display: flex;
+      flex-wrap: wrap;
+    }
+  }
+
+  ::v-deep .el-dialog__header {
+    .el-dialog__headerbtn {
+      right: 20px;
+    }
+  }
 }
 </style>
diff --git a/dolphinscheduler-ui/src/js/conf/home/store/dag/actions.js 
b/dolphinscheduler-ui/src/js/conf/home/store/dag/actions.js
index 6341d78..64a83b2 100644
--- a/dolphinscheduler-ui/src/js/conf/home/store/dag/actions.js
+++ b/dolphinscheduler-ui/src/js/conf/home/store/dag/actions.js
@@ -24,7 +24,7 @@ const convertLocations = (locationStr) => {
   if (!locationStr) return locations
   try {
     locations = JSON.parse(locationStr)
-  } catch (error) {}
+  } catch (error) { }
   return Array.isArray(locations) ? locations : null
 }
 
@@ -870,7 +870,7 @@ export default {
    */
   deleteTaskDefinition ({ state }, payload) {
     return new Promise((resolve, reject) => {
-      
io.delete(`projects/${state.projectCode}/task-definition/${payload.code}`, 
payload, res => {
+      
io.delete(`projects/${state.projectCode}/task-definition/${payload.taskCode}`, 
res => {
         resolve(res)
       }).catch(e => {
         reject(e)
@@ -891,15 +891,143 @@ export default {
       })
     })
   },
-  updateTaskDefinition ({ state }, taskDefinition) {
+  /**
+   * Save Task Definition with upstreams
+   * @param {Object} taskDefinition
+   * @param {number[]} prevTasks
+   * @param {number} processDefinitionCode
+   */
+  saveTaskDefinitionWithUpstreams ({ state }, payload) {
+    return new Promise((resolve, reject) => {
+      io.post(`projects/${state.projectCode}/task-definition/save-single`, {
+        taskDefinitionJsonObj: JSON.stringify(payload.taskDefinition),
+        upstreamCodes: payload.prevTasks.join(','),
+        processDefinitionCode: payload.processDefinitionCode
+      }, res => {
+        resolve(res)
+      }).catch(e => {
+        reject(e)
+      })
+    })
+  },
+  /**
+   *
+   * @param {Object} taskDefinition
+   * @param {number[]} taskDefinition
+   * @returns
+   */
+  updateTaskDefinition ({ state }, payload) {
+    return new Promise((resolve, reject) => {
+      
io.put(`projects/${state.projectCode}/task-definition/${payload.taskDefinition.code}/with-upstream`,
 {
+        taskDefinitionJsonObj: JSON.stringify(payload.taskDefinition),
+        upstreamCodes: payload.prevTasks.join(',')
+      }, res => {
+        resolve(res)
+      }).catch(e => {
+        reject(e)
+      })
+    })
+  },
+  /**
+   * Query taskDefinition by code
+   * @param {*} param0
+   */
+  getTaskDefinition ({ state }, taskDefinitionCode) {
+    return new Promise((resolve, reject) => {
+      
io.get(`projects/${state.projectCode}/task-definition/${taskDefinitionCode}`, 
res => {
+        resolve(res.data)
+      }).catch(e => {
+        reject(e)
+      })
+    })
+  },
+  /**
+   * Get process definition detail
+   * @param {numbetr} code
+   */
+  getProcessDefinition ({ state }, code) {
+    return new Promise((resolve, reject) => {
+      io.get(`projects/${state.projectCode}/process-definition/${code}`, res 
=> {
+        resolve(res.data)
+      }).catch(res => {
+        reject(res)
+      })
+    })
+  },
+  /**
+   * Move task
+   */
+  moveTaskToProcess ({ state }, payload) {
+    return new Promise((resolve, reject) => {
+      io.post(`projects/${state.projectCode}/process-task-relation/move`, {
+        processDefinitionCode: payload.processDefinitionCode,
+        targetProcessDefinitionCode: payload.targetProcessDefinitionCode,
+        taskCode: payload.taskCode
+      }, res => {
+        resolve(res)
+      }).catch(e => {
+        reject(e)
+      })
+    })
+  },
+  /**
+   * Delete relation
+   */
+  deleteRelation ({ state }, payload) {
     return new Promise((resolve, reject) => {
-      
io.put(`projects/${state.projectCode}/task-definition/${taskDefinition.code}`, {
-        taskDefinitionJsonObj: JSON.stringify(taskDefinition)
+      
io.delete(`projects/${state.projectCode}/process-task-relation/${payload.taskCode}`,
 {
+        processDefinitionCode: payload.processDefinitionCode
       }, res => {
         resolve(res)
       }).catch(e => {
         reject(e)
       })
     })
+  },
+  /**
+   * Query task versions
+   * @param {number} taskCode
+   * @param {number} pageNo
+   * @param {number} pageSize
+   */
+  getTaskVersions ({ state }, payload) {
+    return new Promise((resolve, reject) => {
+      
io.get(`projects/${state.projectCode}/task-definition/${payload.taskCode}/versions`,
 {
+        pageNo: payload.pageNo,
+        pageSize: payload.pageSize
+      }, res => {
+        resolve(res.data)
+      }).catch(res => {
+        reject(res)
+      })
+    })
+  },
+  /**
+   * Switch task version
+   * @param {number} taskCode
+   * @param {number} version
+   */
+  switchTaskVersion ({ state }, payload) {
+    return new Promise((resolve, reject) => {
+      
io.get(`projects/${state.projectCode}/task-definition/${payload.taskCode}/versions/${payload.version}`,
 res => {
+        resolve(res)
+      }).catch(res => {
+        reject(res)
+      })
+    })
+  },
+  /**
+   * Delete task version
+   * @param {number} taskCode
+   * @param {number} version
+   */
+  deleteTaskVersion ({ state }, payload) {
+    return new Promise((resolve, reject) => {
+      
io.delete(`projects/${state.projectCode}/task-definition/${payload.taskCode}/versions/${payload.version}`,
 res => {
+        resolve(res)
+      }).catch(e => {
+        reject(e)
+      })
+    })
   }
 }
diff --git 
a/dolphinscheduler-ui/src/js/module/components/conditions/conditions.vue 
b/dolphinscheduler-ui/src/js/module/components/conditions/conditions.vue
index 4f11dc5..4ffd030 100644
--- a/dolphinscheduler-ui/src/js/module/components/conditions/conditions.vue
+++ b/dolphinscheduler-ui/src/js/module/components/conditions/conditions.vue
@@ -42,24 +42,6 @@
             >
             </el-input>
           </div>
-          <div class="list" v-if="taskTypeShow">
-            <el-select
-              size="mini"
-              style="width: 140px"
-              :placeholder="$t('type')"
-              :value="taskType"
-              @change="_onChangeTaskType"
-              clearable
-            >
-              <el-option
-                v-for="(task, index) in taskTypeList"
-                :key="index"
-                :value="task.desc"
-                :label="index"
-              >
-              </el-option>
-            </el-select>
-          </div>
         </template>
       </div>
     </div>
@@ -67,40 +49,24 @@
 </template>
 <script>
   import _ from 'lodash'
-  /**
-   * taskType list
-   */
-  import { tasksType } from '@/conf/home/pages/dag/_source/config.js'
   export default {
     name: 'conditions',
     data () {
       return {
-        // taskType list
-        taskTypeList: tasksType,
         // search value
-        searchVal: '',
-        // taskType switch
-        taskType: ''
+        searchVal: ''
       }
     },
     props: {
-      taskTypeShow: Boolean,
       operation: Array
     },
     methods: {
       /**
-       * switch taskType
-       */
-      _onChangeTaskType (val) {
-        this.taskType = val
-      },
-      /**
        * emit Query parameter
        */
       _ckQuery () {
         this.$emit('on-conditions', {
-          searchVal: _.trim(this.searchVal),
-          taskType: this.taskType
+          searchVal: _.trim(this.searchVal)
         })
       }
     },
@@ -114,7 +80,6 @@
       // Routing parameter merging
       if (!_.isEmpty(this.$route.query)) {
         this.searchVal = this.$route.query.searchVal || ''
-        this.taskType = this.$route.query.taskType || ''
       }
     },
     components: {}
diff --git 
a/dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js 
b/dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js
index f58f98d..2250afe 100644
--- a/dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js
+++ b/dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js
@@ -55,6 +55,12 @@ const menu = {
           classNames: 'tab-process-definition'
         },
         {
+          name: `${i18n.$t('Task Definition')}`,
+          path: 'task-definition',
+          id: 5,
+          enabled: true
+        },
+        {
           name: `${i18n.$t('Process Instance')}`,
           path: 'instance',
           id: 1,
@@ -78,17 +84,10 @@ const menu = {
           path: 'history-task-record',
           id: 4,
           enabled: config.recordSwitch
-        },
-        {
-          name: `${i18n.$t('Task Definition')}`,
-          path: 'task-definition',
-          id: 5,
-          enabled: true
         }
       ]
     }
   ],
-
   security: [
     {
       name: `${i18n.$t('Tenant Manage')}`,
diff --git a/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js 
b/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
index 1e700ab..aa6cee9 100755
--- a/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
+++ b/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
@@ -797,5 +797,14 @@ export default {
   'Modify task group queue priority': 'Edit the priority of the task group 
queue',
   'Priority not empty': 'The value of priority can not be empty',
   'Priority must be number': 'The value of priority should be number',
-  'Please select task name': 'Please select a task name'
+  'Please select task name': 'Please select a task name',
+  'Process State': 'Process State',
+  'Upstream Tasks': 'Upstream Tasks',
+  'and {n} more': '… and {n} more',
+  'Move task': 'Move task',
+  'Delete task {taskName} from process {processName}?': 'Delete task 
{taskName} from process {processName}?',
+  'Delete task completely': 'Delete task completely',
+  'Please select a process': 'Please select a process',
+  'Delete {taskName}?': 'Delete {taskName}?',
+  'Please select a process (required)': 'Please select a process (required)'
 }
diff --git a/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js 
b/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
index 17a726a..814f20a 100644
--- a/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
+++ b/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
@@ -799,5 +799,14 @@ export default {
   'Force to start task': '强制启动',
   'Priority not empty': '优先级不能为空',
   'Priority must be number': '优先级必须是数值',
-  'Please select task name': '请选择节点名称'
+  'Please select task name': '请选择节点名称',
+  'Process State': '工作流状态',
+  'Upstream Tasks': '上游任务',
+  'and {n} more': '…等{n}个',
+  'Move task': '移动任务',
+  'Delete task {taskName} from process {processName}?': '将任务 {taskName} 从工作流 
{processName} 中删除?',
+  'Delete task completely': '彻底删除任务',
+  'Please select a process': '请选择工作流',
+  'Delete {taskName}?': '确定删除 {taskName} ?',
+  'Please select a process (required)': '请选择工作流(必选)'
 }

Reply via email to