diff --git a/dolphinscheduler-ui-next/src/components/form/fields/checkbox.ts b/dolphinscheduler-ui-next/src/components/form/fields/checkbox.ts new file mode 100644 index 000000000..bfb405dda --- /dev/null +++ b/dolphinscheduler-ui-next/src/components/form/fields/checkbox.ts @@ -0,0 +1,45 @@ +/* + * 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 { h } from 'vue' +import { NCheckbox, NCheckboxGroup, NSpace } from 'naive-ui' +import type { IJsonItem } from '../types' + +export function renderCheckbox( + item: IJsonItem, + fields: { [field: string]: any } +) { + const { props, field, options } = item + if (!options || options.length === 0) { + return h(NCheckbox, { + ...props, + value: fields[field], + onUpdateChecked: (checked: boolean) => void (fields[field] = checked) + }) + } + return h( + NCheckboxGroup, + { + value: fields[field], + onUpdateValue: (value) => void (fields[field] = value) + }, + () => + h(NSpace, null, () => + options.map((option: object) => h(NCheckbox, { ...option })) + ) + ) +} 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 40b290148..f28a7007c 100644 --- a/dolphinscheduler-ui-next/src/components/form/fields/custom-parameters.ts +++ b/dolphinscheduler-ui-next/src/components/form/fields/custom-parameters.ts @@ -15,13 +15,48 @@ * limitations under the License. */ -import { h } from 'vue' -import { NFormItem, NSpace, NButton, NIcon } from 'naive-ui' +import { defineComponent, h, renderSlot } from 'vue' +import { useFormItem } from 'naive-ui/es/_mixins' +import { NFormItemGi, NSpace, NButton, NIcon, NGrid } from 'naive-ui' import { PlusCircleOutlined, DeleteOutlined } from '@vicons/antd' +import { omit } from 'lodash' import getField from './get-field' import { formatValidate } from '../utils' import type { IJsonItem, FormItemRule } from '../types' +const CustomParameters = defineComponent({ + name: 'CustomParameters', + emits: ['add'], + setup(props, ctx) { + const formItem = useFormItem({}) + + const onAdd = () => void ctx.emit('add') + + return { onAdd, disabled: formItem.mergedDisabledRef } + }, + render() { + const { disabled, $slots, onAdd } = this + return h(NSpace, null, { + default: () => { + return [ + renderSlot($slots, 'default', { disabled }), + h( + NButton, + { + tertiary: true, + circle: true, + type: 'info', + disabled, + onClick: onAdd + }, + () => h(NIcon, { size: 24 }, () => h(PlusCircleOutlined)) + ) + ] + } + }) + } +}) + export function renderCustomParameters( item: IJsonItem, fields: { [field: string]: any }, @@ -30,6 +65,7 @@ export function renderCustomParameters( const { field, children = [] } = item let defaultValue: { [field: string]: any } = {} let ruleItem: { [key: string]: FormItemRule } = {} + children.forEach((child) => { defaultValue[child.field] = child.value || null if (child.validate) ruleItem[child.field] = formatValidate(child.validate) @@ -37,18 +73,19 @@ export function renderCustomParameters( const getChild = (item: object, i: number) => children.map((child: IJsonItem) => { return h( - NFormItem, + NFormItemGi, { showLabel: false, - path: `${field}[${i}].${child.field}` + ...omit(item, ['field', 'type', 'props', 'options']), + path: `${field}[${i}].${child.field}`, + span: 6 }, () => getField(child, item) ) }) - - const getChildren = () => + const getChildren = ({ disabled }: { disabled: boolean }) => fields[field].map((item: object, i: number) => { - return h(NSpace, { ':key': i }, () => [ + return h(NGrid, { xGap: 10 }, () => [ ...getChild(item, i), h( NButton, @@ -56,6 +93,7 @@ export function renderCustomParameters( tertiary: true, circle: true, type: 'error', + disabled, onClick: () => { fields[field].splice(i, 1) rules.splice(i, 1) @@ -66,20 +104,16 @@ export function renderCustomParameters( ]) }) - return h(NSpace, null, () => [ - ...getChildren(), - h( - NButton, - { - tertiary: true, - circle: true, - type: 'info', - onClick: () => { - rules.push(ruleItem) - fields[field].push({ ...defaultValue }) - } - }, - () => h(NIcon, { size: 24 }, () => h(PlusCircleOutlined)) - ) - ]) + return h( + CustomParameters, + { + onAdd: () => { + rules.push(ruleItem) + fields[field].push({ ...defaultValue }) + } + }, + { + default: getChildren + } + ) } diff --git a/dolphinscheduler-ui-next/src/components/form/fields/index.ts b/dolphinscheduler-ui-next/src/components/form/fields/index.ts index 75b71a46f..82ca19d28 100644 --- a/dolphinscheduler-ui-next/src/components/form/fields/index.ts +++ b/dolphinscheduler-ui-next/src/components/form/fields/index.ts @@ -22,3 +22,5 @@ export { renderCustomParameters } from './custom-parameters' export { renderSwitch } from './switch' export { renderInputNumber } from './input-number' export { renderSelect } from './select' +export { renderCheckbox } from './checkbox' +export { renderTreeSelect } from './tree-select' 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 be05f5c5a..6a7833af0 100644 --- a/dolphinscheduler-ui-next/src/components/form/fields/input-number.ts +++ b/dolphinscheduler-ui-next/src/components/form/fields/input-number.ts @@ -23,11 +23,17 @@ export function renderInputNumber( item: IJsonItem, fields: { [field: string]: any } ) { - const { props, field } = item + const { props, field, slots = {} } = item - return h(NInputNumber, { - ...props, - value: fields[field], - onUpdateValue: (value) => void (fields[field] = value) - }) + return h( + NInputNumber, + { + ...props, + value: fields[field], + onUpdateValue: (value) => void (fields[field] = value) + }, + { + ...slots + } + ) } diff --git a/dolphinscheduler-ui-next/src/components/form/fields/tree-select.ts b/dolphinscheduler-ui-next/src/components/form/fields/tree-select.ts new file mode 100644 index 000000000..fec6df50b --- /dev/null +++ b/dolphinscheduler-ui-next/src/components/form/fields/tree-select.ts @@ -0,0 +1,33 @@ +/* + * 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 { h } from 'vue' +import { NTreeSelect } from 'naive-ui' +import type { IJsonItem } from '../types' + +export function renderTreeSelect( + item: IJsonItem, + fields: { [field: string]: any } +) { + const { props = {}, field, options = [] } = item + return h(NTreeSelect, { + ...props, + value: fields[field], + onUpdateValue: (value) => void (fields[field] = value), + 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 d2df03195..71f2b81fb 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 @@ -15,6 +15,7 @@ * limitations under the License. */ +import { toRef } from 'vue' import { formatValidate } from './utils' import getField from './fields/get-field' import { omit } from 'lodash' @@ -29,18 +30,20 @@ export default function getElementByJson( const initialValues: { [field: string]: any } = {} const elements = [] for (let item of json) { - const { name, value, field, children, validate, ...rest } = item - if (value) { + const { name, value, field, span, children, validate, ...rest } = item + if (value || value === 0) { fields[field] = value initialValues[field] = value } if (validate) rules[field] = formatValidate(validate) + const spanRef = span === void 0 ? 24 : toRef(item, 'span') elements.push({ showLabel: !!name, ...omit(rest, ['type', 'props', 'options']), label: name, path: !children ? field : '', - widget: () => getField(item, fields, rules) + widget: () => getField(item, fields, rules), + span: spanRef }) } return { rules, elements, initialValues } diff --git a/dolphinscheduler-ui-next/src/components/form/index.tsx b/dolphinscheduler-ui-next/src/components/form/index.tsx index 12e77e0be..68fd8b54d 100644 --- a/dolphinscheduler-ui-next/src/components/form/index.tsx +++ b/dolphinscheduler-ui-next/src/components/form/index.tsx @@ -15,7 +15,7 @@ * limitations under the License. */ -import { defineComponent, PropType, toRefs, h } from 'vue' +import { defineComponent, PropType, toRefs, h, toRef, isRef } from 'vue' import { NSpin, NGrid, NForm, NFormItemGi } from 'naive-ui' import { useForm } from './use-form' import type { GridProps, IMeta } from './types' @@ -55,7 +55,11 @@ const Form = defineComponent({ {elements.map((element) => { const { span = 24, path, widget, ...formItemProps } = element return ( - + {h(widget)} ) diff --git a/dolphinscheduler-ui-next/src/components/form/types.ts b/dolphinscheduler-ui-next/src/components/form/types.ts index 26e928c4b..e47b79aab 100644 --- a/dolphinscheduler-ui-next/src/components/form/types.ts +++ b/dolphinscheduler-ui-next/src/components/form/types.ts @@ -14,14 +14,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +import { Ref } from 'vue' import type { GridProps, FormProps, FormItemGiProps, FormItemRule, FormRules, - SelectOption + SelectOption, + TreeSelectOption } from 'naive-ui' type IType = @@ -32,11 +33,16 @@ type IType = | 'switch' | 'input-number' | 'select' + | 'checkbox' + | 'tree-select' -type IOption = SelectOption +interface IOption extends SelectOption, TreeSelectOption { + label: string +} -interface IFormItem extends FormItemGiProps { +interface IFormItem extends Omit { widget: any + span?: any } interface IMeta extends Omit { @@ -54,6 +60,8 @@ interface IJsonItem { value?: any options?: IOption[] children?: IJsonItem[] + slots?: object + span?: number | Ref } export { diff --git a/dolphinscheduler-ui-next/src/components/modal/index.module.scss b/dolphinscheduler-ui-next/src/components/modal/index.module.scss index 8044aa247..a47563d5e 100644 --- a/dolphinscheduler-ui-next/src/components/modal/index.module.scss +++ b/dolphinscheduler-ui-next/src/components/modal/index.module.scss @@ -18,3 +18,6 @@ .container { width: 600px; } +.modal-card { + max-height: 100vh; +} diff --git a/dolphinscheduler-ui-next/src/components/modal/index.tsx b/dolphinscheduler-ui-next/src/components/modal/index.tsx index a5e2769f1..9c2b979d8 100644 --- a/dolphinscheduler-ui-next/src/components/modal/index.tsx +++ b/dolphinscheduler-ui-next/src/components/modal/index.tsx @@ -81,7 +81,11 @@ const Modal = defineComponent({ mask-closable={false} auto-focus={this.autoFocus} > - + {{ default: () => renderSlot($slots, 'default'), footer: () => ( diff --git a/dolphinscheduler-ui-next/src/components/monaco-editor/index.tsx b/dolphinscheduler-ui-next/src/components/monaco-editor/index.tsx index a0f21c307..b9d166b2b 100644 --- a/dolphinscheduler-ui-next/src/components/monaco-editor/index.tsx +++ b/dolphinscheduler-ui-next/src/components/monaco-editor/index.tsx @@ -98,17 +98,30 @@ export default defineComponent({ } } ) + watch( + () => formItem.mergedDisabledRef.value, + (value) => { + editor?.updateOptions({ readOnly: value }) + } + ) onMounted(async () => { await nextTick() const dom = editorRef.value if (dom) { - editor = monaco.editor.create(dom, props.options, { - value: props.defaultValue ?? props.value, - language: props.language, - readOnly: props.readOnly, - automaticLayout: true - }) + editor = monaco.editor.create( + dom, + { + ...props.options, + readOnly: + formItem.mergedDisabledRef.value || props.options?.readOnly + }, + { + value: props.defaultValue ?? props.value, + language: props.language, + automaticLayout: true + } + ) editor.onDidChangeModelContent(() => { const { onUpdateValue, 'onUpdate:value': _onUpdateValue } = props const value = editor?.getValue() || '' diff --git a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts index 1bd8caae0..ddf0067c8 100644 --- a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts +++ b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts @@ -497,6 +497,67 @@ const project = { rows: 'Rows', cols: 'Cols', copy_success: 'Copy Success' + }, + node: { + current_node_settings: 'Current node settings', + instructions: 'Instructions', + view_history: 'View history', + view_log: 'View log', + enter_this_child_node: 'Enter this child node', + name: 'Node name', + name_tips: 'Please enter name (required)', + task_type: 'Task Type', + task_type_tips: 'Please select a task type (required)', + process_name: 'Process Name', + run_flag: 'Run flag', + normal: 'Normal', + prohibition_execution: 'Prohibition execution', + description: 'Description', + description_tips: 'Please enter description', + task_priority: 'Task priority', + worker_group: 'Worker group', + worker_group_tips: + 'The Worker group no longer exists, please select the correct Worker group!', + environment_name: 'Environment Name', + task_group_name: 'Task group name', + task_group_queue_priority: 'Priority', + number_of_failed_retries: 'Number of failed retries', + times: 'Times', + failed_retry_interval: 'Failed retry interval', + minute: 'Minute', + delay_execution_time: 'Delay execution time', + state: 'State', + branch_flow: 'Branch flow', + cancel: 'Cancel', + loading: 'Loading...', + confirm: 'Confirm', + success: 'Success', + failed: 'Failed', + backfill_tips: + 'The newly created sub-Process has not yet been executed and cannot enter the sub-Process', + task_instance_tips: + 'The task has not been executed and cannot enter the sub-Process', + branch_tips: + 'Cannot select the same node for successful branch flow and failed branch flow', + timeout_alarm: 'Timeout alarm', + timeout_strategy: 'Timeout strategy', + timeout_strategy_tips: 'Timeout strategy must be selected', + timeout_failure: 'Timeout failure', + timeout_period: 'Timeout period', + timeout_period_tips: 'Timeout must be a positive integer', + script: 'Script', + script_tips: 'Please enter script(required)', + resources: 'Resources', + resources_tips: 'Please select resources', + non_resources_tips: 'Please delete all non-existent resources', + useless_resources_tips: 'Unauthorized or deleted resources', + custom_parameters: 'Custom Parameters', + copy_success: 'Copy success', + copy_failed: 'The browser does not support automatic copying', + prop_tips: 'prop(required)', + prop_repeat: 'prop is repeat', + value_tips: 'value(optional)', + pre_tasks: 'Pre tasks' } } diff --git a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts index 00cefaa46..e8e42a666 100644 --- a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts +++ b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts @@ -496,6 +496,62 @@ const project = { rows: '行数', cols: '列数', copy_success: '复制成功' + }, + node: { + current_node_settings: '当前节点设置', + instructions: '使用说明', + view_history: '查看历史', + view_log: '查看日志', + enter_this_child_node: '进入该子节点', + name: '节点名称', + name_tips: '请输入名称(必填)', + task_type: '任务类型', + task_type_tips: '请选择任务类型(必选)', + process_name: '工作流名称', + run_flag: '运行标志', + normal: '正常', + prohibition_execution: '禁止执行', + description: '描述', + description_tips: '请输入描述', + task_priority: '任务优先级', + worker_group: 'Worker分组', + worker_group_tips: '该Worker分组已经不存在,请选择正确的Worker分组!', + environment_name: '环境名称', + task_group_name: '任务组名称', + task_group_queue_priority: '组内优先级', + number_of_failed_retries: '失败重试次数', + times: '次', + failed_retry_interval: '失败重试间隔', + minute: '分', + delay_execution_time: '延时执行时间', + state: '状态', + branch_flow: '分支流转', + cancel: '取消', + loading: '正在努力加载中...', + confirm: '确定', + success: '成功', + failed: '失败', + backfill_tips: '新创建子工作流还未执行,不能进入子工作流', + task_instance_tips: '该任务还未执行,不能进入子工作流', + branch_tips: '成功分支流转和失败分支流转不能选择同一个节点', + timeout_alarm: '超时告警', + timeout_strategy: '超时策略', + timeout_strategy_tips: '超时策略必须选一个', + timeout_failure: '超时失败', + timeout_period: '超时时长', + timeout_period_tips: '超时时长必须为正整数', + script: '脚本', + script_tips: '请输入脚本(必填)', + resources: '资源', + resources_tips: '请选择资源', + no_resources_tips: '请删除所有未授权或已删除资源', + useless_resources_tips: '未授权或已删除资源', + custom_parameters: '自定义参数', + copy_failed: '该浏览器不支持自动复制', + prop_tips: 'prop(必填)', + prop_repeat: 'prop中有重复', + value_tips: 'value(选填)', + pre_tasks: '前置任务' } } diff --git a/dolphinscheduler-ui-next/src/service/modules/task-group/types.ts b/dolphinscheduler-ui-next/src/service/modules/task-group/types.ts index bdda4df35..984c33bd0 100644 --- a/dolphinscheduler-ui-next/src/service/modules/task-group/types.ts +++ b/dolphinscheduler-ui-next/src/service/modules/task-group/types.ts @@ -18,7 +18,7 @@ interface ListReq { pageNo: number pageSize: number - searchVal?: string + projectCode?: number } interface TaskGroupIdReq { diff --git a/dolphinscheduler-ui-next/src/views/projects/node/detail-modal.tsx b/dolphinscheduler-ui-next/src/views/projects/node/detail-modal.tsx new file mode 100644 index 000000000..b1c38e504 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/detail-modal.tsx @@ -0,0 +1,81 @@ +/* + * 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 { defineComponent, PropType, ref } from 'vue' +import { useI18n } from 'vue-i18n' +import Modal from '@/components/modal' +import Detail from './detail' +import type { IDataNode, ITask } from './types' + +const props = { + show: { + type: Boolean as PropType, + default: false + }, + nodeData: { + type: Object as PropType, + default: { + taskType: 'SHELL' + } + }, + type: { + type: String as PropType, + default: '' + }, + taskDefinition: { + type: Object as PropType + } +} + +const NodeDetailModal = defineComponent({ + name: 'NodeDetailModal', + props, + emits: ['cancel', 'update'], + setup(props, { emit }) { + const { t } = useI18n() + const detailRef = ref() + const onConfirm = () => { + detailRef.value.onSubmit() + } + const onCancel = () => { + emit('cancel') + } + + return { + t, + detailRef, + onConfirm, + onCancel + } + }, + render() { + const { t, show, onConfirm, onCancel } = this + return ( + void onCancel()} + > + + + ) + } +}) + +export default NodeDetailModal diff --git a/dolphinscheduler-ui-next/src/views/projects/node/detail.tsx b/dolphinscheduler-ui-next/src/views/projects/node/detail.tsx new file mode 100644 index 000000000..0ced92b5d --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/detail.tsx @@ -0,0 +1,73 @@ +/* + * 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 { defineComponent, PropType, ref, toRefs } from 'vue' +import Form from '@/components/form' +import { useTask } from './use-task' +import { useDetail } from './use-detail' +import type { ITaskType } from './types' +import getElementByJson from '@/components/form/get-elements-by-json' + +const props = { + projectCode: { + type: Number as PropType + }, + taskType: { + type: String as PropType, + default: 'SHELL', + required: true + } +} + +const NodeDetail = defineComponent({ + name: 'NodeDetail', + props, + setup(props, { expose }) { + const { taskType, projectCode } = props + + const { json, model } = useTask({ taskType, projectCode }) + const { state, onSubmit } = useDetail() + + const jsonRef = ref(json) + + const { rules, elements } = getElementByJson(jsonRef.value, model) + + expose({ + onSubmit: () => void onSubmit(model) + }) + + return { rules, elements, model, ...toRefs(state) } + }, + render() { + const { rules, elements, model } = this + return ( +
+ ) + } +}) + +export default NodeDetail diff --git a/dolphinscheduler-ui-next/src/views/projects/node/fields/index.ts b/dolphinscheduler-ui-next/src/views/projects/node/fields/index.ts new file mode 100644 index 000000000..fee5719bc --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/fields/index.ts @@ -0,0 +1,29 @@ +/* + * 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. + */ + +export { useName } from './use-name' +export { useRunFlag } from './use-run-flag' +export { useDescription } from './use-description' +export { useTaskPriority } from './use-task-priority' +export { useWorkerGroup } from './use-worker-group' +export { useEnvironmentName } from './use-environment-name' +export { useTaskGroup } from './use-task-group' +export { useFailed } from './use-failed' +export { useDelayTime } from './use-delay-time' +export { useTimeoutAlarm } from './use-timeout-alarm' +export { usePreTasks } from './use-pre-tasks' +export { useShell } from './use-shell' diff --git a/dolphinscheduler-ui-next/src/views/projects/node/fields/use-delay-time.ts b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-delay-time.ts new file mode 100644 index 000000000..5189d8107 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-delay-time.ts @@ -0,0 +1,31 @@ +/* + * 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 { useI18n } from 'vue-i18n' + +export function useDelayTime() { + const { t } = useI18n() + return { + type: 'input-number', + field: 'delayTime', + name: t('project.node.delay_execution_time'), + span: 12, + slots: { + suffix: () => t('project.node.minute') + } + } +} diff --git a/dolphinscheduler-ui-next/src/views/projects/node/fields/use-description.ts b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-description.ts new file mode 100644 index 000000000..42edd9151 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-description.ts @@ -0,0 +1,32 @@ +/* + * 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 { useI18n } from 'vue-i18n' + +export function useDescription() { + const { t } = useI18n() + return { + type: 'input', + field: 'desc', + name: t('project.node.description'), + props: { + placeholder: t('project.node.description_tips'), + rows: 2, + type: 'textarea' + } + } +} diff --git a/dolphinscheduler-ui-next/src/views/projects/node/fields/use-environment-name.ts b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-environment-name.ts new file mode 100644 index 000000000..8786c9350 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-environment-name.ts @@ -0,0 +1,94 @@ +/* + * 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, onMounted, watch } from 'vue' +import { useI18n } from 'vue-i18n' +import { queryAllEnvironmentList } from '@/service/modules/environment' +import type { IEnvironmentNameOption } from '../types' + +export function useEnvironmentName( + model: { [field: string]: any }, + isCreate: boolean +) { + const { t } = useI18n() + + let environmentList = [] as IEnvironmentNameOption[] + const options = ref([] as IEnvironmentNameOption[]) + const loading = ref(false) + const value = ref() + + const getEnvironmentList = async () => { + if (loading.value) return + loading.value = true + try { + const res = await queryAllEnvironmentList() + environmentList = res.map((item: { code: string; name: string }) => ({ + label: item.name, + value: item.code + })) + options.value = environmentList.filter((option: IEnvironmentNameOption) => + filterByWorkerGroup(option) + ) + loading.value = false + } catch (err) { + loading.value = false + } + } + + const filterByWorkerGroup = (option: IEnvironmentNameOption) => { + if (!model.workerGroup) return false + if (!option?.workerGroups?.length) return false + if (option.workerGroups.indexOf(model.workerGroup) === -1) return false + return true + } + + watch( + () => options.value.length, + () => { + if (isCreate && options.value.length === 1 && !value.value) { + model.environmentCode = options.value[0].value + } + if (options.value.length === 0) model.environmentCode = null + } + ) + + watch( + () => model.workerGroup, + () => { + if (!model.workerGroup) return + options.value = environmentList.filter((option: IEnvironmentNameOption) => + filterByWorkerGroup(option) + ) + } + ) + + onMounted(() => { + getEnvironmentList() + }) + + return { + type: 'select', + field: 'environmentCode', + span: 12, + name: t('project.node.environment_name'), + props: { + loading: loading, + clearable: true + }, + options: options + } +} diff --git a/dolphinscheduler-ui-next/src/views/projects/node/fields/use-failed.ts b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-failed.ts new file mode 100644 index 000000000..72f01cf8d --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-failed.ts @@ -0,0 +1,42 @@ +/* + * 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 { useI18n } from 'vue-i18n' + +export function useFailed() { + const { t } = useI18n() + return [ + { + type: 'input-number', + field: 'maxRetryTimes', + name: t('project.node.number_of_failed_retries'), + span: 12, + slots: { + suffix: () => t('project.node.times') + } + }, + { + type: 'input-number', + field: 'retryInterval', + name: t('project.node.failed_retry_interval'), + span: 12, + slots: { + suffix: () => t('project.node.minute') + } + } + ] +} diff --git a/dolphinscheduler-ui-next/src/views/projects/node/fields/use-name.ts b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-name.ts new file mode 100644 index 000000000..69f0fd424 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-name.ts @@ -0,0 +1,36 @@ +/* + * 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 { useI18n } from 'vue-i18n' + +export function useName() { + const { t } = useI18n() + return { + type: 'input', + field: 'name', + name: t('project.node.name'), + props: { + placeholder: t('project.node.name_tips'), + maxLength: 100 + }, + validate: { + trigger: ['input', 'blur'], + required: true, + message: t('project.node.name_tips') + } + } +} diff --git a/dolphinscheduler-ui-next/src/views/projects/node/fields/use-pre-tasks.ts b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-pre-tasks.ts new file mode 100644 index 000000000..d894c168f --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-pre-tasks.ts @@ -0,0 +1,41 @@ +/* + * 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 } from 'vue' +import { useI18n } from 'vue-i18n' + +export function usePreTasks() { + const { t } = useI18n() + + const options = ref([]) + const loading = ref(false) + + onMounted(() => {}) + + return { + type: 'select', + field: 'preTasks', + span: 24, + name: t('project.node.pre_tasks'), + props: { + loading, + multiple: true, + filterable: true + }, + options + } +} diff --git a/dolphinscheduler-ui-next/src/views/projects/node/fields/use-run-flag.ts b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-run-flag.ts new file mode 100644 index 000000000..23817b5b9 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-run-flag.ts @@ -0,0 +1,38 @@ +/* + * 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 { useI18n } from 'vue-i18n' + +export function useRunFlag() { + const { t } = useI18n() + const options = [ + { + label: t('project.node.normal'), + value: 'YES' + }, + { + label: t('project.node.prohibition_execution'), + value: 'NO' + } + ] + return { + type: 'radio', + field: 'runFlag', + name: t('project.node.run_flag'), + options: options + } +} diff --git a/dolphinscheduler-ui-next/src/views/projects/node/fields/use-shell.ts b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-shell.ts new file mode 100644 index 000000000..aeabded9b --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-shell.ts @@ -0,0 +1,191 @@ +/* + * 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 } from 'vue' +import { useI18n } from 'vue-i18n' +import { queryResourceList } from '@/service/modules/resources' + +export function useShell(model: { [field: string]: any }) { + const { t } = useI18n() + const options = ref([]) + + const loading = ref(false) + + const getResourceList = async () => { + if (loading.value) return + loading.value = true + try { + const res = await queryResourceList({ type: 'FILE' }) + removeUselessChildren(res) + options.value = res || [] + loading.value = false + } catch (err) { + loading.value = false + } + } + + onMounted(() => { + getResourceList() + }) + + return [ + { + type: 'editor', + field: 'shell', + name: t('project.node.script'), + validate: { + trigger: ['input', 'trigger'], + required: true, + message: t('project.node.script_tips') + } + }, + { + type: 'tree-select', + field: 'resourceList', + name: t('project.node.resources'), + options, + props: { + multiple: true, + checkable: true, + cascade: true, + showPath: true, + checkStrategy: 'child', + placeholder: t('project.node.resources_tips'), + keyField: 'id', + labelField: 'name', + loading + } + }, + { + type: 'custom-parameters', + field: 'localParams', + name: t('project.node.custom_parameters'), + children: [ + { + type: 'input', + field: 'prop', + span: 6, + props: { + placeholder: t('project.node.prop_tips'), + maxLength: 256 + }, + validate: { + trigger: ['input', 'blur'], + required: true, + validator(validate: any, value: string) { + if (!value) { + return new Error(t('project.node.prop_tips')) + } + + const sameItems = model.localParams.filter( + (item: { prop: string }) => item.prop === value + ) + + if (sameItems.length > 1) { + return new Error(t('project.node.prop_repeat')) + } + } + } + }, + { + type: 'select', + field: 'direct', + span: 4, + options: DIRECT_LIST, + value: 'IN' + }, + { + type: 'select', + field: 'type', + span: 6, + options: TYPE_LIST, + value: 'VARCHAR' + }, + { + type: 'input', + field: 'value', + span: 6, + props: { + placeholder: t('project.node.value_tips'), + maxLength: 256 + } + } + ] + } + ] +} + +function removeUselessChildren(list: { children?: [] }[]) { + if (!list.length) return + list.forEach((item) => { + if (!item.children) return + if (item.children.length === 0) { + delete item.children + return + } + removeUselessChildren(item.children) + }) +} + +export const TYPE_LIST = [ + { + value: 'VARCHAR', + label: 'VARCHAR' + }, + { + value: 'INTEGER', + label: 'INTEGER' + }, + { + value: 'LONG', + label: 'LONG' + }, + { + value: 'FLOAT', + label: 'FLOAT' + }, + { + value: 'DOUBLE', + label: 'DOUBLE' + }, + { + value: 'DATE', + label: 'DATE' + }, + { + value: 'TIME', + label: 'TIME' + }, + { + value: 'TIMESTAMP', + label: 'TIMESTAMP' + }, + { + value: 'BOOLEAN', + label: 'BOOLEAN' + } +] + +export const DIRECT_LIST = [ + { + value: 'IN', + label: 'IN' + }, + { + value: 'OUT', + label: 'OUT' + } +] diff --git a/dolphinscheduler-ui-next/src/views/projects/node/fields/use-task-group.ts b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-task-group.ts new file mode 100644 index 000000000..7ac0220e9 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-task-group.ts @@ -0,0 +1,85 @@ +/* + * 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, computed, onMounted } from 'vue' +import { useI18n } from 'vue-i18n' +import { queryTaskGroupListPagingByProjectCode } from '@/service/modules/task-group' + +export function useTaskGroup( + model: { [field: string]: any }, + projectCode: number +) { + const { t } = useI18n() + + const options = ref([]) + const loading = ref(false) + const priorityDisabled = computed(() => !model.taskGroupId) + + const getTaskGroupList = async () => { + if (loading.value) return + loading.value = true + try { + const { totalList = [] } = await queryTaskGroupListPagingByProjectCode({ + pageNo: 1, + pageSize: 2147483647, + projectCode + }) + options.value = totalList.map((item: { id: string; name: string }) => ({ + label: item.name, + value: item.id + })) + loading.value = false + } catch (err) { + loading.value = false + } + } + + onMounted(() => { + getTaskGroupList() + }) + + watch( + () => model.taskGroupId, + (taskGroupId) => { + if (!taskGroupId) model.taskGroupPriority = 0 + } + ) + + return [ + { + type: 'select', + field: 'taskGroupId', + span: 12, + name: t('project.node.task_group_name'), + props: { + loading + }, + options + }, + { + type: 'input-number', + field: 'taskGroupPriority', + name: t('project.node.task_group_queue_priority'), + props: { + max: Math.pow(10, 60) - 1, + disabled: priorityDisabled + }, + span: 12, + value: 0 + } + ] +} diff --git a/dolphinscheduler-ui-next/src/views/projects/node/fields/use-task-priority.ts b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-task-priority.ts new file mode 100644 index 000000000..134f16535 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-task-priority.ts @@ -0,0 +1,92 @@ +/* + * 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 { h, markRaw, VNode, VNodeChild } from 'vue' +import { NIcon } from 'naive-ui' +import { useI18n } from 'vue-i18n' +import { ArrowUpOutlined, ArrowDownOutlined } from '@vicons/antd' +import type { ITaskPriorityOption } from '../types' + +export function useTaskPriority() { + const { t } = useI18n() + const options = markRaw([ + { + label: 'HIGHEST', + value: 'HIGHEST', + icon: ArrowUpOutlined, + color: '#ff0000' + }, + { + label: 'HIGH', + value: 'HIGH', + icon: ArrowUpOutlined, + color: '#ff0000' + }, + { + label: 'MEDIUM', + value: 'MEDIUM', + icon: ArrowUpOutlined, + color: '#EA7D24' + }, + { + label: 'LOW', + value: 'LOW', + icon: ArrowDownOutlined, + color: '#2A8734' + }, + { + label: 'LOWEST', + value: 'LOWEST', + icon: ArrowDownOutlined, + color: '#2A8734' + } + ]) + const renderOption = ({ + node, + option + }: { + node: VNode + option: ITaskPriorityOption + }): VNodeChild => + h(node, null, { + default: () => [ + h( + NIcon, + { + color: option.color + }, + { + default: () => h(option.icon) + } + ), + option.label as string + ] + }) + return { + type: 'select', + field: 'taskInstancePriority', + name: t('project.node.task_priority'), + options, + validate: { + required: true + }, + props: { + renderOption + }, + value: 'MEDIUM' + } +} diff --git a/dolphinscheduler-ui-next/src/views/projects/node/fields/use-timeout-alarm.ts b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-timeout-alarm.ts new file mode 100644 index 000000000..a5a8d4a25 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-timeout-alarm.ts @@ -0,0 +1,86 @@ +/* + * 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' + +export function useTimeoutAlarm(model: { [field: string]: any }) { + const { t } = useI18n() + const span = computed(() => (model.enable ? 12 : 0)) + + const strategyOptions = [ + { + label: t('project.node.timeout_alarm'), + value: 'WARN' + }, + { + label: t('project.node.timeout_failure'), + value: 'FAILED' + } + ] + watch( + () => model.enable, + (enable) => { + model.strategy = enable ? ['WARN'] : [] + model.interval = enable ? 30 : null + } + ) + + return [ + { + type: 'switch', + field: 'enable', + name: t('project.node.timeout_alarm') + }, + { + type: 'checkbox', + field: 'strategy', + name: t('project.node.timeout_strategy'), + options: strategyOptions, + span: span, + validate: { + trigger: ['input'], + validator(validate: any, value: []) { + if (model.enable && !value.length) { + return new Error(t('project.node.timeout_strategy_tips')) + } + } + }, + value: ['WARN'] + }, + { + type: 'input-number', + field: 'interval', + name: t('project.node.timeout_period'), + span, + props: { + max: Math.pow(10, 10) - 1 + }, + slots: { + suffix: () => t('project.node.minute') + }, + validate: { + trigger: ['input'], + validator(validate: any, value: number) { + if (model.enable && !/^[1-9]\d*$/.test(String(value))) { + return new Error(t('project.node.timeout_period_tips')) + } + } + } + } + ] +} diff --git a/dolphinscheduler-ui-next/src/views/projects/node/fields/use-worker-group.ts b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-worker-group.ts new file mode 100644 index 000000000..698a219c4 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/fields/use-worker-group.ts @@ -0,0 +1,59 @@ +/* + * 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 } from 'vue' +import { useI18n } from 'vue-i18n' +import { queryAllWorkerGroups } from '@/service/modules/worker-groups' + +export function useWorkerGroup() { + const { t } = useI18n() + + const options = ref([] as { label: string; value: string }[]) + const loading = ref(false) + + const getWorkerGroups = async () => { + if (loading.value) return + loading.value = true + try { + const res = await queryAllWorkerGroups() + options.value = res.map((item: string) => ({ label: item, value: item })) + loading.value = false + } catch (err) { + loading.value = false + } + } + + onMounted(() => { + getWorkerGroups() + }) + return { + type: 'select', + field: 'workerGroup', + span: 12, + name: t('project.node.worker_group'), + props: { + loading: loading + }, + options: options, + validate: { + trigger: ['input', 'blur'], + required: true, + message: t('project.node.worker_group_tips') + }, + value: 'default' + } +} diff --git a/dolphinscheduler-ui-next/src/views/projects/node/tasks/index.ts b/dolphinscheduler-ui-next/src/views/projects/node/tasks/index.ts new file mode 100644 index 000000000..3e7c6c26f --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/tasks/index.ts @@ -0,0 +1,16 @@ +/* + * 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. + */ diff --git a/dolphinscheduler-ui-next/src/views/projects/node/tasks/use-shell.ts b/dolphinscheduler-ui-next/src/views/projects/node/tasks/use-shell.ts new file mode 100644 index 000000000..1d379cd2d --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/tasks/use-shell.ts @@ -0,0 +1,65 @@ +/* + * 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 { reactive } from 'vue' +import * as Fields from '../fields/index' +import { IJsonItem } from '../types' + +export function useShell({ + isCreate, + projectCode +}: { + isCreate: boolean + projectCode: number +}) { + const model = reactive({ + name: '', + runFlag: 'YES', + desc: '', + enable: false, + localParams: [], + environmentCode: null, + workerGroup: 'default' + } as { + name: string + runFlag: string + desc: string + workerGroup: string + taskGroupId: string + enable: boolean + localParams: [] + environmentCode: string | null + }) + + return { + json: [ + Fields.useName(), + Fields.useRunFlag(), + Fields.useDescription(), + Fields.useTaskPriority(), + Fields.useWorkerGroup(), + Fields.useEnvironmentName(model, isCreate), + ...Fields.useTaskGroup(model, projectCode), + ...Fields.useFailed(), + Fields.useDelayTime(), + ...Fields.useTimeoutAlarm(model), + ...Fields.useShell(model), + Fields.usePreTasks() + ] as IJsonItem[], + model + } +} diff --git a/dolphinscheduler-ui-next/src/views/projects/node/types.ts b/dolphinscheduler-ui-next/src/views/projects/node/types.ts new file mode 100644 index 000000000..68d5e9053 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/types.ts @@ -0,0 +1,104 @@ +/* + * 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 { VNode } from 'vue' +import type { SelectOption } from 'naive-ui' +import type { IFormItem, IJsonItem } from '@/components/form/types' + +interface ITaskPriorityOption extends SelectOption { + icon: VNode + color: string +} +interface IEnvironmentNameOption { + label: string + value: string + workerGroups?: string[] +} +interface ILocalParam { + prop: string + direct: string + type: string + value?: string +} +interface ITaskParams { + conditionResult?: string + switchResult?: string + delayTime?: string + dependence?: string + waitStartTimeout?: string +} +interface ITimeout { + enable: boolean + timeout?: number + strategy?: string +} +type ITaskType = + | 'SHELL' + | 'SUB_PROCESS' + | 'PROCEDURE' + | 'SQL' + | 'SPARK' + | 'FLINK' + | 'MapReduce' + | 'PYTHON' + | 'DEPENDENT' + | 'HTTP' + | 'DataX' + | 'PIGEON' + | 'SQOOP' + | 'CONDITIONS' + | 'DATA_QUALITY' + | 'SWITCH' + | 'SEATUNNEL' + +interface ITask { + code?: string + timeoutNotifyStrategy?: string + taskParams: ITaskParams + description?: string + id: number + delayTime?: number + failRetryTimes?: number + name: string + params?: object + failRetryInterval?: number + flag: string + taskPriority?: number + timeout: ITimeout + timeoutFlag: 'CLOSE' | 'OPEN' + taskType?: ITaskType + workerGroup?: string + environmentCode?: string + taskGroupId?: string + taskGroupPriority?: number +} + +interface IDataNode { + id?: string + taskType: ITaskType +} + +export { + ITaskPriorityOption, + IEnvironmentNameOption, + ILocalParam, + ITaskType, + ITask, + IDataNode, + IFormItem, + IJsonItem +} diff --git a/dolphinscheduler-ui-next/src/views/projects/node/use-data.ts b/dolphinscheduler-ui-next/src/views/projects/node/use-data.ts new file mode 100644 index 000000000..0dbe22f08 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/use-data.ts @@ -0,0 +1,84 @@ +/* + * 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 { omit } from 'lodash' +import type { IDataNode, ITask } from './types' + +export function useData({ + nodeData, + type, + taskDefinition +}: { + nodeData: IDataNode + type: string + taskDefinition?: ITask +}) { + const data = { + backfill: {}, + isCreate: false + } + + if (type === 'task-definition') { + if (taskDefinition) { + data.backfill = formatBackfill(taskDefinition, nodeData.taskType) + data.isCreate = false + } + } else { + } + + return { + code: nodeData.id + } +} + +export function formatBackfill(task: ITask, taskType: string) { + let strategy: string | undefined = task.timeoutNotifyStrategy + if (taskType === 'DEPENDENT' && task.timeoutNotifyStrategy === 'WARNFAILED') { + strategy = 'WARN,FAILED' + } + return { + code: task.code, + conditionResult: task.taskParams.conditionResult, + switchResult: task.taskParams.switchResult, + delayTime: task.delayTime, + dependence: task.taskParams.dependence, + desc: task.description, + id: task.id, + maxRetryTimes: task.failRetryTimes, + name: task.name, + params: omit(task.taskParams, [ + 'conditionResult', + 'dependence', + 'waitStartTimeout', + 'switchResult' + ]), + retryInterval: task.failRetryInterval, + runFlag: task.flag, + taskInstancePriority: task.taskPriority, + timeout: { + interval: task.timeout, + strategy, + enable: task.timeoutFlag === 'OPEN' + }, + type: task.taskType, + waitStartTimeout: task.taskParams.waitStartTimeout, + workerGroup: task.workerGroup, + environmentCode: task.environmentCode, + taskGroupId: task.taskGroupId, + taskGroupPriority: task.taskGroupPriority + } +} diff --git a/dolphinscheduler-ui-next/src/views/projects/node/use-detail.ts b/dolphinscheduler-ui-next/src/views/projects/node/use-detail.ts new file mode 100644 index 000000000..1a17a900c --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/use-detail.ts @@ -0,0 +1,33 @@ +/* + * 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 { reactive, ref } from 'vue' + +export function useDetail() { + const state = reactive({ + formRef: ref(), + loading: false, + saving: false + }) + + const onSubmit = async (model: object) => { + await state.formRef.validate() + } + return { + state, + onSubmit + } +} diff --git a/dolphinscheduler-ui-next/src/views/projects/node/use-task.ts b/dolphinscheduler-ui-next/src/views/projects/node/use-task.ts new file mode 100644 index 000000000..6d1eaac2c --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/node/use-task.ts @@ -0,0 +1,32 @@ +/* + * 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 { useShell } from './tasks/use-shell' +import { IJsonItem, ITaskType } from './types' + +export function useTask({ + taskType, + projectCode +}: { + taskType: ITaskType + projectCode?: number +}): { json: IJsonItem[]; model: object } { + let node = {} as { json: IJsonItem[]; model: object } + if (taskType === 'SHELL' && projectCode) { + node = useShell({ isCreate: true, projectCode: projectCode }) + } + return node +}