Explorar el Código

[Bug][UI Next][V1.0.0-Alpha] Fix workflow instance save is not responding bug (#8926)

* fix workflow instance save is not responding bug

* add WorkflowInstance interface
Devosend hace 3 años
padre
commit
276a68a23e

+ 1 - 0
dolphinscheduler-ui-next/src/locales/modules/en_US.ts

@@ -586,6 +586,7 @@ const project = {
     success: 'Success',
     delete_cell: 'Delete selected edges and nodes',
     online_directly: 'Whether to go online the process definition',
+    update_directly: 'Whether to update the process definition',
     dag_name_empty: 'DAG graph name cannot be empty',
     positive_integer: 'Please enter a positive integer greater than 0',
     prop_empty: 'prop is empty',

+ 1 - 0
dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts

@@ -583,6 +583,7 @@ const project = {
     success: '成功',
     delete_cell: '删除选中的线或节点',
     online_directly: '是否上线流程定义',
+    update_directly: '是否更新流程定义',
     dag_name_empty: 'DAG图名称不能为空',
     positive_integer: '请输入大于 0 的正整数',
     prop_empty: '自定义参数prop不能为空',

+ 2 - 3
dolphinscheduler-ui-next/src/service/modules/process-instances/index.ts

@@ -23,7 +23,6 @@ import {
   SubIdReq,
   TaskReq,
   LongestReq,
-  IdReq,
   ProcessInstanceReq
 } from './types'
 
@@ -94,8 +93,8 @@ export function queryProcessInstanceById(
 
 export function updateProcessInstance(
   data: ProcessInstanceReq,
-  id: IdReq,
-  code: CodeReq
+  id: number,
+  code: number
 ): any {
   return axios({
     url: `/projects/${code}/process-instances/${id}`,

+ 2 - 2
dolphinscheduler-ui-next/src/service/modules/process-instances/types.ts

@@ -71,7 +71,7 @@ interface IdReq {
 }
 
 interface ProcessInstanceReq {
-  syncDefine: string
+  syncDefine: boolean
   flag?: string
   globalParams?: string
   locations?: string
@@ -79,7 +79,7 @@ interface ProcessInstanceReq {
   taskDefinitionJson?: string
   taskRelationJson?: string
   tenantCode?: string
-  timeout?: string
+  timeout?: number
 }
 
 interface IWorkflowInstance {

+ 5 - 2
dolphinscheduler-ui-next/src/views/projects/task/components/node/detail-modal.tsx

@@ -38,7 +38,10 @@ import {
 import { NIcon } from 'naive-ui'
 import { TASK_TYPES_MAP } from '../../constants/task-type'
 import { Router, useRouter } from 'vue-router'
-import { IWorkflowTaskInstance } from '@/views/projects/workflow/components/dag/types'
+import {
+  IWorkflowTaskInstance,
+  WorkflowInstance
+} from '@/views/projects/workflow/components/dag/types'
 
 const props = {
   show: {
@@ -65,7 +68,7 @@ const props = {
     type: Object as PropType<any>
   },
   processInstance: {
-    type: Object as PropType<any>
+    type: Object as PropType<WorkflowInstance>
   },
   taskInstance: {
     type: Object as PropType<IWorkflowTaskInstance>

+ 17 - 5
dolphinscheduler-ui-next/src/views/projects/workflow/components/dag/dag-save-modal.tsx

@@ -29,7 +29,7 @@ import {
   NCheckbox
 } from 'naive-ui'
 import { queryTenantList } from '@/service/modules/tenants'
-import { SaveForm, WorkflowDefinition } from './types'
+import { SaveForm, WorkflowDefinition, WorkflowInstance } from './types'
 import { useRoute } from 'vue-router'
 import { verifyName } from '@/service/modules/process-definition'
 import './x6-style.scss'
@@ -44,6 +44,10 @@ const props = {
   definition: {
     type: Object as PropType<WorkflowDefinition>,
     default: undefined
+  },
+  instance: {
+    type: Object as PropType<WorkflowInstance>,
+    default: undefined
   }
 }
 
@@ -86,7 +90,8 @@ export default defineComponent({
       timeoutFlag: false,
       timeout: 0,
       globalParams: [],
-      release: false
+      release: false,
+      sync: false
     })
     const formRef = ref()
     const rule = {
@@ -178,7 +183,7 @@ export default defineComponent({
       >
         <NForm model={formValue.value} rules={rule} ref={formRef}>
           <NFormItem label={t('project.dag.workflow_name')} path='name'>
-            <NInput v-model:value={formValue.value.name} class='input-name'/>
+            <NInput v-model:value={formValue.value.name} class='input-name' />
           </NFormItem>
           <NFormItem label={t('project.dag.description')} path='description'>
             <NInput
@@ -218,16 +223,23 @@ export default defineComponent({
               preset='pair'
               key-placeholder={t('project.dag.key')}
               value-placeholder={t('project.dag.value')}
-                class='input-global-params'
+              class='input-global-params'
             />
           </NFormItem>
-          {props.definition && (
+          {props.definition && !props.instance && (
             <NFormItem path='timeoutFlag'>
               <NCheckbox v-model:checked={formValue.value.release}>
                 {t('project.dag.online_directly')}
               </NCheckbox>
             </NFormItem>
           )}
+          {props.instance && (
+            <NFormItem path='sync'>
+              <NCheckbox v-model:checked={formValue.value.sync}>
+                {t('project.dag.update_directly')}
+              </NCheckbox>
+            </NFormItem>
+          )}
         </NForm>
       </Modal>
     )

+ 3 - 2
dolphinscheduler-ui-next/src/views/projects/workflow/components/dag/dag-toolbar.tsx

@@ -40,6 +40,7 @@ import { useThemeStore } from '@/store/theme/theme'
 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'
 
 const props = {
   layoutToggle: {
@@ -48,12 +49,12 @@ const props = {
   },
   // If this prop is passed, it means from definition detail
   instance: {
-    type: Object as PropType<any>,
+    type: Object as PropType<WorkflowInstance>,
     default: null
   },
   definition: {
     // The same as the structure responsed by the queryProcessDefinitionByCode api
-    type: Object as PropType<any>,
+    type: Object as PropType<WorkflowDefinition>,
     default: null
   }
 }

+ 3 - 2
dolphinscheduler-ui-next/src/views/projects/workflow/components/dag/index.tsx

@@ -44,7 +44,7 @@ import {
 } from './dag-hooks'
 import { useThemeStore } from '@/store/theme/theme'
 import VersionModal from '../../definition/components/version-modal'
-import { WorkflowDefinition } from './types'
+import { WorkflowDefinition, WorkflowInstance } from './types'
 import DagSaveModal from './dag-save-modal'
 import ContextMenuItem from './dag-context-menu'
 import TaskModal from '@/views/projects/task/components/node/detail-modal'
@@ -55,7 +55,7 @@ import './x6-style.scss'
 const props = {
   // If this prop is passed, it means from definition detail
   instance: {
-    type: Object as PropType<any>,
+    type: Object as PropType<WorkflowInstance>,
     default: undefined
   },
   definition: {
@@ -278,6 +278,7 @@ export default defineComponent({
           v-model:show={saveModalShow.value}
           onSave={onSave}
           definition={props.definition}
+          instance={props.instance}
         />
         <TaskModal
           readonly={props.readonly}

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

@@ -102,6 +102,19 @@ export interface WorkflowDefinition {
   taskDefinitionList: TaskDefinition[]
 }
 
+export interface WorkflowInstance {
+  name: string
+  state: string
+  dagData: WorkflowDefinition
+  commandType: string
+  commandParam: string
+  failureStrategy: string
+  processInstancePriority: string
+  workerGroup: string
+  warningType: string
+  warningGroupId: number
+}
+
 export interface Dragged {
   x: number
   y: number
@@ -126,6 +139,7 @@ export interface SaveForm {
   timeout: number
   globalParams: GlobalParam[]
   release: boolean
+  sync: boolean
 }
 
 export interface Location {

+ 56 - 5
dolphinscheduler-ui-next/src/views/projects/workflow/instance/detail/index.tsx

@@ -16,23 +16,43 @@
  */
 
 import { defineComponent, onMounted, ref } from 'vue'
-import { useRoute } from 'vue-router'
+import { useRoute, useRouter } from 'vue-router'
 import { useThemeStore } from '@/store/theme/theme'
+import { useI18n } from 'vue-i18n'
 import Dag from '../../components/dag'
-import { queryProcessInstanceById } from '@/service/modules/process-instances'
-import { WorkflowDefinition } from '../../components/dag/types'
+import {
+  queryProcessInstanceById,
+  updateProcessInstance
+} from '@/service/modules/process-instances'
+import {
+  WorkflowDefinition,
+  WorkflowInstance,
+  SaveForm,
+  TaskDefinition,
+  Connect,
+  Location
+} from '../../components/dag/types'
 import Styles from './index.module.scss'
 
+interface SaveData {
+  saveForm: SaveForm
+  taskDefinitions: TaskDefinition[]
+  connects: Connect[]
+  locations: Location[]
+}
+
 export default defineComponent({
   name: 'WorkflowInstanceDetails',
   setup() {
     const theme = useThemeStore()
     const route = useRoute()
+    const router = useRouter()
+    const { t } = useI18n()
     const projectCode = Number(route.params.projectCode)
     const id = Number(route.params.id)
 
     const definition = ref<WorkflowDefinition>()
-    const instance = ref<any>()
+    const instance = ref<WorkflowInstance>()
 
     const refresh = () => {
       queryProcessInstanceById(id, projectCode).then((res: any) => {
@@ -43,7 +63,38 @@ export default defineComponent({
       })
     }
 
-    const save = () => {}
+    const save = ({
+      taskDefinitions,
+      saveForm,
+      connects,
+      locations
+    }: SaveData) => {
+      const globalParams = saveForm.globalParams.map((p) => {
+        return {
+          prop: p.key,
+          value: p.value,
+          direct: 'IN',
+          type: 'VARCHAR'
+        }
+      })
+
+      updateProcessInstance(
+        {
+          syncDefine: saveForm.sync,
+          globalParams: JSON.stringify(globalParams),
+          locations: JSON.stringify(locations),
+          taskDefinitionJson: JSON.stringify(taskDefinitions),
+          taskRelationJson: JSON.stringify(connects),
+          tenantCode: saveForm.tenantCode,
+          timeout: saveForm.timeoutFlag ? saveForm.timeout : 0
+        },
+        id,
+        projectCode
+      ).then((ignored: any) => {
+        window.$message.success(t('project.dag.success'))
+        router.push({ path: `/projects/${projectCode}/workflow/instances` })
+      })
+    }
 
     onMounted(() => {
       if (!id || !projectCode) return