From 2f953fb945878baff03bf590cb2a178df117e2c6 Mon Sep 17 00:00:00 2001 From: Amy0104 <97265214+Amy0104@users.noreply.github.com> Date: Sat, 19 Feb 2022 10:18:36 +0800 Subject: [PATCH] [Feature][UI Next] Add process name and pre tasks into SHELL. (#8437) --- .../service/modules/task-definition/types.ts | 2 +- .../projects/task/components/node/detail.tsx | 5 +- .../components/node/fields/use-pre-tasks.ts | 21 ++++- .../node/fields/use-process-name.ts | 92 +++++++++++++++++-- .../task/components/node/format-data.ts | 22 +++-- .../task/components/node/tasks/use-shell.ts | 19 +++- .../projects/task/components/node/types.ts | 9 +- .../projects/task/components/node/use-task.ts | 19 ++-- .../views/projects/task/definition/index.tsx | 4 +- .../projects/task/definition/use-task.ts | 32 +++++-- 10 files changed, 176 insertions(+), 49 deletions(-) diff --git a/dolphinscheduler-ui-next/src/service/modules/task-definition/types.ts b/dolphinscheduler-ui-next/src/service/modules/task-definition/types.ts index 4a79dda91..78482510a 100644 --- a/dolphinscheduler-ui-next/src/service/modules/task-definition/types.ts +++ b/dolphinscheduler-ui-next/src/service/modules/task-definition/types.ts @@ -123,7 +123,7 @@ interface TaskDefinitionVersionRes { } interface ISingleSaveReq { - processDefinitionCode: string + processDefinitionCode?: string upstreamCodes: string taskDefinitionJsonObj: string } diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/detail.tsx b/dolphinscheduler-ui-next/src/views/projects/task/components/node/detail.tsx index 2fbe52c10..237f52448 100644 --- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/detail.tsx +++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/detail.tsx @@ -24,7 +24,8 @@ import { useI18n } from 'vue-i18n' const props = { projectCode: { - type: Number as PropType + type: Number as PropType, + default: 0 }, data: { type: Object as PropType, @@ -53,7 +54,7 @@ const NodeDetail = defineComponent({ const { t } = useI18n() const { json, model } = useTask({ - taskType: data.taskType, + data, projectCode, from, readonly diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-pre-tasks.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-pre-tasks.ts index a0e75d291..f713a8e41 100644 --- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-pre-tasks.ts +++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-pre-tasks.ts @@ -15,17 +15,29 @@ * limitations under the License. */ -import { ref, onMounted } from 'vue' +import { ref, watch } from 'vue' import { useI18n } from 'vue-i18n' import type { IJsonItem } from '../types' -export function usePreTasks(): IJsonItem { +export function usePreTasks(model: { [field: string]: any }): IJsonItem { const { t } = useI18n() const options = ref([]) - const loading = ref(false) - onMounted(() => {}) + const getOptions = () => { + if (!model.preTaskOptions?.length) return [] + return model.preTaskOptions.map((task: { code: number; name: string }) => ({ + value: task.code, + label: task.name + })) + } + + watch( + () => model.preTaskOptions, + () => { + options.value = getOptions() + } + ) return { type: 'select', @@ -33,7 +45,6 @@ export function usePreTasks(): IJsonItem { span: 24, name: t('project.node.pre_tasks'), props: { - loading, multiple: true, filterable: true }, diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-process-name.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-process-name.ts index f971a61e8..bce58895f 100644 --- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-process-name.ts +++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-process-name.ts @@ -17,13 +17,29 @@ import { ref, onMounted } from 'vue' import { useI18n } from 'vue-i18n' -import { querySimpleList } from '@/service/modules/process-definition' +import { uniqBy } from 'lodash' +import { + querySimpleList, + queryProcessDefinitionByCode +} from '@/service/modules/process-definition' import type { IJsonItem } from '../types' +import { number } from 'echarts' -export function useProcessName( - projectCode: number, +export function useProcessName({ + model, + projectCode, + isCreate, + from, + processName, + code +}: { + model: { [field: string]: any } + projectCode: number isCreate: boolean -): IJsonItem { + from?: number + processName?: number + code?: number +}): IJsonItem { const { t } = useI18n() const options = ref([] as { label: string; value: string }[]) @@ -43,19 +59,83 @@ export function useProcessName( 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: 'processCode', + field: 'processName', span: 24, name: t('project.node.process_name'), props: { loading: loading, - disabled: !isCreate + disabled: !isCreate, + 'on-update:value': onChange }, options: options } diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/format-data.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/format-data.ts index 4c570ffd0..717a30306 100644 --- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/format-data.ts +++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/format-data.ts @@ -24,11 +24,10 @@ export function formatParams(data: INodeData): { taskDefinitionJsonObj: object } { const params = { - processDefinitionCode: data.processCode ? String(data.processCode) : '', - upstreamCodes: '', + processDefinitionCode: data.processName ? String(data.processName) : '', + upstreamCodes: data?.preTasks?.join(','), taskDefinitionJsonObj: { ...omit(data, [ - 'processCode', 'delayTime', 'environmentCode', 'failRetryTimes', @@ -37,7 +36,11 @@ export function formatParams(data: INodeData): { 'localParams', 'timeoutFlag', 'timeoutNotifyStrategy', - 'resourceList' + 'resourceList', + 'postTaskOptions', + 'preTaskOptions', + 'preTasks', + 'processName' ]), code: data.code, delayTime: data.delayTime ? '0' : String(data.delayTime), @@ -46,7 +49,7 @@ export function formatParams(data: INodeData): { failRetryInterval: data.failRetryTimes ? String(data.failRetryTimes) : '0', - taskGroupId: data.taskGroupId || '', + taskGroupId: data.taskGroupId || 0, taskParams: { localParams: data.localParams, rawScript: data.rawScript, @@ -86,11 +89,10 @@ export function formatModel(data: ITaskData) { delayTime: data.delayTime, timeoutFlag: data.timeoutFlag === 'OPEN', timeoutNotifyStrategy: [data.timeoutNotifyStrategy] || [], - resourceList: data.taskParams.resourceList, + resourceList: data.taskParams?.resourceList || [], timeout: data.timeout, - rawScript: data.taskParams.rawScript, - localParams: data.taskParams.localParams, - preTasks: [], + rawScript: data.taskParams?.rawScript, + localParams: data.taskParams?.localParams || [], id: data.id, code: data.code } as { @@ -100,7 +102,7 @@ export function formatModel(data: ITaskData) { if (data.timeoutNotifyStrategy === 'WARNFAILED') { params.timeoutNotifyStrategy = ['WARN', 'FAILED'] } - if (data.taskParams.resourceList) { + if (data.taskParams?.resourceList) { params.resourceList = data.taskParams.resourceList.map( (item: { id: number }) => item.id ) diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-shell.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-shell.ts index 1815a6a10..865ae87a2 100644 --- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-shell.ts +++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-shell.ts @@ -17,16 +17,18 @@ import { reactive } from 'vue' import * as Fields from '../fields/index' -import type { IJsonItem, INodeData } from '../types' +import type { IJsonItem, INodeData, ITaskData } from '../types' export function useShell({ projectCode, from = 0, - readonly + readonly, + data }: { projectCode: number from?: number readonly?: boolean + data?: ITaskData }) { const model = reactive({ name: '', @@ -47,7 +49,14 @@ export function useShell({ if (from === 1) { extra = [ Fields.useTaskType(model, readonly), - Fields.useProcessName(projectCode, !model.id) + Fields.useProcessName({ + model, + projectCode, + isCreate: !data?.id, + from, + processName: data?.processName, + code: data?.code + }) ] } @@ -59,13 +68,13 @@ export function useShell({ Fields.useDescription(), Fields.useTaskPriority(), Fields.useWorkerGroup(), - Fields.useEnvironmentName(model, !model.id), + Fields.useEnvironmentName(model, !data?.id), ...Fields.useTaskGroup(model, projectCode), ...Fields.useFailed(), Fields.useDelayTime(), ...Fields.useTimeoutAlarm(model), ...Fields.useShell(model), - Fields.usePreTasks() + Fields.usePreTasks(model) ] as IJsonItem[], model } diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/types.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/types.ts index f278d9a52..af128876a 100644 --- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/types.ts +++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/types.ts @@ -40,7 +40,7 @@ type ITaskType = TaskType interface INodeData { id?: string taskType?: ITaskType - processCode?: string + processName?: number delayTime?: number description?: string environmentCode?: number | null @@ -59,6 +59,9 @@ interface INodeData { resourceList?: number[] code?: number name?: string + preTasks?: [] + preTaskOptions?: [] + postTaskOptions?: [] } interface ITaskData @@ -67,16 +70,14 @@ interface ITaskData 'timeoutFlag' | 'taskPriority' | 'timeoutNotifyStrategy' > { name?: string - processName?: number taskPriority?: string timeoutFlag: 'OPEN' | 'CLOSE' timeoutNotifyStrategy?: string | [] - taskParams: { + taskParams?: { resourceList: [] rawScript: string localParams: ILocalParam[] } - preTasks?: [] } export { 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 6ffc033f0..c0b5d0319 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,23 +16,28 @@ */ import { useShell } from './tasks/use-shell' -import { IJsonItem, ITaskType, INodeData } from './types' +import { IJsonItem, INodeData, ITaskData } from './types' export function useTask({ - taskType = 'SHELL', + data, projectCode, from, readonly }: { - taskType?: ITaskType + data: ITaskData + projectCode: number from?: number - projectCode?: number readonly?: boolean }): { json: IJsonItem[]; model: INodeData } { - console.log(taskType, 'taskType') + const { taskType = 'SHELL' } = data let node = {} as { json: IJsonItem[]; model: INodeData } - if (taskType === 'SHELL' && projectCode) { - node = useShell({ projectCode, from, readonly }) + if (taskType === 'SHELL') { + node = useShell({ + projectCode, + from, + readonly, + data + }) } return node } diff --git a/dolphinscheduler-ui-next/src/views/projects/task/definition/index.tsx b/dolphinscheduler-ui-next/src/views/projects/task/definition/index.tsx index 946265479..74022dabe 100644 --- a/dolphinscheduler-ui-next/src/views/projects/task/definition/index.tsx +++ b/dolphinscheduler-ui-next/src/views/projects/task/definition/index.tsx @@ -46,7 +46,8 @@ const TaskDefinition = defineComponent({ const projectCode = Number(route.params.projectCode) const { t } = useI18n() - const { task, onToggleShow, onTaskSave, onEditTask } = useTask(projectCode) + const { task, onToggleShow, onTaskSave, onEditTask, onInitTask } = + useTask(projectCode) const { variables, getTableData, createColumns } = useTable(onEditTask) @@ -80,6 +81,7 @@ const TaskDefinition = defineComponent({ } const onTaskCancel = () => { onToggleShow(false) + onInitTask() } const onTaskSubmit = async (params: { data: INodeData }) => { const result = await onTaskSave(params.data) diff --git a/dolphinscheduler-ui-next/src/views/projects/task/definition/use-task.ts b/dolphinscheduler-ui-next/src/views/projects/task/definition/use-task.ts index acd5c553b..69e64cade 100644 --- a/dolphinscheduler-ui-next/src/views/projects/task/definition/use-task.ts +++ b/dolphinscheduler-ui-next/src/views/projects/task/definition/use-task.ts @@ -26,19 +26,26 @@ import { formatParams as formatData } from '../components/node/format-data' import type { ITaskData, INodeData, ISingleSaveReq, IRecord } from './types' export function useTask(projectCode: number) { + const initalTask = { + taskType: 'SHELL' + } as ITaskData const task = reactive({ taskShow: false, - taskData: { - taskType: 'SHELL' - }, + taskData: { ...initalTask }, taskSaving: false, taskReadonly: false } as { taskShow: boolean; taskData: ITaskData; taskSaving: boolean; taskReadonly: boolean }) - const formatParams = (data: INodeData): ISingleSaveReq => { + const formatParams = (data: INodeData, isCreate: boolean): ISingleSaveReq => { const params = formatData(data) + if (isCreate) { + return { + processDefinitionCode: params.processDefinitionCode, + upstreamCodes: params.upstreamCodes, + taskDefinitionJsonObj: JSON.stringify(params.taskDefinitionJsonObj) + } + } return { - processDefinitionCode: params.processDefinitionCode, upstreamCodes: params.upstreamCodes, taskDefinitionJsonObj: JSON.stringify(params.taskDefinitionJsonObj) } @@ -61,11 +68,14 @@ export function useTask(projectCode: number) { (await updateWithUpstream( projectCode, data.code, - formatParams({ ...data, code: data.code }) + formatParams({ ...data, code: data.code }, false) )) } else { const taskCode = await getTaskCode() - await saveSingle(projectCode, formatParams({ ...data, code: taskCode })) + await saveSingle( + projectCode, + formatParams({ ...data, code: taskCode }, true) + ) } task.taskSaving = false @@ -88,10 +98,16 @@ export function useTask(projectCode: number) { } } + const onInitTask = () => { + task.taskData = { ...initalTask } + task.taskReadonly = false + } + return { task, onToggleShow, onTaskSave, - onEditTask + onEditTask, + onInitTask } } -- GitLab