From 059650effb8ba6622cf111d60ae894bb636f1640 Mon Sep 17 00:00:00 2001 From: Amy0104 <97265214+Amy0104@users.noreply.github.com> Date: Sun, 27 Feb 2022 18:02:58 +0800 Subject: [PATCH] [Feature][UI Next] Add DEPENDENT. (#8556) --- .../src/components/form/fields/checkbox.ts | 3 +- .../form/fields/custom-parameters.ts | 28 +- .../src/components/form/fields/get-field.ts | 8 +- .../components/form/fields/input-number.ts | 5 +- .../src/components/form/fields/input.ts | 3 +- .../components/form/fields/monaco-editor.ts | 3 +- .../components/form/fields/multi-condition.ts | 28 +- .../src/components/form/fields/multi-input.ts | 25 +- .../src/components/form/fields/radio.ts | 3 +- .../src/components/form/fields/select.ts | 8 +- .../src/components/form/fields/switch.ts | 3 +- .../src/components/form/fields/tree-select.ts | 5 +- .../components/form/get-elements-by-json.ts | 15 +- .../src/components/form/types.ts | 8 +- .../src/locales/modules/en_US.ts | 33 +- .../src/locales/modules/zh_CN.ts | 33 +- .../modules/process-definition/index.ts | 10 +- .../task/components/node/fields/index.ts | 3 + .../components/node/fields/use-conditions.ts | 136 ++++++++ .../node/fields/use-dependent-timeout.ts | 101 ++++++ .../components/node/fields/use-dependent.ts | 318 ++++++++++++++++++ .../node/fields/use-relation-custom-params.ts | 9 +- .../node/fields/use-timeout-alarm.ts | 10 +- .../task/components/node/format-data.ts | 23 +- .../components/node/tasks/use-conditions.ts | 60 +--- .../components/node/tasks/use-dependent.ts | 101 ++++++ .../task/components/node/tasks/use-shell.ts | 3 +- .../projects/task/components/node/types.ts | 18 +- .../projects/task/components/node/use-task.ts | 9 + .../projects/task/definition/use-task.ts | 4 +- .../security/alarm-instance-manage/detail.tsx | 6 +- .../alarm-instance-manage/use-detail.ts | 4 +- 32 files changed, 886 insertions(+), 140 deletions(-) create mode 100644 dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-conditions.ts create mode 100644 dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-dependent-timeout.ts create mode 100644 dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-dependent.ts create mode 100644 dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-dependent.ts diff --git a/dolphinscheduler-ui-next/src/components/form/fields/checkbox.ts b/dolphinscheduler-ui-next/src/components/form/fields/checkbox.ts index 1408b951a..a8af013e6 100644 --- a/dolphinscheduler-ui-next/src/components/form/fields/checkbox.ts +++ b/dolphinscheduler-ui-next/src/components/form/fields/checkbox.ts @@ -17,13 +17,14 @@ import { h, unref } from 'vue' import { NCheckbox, NCheckboxGroup, NSpace } from 'naive-ui' +import { isFunction } from 'lodash' import type { IJsonItem } from '../types' export function renderCheckbox( item: IJsonItem, fields: { [field: string]: any } ) { - const { props, field, options } = item + const { props, field, options } = isFunction(item) ? item() : item if (!options) { return h(NCheckbox, { ...props, diff --git a/dolphinscheduler-ui-next/src/components/form/fields/custom-parameters.ts b/dolphinscheduler-ui-next/src/components/form/fields/custom-parameters.ts index 0003ed6fb..0f57d0832 100644 --- a/dolphinscheduler-ui-next/src/components/form/fields/custom-parameters.ts +++ b/dolphinscheduler-ui-next/src/components/form/fields/custom-parameters.ts @@ -18,6 +18,7 @@ import { defineComponent, h, unref, renderSlot } from 'vue' import { useFormItem } from 'naive-ui/es/_mixins' import { NFormItemGi, NSpace, NButton, NGrid, NGridItem } from 'naive-ui' +import { isFunction } from 'lodash' import { PlusOutlined, DeleteOutlined } from '@vicons/antd' import getField from './get-field' import { formatValidate } from '../utils' @@ -67,20 +68,21 @@ const getDefaultValue = (children: IJsonItem[]) => { ruleParent: { [key: string]: FormItemRule[] | FormItemRule } ) => { children.forEach((child) => { - if (Array.isArray(child.children)) { + const mergedChild = isFunction(child) ? child() : child + if (Array.isArray(mergedChild.children)) { const childDefaultValue = {} const childRuleItem = {} - loop(child.children, childDefaultValue, childRuleItem) - parent[child.field] = [childDefaultValue] - ruleParent[child.field] = { + loop(mergedChild.children, childDefaultValue, childRuleItem) + parent[mergedChild.field] = [childDefaultValue] + ruleParent[mergedChild.field] = { type: 'array', fields: childRuleItem } return } else { - parent[child.field] = child.value || null - if (child.validate) - ruleParent[child.field] = formatValidate(child.validate) + parent[mergedChild.field] = mergedChild.value || null + if (mergedChild.validate) + ruleParent[mergedChild.field] = formatValidate(mergedChild.validate) } }) } @@ -97,20 +99,22 @@ export function renderCustomParameters( fields: { [field: string]: any }, rules: { [key: string]: FormItemRule | FormItemRule[] }[] ) { - const { field, children = [] } = item + const mergedItem = isFunction(item) ? item() : item + const { field, children = [] } = mergedItem const { defaultValue, ruleItem } = getDefaultValue(children) rules.push(ruleItem) const getChild = (item: object, i: number, disabled: boolean) => children.map((child: IJsonItem) => { + const mergedChild = isFunction(child) ? child(i) : child return h( NFormItemGi, { showLabel: false, - path: `${field}[${i}].${child.field}`, - span: unref(child.span), - class: child.class + path: `${field}[${i}].${mergedChild.field}`, + span: unref(mergedChild.span), + class: mergedChild.class }, - () => getField(child, item) + () => getField(mergedChild, item) ) }) const getChildren = ({ disabled }: { disabled: boolean }) => diff --git a/dolphinscheduler-ui-next/src/components/form/fields/get-field.ts b/dolphinscheduler-ui-next/src/components/form/fields/get-field.ts index 3cb5affef..94139bb1b 100644 --- a/dolphinscheduler-ui-next/src/components/form/fields/get-field.ts +++ b/dolphinscheduler-ui-next/src/components/form/fields/get-field.ts @@ -15,7 +15,7 @@ * limitations under the License. */ import * as Field from './index' -import { camelCase, upperFirst } from 'lodash' +import { camelCase, upperFirst, isFunction } from 'lodash' import type { FormRules, FormItemRule } from 'naive-ui' import type { IJsonItem } from '../types' @@ -24,15 +24,15 @@ const getField = ( fields: { [field: string]: any }, rules?: FormRules ) => { - const { type = 'input' } = item + const { type = 'input', widget, field } = isFunction(item) ? item() : item const renderTypeName = `render${upperFirst(camelCase(type))}` if (type === 'custom') { - return item.widget || null + return widget || null } // TODO Support other widgets later if (type === 'custom-parameters') { let fieldRules: { [key: string]: FormItemRule }[] = [] - if (rules && !rules[item.field]) fieldRules = rules[item.field] = [] + if (rules && !rules[field]) fieldRules = rules[field] = [] // @ts-ignore return Field[renderTypeName](item, fields, fieldRules) } diff --git a/dolphinscheduler-ui-next/src/components/form/fields/input-number.ts b/dolphinscheduler-ui-next/src/components/form/fields/input-number.ts index 6a7833af0..8bac5671f 100644 --- a/dolphinscheduler-ui-next/src/components/form/fields/input-number.ts +++ b/dolphinscheduler-ui-next/src/components/form/fields/input-number.ts @@ -17,20 +17,21 @@ import { h } from 'vue' import { NInputNumber } from 'naive-ui' +import { isFunction } from 'lodash' import type { IJsonItem } from '../types' export function renderInputNumber( item: IJsonItem, fields: { [field: string]: any } ) { - const { props, field, slots = {} } = item + const { props, field, slots = {} } = isFunction(item) ? item() : item return h( NInputNumber, { ...props, value: fields[field], - onUpdateValue: (value) => void (fields[field] = value) + onUpdateValue: (value: number) => void (fields[field] = value) }, { ...slots diff --git a/dolphinscheduler-ui-next/src/components/form/fields/input.ts b/dolphinscheduler-ui-next/src/components/form/fields/input.ts index 2f1cc88ac..b9f8908db 100644 --- a/dolphinscheduler-ui-next/src/components/form/fields/input.ts +++ b/dolphinscheduler-ui-next/src/components/form/fields/input.ts @@ -17,10 +17,11 @@ import { h } from 'vue' import { NInput } from 'naive-ui' +import { isFunction } from 'lodash' import type { IJsonItem } from '../types' export function renderInput(item: IJsonItem, fields: { [field: string]: any }) { - const { props, field } = item + const { props, field } = isFunction(item) ? item() : item return h(NInput, { ...props, value: fields[field], diff --git a/dolphinscheduler-ui-next/src/components/form/fields/monaco-editor.ts b/dolphinscheduler-ui-next/src/components/form/fields/monaco-editor.ts index 6597b5d42..b7e067650 100644 --- a/dolphinscheduler-ui-next/src/components/form/fields/monaco-editor.ts +++ b/dolphinscheduler-ui-next/src/components/form/fields/monaco-editor.ts @@ -17,13 +17,14 @@ import { h } from 'vue' import Editor from '@/components/monaco-editor' +import { isFunction } from 'lodash' import type { IJsonItem } from '../types' export function renderEditor( item: IJsonItem, fields: { [field: string]: any } ) { - const { props, field } = item + const { props, field } = isFunction(item) ? item() : item return h(Editor, { ...props, value: fields[field], diff --git a/dolphinscheduler-ui-next/src/components/form/fields/multi-condition.ts b/dolphinscheduler-ui-next/src/components/form/fields/multi-condition.ts index c091eebdd..795a1e0d5 100644 --- a/dolphinscheduler-ui-next/src/components/form/fields/multi-condition.ts +++ b/dolphinscheduler-ui-next/src/components/form/fields/multi-condition.ts @@ -17,16 +17,9 @@ import { defineComponent, h, unref, renderSlot } from 'vue' import { useFormItem } from 'naive-ui/es/_mixins' -import { - NFormItemGi, - NSpace, - NButton, - NGrid, - NGridItem, - NInput, - NSelect -} from 'naive-ui' +import { NFormItemGi, NSpace, NButton, NGrid, NGridItem } from 'naive-ui' import { PlusOutlined, DeleteOutlined } from '@vicons/antd' +import { isFunction } from 'lodash' import type { IJsonItem, FormItemRule } from '../types' import getField from '@/components/form/fields/get-field' import { formatValidate } from '@/components/form/utils' @@ -79,23 +72,25 @@ export function renderMultiCondition( // the fields is the data of the task definition. // the item is the options of this component in the form. - const { field, children = [] } = item + const { field, children = [] } = isFunction(item) ? item() : item children.forEach((child: IJsonItem) => { - if (child.validate) { - ruleItem[child.field] = formatValidate(child.validate) + const mergedChild = isFunction(child) ? child() : child + if (mergedChild.validate) { + ruleItem[mergedChild.field] = formatValidate(mergedChild.validate) } }) const getChild = (item: object, i: number) => children.map((child: IJsonItem) => { + const mergedChild = isFunction(child) ? child() : child return h( NFormItemGi, { showLabel: child.name ? true : false, label: child.name ? child.name : '', - path: `${fields[field]}[${i}].${child.field}`, - span: unref(child.span) + path: `${fields[field]}[${i}].${mergedChild.field}`, + span: unref(mergedChild.span) }, () => getField(child, fields[field][i]) ) @@ -139,8 +134,9 @@ export function renderMultiCondition( onAdd: () => { const newCondition = {} as any children.map((child: IJsonItem) => { - if (child.field) { - newCondition[child.field] = null + const { field } = isFunction(child) ? child() : child + if (field) { + newCondition[field] = null } }) fields[field].push(newCondition) diff --git a/dolphinscheduler-ui-next/src/components/form/fields/multi-input.ts b/dolphinscheduler-ui-next/src/components/form/fields/multi-input.ts index 1ffbd4862..2084e68b1 100644 --- a/dolphinscheduler-ui-next/src/components/form/fields/multi-input.ts +++ b/dolphinscheduler-ui-next/src/components/form/fields/multi-input.ts @@ -25,6 +25,7 @@ import { NGridItem, NInput } from 'naive-ui' +import { isFunction } from 'lodash' import { PlusOutlined, DeleteOutlined } from '@vicons/antd' import type { IJsonItem, FormItemRule } from '../types' @@ -72,31 +73,32 @@ export function renderMultiInput( fields: { [field: string]: any }, rules: { [key: string]: FormItemRule }[] ) { - let ruleItem: { [key: string]: FormItemRule } = {} - + const { field } = isFunction(item) ? item() : item // the fields is the data of the task definition. // the item is the options of this component in the form. const getChild = (value: string, i: number) => { + const mergedItem = isFunction(item) ? item() : item return h( NFormItemGi, { showLabel: false, - path: `${item.field}[${i}]`, - span: unref(item.span) + path: `${mergedItem.field}[${i}]`, + span: unref(mergedItem.span) }, () => h(NInput, { - ...item.props, + ...mergedItem.props, value: value, - onUpdateValue: (value: string) => void (fields[item.field][i] = value) + onUpdateValue: (value: string) => + void (fields[mergedItem.field][i] = value) }) ) } //initialize the component by using data - const getChildren = ({ disabled }: { disabled: boolean }) => - fields[item.field].map((value: string, i: number) => { + const getChildren = ({ disabled }: { disabled: boolean }) => { + return fields[field].map((value: string, i: number) => { return h(NGrid, { xGap: 10 }, () => [ getChild(value, i), h( @@ -113,7 +115,7 @@ export function renderMultiInput( size: 'small', disabled, onClick: () => { - fields[item.field].splice(i, 1) + fields[field].splice(i, 1) } }, { @@ -123,13 +125,14 @@ export function renderMultiInput( ) ]) }) + } return h( MultiInput, { - name: item.field, + name: field, onAdd: () => { - fields[item.field].push('') + fields[field].push('') } }, { diff --git a/dolphinscheduler-ui-next/src/components/form/fields/radio.ts b/dolphinscheduler-ui-next/src/components/form/fields/radio.ts index f198b7b0f..553680f0b 100644 --- a/dolphinscheduler-ui-next/src/components/form/fields/radio.ts +++ b/dolphinscheduler-ui-next/src/components/form/fields/radio.ts @@ -17,10 +17,11 @@ import { h, unref } from 'vue' import { NRadio, NRadioGroup, NSpace } from 'naive-ui' +import { isFunction } from 'lodash' import type { IJsonItem, IOption } from '../types' export function renderRadio(item: IJsonItem, fields: { [field: string]: any }) { - const { props, field, options } = item + const { props, field, options } = isFunction(item) ? item() : item if (!options) { return h(NRadio, { ...props, diff --git a/dolphinscheduler-ui-next/src/components/form/fields/select.ts b/dolphinscheduler-ui-next/src/components/form/fields/select.ts index 16c4760e4..0bd82ddce 100644 --- a/dolphinscheduler-ui-next/src/components/form/fields/select.ts +++ b/dolphinscheduler-ui-next/src/components/form/fields/select.ts @@ -17,17 +17,21 @@ import { h, unref } from 'vue' import { NSelect } from 'naive-ui' +import { isFunction } from 'lodash' import type { IJsonItem } from '../types' export function renderSelect( item: IJsonItem, fields: { [field: string]: any } ) { - const { props, field, options = [] } = item + const { props, field, options = [] } = isFunction(item) ? item() : item return h(NSelect, { ...props, value: fields[field], - onUpdateValue: (value) => void (fields[field] = value), + onUpdateValue: (value: any) => { + void (fields[field] = value) + if (props?.onUpdateValue) props.onUpdateValue(value) + }, options: unref(options) }) } diff --git a/dolphinscheduler-ui-next/src/components/form/fields/switch.ts b/dolphinscheduler-ui-next/src/components/form/fields/switch.ts index c1f77724d..ab8c50d72 100644 --- a/dolphinscheduler-ui-next/src/components/form/fields/switch.ts +++ b/dolphinscheduler-ui-next/src/components/form/fields/switch.ts @@ -17,13 +17,14 @@ import { h } from 'vue' import { NSwitch } from 'naive-ui' +import { isFunction } from 'lodash' import type { IJsonItem } from '../types' export function renderSwitch( item: IJsonItem, fields: { [field: string]: any } ) { - const { props, field, slots = {} } = item + const { props, field, slots = {} } = isFunction(item) ? item() : item return h( NSwitch, { diff --git a/dolphinscheduler-ui-next/src/components/form/fields/tree-select.ts b/dolphinscheduler-ui-next/src/components/form/fields/tree-select.ts index 0c04790f5..e7428055e 100644 --- a/dolphinscheduler-ui-next/src/components/form/fields/tree-select.ts +++ b/dolphinscheduler-ui-next/src/components/form/fields/tree-select.ts @@ -17,17 +17,18 @@ import { h, unref } from 'vue' import { NTreeSelect } from 'naive-ui' +import { isFunction } from 'lodash' import type { IJsonItem } from '../types' export function renderTreeSelect( item: IJsonItem, fields: { [field: string]: any } ) { - const { props = {}, field, options = [] } = item + const { props = {}, field, options = [] } = isFunction(item) ? item() : item return h(NTreeSelect, { ...props, value: fields[field], - onUpdateValue: (value) => void (fields[field] = value), + onUpdateValue: (value: []) => void (fields[field] = value), options: unref(options) }) } diff --git a/dolphinscheduler-ui-next/src/components/form/get-elements-by-json.ts b/dolphinscheduler-ui-next/src/components/form/get-elements-by-json.ts index 4956eab32..b36673438 100644 --- a/dolphinscheduler-ui-next/src/components/form/get-elements-by-json.ts +++ b/dolphinscheduler-ui-next/src/components/form/get-elements-by-json.ts @@ -18,7 +18,7 @@ import { toRef, Ref } from 'vue' import { formatValidate } from './utils' import getField from './fields/get-field' -import { omit } from 'lodash' +import { omit, isFunction } from 'lodash' import type { FormRules } from 'naive-ui' import type { IFormItem, IJsonItem } from './types' @@ -30,7 +30,16 @@ export default function getElementByJson( const initialValues: { [field: string]: any } = {} const elements: IFormItem[] = [] for (let item of json) { - const { name, value, field, span = 24, children, validate, ...rest } = item + const mergedItem = isFunction(item) ? item() : item + const { + name, + value, + field, + span = 24, + children, + validate, + ...rest + } = mergedItem if (value || value === 0) { fields[field] = value initialValues[field] = value @@ -42,7 +51,7 @@ export default function getElementByJson( label: name, path: !children ? field : '', widget: () => getField(item, fields, rules), - span: toRef(item, 'span') as Ref + span: toRef(mergedItem, 'span') as Ref } elements.push(element) } diff --git a/dolphinscheduler-ui-next/src/components/form/types.ts b/dolphinscheduler-ui-next/src/components/form/types.ts index 402f8a65b..8f7c266a6 100644 --- a/dolphinscheduler-ui-next/src/components/form/types.ts +++ b/dolphinscheduler-ui-next/src/components/form/types.ts @@ -57,10 +57,10 @@ interface IMeta extends Omit { model: object } -interface IJsonItem { +interface IJsonItemParams { field: string name?: string - props?: object + props?: any title?: string type?: IType validate?: FormItemRule @@ -73,6 +73,10 @@ interface IJsonItem { class?: string } +type IJsonItemFn = (i?: number) => IJsonItemParams + +type IJsonItem = IJsonItemParams | IJsonItemFn + export { IMeta, IType, diff --git a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts index 274b2ef6b..14cc11a22 100644 --- a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts +++ b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts @@ -790,7 +790,38 @@ const project = { datax_job_runtime_memory: 'Runtime Memory Limits', datax_job_runtime_memory_xms: 'Low Limit Value', datax_job_runtime_memory_xmx: 'High Limit Value', - datax_job_runtime_memory_unit: 'G' + datax_job_runtime_memory_unit: 'G', + current_hour: 'CurrentHour', + last_1_hour: 'Last1Hour', + last_2_hour: 'Last2Hours', + last_3_hour: 'Last3Hours', + last_24_hour: 'Last24Hours', + today: 'today', + last_1_days: 'Last1Days', + last_2_days: 'Last2Days', + last_3_days: 'Last3Days', + last_7_days: 'Last7Days', + this_week: 'ThisWeek', + last_week: 'LastWeek', + last_monday: 'LastMonday', + last_tuesday: 'LastTuesday', + last_wednesday: 'LastWednesday', + last_thursday: 'LastThursday', + last_friday: 'LastFriday', + last_saturday: 'LastSaturday', + last_sunday: 'LastSunday', + this_month: 'ThisMonth', + last_month: 'LastMonth', + last_month_begin: 'LastMonthBegin', + last_month_end: 'LastMonthEnd', + month: 'month', + week: 'week', + day: 'day', + hour: 'hour', + add_dependency: 'Add dependency', + waiting_dependent_start: 'Waiting Dependent start', + check_interval: 'Check interval', + waiting_dependent_complete: 'Waiting Dependent complete' } } diff --git a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts index 0b0765b37..1a8d29946 100644 --- a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts +++ b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts @@ -781,7 +781,38 @@ const project = { datax_job_runtime_memory: '运行内存', datax_job_runtime_memory_xms: '最小内存', datax_job_runtime_memory_xmx: '最大内存', - datax_job_runtime_memory_unit: 'G' + datax_job_runtime_memory_unit: 'G', + current_hour: '当前小时', + last_1_hour: '前1小时', + last_2_hour: '前2小时', + last_3_hour: '前3小时', + last_24_hour: '前24小时', + today: '今天', + last_1_days: '昨天', + last_2_days: '前两天', + last_3_days: '前三天', + last_7_days: '前七天', + this_week: '本周', + last_week: '上周', + last_monday: '上周一', + last_tuesday: '上周二', + last_wednesday: '上周三', + last_thursday: '上周四', + last_friday: '上周五', + last_saturday: '上周六', + last_sunday: '上周日', + this_month: '本月', + last_month: '上月', + last_month_begin: '上月初', + last_month_end: '上月末', + month: '月', + week: '周', + day: '日', + hour: '时', + add_dependency: '添加依赖', + waiting_dependent_start: '等待依赖启动', + check_interval: '检查间隔', + waiting_dependent_complete: '等待依赖完成' } } diff --git a/dolphinscheduler-ui-next/src/service/modules/process-definition/index.ts b/dolphinscheduler-ui-next/src/service/modules/process-definition/index.ts index b17798863..0d329fdf6 100644 --- a/dolphinscheduler-ui-next/src/service/modules/process-definition/index.ts +++ b/dolphinscheduler-ui-next/src/service/modules/process-definition/index.ts @@ -49,10 +49,10 @@ export function createProcessDefinition( }) } -export function queryAllByProjectCode(code: CodeReq): any { +export function queryAllByProjectCode(code: number): any { return axios({ url: `/projects/${code}/process-definition/all`, - method: 'post' + method: 'get' }) } @@ -97,7 +97,7 @@ export function batchMoveByCodes( export function getTaskListByDefinitionCodes( params: CodesReq, - code: CodeReq + code: number ): any { return axios({ url: `/projects/${code}/process-definition/batch-query-tasks`, @@ -189,8 +189,8 @@ export function release( } export function getTasksByDefinitionCode( - code: CodeReq, - processCode: CodeReq + code: number, + processCode: number ): any { return axios({ url: `/projects/${code}/process-definition/${processCode}/tasks`, diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/index.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/index.ts index e3d5c7d15..2998ef76c 100644 --- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/index.ts +++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/index.ts @@ -38,6 +38,7 @@ export { useCustomParams } from './use-custom-params' export { useSourceType } from './use-sqoop-source-type' export { useTargetType } from './use-sqoop-target-type' export { useRelationCustomParams } from './use-relation-custom-params' +export { useDependentTimeout } from './use-dependent-timeout' export { useShell } from './use-shell' export { useSpark } from './use-spark' @@ -49,3 +50,5 @@ export { useSqoop } from './use-sqoop' export { useSeaTunnel } from './use-sea-tunnel' export { useSwitch } from './use-switch' export { useDataX } from './use-datax' +export { useConditions } from './use-conditions' +export { useDependent } from './use-dependent' diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-conditions.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-conditions.ts new file mode 100644 index 000000000..349e7f050 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-conditions.ts @@ -0,0 +1,136 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ref, watch } from 'vue' +import { useI18n } from 'vue-i18n' +import { useRelationCustomParams, useTimeoutAlarm } from '.' +import type { IJsonItem } from '../types' + +export function useConditions(model: { [field: string]: any }): IJsonItem[] { + const { t } = useI18n() + + const taskCodeOptions = ref([] as { label: string; value: number }[]) + const postTasksOptions = ref([] as { label: string; value: number }[]) + const stateOptions = [ + { label: t('project.node.success'), value: 'success' }, + { label: t('project.node.failed'), value: 'failed' } + ] + + watch( + () => model.preTasks, + () => { + taskCodeOptions.value = + model.preTaskOptions + ?.filter((task: { code: number }) => + model.preTasks?.includes(task.code) + ) + .map((task: { code: number; name: string }) => ({ + value: task.code, + label: task.name + })) || [] + } + ) + + watch( + () => model.postTaskOptions, + () => { + postTasksOptions.value = model.postTasksOptions.map( + (task: { code: number; name: string }) => ({ + value: task.code, + label: task.name + }) + ) + } + ) + + return [ + { + type: 'select', + field: 'successNode', + name: t('project.node.state'), + span: 12, + props: { + disabled: true + }, + options: stateOptions + }, + { + type: 'select', + field: 'successBranch', + name: t('project.node.branch_flow'), + span: 12, + props: { + clearable: true + }, + options: postTasksOptions + }, + { + type: 'select', + field: 'failedNode', + name: t('project.node.state'), + span: 12, + props: { + disabled: true + }, + options: stateOptions + }, + { + type: 'select', + field: 'failedBranch', + name: t('project.node.branch_flow'), + span: 12, + props: { + clearable: true + }, + options: postTasksOptions + }, + ...useTimeoutAlarm(model), + ...useRelationCustomParams({ + model, + children: { + type: 'custom-parameters', + field: 'dependItemList', + span: 18, + children: [ + { + type: 'select', + field: 'depTaskCode', + span: 10, + options: taskCodeOptions + }, + { + type: 'select', + field: 'status', + span: 10, + options: [ + { + value: 'SUCCESS', + label: t('project.node.success') + }, + { + value: 'FAILURE', + label: t('project.node.failed') + } + ] + } + ] + }, + childrenField: 'dependItemList', + name: 'custom_parameters' + }) + ] +} diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-dependent-timeout.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-dependent-timeout.ts new file mode 100644 index 000000000..09df39100 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-dependent-timeout.ts @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { computed, watch } from 'vue' +import { useI18n } from 'vue-i18n' +import type { IJsonItem } from '../types' + +export function useDependentTimeout(model: { + [field: string]: any +}): IJsonItem[] { + const { t } = useI18n() + const timeCompleteSpan = computed(() => (model.timeoutShowFlag ? 24 : 0)) + const timeCompleteEnableSpan = computed(() => (model.timeoutFlag ? 12 : 0)) + + const strategyOptions = [ + { + label: t('project.node.timeout_alarm'), + value: 'WARN' + }, + { + label: t('project.node.timeout_failure'), + value: 'FAILED' + } + ] + watch( + () => model.timeoutFlag, + (timeoutFlag) => { + model.timeoutNotifyStrategy = timeoutFlag ? ['WARN'] : [] + model.timeout = timeoutFlag ? 30 : null + } + ) + + return [ + { + type: 'switch', + field: 'timeoutShowFlag', + name: t('project.node.timeout_alarm') + }, + { + type: 'switch', + field: 'timeoutFlag', + name: t('project.node.waiting_dependent_complete'), + props: { + 'on-update:value': (value: boolean) => { + model.timeoutNotifyStrategy = value ? ['WARN'] : null + model.timeout = value ? 30 : null + } + }, + span: timeCompleteSpan + }, + { + type: 'input-number', + field: 'timeout', + name: t('project.node.timeout_period'), + span: timeCompleteEnableSpan, + props: { + max: Math.pow(9, 10) - 1 + }, + slots: { + suffix: () => t('project.node.minute') + }, + validate: { + trigger: ['input'], + validator(validate: any, value: number) { + if (model.timeoutFlag && !/^[1-9]\d*$/.test(String(value))) { + return new Error(t('project.node.timeout_period_tips')) + } + } + } + }, + { + type: 'checkbox', + field: 'timeoutNotifyStrategy', + name: t('project.node.timeout_strategy'), + options: strategyOptions, + span: timeCompleteEnableSpan, + validate: { + trigger: ['input'], + validator(validate: any, value: []) { + if (model.waitCompleteTimeoutEnable && !value.length) { + return new Error(t('project.node.timeout_strategy_tips')) + } + } + } + } + ] +} diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-dependent.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-dependent.ts new file mode 100644 index 000000000..74df0bceb --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-dependent.ts @@ -0,0 +1,318 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ref, onMounted, watch } from 'vue' +import { useI18n } from 'vue-i18n' +import { useRelationCustomParams, useDependentTimeout } from '.' +import { queryProjectCreatedAndAuthorizedByUser } from '@/service/modules/projects' +import { + queryAllByProjectCode, + getTasksByDefinitionCode +} from '@/service/modules/process-definition' +import type { IJsonItem, IDependpendItem, IDependTask } from '../types' + +export function useDependent(model: { [field: string]: any }): IJsonItem[] { + const { t } = useI18n() + const projectList = ref([] as { label: string; value: number }[]) + const processCache = {} as { + [key: number]: { label: string; value: number }[] + } + const taskCache = {} as { + [key: number]: { label: string; value: number }[] + } + + const CYCLE_LIST = [ + { + value: 'month', + label: t('project.node.month') + }, + { + value: 'week', + label: t('project.node.week') + }, + { + value: 'day', + label: t('project.node.day') + }, + { + value: 'hour', + label: t('project.node.hour') + } + ] + const DATE_LSIT = { + hour: [ + { + value: 'currentHour', + label: t('project.node.current_hour') + }, + { + value: 'last1Hour', + label: t('project.node.last_1_hour') + }, + { + value: 'last2Hours', + label: t('project.node.last_2_hour') + }, + { + value: 'last3Hours', + label: t('project.node.last_3_hour') + }, + { + value: 'last24Hours', + label: t('project.node.last_24_hour') + } + ], + day: [ + { + value: 'today', + label: t('project.node.today') + }, + { + value: 'last1Days', + label: t('project.node.last_1_days') + }, + { + value: 'last2Days', + label: t('project.node.last_2_days') + }, + { + value: 'last3Days', + label: t('project.node.last_3_days') + }, + { + value: 'last7Days', + label: t('project.node.last_7_days') + } + ], + week: [ + { + value: 'thisWeek', + label: t('project.node.this_week') + }, + { + value: 'lastWeek', + label: t('project.node.last_week') + }, + { + value: 'lastMonday', + label: t('project.node.last_monday') + }, + { + value: 'lastTuesday', + label: t('project.node.last_tuesday') + }, + { + value: 'lastWednesday', + label: t('project.node.last_wednesday') + }, + { + value: 'lastThursday', + label: t('project.node.last_thursday') + }, + { + value: 'lastFriday', + label: t('project.node.last_friday') + }, + { + value: 'lastSaturday', + label: t('project.node.last_saturday') + }, + { + value: 'lastSunday', + label: t('project.node.last_sunday') + } + ], + month: [ + { + value: 'thisMonth', + label: t('project.node.this_month') + }, + { + value: 'lastMonth', + label: t('project.node.last_month') + }, + { + value: 'lastMonthBegin', + label: t('project.node.last_month_begin') + }, + { + value: 'lastMonthEnd', + label: t('project.node.last_month_end') + } + ] + } + + const getProjectList = async () => { + try { + const result = await queryProjectCreatedAndAuthorizedByUser() + projectList.value = result.map( + (item: { code: number; name: string }) => ({ + value: item.code, + label: item.name + }) + ) + return projectList + } catch (err) {} + } + const getProcessList = async (code: number) => { + if (processCache[code]) { + return processCache[code] + } + try { + const result = await queryAllByProjectCode(code) + const processList = result.map( + (item: { processDefinition: { code: number; name: string } }) => ({ + value: item.processDefinition.code, + label: item.processDefinition.name + }) + ) + processCache[code] = processList + + return processList + } catch (err) {} + } + + const getTaskList = async (code: number, processCode: number) => { + if (taskCache[processCode]) { + return taskCache[processCode] + } + try { + const result = await getTasksByDefinitionCode(code, processCode) + const taskList = result.map((item: { code: number; name: string }) => ({ + value: item.code, + label: item.name + })) + taskList.unshift({ + value: 0, + label: 'ALL' + }) + taskCache[processCode] = taskList + return taskList + } catch (err) {} + } + + onMounted(() => { + getProjectList() + }) + + watch( + () => model.dependTaskList, + (value) => { + value.forEach((item: IDependTask) => { + if (!item.dependItemList?.length) return + + item.dependItemList?.forEach(async (dependItem: IDependpendItem) => { + if (dependItem.projectCode) { + dependItem.definitionCodeOptions = await getProcessList( + dependItem.projectCode + ) + } + if (dependItem.projectCode && dependItem.definitionCode) { + dependItem.depTaskCodeOptions = await getTaskList( + dependItem.projectCode, + dependItem.definitionCode + ) + } + console.log(dependItem) + if (dependItem.cycle) { + dependItem.dateOptions = DATE_LSIT[dependItem.cycle] + } + }) + }) + } + ) + + return [ + ...useDependentTimeout(model), + ...useRelationCustomParams({ + model, + children: (i: number = 0) => ({ + type: 'custom-parameters', + field: 'dependItemList', + span: 18, + children: [ + (j = 0) => ({ + type: 'select', + field: 'projectCode', + span: 12, + props: { + filterable: true, + onUpdateValue: async (projectCode: number) => { + const item = model.dependTaskList[i].dependItemList[j] + item.definitionCodeOptions = await getProcessList(projectCode) + item.depTaskCode = null + item.definitionCode = null + } + }, + options: projectList + }), + (j: number = 0) => ({ + type: 'select', + field: 'definitionCode', + span: 12, + props: { + filterable: true, + onUpdateValue: async (processCode: number) => { + const item = model.dependTaskList[i].dependItemList[j] + item.depTaskCodeOptions = await getTaskList( + item.projectCode, + processCode + ) + item.depTaskCode = 0 + } + }, + options: + model.dependTaskList[i]?.dependItemList[j] + ?.definitionCodeOptions || [] + }), + (j: number = 0) => ({ + type: 'select', + field: 'depTaskCode', + span: 12, + props: { + filterable: true + }, + options: + model.dependTaskList[i]?.dependItemList[j]?.depTaskCodeOptions || + [] + }), + (j: number = 0) => ({ + type: 'select', + field: 'cycle', + span: 12, + props: { + onUpdateValue: (value: 'month') => { + model.dependTaskList[i].dependItemList[j].dateOptions = + DATE_LSIT[value] + } + }, + options: CYCLE_LIST + }), + (j: number = 0) => ({ + type: 'select', + field: 'dateValue', + span: 12, + options: + model.dependTaskList[i]?.dependItemList[j]?.dateOptions || [] + }) + ] + }), + childrenField: 'dependItemList', + name: 'add_dependency' + }) + ] +} diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-relation-custom-params.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-relation-custom-params.ts index b7a2734c8..c194f83a6 100644 --- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-relation-custom-params.ts +++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-relation-custom-params.ts @@ -14,22 +14,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { computed, h, watchEffect } from 'vue' +import { computed, watchEffect } from 'vue' import { useI18n } from 'vue-i18n' -import { NButton } from 'naive-ui' import styles from '../index.module.scss' import type { IJsonItem } from '../types' export function useRelationCustomParams({ model, children, - childrenField + childrenField, + name }: { model: { [field: string]: any } children: IJsonItem childrenField: string + name: string }): IJsonItem[] { const { t } = useI18n() const firstLevelRelationSpan = computed(() => @@ -48,7 +49,7 @@ export function useRelationCustomParams({ return [ { type: 'custom', - name: t('project.node.custom_parameters'), + name: t(`project.node.${name}`), field: 'relationLabel', span: 24, class: styles['relaction-label'] diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-timeout-alarm.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-timeout-alarm.ts index f87e54efd..a927152c7 100644 --- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-timeout-alarm.ts +++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-timeout-alarm.ts @@ -36,8 +36,8 @@ export function useTimeoutAlarm(model: { [field: string]: any }): IJsonItem[] { watch( () => model.timeoutFlag, (timeoutFlag) => { - model.strategy = timeoutFlag ? ['WARN'] : [] - model.interval = timeoutFlag ? 30 : null + model.timeoutNotifyStrategy = timeoutFlag ? ['WARN'] : [] + model.timeout = timeoutFlag ? 30 : null } ) @@ -60,8 +60,7 @@ export function useTimeoutAlarm(model: { [field: string]: any }): IJsonItem[] { return new Error(t('project.node.timeout_strategy_tips')) } } - }, - value: ['WARN'] + } }, { type: 'input-number', @@ -81,8 +80,7 @@ export function useTimeoutAlarm(model: { [field: string]: any }): IJsonItem[] { return new Error(t('project.node.timeout_period_tips')) } } - }, - value: 30 + } } ] } 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 a270c94ff..91e4d88d2 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 @@ -15,14 +15,15 @@ * limitations under the License. */ -import { find, omit } from 'lodash' +import { find, omit, cloneDeep } from 'lodash' import type { INodeData, ITaskData, ITaskParams, ISqoopTargetParams, ISqoopSourceParams, - ILocalParam + ILocalParam, + IDependTask } from './types' export function formatParams(data: INodeData): { @@ -228,6 +229,24 @@ export function formatParams(data: INodeData): { taskParams.xms = data.xms taskParams.xmx = data.xmx } + if (data.taskType === 'DEPENDENT') { + const dependTaskList = cloneDeep(data.dependTaskList)?.map( + (taskItem: IDependTask) => { + if (taskItem.dependItemList?.length) { + taskItem.dependItemList.forEach((dependItem) => { + delete dependItem.definitionCodeOptions + delete dependItem.depTaskCodeOptions + delete dependItem.dateOptions + }) + } + return taskItem + } + ) + taskParams.dependence = { + relation: data.relation, + dependTaskList: dependTaskList + } + } const params = { processDefinitionCode: data.processName ? String(data.processName) : '', diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-conditions.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-conditions.ts index cccfa3099..d3810f0e2 100644 --- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-conditions.ts +++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-conditions.ts @@ -15,8 +15,7 @@ * limitations under the License. */ -import { ref, reactive, watch } from 'vue' -import { useI18n } from 'vue-i18n' +import { reactive, watch } from 'vue' import * as Fields from '../fields/index' import type { IJsonItem, INodeData, ITaskData } from '../types' @@ -31,8 +30,6 @@ export function useConditions({ readonly?: boolean data?: ITaskData }) { - const { t } = useI18n() - const taskCodeOptions = ref([] as { label: string; value: number }[]) const model = reactive({ taskType: 'CONDITIONS', name: '', @@ -44,11 +41,12 @@ export function useConditions({ failRetryInterval: 1, failRetryTimes: 0, workerGroup: 'default', - delayTime: 0, timeout: 30, relation: 'AND', dependTaskList: [], - preTasks: [] + preTasks: [], + successNode: 'success', + failedNode: 'failed' } as INodeData) let extra: IJsonItem[] = [] @@ -66,21 +64,6 @@ export function useConditions({ ] } - watch( - () => model.preTasks, - () => { - taskCodeOptions.value = - model.preTaskOptions - ?.filter((task: { code: number }) => - model.preTasks?.includes(task.code) - ) - .map((task: { code: number; name: string }) => ({ - value: task.code, - label: task.name - })) || [] - } - ) - return { json: [ Fields.useName(), @@ -92,40 +75,7 @@ export function useConditions({ Fields.useEnvironmentName(model, !data?.id), ...Fields.useTaskGroup(model, projectCode), ...Fields.useFailed(), - Fields.useDelayTime(model), - ...Fields.useTimeoutAlarm(model), - ...Fields.useRelationCustomParams({ - model, - children: { - type: 'custom-parameters', - field: 'dependItemList', - span: 18, - children: [ - { - type: 'select', - field: 'depTaskCode', - span: 10, - options: taskCodeOptions - }, - { - type: 'select', - field: 'status', - span: 10, - options: [ - { - value: 'SUCCESS', - label: t('project.node.success') - }, - { - value: 'FAILURE', - label: t('project.node.failed') - } - ] - } - ] - }, - childrenField: 'dependItemList' - }), + ...Fields.useConditions(model), Fields.usePreTasks(model) ] as IJsonItem[], model diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-dependent.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-dependent.ts new file mode 100644 index 000000000..b5ef6eb1c --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-dependent.ts @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ref, reactive, watch } from 'vue' +import * as Fields from '../fields/index' +import type { IJsonItem, INodeData, ITaskData } from '../types' + +export function useDependent({ + projectCode, + from = 0, + readonly, + data +}: { + projectCode: number + from?: number + readonly?: boolean + data?: ITaskData +}) { + const taskCodeOptions = ref([] as { label: string; value: number }[]) + const model = reactive({ + taskType: 'DEPENDENT', + name: '', + flag: 'YES', + description: '', + timeoutShowFlag: false, + localParams: [], + environmentCode: null, + failRetryInterval: 1, + failRetryTimes: 0, + workerGroup: 'default', + delayTime: 0, + relation: 'AND', + dependTaskList: [], + preTasks: [], + timeoutNotifyStrategy: [], + timeout: 30, + timeoutFlag: false, + ...data + } as INodeData) + + let extra: IJsonItem[] = [] + if (from === 1) { + extra = [ + Fields.useTaskType(model, readonly), + Fields.useProcessName({ + model, + projectCode, + isCreate: !data?.id, + from, + processName: data?.processName, + code: data?.code + }) + ] + } + + watch( + () => model.preTasks, + () => { + taskCodeOptions.value = + model.preTaskOptions + ?.filter((task: { code: number }) => + model.preTasks?.includes(task.code) + ) + .map((task: { code: number; name: string }) => ({ + value: task.code, + label: task.name + })) || [] + } + ) + + return { + json: [ + Fields.useName(), + ...extra, + Fields.useRunFlag(), + Fields.useDescription(), + Fields.useTaskPriority(), + Fields.useWorkerGroup(), + Fields.useEnvironmentName(model, !data?.id), + ...Fields.useTaskGroup(model, projectCode), + ...Fields.useFailed(), + ...Fields.useDependent(model), + Fields.usePreTasks(model) + ] as IJsonItem[], + model + } +} 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 fefec0339..e5af6a426 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 @@ -36,13 +36,14 @@ export function useShell({ flag: 'YES', description: '', timeoutFlag: false, + timeoutNotifyStrategy: ['WARN'], + timeout: 30, localParams: [], environmentCode: null, failRetryInterval: 1, failRetryTimes: 0, workerGroup: 'default', delayTime: 0, - timeout: 30, rawScript: '' } as INodeData) 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 d508c518e..2e89b4579 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 @@ -49,11 +49,23 @@ interface ILocalParam { value?: string } +interface IDependpendItem { + depTaskCode?: number + status?: 'SUCCESS' | 'FAILURE' + definitionCodeOptions?: IOption[] + depTaskCodeOptions?: IOption[] + dateOptions?: IOption[] + projectCode?: number + definitionCode?: number + cycle?: 'month' | 'week' | 'day' | 'hour' + dateValue?: string +} + interface IDependTask { condition?: string nextNode?: number relation?: RelationType - dependItemList?: { depTaskCode?: number; status?: 'SUCCESS' | 'FAILURE' }[] + dependItemList?: IDependpendItem[] } interface ISwitchResult { @@ -289,5 +301,7 @@ export { ModelType, SourceType, ISqoopSourceParams, - ISqoopTargetParams + ISqoopTargetParams, + IDependTask, + IDependpendItem } 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 3531ea8da..d23fbabf1 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 @@ -30,6 +30,7 @@ import { useSeaTunnel } from './tasks/use-sea-tunnel' import { useSwitch } from './tasks/use-switch' import { useConditions } from './tasks/use-conditions' import { useDataX } from './tasks/use-datax' +import { useDependent } from './tasks/use-dependent' import { IJsonItem, INodeData, ITaskData } from './types' export function useTask({ @@ -168,6 +169,14 @@ export function useTask({ data }) } + if (taskType === 'DEPENDENT') { + node = useDependent({ + projectCode, + from, + readonly, + data + }) + } return node } 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 69e64cade..9f3da28b9 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 @@ -15,7 +15,7 @@ * limitations under the License. */ -import { reactive } from 'vue' +import { reactive, onMounted } from 'vue' import { genTaskCodeList, saveSingle, @@ -27,7 +27,7 @@ import type { ITaskData, INodeData, ISingleSaveReq, IRecord } from './types' export function useTask(projectCode: number) { const initalTask = { - taskType: 'SHELL' + taskType: 'DEPENDENT' } as ITaskData const task = reactive({ taskShow: false, diff --git a/dolphinscheduler-ui-next/src/views/security/alarm-instance-manage/detail.tsx b/dolphinscheduler-ui-next/src/views/security/alarm-instance-manage/detail.tsx index 056c4ef9e..64ecafdc3 100644 --- a/dolphinscheduler-ui-next/src/views/security/alarm-instance-manage/detail.tsx +++ b/dolphinscheduler-ui-next/src/views/security/alarm-instance-manage/detail.tsx @@ -25,6 +25,7 @@ import { Ref } from 'vue' import { NSelect, NInput } from 'naive-ui' +import { isFunction } from 'lodash' import Modal from '@/components/modal' import Form from '@/components/form' import { useI18n } from 'vue-i18n' @@ -97,7 +98,10 @@ const DetailModal = defineComponent({ () => { if (!state.json?.length) return state.json.forEach((item) => { - item.name = t('security.alarm_instance' + '.' + item.field) + const mergedItem = isFunction(item) ? item() : item + mergedItem.name = t( + 'security.alarm_instance' + '.' + mergedItem.field + ) }) const { rules: fieldsRules, elements: fieldsElements } = getElementByJson(state.json, state.detailForm) diff --git a/dolphinscheduler-ui-next/src/views/security/alarm-instance-manage/use-detail.ts b/dolphinscheduler-ui-next/src/views/security/alarm-instance-manage/use-detail.ts index 05efe4818..a42ca954e 100644 --- a/dolphinscheduler-ui-next/src/views/security/alarm-instance-manage/use-detail.ts +++ b/dolphinscheduler-ui-next/src/views/security/alarm-instance-manage/use-detail.ts @@ -16,6 +16,7 @@ */ import { reactive } from 'vue' +import { isFunction } from 'lodash' import { createAlertPluginInstance, updateAlertPluginInstance, @@ -34,7 +35,8 @@ export function useDetail(getFormValues: Function) { values: { [field: string]: any } = {} ): string => { json?.forEach((item) => { - item.value = values[item.field] + const mergedItem = isFunction(item) ? item() : item + mergedItem.value = values[mergedItem.field] }) return JSON.stringify(json) } -- GitLab