From 5044e8568e666a3904dbdf54a514446275941782 Mon Sep 17 00:00:00 2001 From: shenghang Date: Sun, 5 Jan 2025 22:58:12 +0800 Subject: [PATCH 1/8] init --- seatunnel-ui/src/locales/en_US/project.ts | 2 +- seatunnel-ui/src/locales/zh_CN/project.ts | 5 +- .../dag/configuration-form.tsx | 48 +++++++++++++++---- 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/seatunnel-ui/src/locales/en_US/project.ts b/seatunnel-ui/src/locales/en_US/project.ts index 6327cb0f3..5bd8c3e8a 100644 --- a/seatunnel-ui/src/locales/en_US/project.ts +++ b/seatunnel-ui/src/locales/en_US/project.ts @@ -1098,7 +1098,7 @@ export default { sql_content_label: 'sql', sql_content_label_placeholder: 'please input the SQL statement', query_validate: 'please input the SQL statement', - + target_name_tips: 'Please enter or select table name', }, synchronization_instance: { pipeline_id: 'Pipeline Id', diff --git a/seatunnel-ui/src/locales/zh_CN/project.ts b/seatunnel-ui/src/locales/zh_CN/project.ts index 83b98aa03..71088d479 100644 --- a/seatunnel-ui/src/locales/zh_CN/project.ts +++ b/seatunnel-ui/src/locales/zh_CN/project.ts @@ -1065,7 +1065,8 @@ export default { check_model: '请检查模型信息', sql_content_label: 'sql', sql_content_label_placeholder: '请输入sql语句', - query_validate: '请输入sql语句' + query_validate: '请输入sql语句', + target_name_tips: '请输入或选择表名(必填)' }, synchronization_instance: { pipeline_id: 'Pipeline ID', @@ -1110,7 +1111,7 @@ export default { confirm: '确定', cancel: '取消', delete: '删除', - delete_confirm: '确定删除吗?', + delete_confirm: '确定删除吗?' }, menu: { fav: '收藏组件', diff --git a/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx b/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx index 2554870cf..6308e6d22 100644 --- a/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx +++ b/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx @@ -78,13 +78,40 @@ const ConfigurationForm = defineComponent({ emit('tableNameChange', state.model) } - - const prevQueryTableName = ref(''); - const onTableSearch = debounce((tableName: any) => { - // rely on database - if(state.model.database && prevQueryTableName.value !== tableName) { - getTableOptions(state.model.database, tableName) - prevQueryTableName.value = tableName + const prevQueryTableName = ref('') + const onTableSearch = debounce(async (tableName: any) => { + // If it is a sink node and there is input content. + if (props.nodeType === 'sink' && tableName) { + try { + // rely on database + if (state.model.database && prevQueryTableName.value !== tableName) { + await getTableOptions(state.model.database, tableName) + prevQueryTableName.value = tableName + + // If there are no results after searching, add user input as a custom value to the options + if (state.tableOptions.length === 0) { + state.tableOptions.push({ + label: tableName, + value: tableName + }) + // Update selected values + state.model.tableName = tableName + } + } + } catch (err) { + // If the interface call fails, also use user input as a custom value + state.tableOptions.push({ + label: tableName, + value: tableName + }) + state.model.tableName = tableName + } + } else { + // The source node maintains its original logic + if (state.model.database && prevQueryTableName.value !== tableName) { + getTableOptions(state.model.database, tableName) + prevQueryTableName.value = tableName + } } }, 1000) @@ -214,7 +241,12 @@ const ConfigurationForm = defineComponent({ onSearch={onTableSearch} remote virtualScroll - /> + clearable + tag={props.nodeType === 'sink'} + showArrow={true} + allowInput={props.nodeType === 'sink'} + placeholder={t('project.synchronization_definition.target_name_tips')} + /> )} From 03717b8b88e5b4d5d57922a76ca2b328c6b180a7 Mon Sep 17 00:00:00 2001 From: shenghang Date: Sun, 5 Jan 2025 20:15:37 +0800 Subject: [PATCH 2/8] improve --- .../dag/configuration-form.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx b/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx index 6308e6d22..34b887b00 100644 --- a/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx +++ b/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx @@ -40,6 +40,11 @@ import type { NodeType } from './types' import { debounce } from 'lodash' +interface TableOption { + label: string | string + value: string | string +} + const ConfigurationForm = defineComponent({ name: 'ConfigurationForm', props: { @@ -90,7 +95,7 @@ const ConfigurationForm = defineComponent({ // If there are no results after searching, add user input as a custom value to the options if (state.tableOptions.length === 0) { - state.tableOptions.push({ + (state.tableOptions as TableOption[]).push({ label: tableName, value: tableName }) @@ -100,7 +105,7 @@ const ConfigurationForm = defineComponent({ } } catch (err) { // If the interface call fails, also use user input as a custom value - state.tableOptions.push({ + (state.tableOptions as TableOption[]).push({ label: tableName, value: tableName }) From bfc6d08a7743c70c2d6ac0bd49a98d68e72d5a59 Mon Sep 17 00:00:00 2001 From: shenghang Date: Tue, 7 Jan 2025 21:57:22 +0800 Subject: [PATCH 3/8] fix bug --- .../dag/configuration-form.tsx | 40 +++++++++++++------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx b/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx index 34b887b00..ecc147607 100644 --- a/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx +++ b/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx @@ -80,6 +80,9 @@ const ConfigurationForm = defineComponent({ const onTableChange = (tableName: any) => { state.model.tableName = tableName + if (props.nodeType === 'sink' && state.model.database) { + getTableOptions(state.model.database, '') + } emit('tableNameChange', state.model) } @@ -94,22 +97,35 @@ const ConfigurationForm = defineComponent({ prevQueryTableName.value = tableName // If there are no results after searching, add user input as a custom value to the options - if (state.tableOptions.length === 0) { - (state.tableOptions as TableOption[]).push({ - label: tableName, - value: tableName - }) - // Update selected values - state.model.tableName = tableName + const existingOption = state.tableOptions.find( + (option: TableOption) => option.value === tableName + ) + + if (!existingOption) { + state.tableOptions = [ + ...state.tableOptions, + { + label: tableName, + value: tableName + } + ] } } } catch (err) { // If the interface call fails, also use user input as a custom value - (state.tableOptions as TableOption[]).push({ - label: tableName, - value: tableName - }) - state.model.tableName = tableName + const existingOption = state.tableOptions.find( + (option: TableOption) => option.value === tableName + ) + + if (!existingOption) { + state.tableOptions = [ + ...state.tableOptions, + { + label: tableName, + value: tableName + } + ] + } } } else { // The source node maintains its original logic From b7eee91b17094944a21ae49c1c7e54527d162c62 Mon Sep 17 00:00:00 2001 From: shenghang Date: Tue, 7 Jan 2025 22:47:31 +0800 Subject: [PATCH 4/8] fix ci --- .../dag/configuration-form.tsx | 32 +++++++------------ .../synchronization-definition/dag/types.ts | 22 +++++++++++++ .../dag/use-configuration-form.ts | 22 +++++++++++-- 3 files changed, 53 insertions(+), 23 deletions(-) diff --git a/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx b/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx index ecc147607..6d0ba4727 100644 --- a/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx +++ b/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx @@ -36,15 +36,9 @@ import { getSceneModeOptions } from './use-configuration-form' import { useI18n } from 'vue-i18n' -import type { NodeType } from './types' - +import type { NodeType, TableOption, State } from './types' import { debounce } from 'lodash' -interface TableOption { - label: string | string - value: string | string -} - const ConfigurationForm = defineComponent({ name: 'ConfigurationForm', props: { @@ -102,13 +96,11 @@ const ConfigurationForm = defineComponent({ ) if (!existingOption) { - state.tableOptions = [ - ...state.tableOptions, - { - label: tableName, - value: tableName - } - ] + const newOption: TableOption = { + label: tableName, + value: tableName + } + state.tableOptions = [...state.tableOptions, newOption] } } } catch (err) { @@ -118,13 +110,11 @@ const ConfigurationForm = defineComponent({ ) if (!existingOption) { - state.tableOptions = [ - ...state.tableOptions, - { - label: tableName, - value: tableName - } - ] + const newOption: TableOption = { + label: tableName, + value: tableName + } + state.tableOptions = [...state.tableOptions, newOption] } } } else { diff --git a/seatunnel-ui/src/views/task/synchronization-definition/dag/types.ts b/seatunnel-ui/src/views/task/synchronization-definition/dag/types.ts index 3ebc7c433..965c7bd27 100644 --- a/seatunnel-ui/src/views/task/synchronization-definition/dag/types.ts +++ b/seatunnel-ui/src/views/task/synchronization-definition/dag/types.ts @@ -15,6 +15,8 @@ * limitations under the License. */ +import type { SelectOption } from 'naive-ui' + export type NodeType = 'source' | 'sink' | 'transform' export type OptionType = 'datasource' | 'database' | 'table' export type { TableColumns } from 'naive-ui/es/data-table/src/interface' @@ -59,3 +61,23 @@ export type InputPlugin = { type: NodeType } export type NodeInfo = { [key: string]: any } + +export interface TableOption { + label: string; + value: string; +} + +export interface State { + model: any; + rules: any; + loading: boolean; + tableLoading: boolean; + databaseLoading: boolean; + datasourceLoading: boolean; + formStructure: any[]; + formName: string; + formLocales: any; + datasourceOptions: SelectOption[]; + databaseOptions: SelectOption[]; + tableOptions: TableOption[]; +} diff --git a/seatunnel-ui/src/views/task/synchronization-definition/dag/use-configuration-form.ts b/seatunnel-ui/src/views/task/synchronization-definition/dag/use-configuration-form.ts index 5252d7d86..d4340bbc7 100644 --- a/seatunnel-ui/src/views/task/synchronization-definition/dag/use-configuration-form.ts +++ b/seatunnel-ui/src/views/task/synchronization-definition/dag/use-configuration-form.ts @@ -32,7 +32,8 @@ import { findSink } from '@/service/sync-task-definition' import { useSynchronizationDefinitionStore } from '@/store/synchronization-definition' -import type { NodeType } from './types' +import type { NodeType, TableOption, State } from './types' +import type { SelectOption } from 'naive-ui' export const useConfigurationForm = ( nodeType: NodeType, @@ -56,7 +57,24 @@ export const useConfigurationForm = ( query: '' } - const state = reactive({ + const state = reactive<{ + model: typeof initialModel; + loading: boolean; + datasourceOptions: any[]; + datasourceLoading: boolean; + databaseOptions: any[]; + databaseLoading: boolean; + tableOptions: TableOption[]; + tableLoading: boolean; + formStructure: any[]; + formLocales: any; + formName: string; + formLoading: boolean; + inputTableData: any[]; + outputTableData: any[]; + tableColumnsLoading: boolean; + rules: any; + }>({ model: cloneDeep(initialModel), loading: false, datasourceOptions: [], From 72b9e18b77be5c423830609989378159e9e27ec8 Mon Sep 17 00:00:00 2001 From: shenghang Date: Sun, 5 Jan 2025 22:58:12 +0800 Subject: [PATCH 5/8] init --- seatunnel-ui/src/locales/en_US/project.ts | 1 + seatunnel-ui/src/locales/zh_CN/project.ts | 5 +- .../dag/configuration-form.tsx | 48 +++++++++++++++---- 3 files changed, 44 insertions(+), 10 deletions(-) diff --git a/seatunnel-ui/src/locales/en_US/project.ts b/seatunnel-ui/src/locales/en_US/project.ts index c3af0f871..2ec5c8ccb 100644 --- a/seatunnel-ui/src/locales/en_US/project.ts +++ b/seatunnel-ui/src/locales/en_US/project.ts @@ -1098,6 +1098,7 @@ export default { sql_content_label: 'SQL', sql_content_label_placeholder: 'please input the SQL statement', query_validate: 'please input the SQL statement', + target_name_tips: 'Please enter or select table name', }, synchronization_instance: { pipeline_id: 'Pipeline Id', diff --git a/seatunnel-ui/src/locales/zh_CN/project.ts b/seatunnel-ui/src/locales/zh_CN/project.ts index 4f09acaa8..774b6187e 100644 --- a/seatunnel-ui/src/locales/zh_CN/project.ts +++ b/seatunnel-ui/src/locales/zh_CN/project.ts @@ -1065,7 +1065,8 @@ export default { check_model: '请检查模型信息', sql_content_label: 'SQL', sql_content_label_placeholder: '请输入SQL语句', - query_validate: '请输入SQL语句' + query_validate: '请输入SQL语句', + target_name_tips: '请输入或选择表名(必填)' }, synchronization_instance: { pipeline_id: 'Pipeline ID', @@ -1110,7 +1111,7 @@ export default { confirm: '确定', cancel: '取消', delete: '删除', - delete_confirm: '确定删除吗?', + delete_confirm: '确定删除吗?' }, menu: { fav: '收藏组件', diff --git a/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx b/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx index 2554870cf..6308e6d22 100644 --- a/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx +++ b/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx @@ -78,13 +78,40 @@ const ConfigurationForm = defineComponent({ emit('tableNameChange', state.model) } - - const prevQueryTableName = ref(''); - const onTableSearch = debounce((tableName: any) => { - // rely on database - if(state.model.database && prevQueryTableName.value !== tableName) { - getTableOptions(state.model.database, tableName) - prevQueryTableName.value = tableName + const prevQueryTableName = ref('') + const onTableSearch = debounce(async (tableName: any) => { + // If it is a sink node and there is input content. + if (props.nodeType === 'sink' && tableName) { + try { + // rely on database + if (state.model.database && prevQueryTableName.value !== tableName) { + await getTableOptions(state.model.database, tableName) + prevQueryTableName.value = tableName + + // If there are no results after searching, add user input as a custom value to the options + if (state.tableOptions.length === 0) { + state.tableOptions.push({ + label: tableName, + value: tableName + }) + // Update selected values + state.model.tableName = tableName + } + } + } catch (err) { + // If the interface call fails, also use user input as a custom value + state.tableOptions.push({ + label: tableName, + value: tableName + }) + state.model.tableName = tableName + } + } else { + // The source node maintains its original logic + if (state.model.database && prevQueryTableName.value !== tableName) { + getTableOptions(state.model.database, tableName) + prevQueryTableName.value = tableName + } } }, 1000) @@ -214,7 +241,12 @@ const ConfigurationForm = defineComponent({ onSearch={onTableSearch} remote virtualScroll - /> + clearable + tag={props.nodeType === 'sink'} + showArrow={true} + allowInput={props.nodeType === 'sink'} + placeholder={t('project.synchronization_definition.target_name_tips')} + /> )} From 6316ac7b04f14ab2598a41b3316578243d5825af Mon Sep 17 00:00:00 2001 From: shenghang Date: Sun, 5 Jan 2025 20:15:37 +0800 Subject: [PATCH 6/8] improve --- .../dag/configuration-form.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx b/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx index 6308e6d22..34b887b00 100644 --- a/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx +++ b/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx @@ -40,6 +40,11 @@ import type { NodeType } from './types' import { debounce } from 'lodash' +interface TableOption { + label: string | string + value: string | string +} + const ConfigurationForm = defineComponent({ name: 'ConfigurationForm', props: { @@ -90,7 +95,7 @@ const ConfigurationForm = defineComponent({ // If there are no results after searching, add user input as a custom value to the options if (state.tableOptions.length === 0) { - state.tableOptions.push({ + (state.tableOptions as TableOption[]).push({ label: tableName, value: tableName }) @@ -100,7 +105,7 @@ const ConfigurationForm = defineComponent({ } } catch (err) { // If the interface call fails, also use user input as a custom value - state.tableOptions.push({ + (state.tableOptions as TableOption[]).push({ label: tableName, value: tableName }) From 1164fa05e78b62e9448fbf49eaef1ddb37cf1681 Mon Sep 17 00:00:00 2001 From: shenghang Date: Tue, 7 Jan 2025 21:57:22 +0800 Subject: [PATCH 7/8] fix bug --- .../dag/configuration-form.tsx | 40 +++++++++++++------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx b/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx index 34b887b00..ecc147607 100644 --- a/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx +++ b/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx @@ -80,6 +80,9 @@ const ConfigurationForm = defineComponent({ const onTableChange = (tableName: any) => { state.model.tableName = tableName + if (props.nodeType === 'sink' && state.model.database) { + getTableOptions(state.model.database, '') + } emit('tableNameChange', state.model) } @@ -94,22 +97,35 @@ const ConfigurationForm = defineComponent({ prevQueryTableName.value = tableName // If there are no results after searching, add user input as a custom value to the options - if (state.tableOptions.length === 0) { - (state.tableOptions as TableOption[]).push({ - label: tableName, - value: tableName - }) - // Update selected values - state.model.tableName = tableName + const existingOption = state.tableOptions.find( + (option: TableOption) => option.value === tableName + ) + + if (!existingOption) { + state.tableOptions = [ + ...state.tableOptions, + { + label: tableName, + value: tableName + } + ] } } } catch (err) { // If the interface call fails, also use user input as a custom value - (state.tableOptions as TableOption[]).push({ - label: tableName, - value: tableName - }) - state.model.tableName = tableName + const existingOption = state.tableOptions.find( + (option: TableOption) => option.value === tableName + ) + + if (!existingOption) { + state.tableOptions = [ + ...state.tableOptions, + { + label: tableName, + value: tableName + } + ] + } } } else { // The source node maintains its original logic From 84a968be57786d0bcd96ba8dc31b54bd25167ba8 Mon Sep 17 00:00:00 2001 From: shenghang Date: Tue, 7 Jan 2025 22:47:31 +0800 Subject: [PATCH 8/8] fix ci --- .../dag/configuration-form.tsx | 32 +++++++------------ .../synchronization-definition/dag/types.ts | 22 +++++++++++++ .../dag/use-configuration-form.ts | 22 +++++++++++-- 3 files changed, 53 insertions(+), 23 deletions(-) diff --git a/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx b/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx index ecc147607..6d0ba4727 100644 --- a/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx +++ b/seatunnel-ui/src/views/task/synchronization-definition/dag/configuration-form.tsx @@ -36,15 +36,9 @@ import { getSceneModeOptions } from './use-configuration-form' import { useI18n } from 'vue-i18n' -import type { NodeType } from './types' - +import type { NodeType, TableOption, State } from './types' import { debounce } from 'lodash' -interface TableOption { - label: string | string - value: string | string -} - const ConfigurationForm = defineComponent({ name: 'ConfigurationForm', props: { @@ -102,13 +96,11 @@ const ConfigurationForm = defineComponent({ ) if (!existingOption) { - state.tableOptions = [ - ...state.tableOptions, - { - label: tableName, - value: tableName - } - ] + const newOption: TableOption = { + label: tableName, + value: tableName + } + state.tableOptions = [...state.tableOptions, newOption] } } } catch (err) { @@ -118,13 +110,11 @@ const ConfigurationForm = defineComponent({ ) if (!existingOption) { - state.tableOptions = [ - ...state.tableOptions, - { - label: tableName, - value: tableName - } - ] + const newOption: TableOption = { + label: tableName, + value: tableName + } + state.tableOptions = [...state.tableOptions, newOption] } } } else { diff --git a/seatunnel-ui/src/views/task/synchronization-definition/dag/types.ts b/seatunnel-ui/src/views/task/synchronization-definition/dag/types.ts index 3ebc7c433..965c7bd27 100644 --- a/seatunnel-ui/src/views/task/synchronization-definition/dag/types.ts +++ b/seatunnel-ui/src/views/task/synchronization-definition/dag/types.ts @@ -15,6 +15,8 @@ * limitations under the License. */ +import type { SelectOption } from 'naive-ui' + export type NodeType = 'source' | 'sink' | 'transform' export type OptionType = 'datasource' | 'database' | 'table' export type { TableColumns } from 'naive-ui/es/data-table/src/interface' @@ -59,3 +61,23 @@ export type InputPlugin = { type: NodeType } export type NodeInfo = { [key: string]: any } + +export interface TableOption { + label: string; + value: string; +} + +export interface State { + model: any; + rules: any; + loading: boolean; + tableLoading: boolean; + databaseLoading: boolean; + datasourceLoading: boolean; + formStructure: any[]; + formName: string; + formLocales: any; + datasourceOptions: SelectOption[]; + databaseOptions: SelectOption[]; + tableOptions: TableOption[]; +} diff --git a/seatunnel-ui/src/views/task/synchronization-definition/dag/use-configuration-form.ts b/seatunnel-ui/src/views/task/synchronization-definition/dag/use-configuration-form.ts index 5252d7d86..d4340bbc7 100644 --- a/seatunnel-ui/src/views/task/synchronization-definition/dag/use-configuration-form.ts +++ b/seatunnel-ui/src/views/task/synchronization-definition/dag/use-configuration-form.ts @@ -32,7 +32,8 @@ import { findSink } from '@/service/sync-task-definition' import { useSynchronizationDefinitionStore } from '@/store/synchronization-definition' -import type { NodeType } from './types' +import type { NodeType, TableOption, State } from './types' +import type { SelectOption } from 'naive-ui' export const useConfigurationForm = ( nodeType: NodeType, @@ -56,7 +57,24 @@ export const useConfigurationForm = ( query: '' } - const state = reactive({ + const state = reactive<{ + model: typeof initialModel; + loading: boolean; + datasourceOptions: any[]; + datasourceLoading: boolean; + databaseOptions: any[]; + databaseLoading: boolean; + tableOptions: TableOption[]; + tableLoading: boolean; + formStructure: any[]; + formLocales: any; + formName: string; + formLoading: boolean; + inputTableData: any[]; + outputTableData: any[]; + tableColumnsLoading: boolean; + rules: any; + }>({ model: cloneDeep(initialModel), loading: false, datasourceOptions: [],