Browse Source

[Fix-8598][UI Next][V1.0.0-Alpha] Fix menu readonly bug in workflow instance

Devosend 3 years ago
parent
commit
985b4e8520

+ 21 - 34
dolphinscheduler-ui-next/src/views/projects/workflow/components/dag/dag-context-menu.tsx

@@ -17,28 +17,30 @@
 
 import { genTaskCodeList } from '@/service/modules/task-definition'
 import type { Cell } from '@antv/x6'
-import {
-  defineComponent,
-  onMounted,
-  PropType,
-  inject,
-  ref,
-  computed
-} from 'vue'
+import { defineComponent, onMounted, PropType, inject, ref } from 'vue'
 import { useI18n } from 'vue-i18n'
 import { useRoute } from 'vue-router'
 import styles from './menu.module.scss'
 import { uuid } from '@/utils/common'
+import { IWorkflowTaskInstance } from './types'
 
 const props = {
+  startReadonly: {
+    type: Boolean as PropType<boolean>,
+    default: false
+  },
+  menuReadonly: {
+    type: Boolean as PropType<boolean>,
+    default: false
+  },
+  taskInstance: {
+    type: Object as PropType<IWorkflowTaskInstance>,
+    require: true
+  },
   cell: {
     type: Object as PropType<Cell>,
     require: true
   },
-  taskList: {
-    type: Array as PropType<Array<any>>,
-    default: []
-  },
   visible: {
     type: Boolean as PropType<boolean>,
     default: true
@@ -50,10 +52,6 @@ const props = {
   top: {
     type: Number as PropType<number>,
     default: 0
-  },
-  releaseState: {
-    type: String as PropType<string>,
-    default: 'OFFLINE'
   }
 }
 
@@ -66,12 +64,6 @@ export default defineComponent({
     const route = useRoute()
     const projectCode = Number(route.params.projectCode)
 
-    const startAvailable = computed(
-      () =>
-        route.name === 'workflow-definition-detail' &&
-        props.releaseState !== 'NOT_RELEASE'
-    )
-
     const hide = () => {
       ctx.emit('hide', false)
     }
@@ -85,12 +77,8 @@ export default defineComponent({
     }
 
     const handleViewLog = () => {
-      const taskCode = Number(props.cell?.id)
-      const taskInstance = props.taskList.find(
-        (task: any) => task.taskCode === taskCode
-      )
-      if (taskInstance) {
-        ctx.emit('viewLog', taskInstance.id, taskInstance.taskType)
+      if (props.taskInstance) {
+        ctx.emit('viewLog', props.taskInstance.id, props.taskInstance.taskType)
       }
     }
 
@@ -122,7 +110,6 @@ export default defineComponent({
     })
 
     return {
-      startAvailable,
       startRunning,
       handleEdit,
       handleCopy,
@@ -141,7 +128,7 @@ export default defineComponent({
         >
           <div
             class={`${styles['menu-item']} ${
-              !this.startAvailable ? styles['disabled'] : ''
+              this.startReadonly ? styles['disabled'] : ''
             } `}
             onClick={this.startRunning}
           >
@@ -149,7 +136,7 @@ export default defineComponent({
           </div>
           <div
             class={`${styles['menu-item']} ${
-              this.releaseState === 'ONLINE' ? styles['disabled'] : ''
+              this.menuReadonly ? styles['disabled'] : ''
             } `}
             onClick={this.handleEdit}
           >
@@ -157,7 +144,7 @@ export default defineComponent({
           </div>
           <div
             class={`${styles['menu-item']} ${
-              this.releaseState === 'ONLINE' ? styles['disabled'] : ''
+              this.menuReadonly ? styles['disabled'] : ''
             } `}
             onClick={this.handleCopy}
           >
@@ -165,13 +152,13 @@ export default defineComponent({
           </div>
           <div
             class={`${styles['menu-item']} ${
-              this.releaseState === 'ONLINE' ? styles['disabled'] : ''
+              this.menuReadonly ? styles['disabled'] : ''
             } `}
             onClick={this.handleDelete}
           >
             {t('project.node.delete')}
           </div>
-          {this.taskList.length > 0 && (
+          {this.taskInstance && (
             <div class={`${styles['menu-item']}`} onClick={this.handleViewLog}>
               {t('project.node.view_log')}
             </div>

+ 57 - 27
dolphinscheduler-ui-next/src/views/projects/workflow/components/dag/index.tsx

@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-import type { Graph } from '@antv/x6'
+import type { Cell, Graph } from '@antv/x6'
 import {
   defineComponent,
   ref,
@@ -23,9 +23,11 @@ import {
   PropType,
   toRef,
   watch,
-  onBeforeUnmount
+  onBeforeUnmount,
+  computed
 } from 'vue'
 import { useI18n } from 'vue-i18n'
+import { useRoute } from 'vue-router'
 import DagToolbar from './dag-toolbar'
 import DagCanvas from './dag-canvas'
 import DagSidebar from './dag-sidebar'
@@ -76,6 +78,7 @@ export default defineComponent({
   emits: ['refresh', 'save'],
   setup(props, context) {
     const { t } = useI18n()
+    const route = useRoute()
     const theme = useThemeStore()
 
     // Whether the graph can be operated
@@ -108,21 +111,47 @@ export default defineComponent({
     } = useTaskEdit({ graph, definition: toRef(props, 'definition') })
 
     // Right click cell
-    const {
-      menuCell,
-      pageX,
-      pageY,
-      menuVisible,
-      startModalShow,
-      logModalShow,
-      logViewTaskId,
-      logViewTaskType,
-      menuHide,
-      menuStart,
-      viewLog,
-      hideLog
-    } = useNodeMenu({
-      graph
+    const { nodeVariables, menuHide, menuStart, viewLog, hideLog } =
+      useNodeMenu({
+        graph
+      })
+
+    // start button in the dag node menu
+    const startReadonly = computed(() => {
+      if (props.definition) {
+        return (
+          route.name === 'workflow-definition-detail' &&
+          props.definition!.processDefinition.releaseState === 'NOT_RELEASE'
+        )
+      } else {
+        return false
+      }
+    })
+
+    // other button in the dag node menu
+    const menuReadonly = computed(() => {
+      if (props.instance) {
+        return (
+          props.instance.state !== 'WAITING_THREAD' &&
+          props.instance.state !== 'SUCCESS' &&
+          props.instance.state !== 'PAUSE' &&
+          props.instance.state !== 'FAILURE' &&
+          props.instance.state !== 'STOP'
+        )
+      } else if (props.definition) {
+        return props.definition!.processDefinition.releaseState === 'ONLINE'
+      } else {
+        return false
+      }
+    })
+
+    const taskInstance = computed(() => {
+      if (nodeVariables.menuCell) {
+        const taskCode = Number(nodeVariables.menuCell!.id)
+        return taskList.value.find((task: any) => task.taskCode === taskCode)
+      } else {
+        return undefined
+      }
     })
 
     const statusTimerRef = ref()
@@ -240,12 +269,13 @@ export default defineComponent({
           onCancel={taskCancel}
         />
         <ContextMenuItem
-          taskList={taskList.value}
-          cell={menuCell.value}
-          visible={menuVisible.value}
-          left={pageX.value}
-          top={pageY.value}
-          releaseState={props.definition?.processDefinition.releaseState}
+          startReadonly={startReadonly.value}
+          menuReadonly={menuReadonly.value}
+          taskInstance={taskInstance.value}
+          cell={nodeVariables.menuCell as Cell}
+          visible={nodeVariables.menuVisible}
+          left={nodeVariables.pageX}
+          top={nodeVariables.pageY}
           onHide={menuHide}
           onStart={menuStart}
           onEdit={editTask}
@@ -256,13 +286,13 @@ export default defineComponent({
         {!!props.definition && (
           <StartModal
             v-model:row={props.definition.processDefinition}
-            v-model:show={startModalShow.value}
+            v-model:show={nodeVariables.startModalShow}
           />
         )}
-        {!!props.instance && logModalShow.value && (
+        {!!props.instance && nodeVariables.logModalShow && (
           <LogModal
-            taskInstanceId={logViewTaskId.value}
-            taskInstanceType={logViewTaskType.value}
+            taskInstanceId={nodeVariables.logTaskId}
+            taskInstanceType={nodeVariables.logTaskType}
             onHideLog={hideLog}
           />
         )}

+ 6 - 0
dolphinscheduler-ui-next/src/views/projects/workflow/components/dag/types.ts

@@ -143,3 +143,9 @@ export interface IStartupParam {
   warningType: string
   warningGroupId: number
 }
+
+export interface IWorkflowTaskInstance {
+  id: number
+  taskCode: number
+  taskType: string
+}

+ 26 - 30
dolphinscheduler-ui-next/src/views/projects/workflow/components/dag/use-node-menu.ts

@@ -15,8 +15,8 @@
  * limitations under the License.
  */
 
-import type { Ref } from 'vue'
-import { onMounted, ref } from 'vue'
+import { reactive, Ref } from 'vue'
+import { onMounted } from 'vue'
 import type { Graph, Cell } from '@antv/x6'
 
 interface Options {
@@ -28,63 +28,59 @@ interface Options {
  */
 export function useNodeMenu(options: Options) {
   const { graph } = options
-  const startModalShow = ref(false)
-  const logModalShow = ref(false)
-  const logViewTaskId = ref()
-  const logViewTaskType = ref()
-  const menuVisible = ref(false)
-  const pageX = ref()
-  const pageY = ref()
-  const menuCell = ref<Cell>()
+
+  const nodeVariables = reactive({
+    menuVisible: false,
+    startModalShow: false,
+    logModalShow: false,
+    logTaskId: -1,
+    logTaskType: '',
+    pageX: 0,
+    pageY: 0,
+    menuCell: {} as Cell
+  })
 
   const menuHide = () => {
-    menuVisible.value = false
+    nodeVariables.menuVisible = false
 
     // unlock scroller
     graph.value?.unlockScroller()
   }
 
   const menuStart = () => {
-    startModalShow.value = true
+    nodeVariables.startModalShow = true
   }
 
   const viewLog = (taskId: number, taskType: string) => {
-    logViewTaskId.value = taskId
-    logViewTaskType.value = taskType
-    logModalShow.value = true
+    nodeVariables.logTaskId = taskId
+    nodeVariables.logTaskType = taskType
+    nodeVariables.logModalShow = true
   }
 
   const hideLog = () => {
-    logModalShow.value = false
+    nodeVariables.logModalShow = false
   }
 
   onMounted(() => {
     if (graph.value) {
       // contextmenu
       graph.value.on('node:contextmenu', ({ cell, x, y }) => {
-        menuCell.value = cell
-        const data = graph.value?.localToPage(x, y)
-        pageX.value = data?.x
-        pageY.value = data?.y
+        nodeVariables.menuCell = cell
+        const data = graph.value!.localToPage(x, y)
+        nodeVariables.pageX = data.x
+        nodeVariables.pageY = data.y
 
         // show menu
-        menuVisible.value = true
+        nodeVariables.menuVisible = true
 
         // lock scroller
-        graph.value?.lockScroller()
+        graph.value!.lockScroller()
       })
     }
   })
 
   return {
-    pageX,
-    pageY,
-    startModalShow,
-    logModalShow,
-    logViewTaskId,
-    logViewTaskType,
-    menuVisible,
-    menuCell,
+    nodeVariables,
     menuHide,
     menuStart,
     viewLog,

+ 2 - 1
dolphinscheduler-ui-next/src/views/projects/workflow/components/dag/use-node-status.ts

@@ -24,6 +24,7 @@ import { tasksState } from '@/utils/common'
 import { NODE, NODE_STATUS_MARKUP } from './dag-config'
 import { queryTaskListByProcessId } from '@/service/modules/process-instances'
 import NodeStatus from '@/views/projects/workflow/components/dag/dag-node-status'
+import { IWorkflowTaskInstance } from './types'
 
 interface Options {
   graph: Ref<Graph | undefined>
@@ -35,7 +36,7 @@ interface Options {
 export function useNodeStatus(options: Options) {
   const { graph } = options
   const route = useRoute()
-  const taskList = ref<Array<Object>>([])
+  const taskList = ref<Array<IWorkflowTaskInstance>>([])
 
   const { t } = useI18n()