From 79733643aab64af78c13f59fcaf2f9b3a4e3a068 Mon Sep 17 00:00:00 2001
From: Amy0104 <97265214+Amy0104@users.noreply.github.com>
Date: Fri, 4 Mar 2022 18:29:12 +0800
Subject: [PATCH] [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 ++
.../task/components/node/detail-modal.tsx | 71 +++---
.../projects/task/components/node/detail.tsx | 90 +++-----
.../task/components/node/fields/index.ts | 7 +
.../components/node/fields/use-deploy-mode.ts | 45 ++++
.../node/fields/use-driver-cores.ts | 42 ++++
.../node/fields/use-driver-memory.ts | 47 ++++
.../node/fields/use-executor-cores.ts | 42 ++++
.../node/fields/use-executor-memory.ts | 47 ++++
.../node/fields/use-executor-number.ts | 42 ++++
.../task/components/node/fields/use-flink.ts | 20 +-
.../task/components/node/fields/use-http.ts | 4 +-
.../task/components/node/fields/use-rules.ts | 214 ++++++++++++++++++
.../components/node/fields/use-sea-tunnel.ts | 24 +-
.../task/components/node/fields/use-spark.ts | 146 ++----------
.../task/components/node/format-data.ts | 53 +++++
.../task/components/node/tasks/index.ts | 54 +++++
.../components/node/tasks/use-data-quality.ts | 116 ++++++++++
.../task/components/node/tasks/use-flink.ts | 1 +
.../task/components/node/tasks/use-pigeon.ts | 1 +
.../components/node/tasks/use-sub-process.ts | 1 +
.../projects/task/components/node/types.ts | 58 ++++-
.../projects/task/components/node/use-task.ts | 181 +++------------
.../projects/task/constants/task-type.ts | 3 +
.../projects/task/definition/use-task.ts | 2 +-
31 files changed, 1038 insertions(+), 434 deletions(-)
create mode 100644 dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-deploy-mode.ts
create mode 100644 dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-driver-cores.ts
create mode 100644 dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-driver-memory.ts
create mode 100644 dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-executor-cores.ts
create mode 100644 dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-executor-memory.ts
create mode 100644 dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-executor-number.ts
create mode 100644 dolphinscheduler-ui-next/src/views/projects/task/components/node/fields/use-rules.ts
create mode 100644 dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/index.ts
create mode 100644 dolphinscheduler-ui-next/src/views/projects/task/components/node/tasks/use-data-quality.ts
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 94139bb1b4..8508985ec9 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 66829dbdb3..d4962df889 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)}
diff --git a/dolphinscheduler-ui-next/src/components/form/types.ts b/dolphinscheduler-ui-next/src/components/form/types.ts
index 8f7c266a62..c1a7d8a77f 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 376a058672..e0e68a4c32 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 6c633cd675..08a31f9f7b 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 2250b633a1..c58a62e910 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 c24fa821cc..956ff3d3fb 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 c69c56bfbf..c547a403a0 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 () => (
)
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 237f524486..0392ced341 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,
- default: 0
- },
- data: {
- type: Object as PropType,
- default: { taskType: 'SHELL' }
- },
- readonly: {
- type: Boolean as PropType,
- default: false
- },
- loading: {
- type: Boolean as PropType,
- default: false
- },
- from: {
- type: Number as PropType,
- 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 () => (