You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dolphinscheduler.apache.org by so...@apache.org on 2022/03/04 10:29:20 UTC
[dolphinscheduler] branch dev updated: [Feature-8565][Fix-8672][UI Next][V1.0.0-Alpha]: Add DATA_QUALITY and modify task type switching bug. (#8698)
This is an automated email from the ASF dual-hosted git repository.
songjian pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git
The following commit(s) were added to refs/heads/dev by this push:
new 7973364 [Feature-8565][Fix-8672][UI Next][V1.0.0-Alpha]: Add DATA_QUALITY and modify task type switching bug. (#8698)
7973364 is described below
commit 79733643aab64af78c13f59fcaf2f9b3a4e3a068
Author: Amy0104 <97...@users.noreply.github.com>
AuthorDate: Fri Mar 4 18:29:12 2022 +0800
[Feature-8565][Fix-8672][UI Next][V1.0.0-Alpha]: Add DATA_QUALITY and modify task type switching bug. (#8698)
---
.../src/components/form/fields/get-field.ts | 16 ++
.../src/components/form/index.tsx | 1 +
.../src/components/form/types.ts | 3 +-
.../src/locales/modules/en_US.ts | 45 ++++-
.../src/locales/modules/zh_CN.ts | 45 ++++-
.../src/service/modules/data-quality/index.ts | 27 +++
.../src/service/modules/data-source/index.ts | 24 +++
.../projects/task/components/node/detail-modal.tsx | 71 +++----
.../views/projects/task/components/node/detail.tsx | 90 +++------
.../projects/task/components/node/fields/index.ts | 7 +
.../components/node/fields/use-deploy-mode.ts} | 40 ++--
.../components/node/fields/use-driver-cores.ts} | 39 ++--
.../components/node/fields/use-driver-memory.ts} | 50 ++---
.../components/node/fields/use-executor-cores.ts} | 39 ++--
.../components/node/fields/use-executor-memory.ts} | 50 ++---
.../components/node/fields/use-executor-number.ts} | 39 ++--
.../task/components/node/fields/use-flink.ts | 20 +-
.../task/components/node/fields/use-http.ts | 4 +-
.../task/components/node/fields/use-rules.ts | 214 +++++++++++++++++++++
.../task/components/node/fields/use-sea-tunnel.ts | 24 +--
.../task/components/node/fields/use-spark.ts | 146 ++------------
.../projects/task/components/node/format-data.ts | 53 +++++
.../projects/task/components/node/tasks/index.ts | 54 ++++++
.../tasks/{use-flink.ts => use-data-quality.ts} | 56 ++++--
.../task/components/node/tasks/use-flink.ts | 1 +
.../task/components/node/tasks/use-pigeon.ts | 1 +
.../task/components/node/tasks/use-sub-process.ts | 1 +
.../views/projects/task/components/node/types.ts | 58 +++++-
.../projects/task/components/node/use-task.ts | 181 ++++-------------
.../src/views/projects/task/constants/task-type.ts | 3 +
.../src/views/projects/task/definition/use-task.ts | 2 +-
31 files changed, 847 insertions(+), 557 deletions(-)
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 94139bb..8508985 100644
--- a/dolphinscheduler-ui-next/src/components/form/fields/get-field.ts
+++ b/dolphinscheduler-ui-next/src/components/form/fields/get-field.ts
@@ -19,12 +19,28 @@ import { camelCase, upperFirst, isFunction } from 'lodash'
import type { FormRules, FormItemRule } from 'naive-ui'
import type { IJsonItem } from '../types'
+const TYPES = [
+ 'input',
+ 'radio',
+ 'editor',
+ 'custom-parameters',
+ 'switch',
+ 'input-number',
+ 'select',
+ 'checkbox',
+ 'tree-select',
+ 'multi-input',
+ 'custom',
+ 'multi-condition'
+]
+
const getField = (
item: IJsonItem,
fields: { [field: string]: any },
rules?: FormRules
) => {
const { type = 'input', widget, field } = isFunction(item) ? item() : item
+ if (!TYPES.includes(type)) return null
const renderTypeName = `render${upperFirst(camelCase(type))}`
if (type === 'custom') {
return widget || null
diff --git a/dolphinscheduler-ui-next/src/components/form/index.tsx b/dolphinscheduler-ui-next/src/components/form/index.tsx
index 66829db..d4962df 100644
--- a/dolphinscheduler-ui-next/src/components/form/index.tsx
+++ b/dolphinscheduler-ui-next/src/components/form/index.tsx
@@ -60,6 +60,7 @@ const Form = defineComponent({
{...formItemProps}
span={unref(span) === void 0 ? 24 : unref(span)}
path={path}
+ key={path}
>
{h(widget)}
</NFormItemGi>
diff --git a/dolphinscheduler-ui-next/src/components/form/types.ts b/dolphinscheduler-ui-next/src/components/form/types.ts
index 8f7c266..c1a7d8a 100644
--- a/dolphinscheduler-ui-next/src/components/form/types.ts
+++ b/dolphinscheduler-ui-next/src/components/form/types.ts
@@ -85,5 +85,6 @@ export {
FormItemRule,
FormRules,
IFormItem,
- GridProps
+ GridProps,
+ IJsonItemParams
}
diff --git a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts
index 376a058..e0e68a4 100644
--- a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts
+++ b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts
@@ -787,7 +787,6 @@ const project = {
allow_insert: 'AllowInsert',
concurrency: 'Concurrency',
concurrency_tips: 'Please enter Concurrency',
- sea_tunnel_deploy_mode: 'Deploy Mode',
sea_tunnel_master: 'Master',
sea_tunnel_master_url: 'Master URL',
sea_tunnel_queue: 'Queue',
@@ -844,7 +843,49 @@ const project = {
add_dependency: 'Add dependency',
waiting_dependent_start: 'Waiting Dependent start',
check_interval: 'Check interval',
- waiting_dependent_complete: 'Waiting Dependent complete'
+ waiting_dependent_complete: 'Waiting Dependent complete',
+ rule_name: 'Rule Name',
+ null_check: 'NullCheck',
+ custom_sql: 'CustomSql',
+ multi_table_accuracy: 'MulTableAccuracy',
+ multi_table_value_comparison: 'MulTableCompare',
+ field_length_check: 'FieldLengthCheck',
+ uniqueness_check: 'UniquenessCheck',
+ regexp_check: 'RegexpCheck',
+ timeliness_check: 'TimelinessCheck',
+ enumeration_check: 'EnumerationCheck',
+ table_count_check: 'TableCountCheck',
+ src_connector_type: 'SrcConnType',
+ src_datasource_id: 'SrcSource',
+ src_table: 'SrcTable',
+ src_filter: 'SrcFilter',
+ src_field: 'SrcField',
+ statistics_name: 'ActualValName',
+ check_type: 'CheckType',
+ operator: 'Operator',
+ threshold: 'Threshold',
+ failure_strategy: 'FailureStrategy',
+ target_connector_type: 'TargetConnType',
+ target_datasource_id: 'TargetSourceId',
+ target_table: 'TargetTable',
+ target_filter: 'TargetFilter',
+ mapping_columns: 'OnClause',
+ statistics_execute_sql: 'ActualValExecSql',
+ comparison_name: 'ExceptedValName',
+ comparison_execute_sql: 'ExceptedValExecSql',
+ comparison_type: 'ExceptedValType',
+ writer_connector_type: 'WriterConnType',
+ writer_datasource_id: 'WriterSourceId',
+ target_field: 'TargetField',
+ field_length: 'FieldLength',
+ logic_operator: 'LogicOperator',
+ regexp_pattern: 'RegexpPattern',
+ deadline: 'Deadline',
+ datetime_format: 'DatetimeFormat',
+ enum_list: 'EnumList',
+ begin_time: 'BeginTime',
+ fix_value: 'FixValue',
+ required: 'required'
}
}
diff --git a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts
index 6c633cd..08a31f9 100644
--- a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts
+++ b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts
@@ -778,7 +778,6 @@ const project = {
allow_insert: '无更新便插入',
concurrency: '并发度',
concurrency_tips: '请输入并发度',
- sea_tunnel_deploy_mode: '部署方式',
sea_tunnel_master: 'Master',
sea_tunnel_master_url: 'Master URL',
sea_tunnel_queue: '队列',
@@ -834,7 +833,49 @@ const project = {
add_dependency: '添加依赖',
waiting_dependent_start: '等待依赖启动',
check_interval: '检查间隔',
- waiting_dependent_complete: '等待依赖完成'
+ waiting_dependent_complete: '等待依赖完成',
+ rule_name: '规则名称',
+ null_check: '空值检测',
+ custom_sql: '自定义SQL',
+ multi_table_accuracy: '多表准确性',
+ multi_table_value_comparison: '两表值比对',
+ field_length_check: '字段长度校验',
+ uniqueness_check: '唯一性校验',
+ regexp_check: '正则表达式',
+ timeliness_check: '及时性校验',
+ enumeration_check: '枚举值校验',
+ table_count_check: '表行数校验',
+ src_connector_type: '源数据类型',
+ src_datasource_id: '源数据源',
+ src_table: '源数据表',
+ src_filter: '源表过滤条件',
+ src_field: '源表检测列',
+ statistics_name: '实际值名',
+ check_type: '校验方式',
+ operator: '校验操作符',
+ threshold: '阈值',
+ failure_strategy: '失败策略',
+ target_connector_type: '目标数据类型',
+ target_datasource_id: '目标数据源',
+ target_table: '目标数据表',
+ target_filter: '目标表过滤条件',
+ mapping_columns: 'ON语句',
+ statistics_execute_sql: '实际值计算SQL',
+ comparison_name: '期望值名',
+ comparison_execute_sql: '期望值计算SQL',
+ comparison_type: '期望值类型',
+ writer_connector_type: '输出数据类型',
+ writer_datasource_id: '输出数据源',
+ target_field: '目标表检测列',
+ field_length: '字段长度限制',
+ logic_operator: '逻辑操作符',
+ regexp_pattern: '正则表达式',
+ deadline: '截止时间',
+ datetime_format: '时间格式',
+ enum_list: '枚举值列表',
+ begin_time: '起始时间',
+ fix_value: '固定值',
+ required: '必填'
}
}
diff --git a/dolphinscheduler-ui-next/src/service/modules/data-quality/index.ts b/dolphinscheduler-ui-next/src/service/modules/data-quality/index.ts
index 2250b63..c58a62e 100644
--- a/dolphinscheduler-ui-next/src/service/modules/data-quality/index.ts
+++ b/dolphinscheduler-ui-next/src/service/modules/data-quality/index.ts
@@ -33,3 +33,30 @@ export function queryExecuteResultListPaging(params: ResultListReq): any {
params
})
}
+
+export function queryRuleList(): any {
+ return axios({
+ url: '/data-quality/ruleList',
+ method: 'get'
+ })
+}
+
+export function getRuleFormCreateJson(ruleId: number): any {
+ return axios({
+ url: '/data-quality/getRuleFormCreateJson',
+ method: 'get',
+ params: {
+ ruleId
+ }
+ })
+}
+
+export function getDatasourceOptionsById(datasourceId: number): any {
+ return axios({
+ url: '/data-quality/getDatasourceOptionsById',
+ method: 'get',
+ params: {
+ datasourceId
+ }
+ })
+}
diff --git a/dolphinscheduler-ui-next/src/service/modules/data-source/index.ts b/dolphinscheduler-ui-next/src/service/modules/data-source/index.ts
index c24fa82..956ff3d 100644
--- a/dolphinscheduler-ui-next/src/service/modules/data-source/index.ts
+++ b/dolphinscheduler-ui-next/src/service/modules/data-source/index.ts
@@ -128,3 +128,27 @@ export function connectionTest(id: IdReq): any {
method: 'get'
})
}
+
+export function getDatasourceTablesById(datasourceId: number): any {
+ return axios({
+ url: '/datasources/tables',
+ method: 'get',
+ params: {
+ datasourceId
+ }
+ })
+}
+
+export function getDatasourceTableColumnsById(
+ datasourceId: number,
+ tableName: string
+): any {
+ return axios({
+ url: '/datasources/tableColumns',
+ method: 'get',
+ params: {
+ datasourceId,
+ tableName
+ }
+ })
+}
diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/detail-modal.tsx b/dolphinscheduler-ui-next/src/views/projects/task/components/node/detail-modal.tsx
index c69c56b..c547a40 100644
--- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/detail-modal.tsx
+++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/detail-modal.tsx
@@ -20,15 +20,17 @@ import {
PropType,
ref,
reactive,
- toRefs,
watch,
- nextTick
+ nextTick,
+ provide,
+ computed
} from 'vue'
import { useI18n } from 'vue-i18n'
+import { omit } from 'lodash'
import Modal from '@/components/modal'
import Detail from './detail'
import { formatModel } from './format-data'
-import type { ITaskData } from './types'
+import type { ITaskData, ITaskType } from './types'
const props = {
show: {
@@ -59,17 +61,17 @@ const NodeDetailModal = defineComponent({
emits: ['cancel', 'submit'],
setup(props, { emit }) {
const { t } = useI18n()
+ const detailRef = ref()
const state = reactive({
saving: false,
- detailRef: ref(),
linkEventShowRef: ref(),
linkEventTextRef: ref(),
linkUrlRef: ref()
})
const onConfirm = async () => {
- await state.detailRef.form.validate()
- emit('submit', { data: state.detailRef.form.getValues() })
+ await detailRef.value.value.validate()
+ emit('submit', { data: detailRef.value.value.getValues() })
}
const onCancel = () => {
emit('cancel')
@@ -85,54 +87,45 @@ const NodeDetailModal = defineComponent({
state.linkUrlRef = url
}
+ const onTaskTypeChange = (taskType: ITaskType) => {
+ props.data.taskType = taskType
+ }
+
+ provide(
+ 'data',
+ computed(() => ({
+ projectCode: props.projectCode,
+ data: props.data,
+ from: props.from,
+ readonly: props.readonly
+ }))
+ )
+
watch(
() => props.data,
async () => {
+ if (!props.show) return
await nextTick()
- state.detailRef.form.setValues(formatModel(props.data))
+ detailRef.value.value.setValues(formatModel(props.data))
}
)
- return {
- t,
- ...toRefs(state),
- getLinkEventText,
- onConfirm,
- onCancel,
- onJumpLink
- }
- },
- render() {
- const {
- t,
- show,
- onConfirm,
- onCancel,
- projectCode,
- data,
- readonly,
- from,
- onJumpLink
- } = this
- return (
+ return () => (
<Modal
- show={show}
+ show={props.show}
title={`${t('project.node.current_node_settings')}`}
onConfirm={onConfirm}
confirmLoading={false}
- confirmDisabled={readonly}
+ confirmDisabled={props.readonly}
onCancel={onCancel}
- linkEventShow={this.linkEventShowRef}
- linkEventText={this.linkEventTextRef}
+ linkEventShow={state.linkEventShowRef}
+ linkEventText={state.linkEventTextRef}
onJumpLink={onJumpLink}
>
<Detail
- ref='detailRef'
- data={data}
- projectCode={projectCode}
- readonly={readonly}
- from={from}
- onLinkEventText={this.getLinkEventText}
+ ref={detailRef}
+ onTaskTypeChange={onTaskTypeChange}
+ key={props.data.taskType}
/>
</Modal>
)
diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/detail.tsx b/dolphinscheduler-ui-next/src/views/projects/task/components/node/detail.tsx
index 237f524..0392ced 100644
--- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/detail.tsx
+++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/detail.tsx
@@ -15,92 +15,58 @@
* limitations under the License.
*/
-import { defineComponent, PropType, ref, watch } from 'vue'
+import { defineComponent, ref, watch, inject, Ref, unref } from 'vue'
import Form from '@/components/form'
import { useTask } from './use-task'
-import getElementByJson from '@/components/form/get-elements-by-json'
import type { ITaskData } from './types'
-import { useI18n } from 'vue-i18n'
-const props = {
- projectCode: {
- type: Number as PropType<number>,
- default: 0
- },
- data: {
- type: Object as PropType<ITaskData>,
- default: { taskType: 'SHELL' }
- },
- readonly: {
- type: Boolean as PropType<boolean>,
- default: false
- },
- loading: {
- type: Boolean as PropType<boolean>,
- default: false
- },
- from: {
- type: Number as PropType<number>,
- default: 0
- }
+interface IDetailPanel {
+ projectCode: number
+ data: ITaskData
+ readonly: false
+ from: number
+ detailRef?: Ref
}
const NodeDetail = defineComponent({
name: 'NodeDetail',
- props,
- emits: ['linkEventText'],
+ emits: ['taskTypeChange'],
setup(props, { expose, emit }) {
- const { data, projectCode, from, readonly } = props
- const { t } = useI18n()
+ const formRef = ref()
+ const detailData: IDetailPanel = inject('data') || {
+ projectCode: 0,
+ data: {
+ taskType: 'SHELL'
+ },
+ readonly: false,
+ from: 0
+ }
+ const { data, projectCode, from, readonly } = unref(detailData)
- const { json, model } = useTask({
+ const { elementsRef, rulesRef, model } = useTask({
data,
projectCode,
from,
readonly
})
-
- const jsonRef = ref(json)
- const formRef = ref()
-
- const { rules, elements } = getElementByJson(jsonRef.value, model)
-
- expose({
- form: formRef
- })
-
watch(
() => model.taskType,
- (taskType) => {
- // TODO: Change task type
- if (taskType === 'SUB_PROCESS') {
- // TODO: add linkUrl
- emit(
- 'linkEventText',
- true,
- `${t('project.node.enter_child_node')}`,
- ''
- )
- } else {
- emit('linkEventText', false, '', '')
- }
+ async (taskType) => {
+ emit('taskTypeChange', taskType)
}
)
- return { rules, elements, model, formRef }
- },
- render(props: { readonly: boolean; loading: boolean }) {
- const { rules, elements, model } = this
- return (
+ expose(formRef)
+
+ return () => (
<Form
- ref='formRef'
+ ref={formRef}
meta={{
model,
- rules,
- elements,
- disabled: props.readonly
+ rules: rulesRef.value,
+ elements: elementsRef.value,
+ disabled: unref(readonly)
}}
- loading={props.loading}
layout={{
xGap: 10
}}
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 2998ef7..bf6ed25 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
@@ -39,6 +39,13 @@ 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 { useRules } from './use-rules'
+export { useDeployMode } from './use-deploy-mode'
+export { useDriverCores } from './use-driver-cores'
+export { useDriverMemory } from './use-driver-memory'
+export { useExecutorNumber } from './use-executor-number'
+export { useExecutorMemory } from './use-executor-memory'
+export { useExecutorCores } from './use-executor-cores'
export { useShell } from './use-shell'
export { useSpark } from './use-spark'
diff --git a/dolphinscheduler-ui-next/src/service/modules/data-quality/index.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-deploy-mode.ts
similarity index 62%
copy from dolphinscheduler-ui-next/src/service/modules/data-quality/index.ts
copy to dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-deploy-mode.ts
index 2250b63..9b97e34 100644
--- a/dolphinscheduler-ui-next/src/service/modules/data-quality/index.ts
+++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-deploy-mode.ts
@@ -14,22 +14,32 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+import { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
-import { axios } from '@/service/service'
-import type { RuleListReq, ResultListReq } from './types'
+export function useDeployMode(span = 24): IJsonItem {
+ const { t } = useI18n()
-export function queryRuleListPaging(params: RuleListReq): any {
- return axios({
- url: '/data-quality/rule/page',
- method: 'get',
- params
- })
+ return {
+ type: 'radio',
+ field: 'deployMode',
+ name: t('project.node.deploy_mode'),
+ options: DEPLOY_MODES,
+ span
+ }
}
-export function queryExecuteResultListPaging(params: ResultListReq): any {
- return axios({
- url: '/data-quality/result/page',
- method: 'get',
- params
- })
-}
+export const DEPLOY_MODES = [
+ {
+ label: 'cluster',
+ value: 'cluster'
+ },
+ {
+ label: 'client',
+ value: 'client'
+ },
+ {
+ label: 'local',
+ value: 'local'
+ }
+]
diff --git a/dolphinscheduler-ui-next/src/service/modules/data-quality/index.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-driver-cores.ts
similarity index 57%
copy from dolphinscheduler-ui-next/src/service/modules/data-quality/index.ts
copy to dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-driver-cores.ts
index 2250b63..82b06f0 100644
--- a/dolphinscheduler-ui-next/src/service/modules/data-quality/index.ts
+++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-driver-cores.ts
@@ -14,22 +14,29 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+import { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
-import { axios } from '@/service/service'
-import type { RuleListReq, ResultListReq } from './types'
+export function useDriverCores(): IJsonItem {
+ const { t } = useI18n()
-export function queryRuleListPaging(params: RuleListReq): any {
- return axios({
- url: '/data-quality/rule/page',
- method: 'get',
- params
- })
-}
-
-export function queryExecuteResultListPaging(params: ResultListReq): any {
- return axios({
- url: '/data-quality/result/page',
- method: 'get',
- params
- })
+ return {
+ type: 'input-number',
+ field: 'driverCores',
+ name: t('project.node.driver_cores'),
+ span: 12,
+ props: {
+ placeholder: t('project.node.driver_cores_tips'),
+ min: 1
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.driver_cores_tips'))
+ }
+ }
+ }
+ }
}
diff --git a/dolphinscheduler-ui-next/src/components/form/fields/get-field.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-driver-memory.ts
similarity index 51%
copy from dolphinscheduler-ui-next/src/components/form/fields/get-field.ts
copy to dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-driver-memory.ts
index 94139bb..6ba53b1 100644
--- a/dolphinscheduler-ui-next/src/components/form/fields/get-field.ts
+++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-driver-memory.ts
@@ -14,30 +14,34 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import * as Field from './index'
-import { camelCase, upperFirst, isFunction } from 'lodash'
-import type { FormRules, FormItemRule } from 'naive-ui'
+import { useI18n } from 'vue-i18n'
import type { IJsonItem } from '../types'
-const getField = (
- item: IJsonItem,
- fields: { [field: string]: any },
- rules?: FormRules
-) => {
- const { type = 'input', widget, field } = isFunction(item) ? item() : item
- const renderTypeName = `render${upperFirst(camelCase(type))}`
- if (type === 'custom') {
- return widget || null
- }
- // TODO Support other widgets later
- if (type === 'custom-parameters') {
- let fieldRules: { [key: string]: FormItemRule }[] = []
- if (rules && !rules[field]) fieldRules = rules[field] = []
- // @ts-ignore
- return Field[renderTypeName](item, fields, fieldRules)
+export function useDriverMemory(): IJsonItem {
+ const { t } = useI18n()
+
+ return {
+ type: 'input',
+ field: 'driverMemory',
+ name: t('project.node.driver_memory'),
+ span: 12,
+ props: {
+ placeholder: t('project.node.driver_memory_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.driver_memory_tips'))
+ }
+ if (!Number.isInteger(parseInt(value))) {
+ return new Error(
+ t('project.node.driver_memory') +
+ t('project.node.positive_integer_tips')
+ )
+ }
+ }
+ }
}
- // @ts-ignore
- return Field[renderTypeName](item, fields)
}
-
-export default getField
diff --git a/dolphinscheduler-ui-next/src/service/modules/data-quality/index.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-executor-cores.ts
similarity index 57%
copy from dolphinscheduler-ui-next/src/service/modules/data-quality/index.ts
copy to dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-executor-cores.ts
index 2250b63..8754019 100644
--- a/dolphinscheduler-ui-next/src/service/modules/data-quality/index.ts
+++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-executor-cores.ts
@@ -14,22 +14,29 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+import { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
-import { axios } from '@/service/service'
-import type { RuleListReq, ResultListReq } from './types'
+export function useExecutorCores(): IJsonItem {
+ const { t } = useI18n()
-export function queryRuleListPaging(params: RuleListReq): any {
- return axios({
- url: '/data-quality/rule/page',
- method: 'get',
- params
- })
-}
-
-export function queryExecuteResultListPaging(params: ResultListReq): any {
- return axios({
- url: '/data-quality/result/page',
- method: 'get',
- params
- })
+ return {
+ type: 'input-number',
+ field: 'executorCores',
+ name: t('project.node.executor_cores'),
+ span: 12,
+ props: {
+ placeholder: t('project.node.executor_cores_tips'),
+ min: 1
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.executor_cores_tips'))
+ }
+ }
+ }
+ }
}
diff --git a/dolphinscheduler-ui-next/src/components/form/fields/get-field.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-executor-memory.ts
similarity index 51%
copy from dolphinscheduler-ui-next/src/components/form/fields/get-field.ts
copy to dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-executor-memory.ts
index 94139bb..b135d22 100644
--- a/dolphinscheduler-ui-next/src/components/form/fields/get-field.ts
+++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-executor-memory.ts
@@ -14,30 +14,34 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import * as Field from './index'
-import { camelCase, upperFirst, isFunction } from 'lodash'
-import type { FormRules, FormItemRule } from 'naive-ui'
+import { useI18n } from 'vue-i18n'
import type { IJsonItem } from '../types'
-const getField = (
- item: IJsonItem,
- fields: { [field: string]: any },
- rules?: FormRules
-) => {
- const { type = 'input', widget, field } = isFunction(item) ? item() : item
- const renderTypeName = `render${upperFirst(camelCase(type))}`
- if (type === 'custom') {
- return widget || null
- }
- // TODO Support other widgets later
- if (type === 'custom-parameters') {
- let fieldRules: { [key: string]: FormItemRule }[] = []
- if (rules && !rules[field]) fieldRules = rules[field] = []
- // @ts-ignore
- return Field[renderTypeName](item, fields, fieldRules)
+export function useExecutorMemory(): IJsonItem {
+ const { t } = useI18n()
+
+ return {
+ type: 'input',
+ field: 'executorMemory',
+ name: t('project.node.executor_memory'),
+ span: 12,
+ props: {
+ placeholder: t('project.node.executor_memory_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.executor_memory_tips'))
+ }
+ if (!Number.isInteger(parseInt(value))) {
+ return new Error(
+ t('project.node.executor_memory_tips') +
+ t('project.node.positive_integer_tips')
+ )
+ }
+ }
+ }
}
- // @ts-ignore
- return Field[renderTypeName](item, fields)
}
-
-export default getField
diff --git a/dolphinscheduler-ui-next/src/service/modules/data-quality/index.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-executor-number.ts
similarity index 57%
copy from dolphinscheduler-ui-next/src/service/modules/data-quality/index.ts
copy to dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-executor-number.ts
index 2250b63..34ba711 100644
--- a/dolphinscheduler-ui-next/src/service/modules/data-quality/index.ts
+++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-executor-number.ts
@@ -14,22 +14,29 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+import { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
-import { axios } from '@/service/service'
-import type { RuleListReq, ResultListReq } from './types'
+export function useExecutorNumber(): IJsonItem {
+ const { t } = useI18n()
-export function queryRuleListPaging(params: RuleListReq): any {
- return axios({
- url: '/data-quality/rule/page',
- method: 'get',
- params
- })
-}
-
-export function queryExecuteResultListPaging(params: ResultListReq): any {
- return axios({
- url: '/data-quality/result/page',
- method: 'get',
- params
- })
+ return {
+ type: 'input-number',
+ field: 'numExecutors',
+ name: t('project.node.executor_number'),
+ span: 12,
+ props: {
+ placeholder: t('project.node.executor_number_tips'),
+ min: 1
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.executor_number_tips'))
+ }
+ }
+ }
+ }
}
diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-flink.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-flink.ts
index da1cad9..1f80b24 100644
--- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-flink.ts
+++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-flink.ts
@@ -18,7 +18,7 @@ import { ref, onMounted, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { queryResourceByProgramType } from '@/service/modules/resources'
import { removeUselessChildren } from './use-shell'
-import { useCustomParams } from '.'
+import { useCustomParams, useDeployMode } from '.'
import type { IJsonItem, ProgramType } from '../types'
export function useFlink(model: { [field: string]: any }): IJsonItem[] {
@@ -116,12 +116,7 @@ export function useFlink(model: { [field: string]: any }): IJsonItem[] {
},
options: mainJarOptions
},
- {
- type: 'radio',
- field: 'deployMode',
- name: t('project.node.deploy_mode'),
- options: DeployModes
- },
+ useDeployMode(),
{
type: 'select',
field: 'flinkVersion',
@@ -294,14 +289,3 @@ const FLINK_VERSIONS = [
value: '>=1.10'
}
]
-
-const DeployModes = [
- {
- label: 'cluster',
- value: 'cluster'
- },
- {
- label: 'local',
- value: 'local'
- }
-]
diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-http.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-http.ts
index 963cb19..9f21ba7 100644
--- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-http.ts
+++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-http.ts
@@ -23,7 +23,7 @@ export function useHttp(model: { [field: string]: any }): IJsonItem[] {
const { t } = useI18n()
const timeoutSpan = computed(() => (model.timeoutSetting ? 12 : 0))
- const HTTP_CHECK_CONDITIONs = [
+ const HTTP_CHECK_CONDITIONS = [
{
label: t('project.node.status_code_default'),
value: 'STATUS_CODE_DEFAULT'
@@ -129,7 +129,7 @@ export function useHttp(model: { [field: string]: any }): IJsonItem[] {
type: 'select',
field: 'httpCheckCondition',
name: t('project.node.http_check_condition'),
- options: HTTP_CHECK_CONDITIONs
+ options: HTTP_CHECK_CONDITIONS
},
{
type: 'input',
diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-rules.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-rules.ts
new file mode 100644
index 0000000..51653eb
--- /dev/null
+++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-rules.ts
@@ -0,0 +1,214 @@
+/*
+ * 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 {
+ queryRuleList,
+ getRuleFormCreateJson,
+ getDatasourceOptionsById
+} from '@/service/modules/data-quality'
+import {
+ getDatasourceTablesById,
+ getDatasourceTableColumnsById
+} from '@/service/modules/data-source'
+import type { IJsonItem, IResponseJsonItem, IJsonItemParams } from '../types'
+
+export function useRules(
+ model: { [field: string]: any },
+ updateRules: (items: IJsonItem[], len: number) => void
+): IJsonItem[] {
+ const { t } = useI18n()
+ const rules = ref([])
+ const ruleLoading = ref(false)
+ const srcDatasourceOptions = ref([] as { label: string; value: number }[])
+ const srcTableOptions = ref([] as { label: string; value: number }[])
+ const srcTableColumnOptions = ref([] as { label: string; value: number }[])
+ const targetDatasourceOptions = ref([] as { label: string; value: number }[])
+ const targetTableOptions = ref([] as { label: string; value: string }[])
+ const targetTableColumnOptions = ref([] as { label: string; value: number }[])
+ const writerDatasourceOptions = ref([] as { label: string; value: number }[])
+
+ let preItemLen = 0
+
+ const getRuleList = async () => {
+ if (ruleLoading.value) return
+ ruleLoading.value = true
+ try {
+ const result = await queryRuleList()
+ rules.value = result.map((item: { id: number; name: string }) => {
+ let name = ''
+ if (item.name) {
+ name = item.name.replace('$t(', '').replace(')', '')
+ }
+ return {
+ value: item.id,
+ label: name ? t(`project.node.${name}`) : ''
+ }
+ })
+ ruleLoading.value = false
+ } catch (err) {
+ ruleLoading.value = false
+ }
+ }
+
+ const getRuleById = async (ruleId: number) => {
+ if (ruleLoading.value) return
+ ruleLoading.value = true
+ try {
+ const result = await getRuleFormCreateJson(ruleId)
+ const items = JSON.parse(result).map((item: IResponseJsonItem) =>
+ formatResponseJson(item)
+ )
+ updateRules(items, preItemLen)
+ preItemLen = items.length
+ ruleLoading.value = false
+ } catch (err) {
+ ruleLoading.value = false
+ }
+ }
+
+ const formatResponseJson = (
+ responseItem: IResponseJsonItem
+ ): IJsonItemParams => {
+ const item: IJsonItemParams = {
+ field: responseItem.field,
+ options: responseItem.options,
+ validate: responseItem.validate,
+ props: responseItem.props
+ }
+ let name = responseItem.name?.replace('$t(', '').replace(')', '')
+ item.name = name ? t(`project.node.${name}`) : ''
+
+ if (responseItem.type !== 'group') {
+ item.type = responseItem.type
+ } else {
+ item.type = 'custom-parameters'
+ item.children = item.props.rules.map((child: IJsonItemParams) => {
+ child.span = Math.floor(22 / item.props.rules.length)
+ return child
+ })
+ model[item.field] = []
+ delete item.props.rules
+ }
+ if (responseItem.emit) {
+ responseItem.emit.forEach((emit) => {
+ if (emit === 'change') {
+ item.props.onUpdateValue = (value: string | number) => {
+ onFieldChange(value, item.field)
+ }
+ }
+ })
+ }
+ if (item.field === 'src_datasource_id') {
+ item.options = srcDatasourceOptions
+ }
+ if (item.field === 'target_datasource_id') {
+ item.options = targetDatasourceOptions
+ }
+ if (item.field === 'writer_datasource_id') {
+ item.options = writerDatasourceOptions
+ }
+ if (item.field === 'src_table') {
+ item.options = srcTableOptions
+ }
+ if (item.field === 'target_table') {
+ item.options = targetTableOptions
+ }
+ if (item.field === 'src_field') {
+ item.options = srcTableColumnOptions
+ }
+ if (item.field === 'target_field') {
+ item.options = targetTableColumnOptions
+ }
+ return item
+ }
+
+ const onFieldChange = async (value: string | number, field: string) => {
+ try {
+ if (field === 'src_connector_type' && typeof value === 'number') {
+ const result = await getDatasourceOptionsById(value)
+ srcDatasourceOptions.value = result || []
+ srcTableOptions.value = []
+ model.src_datasource_id = null
+ model.src_table = null
+ model.src_field = null
+ return
+ }
+ if (field === 'target_connector_type' && typeof value === 'number') {
+ const result = await getDatasourceOptionsById(value)
+ targetDatasourceOptions.value = result || []
+ targetTableOptions.value = []
+ model.target_datasource_id = null
+ model.target_table = null
+ model.target_field = null
+ return
+ }
+ if (field === 'writer_connector_type' && typeof value === 'number') {
+ const result = await getDatasourceOptionsById(value)
+ writerDatasourceOptions.value = result || []
+ model.writer_datasource_id = null
+ return
+ }
+ if (field === 'src_datasource_id' && typeof value === 'number') {
+ const result = await getDatasourceTablesById(value)
+ srcTableOptions.value = result || []
+ model.src_table = null
+ model.src_field = null
+ }
+ if (field === 'target_datasource_id' && typeof value === 'number') {
+ const result = await getDatasourceTablesById(value)
+ targetTableOptions.value = result || []
+ model.target_table = null
+ model.target_field = null
+ }
+ if (field === 'src_table' && typeof value === 'string') {
+ const result = await getDatasourceTableColumnsById(
+ model.src_datasource_id,
+ value
+ )
+ srcTableColumnOptions.value = result || []
+ model.src_field = null
+ }
+ if (field === 'target_table' && typeof value === 'string') {
+ const result = await getDatasourceTableColumnsById(
+ model.target_datasource_id,
+ value
+ )
+ targetTableColumnOptions.value = result || []
+ model.target_field = null
+ }
+ } catch (err) {}
+ }
+
+ onMounted(async () => {
+ await getRuleList()
+ await getRuleById(model.ruleId)
+ })
+
+ return [
+ {
+ type: 'select',
+ field: 'ruleId',
+ name: t('project.node.rule_name'),
+ props: {
+ loading: ruleLoading,
+ onUpdateValue: getRuleById
+ },
+ options: rules
+ }
+ ]
+}
diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-sea-tunnel.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-sea-tunnel.ts
index eacb911..c8dfdb6 100644
--- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-sea-tunnel.ts
+++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-sea-tunnel.ts
@@ -17,27 +17,13 @@
import { ref, onMounted, watch, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { queryResourceList } from '@/service/modules/resources'
+import { useDeployMode } from '.'
import type { IJsonItem } from '../types'
export function useSeaTunnel(model: { [field: string]: any }): IJsonItem[] {
const { t } = useI18n()
const options = ref([])
- const deployModeOptions = [
- {
- label: 'client',
- value: 'client'
- },
- {
- label: 'cluster',
- value: 'cluster'
- },
- {
- label: 'local',
- value: 'local'
- }
- ]
-
const masterTypeOptions = [
{
label: 'yarn',
@@ -148,13 +134,7 @@ export function useSeaTunnel(model: { [field: string]: any }): IJsonItem[] {
)
return [
- {
- type: 'radio',
- field: 'deployMode',
- name: t('project.node.sea_tunnel_deploy_mode'),
- options: deployModeOptions,
- value: model.deployMode
- },
+ useDeployMode(),
{
type: 'select',
field: 'master',
diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-spark.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-spark.ts
index c17717f..c6f87ee 100644
--- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-spark.ts
+++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-spark.ts
@@ -18,7 +18,15 @@ import { ref, onMounted, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { queryResourceByProgramType } from '@/service/modules/resources'
import { removeUselessChildren } from './use-shell'
-import { useCustomParams } from '.'
+import {
+ useCustomParams,
+ useDeployMode,
+ useDriverCores,
+ useDriverMemory,
+ useExecutorNumber,
+ useExecutorMemory,
+ useExecutorCores
+} from '.'
import type { IJsonItem, ProgramType } from '../types'
export function useSpark(model: { [field: string]: any }): IJsonItem[] {
@@ -116,12 +124,7 @@ export function useSpark(model: { [field: string]: any }): IJsonItem[] {
},
options: mainJarOptions
},
- {
- type: 'radio',
- field: 'deployMode',
- name: t('project.node.deploy_mode'),
- options: DeployModes
- },
+ useDeployMode(),
{
type: 'input',
field: 'appName',
@@ -130,115 +133,11 @@ export function useSpark(model: { [field: string]: any }): IJsonItem[] {
placeholder: t('project.node.app_name_tips')
}
},
- {
- type: 'input-number',
- field: 'driverCores',
- name: t('project.node.driver_cores'),
- span: 12,
- props: {
- placeholder: t('project.node.driver_cores_tips'),
- min: 1
- },
- validate: {
- trigger: ['input', 'blur'],
- required: true,
- validator(validate: any, value: string) {
- if (!value) {
- return new Error(t('project.node.driver_cores_tips'))
- }
- }
- }
- },
- {
- type: 'input',
- field: 'driverMemory',
- name: t('project.node.driver_memory'),
- span: 12,
- props: {
- placeholder: t('project.node.driver_memory_tips')
- },
- validate: {
- trigger: ['input', 'blur'],
- required: true,
- validator(validate: any, value: string) {
- if (!value) {
- return new Error(t('project.node.driver_memory_tips'))
- }
- if (!Number.isInteger(parseInt(value))) {
- return new Error(
- t('project.node.driver_memory') +
- t('project.node.positive_integer_tips')
- )
- }
- }
- },
- value: model.driverMemory
- },
- {
- type: 'input-number',
- field: 'numExecutors',
- name: t('project.node.executor_number'),
- span: 12,
- props: {
- placeholder: t('project.node.executor_number_tips'),
- min: 1
- },
- validate: {
- trigger: ['input', 'blur'],
- required: true,
- validator(validate: any, value: string) {
- if (!value) {
- return new Error(t('project.node.executor_number_tips'))
- }
- }
- },
- value: model.numExecutors
- },
- {
- type: 'input',
- field: 'executorMemory',
- name: t('project.node.executor_memory'),
- span: 12,
- props: {
- placeholder: t('project.node.executor_memory_tips')
- },
- validate: {
- trigger: ['input', 'blur'],
- required: true,
- validator(validate: any, value: string) {
- if (!value) {
- return new Error(t('project.node.executor_memory_tips'))
- }
- if (!Number.isInteger(parseInt(value))) {
- return new Error(
- t('project.node.executor_memory_tips') +
- t('project.node.positive_integer_tips')
- )
- }
- }
- },
- value: model.executorMemory
- },
- {
- type: 'input-number',
- field: 'executorCores',
- name: t('project.node.executor_cores'),
- span: 12,
- props: {
- placeholder: t('project.node.executor_cores_tips'),
- min: 1
- },
- validate: {
- trigger: ['input', 'blur'],
- required: true,
- validator(validate: any, value: string) {
- if (!value) {
- return new Error(t('project.node.executor_cores_tips'))
- }
- }
- },
- value: model.executorCores
- },
+ useDriverCores(),
+ useDriverMemory(),
+ useExecutorNumber(),
+ useExecutorMemory(),
+ useExecutorCores(),
{
type: 'input',
field: 'mainArgs',
@@ -302,18 +201,3 @@ export const SPARK_VERSIONS = [
value: 'SPARK1'
}
]
-
-export const DeployModes = [
- {
- label: 'cluster',
- value: 'cluster'
- },
- {
- label: 'client',
- value: 'client'
- },
- {
- label: 'local',
- value: 'local'
- }
-]
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 32bb970..cb1c50e 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
@@ -247,6 +247,34 @@ export function formatParams(data: INodeData): {
dependTaskList: dependTaskList
}
}
+ if (data.taskType === 'DATA_QUALITY') {
+ taskParams.ruleId = data.ruleId
+ taskParams.ruleInputParameter = {
+ check_type: data.check_type,
+ comparison_execute_sql: data.comparison_execute_sql,
+ comparison_name: data.comparison_name,
+ failure_strategy: data.failure_strategy,
+ operator: data.operator,
+ src_connector_type: data.src_connector_type,
+ src_datasource_id: data.src_datasource_id,
+ src_table: data.src_table,
+ statistics_execute_sql: data.statistics_execute_sql,
+ statistics_name: data.statistics_name,
+ target_connector_type: data.target_connector_type,
+ target_datasource_id: data.target_datasource_id,
+ target_table: data.target_table,
+ threshold: data.threshold
+ }
+ taskParams.sparkParameters = {
+ deployMode: data.deployMode,
+ driverCores: data.driverCores,
+ driverMemory: data.driverMemory,
+ executorCores: data.executorCores,
+ executorMemory: data.executorMemory,
+ numExecutors: data.numExecutors,
+ others: data.others
+ }
+ }
const params = {
processDefinitionCode: data.processName ? String(data.processName) : '',
@@ -394,6 +422,31 @@ export function formatModel(data: ITaskData) {
params.dependTaskList = data.taskParams?.dependence.dependTaskList || []
params.relation = data.taskParams?.dependence.relation
}
+ if (data.taskParams?.ruleInputParameter) {
+ params.check_type = data.check_type
+ params.comparison_execute_sql = data.comparison_execute_sql
+ params.comparison_name = data.comparison_name
+ params.failure_strategy = data.failure_strategy
+ params.operator = data.operator
+ params.src_connector_type = data.src_connector_type
+ params.src_datasource_id = data.src_datasource_id
+ params.src_table = data.src_table
+ params.statistics_execute_sql = data.statistics_execute_sql
+ params.statistics_name = data.statistics_name
+ params.target_connector_type = data.target_connector_type
+ params.target_datasource_id = data.target_datasource_id
+ params.target_table = data.target_table
+ params.threshold = data.threshold
+ }
+ if (data.taskParams?.sparkParameters) {
+ params.deployMode = data.deployMode
+ params.driverCores = data.driverCores
+ params.driverMemory = data.driverMemory
+ params.executorCores = data.executorCores
+ params.executorMemory = data.executorMemory
+ params.numExecutors = data.numExecutors
+ params.others = data.others
+ }
return params
}
diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/index.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/index.ts
new file mode 100644
index 0000000..86202c3
--- /dev/null
+++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/index.ts
@@ -0,0 +1,54 @@
+/*
+ * 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 { useFlink } from './use-flink'
+import { useShell } from './use-shell'
+import { useSubProcess } from './use-sub-process'
+import { usePigeon } from './use-pigeon'
+import { usePython } from './use-python'
+import { useSpark } from './use-spark'
+import { useMr } from './use-mr'
+import { useHttp } from './use-http'
+import { useSql } from './use-sql'
+import { useProcedure } from './use-procedure'
+import { useSqoop } from './use-sqoop'
+import { useSeaTunnel } from './use-sea-tunnel'
+import { useSwitch } from './use-switch'
+import { useConditions } from './use-conditions'
+import { useDataX } from './use-datax'
+import { useDependent } from './use-dependent'
+import { useDataQuality } from './use-data-quality'
+
+export default {
+ SHELL: useShell,
+ SUB_PROCESS: useSubProcess,
+ PYTHON: usePython,
+ SPARK: useSpark,
+ MR: useMr,
+ FLINK: useFlink,
+ HTTP: useHttp,
+ PIGEON: usePigeon,
+ SQL: useSql,
+ PROCEDURE: useProcedure,
+ SQOOP: useSqoop,
+ SEATUNNEL: useSeaTunnel,
+ SWITCH: useSwitch,
+ CONDITIONS: useConditions,
+ DATAX: useDataX,
+ DEPENDENT: useDependent,
+ DATA_QUALITY: useDataQuality
+}
diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-flink.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-data-quality.ts
similarity index 64%
copy from dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-flink.ts
copy to dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-data-quality.ts
index 5b0f7e0..aea55ff 100644
--- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-flink.ts
+++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-data-quality.ts
@@ -15,42 +15,48 @@
* limitations under the License.
*/
-import { reactive } from 'vue'
+import { Ref, reactive } from 'vue'
+import { useI18n } from 'vue-i18n'
import * as Fields from '../fields/index'
import type { IJsonItem, INodeData, ITaskData } from '../types'
-export function useFlink({
+export function useDataQuality({
projectCode,
from = 0,
readonly,
- data
+ data,
+ jsonRef
}: {
projectCode: number
from?: number
readonly?: boolean
data?: ITaskData
+ jsonRef: Ref<IJsonItem[]>
}) {
- const model = reactive<INodeData>({
+ const { t } = useI18n()
+ const model = reactive({
+ taskType: 'DATA_QUALITY',
name: '',
flag: 'YES',
description: '',
timeoutFlag: false,
+ timeoutNotifyStrategy: ['WARN'],
+ timeout: 30,
localParams: [],
environmentCode: null,
failRetryInterval: 1,
failRetryTimes: 0,
workerGroup: 'default',
delayTime: 0,
- timeout: 30,
- programType: 'SCALA',
+ ruleId: 1,
deployMode: 'cluster',
- flinkVersion: '<1.10',
- jobManagerMemory: '1G',
- taskManagerMemory: '2G',
- slot: 1,
- taskManager: 2,
- parallelism: 1
- })
+ driverCores: 1,
+ driverMemory: '512M',
+ numExecutors: 2,
+ executorMemory: '2G',
+ executorCores: 2,
+ others: '--conf spark.yarn.maxAppAttempts=1'
+ } as INodeData)
let extra: IJsonItem[] = []
if (from === 1) {
@@ -80,7 +86,29 @@ export function useFlink({
...Fields.useFailed(),
Fields.useDelayTime(model),
...Fields.useTimeoutAlarm(model),
- ...Fields.useFlink(model),
+ ...Fields.useRules(model, (items: IJsonItem[], len: number) => {
+ jsonRef.value.splice(17, len, ...items)
+ }),
+ Fields.useDeployMode(),
+ Fields.useDriverCores(),
+ Fields.useDriverMemory(),
+ Fields.useExecutorNumber(),
+ Fields.useExecutorMemory(),
+ Fields.useExecutorCores(),
+ {
+ type: 'input',
+ field: 'others',
+ name: t('project.node.option_parameters'),
+ props: {
+ type: 'textarea',
+ placeholder: t('project.node.option_parameters_tips')
+ }
+ },
+ ...Fields.useCustomParams({
+ model,
+ field: 'localParams',
+ isSimple: true
+ }),
Fields.usePreTasks(model)
] as IJsonItem[],
model
diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-flink.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-flink.ts
index 5b0f7e0..4196247 100644
--- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-flink.ts
+++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-flink.ts
@@ -31,6 +31,7 @@ export function useFlink({
data?: ITaskData
}) {
const model = reactive<INodeData>({
+ taskType: 'FLINK',
name: '',
flag: 'YES',
description: '',
diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-pigeon.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-pigeon.ts
index a3eb0ac..78c09ab 100644
--- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-pigeon.ts
+++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-pigeon.ts
@@ -31,6 +31,7 @@ export function usePigeon({
data?: ITaskData
}) {
const model = reactive({
+ taskType: 'PIGEON',
name: '',
flag: 'YES',
description: '',
diff --git a/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-sub-process.ts b/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-sub-process.ts
index f21cbf7..8c9d8d0 100644
--- a/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-sub-process.ts
+++ b/dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-sub-process.ts
@@ -31,6 +31,7 @@ export function useSubProcess({
data?: ITaskData
}) {
const model = reactive({
+ taskType: 'SUB_PROCESS',
name: '',
flag: 'YES',
description: '',
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 2e89b45..17df919 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
@@ -17,9 +17,15 @@
import { VNode } from 'vue'
import type { SelectOption } from 'naive-ui'
-import type { IFormItem, IJsonItem } from '@/components/form/types'
+
import type { TaskType } from '@/views/projects/task/constants/task-type'
import type { IDataBase } from '@/service/modules/data-source/types'
+import type {
+ IFormItem,
+ IJsonItem,
+ FormRules,
+ IJsonItemParams
+} from '@/components/form/types'
type ProgramType = 'JAVA' | 'SCALA' | 'PYTHON'
type SourceType = 'MYSQL' | 'HDFS' | 'HIVE'
@@ -49,6 +55,11 @@ interface ILocalParam {
value?: string
}
+interface IResponseJsonItem extends Omit<IJsonItemParams, 'type'> {
+ type: 'input' | 'select' | 'radio' | 'group'
+ emit: 'change'[]
+}
+
interface IDependpendItem {
depTaskCode?: number
status?: 'SUCCESS' | 'FAILURE'
@@ -161,6 +172,33 @@ interface ISqoopSourceParams {
hivePartitionKey?: string
hivePartitionValue?: string
}
+interface ISparkParameters {
+ deployMode?: string
+ driverCores?: number
+ driverMemory?: string
+ executorCores?: number
+ executorMemory?: string
+ numExecutors?: number
+ others?: string
+}
+
+interface IRuleParameters {
+ check_type?: string
+ comparison_execute_sql?: string
+ comparison_name?: string
+ failure_strategy?: string
+ operator?: string
+ src_connector_type?: number
+ src_datasource_id?: number
+ src_table?: string
+ statistics_execute_sql?: string
+ statistics_name?: string
+ target_connector_type?: number
+ target_datasource_id?: number
+ target_table?: string
+ threshold?: string
+}
+
interface ITaskParams {
resourceList?: ISourceItem[]
mainJar?: ISourceItem
@@ -229,6 +267,9 @@ interface ITaskParams {
jobSpeedRecord?: number
xms?: number
xmx?: number
+ sparkParameters?: ISparkParameters
+ ruleId?: number
+ ruleInputParameter?: IRuleParameters
}
interface INodeData
@@ -239,9 +280,11 @@ interface INodeData
| 'targetParams'
| 'sourceParams'
| 'dependence'
+ | 'sparkParameters'
>,
ISqoopTargetData,
- ISqoopSourceData {
+ ISqoopSourceData,
+ IRuleParameters {
id?: string
taskType?: ITaskType
processName?: number
@@ -280,7 +323,7 @@ interface ITaskData
> {
name?: string
taskPriority?: string
- timeoutFlag: 'OPEN' | 'CLOSE'
+ timeoutFlag?: 'OPEN' | 'CLOSE'
timeoutNotifyStrategy?: string | []
taskParams?: ITaskParams
}
@@ -292,8 +335,6 @@ export {
ITaskType,
ITaskData,
INodeData,
- IFormItem,
- IJsonItem,
ITaskParams,
IOption,
IDataBase,
@@ -303,5 +344,10 @@ export {
ISqoopSourceParams,
ISqoopTargetParams,
IDependTask,
- IDependpendItem
+ IDependpendItem,
+ IFormItem,
+ IJsonItem,
+ FormRules,
+ IJsonItemParams,
+ IResponseJsonItem
}
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 d23fbab..0812375 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
@@ -14,24 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-import { useFlink } from './tasks/use-flink'
-import { useShell } from './tasks/use-shell'
-import { useSubProcess } from './tasks/use-sub-process'
-import { usePigeon } from './tasks/use-pigeon'
-import { usePython } from './tasks/use-python'
-import { useSpark } from './tasks/use-spark'
-import { useMr } from './tasks/use-mr'
-import { useHttp } from './tasks/use-http'
-import { useSql } from './tasks/use-sql'
-import { useProcedure } from './tasks/use-procedure'
-import { useSqoop } from './tasks/use-sqoop'
-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'
+import { ref, Ref, watch } from 'vue'
+import nodes from './tasks'
+import getElementByJson from '@/components/form/get-elements-by-json'
+import { IFormItem, IJsonItem, INodeData, ITaskData, FormRules } from './types'
export function useTask({
data,
@@ -43,140 +29,39 @@ export function useTask({
projectCode: number
from?: number
readonly?: boolean
-}): { json: IJsonItem[]; model: INodeData } {
- const { taskType = 'SHELL' } = data
- let node = {} as { json: IJsonItem[]; model: INodeData }
- if (taskType === 'SHELL') {
- node = useShell({
- projectCode,
- from,
- readonly,
- data
- })
- }
- if (taskType === 'SUB_PROCESS') {
- node = useSubProcess({
- projectCode,
- from,
- readonly,
- data
- })
- }
- if (taskType === 'PYTHON') {
- node = usePython({
- projectCode,
- from,
- readonly,
- data
- })
- }
- if (taskType === 'SPARK') {
- node = useSpark({
- projectCode,
- from,
- readonly,
- data
- })
- }
- if (taskType === 'MR') {
- node = useMr({
- projectCode,
- from,
- readonly,
- data
- })
- }
- if (taskType === 'FLINK') {
- node = useFlink({
- projectCode,
- from,
- readonly,
- data
- })
- }
- if (taskType === 'HTTP') {
- node = useHttp({
- projectCode,
- from,
- readonly,
- data
- })
- }
- if (taskType === 'PIGEON') {
- node = usePigeon({
- projectCode,
- from,
- readonly,
- data
- })
- }
- if (taskType === 'SQL') {
- node = useSql({
- projectCode,
- from,
- readonly,
- data
- })
- }
- if (taskType === 'PROCEDURE') {
- node = useProcedure({
- projectCode,
- from,
- readonly,
- data
- })
- }
- if (taskType === 'SQOOP') {
- node = useSqoop({
- projectCode,
- from,
- readonly,
- data
- })
- }
- if (taskType === 'SEATUNNEL') {
- node = useSeaTunnel({
- projectCode,
- from,
- readonly,
- data
- })
+}): {
+ elementsRef: Ref<IFormItem[]>
+ rulesRef: Ref<FormRules>
+ model: INodeData
+} {
+ const jsonRef = ref([]) as Ref<IJsonItem[]>
+ const elementsRef = ref([]) as Ref<IFormItem[]>
+ const rulesRef = ref({})
+ const params = {
+ projectCode,
+ from,
+ readonly,
+ data,
+ jsonRef
}
- if (taskType === 'SWITCH') {
- node = useSwitch({
- projectCode,
- from,
- readonly,
- data
- })
- }
+ const { model, json } = nodes[data.taskType || 'SHELL'](params)
+ jsonRef.value = json
- if (taskType === 'CONDITIONS') {
- node = useConditions({
- projectCode,
- from,
- readonly,
- data
- })
+ const getElements = () => {
+ const { rules, elements } = getElementByJson(jsonRef.value, model)
+ elementsRef.value = elements
+ rulesRef.value = rules
}
- if (taskType === 'DATAX') {
- node = useDataX({
- projectCode,
- from,
- readonly,
- data
- })
- }
- if (taskType === 'DEPENDENT') {
- node = useDependent({
- projectCode,
- from,
- readonly,
- data
- })
- }
+ getElements()
+
+ watch(
+ () => jsonRef.value.length,
+ () => {
+ getElements()
+ }
+ )
- return node
+ return { elementsRef, rulesRef, model }
}
diff --git a/dolphinscheduler-ui-next/src/views/projects/task/constants/task-type.ts b/dolphinscheduler-ui-next/src/views/projects/task/constants/task-type.ts
index 52878ab..3c2d104 100644
--- a/dolphinscheduler-ui-next/src/views/projects/task/constants/task-type.ts
+++ b/dolphinscheduler-ui-next/src/views/projects/task/constants/task-type.ts
@@ -58,6 +58,9 @@ export const TASK_TYPES_MAP = {
CONDITIONS: {
alias: 'CONDITIONS'
},
+ DATA_QUALITY: {
+ alias: 'DATA_QUALITY'
+ },
SWITCH: {
alias: 'SWITCH'
},
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 2e88746..69e64ca 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
@@ -27,7 +27,7 @@ import type { ITaskData, INodeData, ISingleSaveReq, IRecord } from './types'
export function useTask(projectCode: number) {
const initalTask = {
- taskType: 'DEPENDENT'
+ taskType: 'SHELL'
} as ITaskData
const task = reactive({
taskShow: false,