This is an automated email from the ASF dual-hosted git repository. dockerzhang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/inlong.git
The following commit(s) were added to refs/heads/master by this push: new ca1e5ce1c0 [INLONG-9431][Dashboard] Data synchronization supports entire database migration (#9432) ca1e5ce1c0 is described below commit ca1e5ce1c0fb4e937baa7408ca89a6372dd66f5f Author: Lizhen <88174078+bluew...@users.noreply.github.com> AuthorDate: Thu Dec 7 20:04:06 2023 +0800 [INLONG-9431][Dashboard] Data synchronization supports entire database migration (#9432) --- inlong-dashboard/src/plugins/RenderRow.ts | 14 ++++ .../src/plugins/sinks/common/SinkDefaultInfo.ts | 57 ++++++++++++-- .../src/plugins/sinks/defaults/ClickHouse.ts | 19 ++++- inlong-dashboard/src/plugins/sinks/defaults/Cls.ts | 7 +- .../src/plugins/sinks/defaults/Doris.ts | 13 +++- .../src/plugins/sinks/defaults/Elasticsearch.ts | 6 +- .../src/plugins/sinks/defaults/Greenplum.ts | 9 ++- .../src/plugins/sinks/defaults/HBase.ts | 11 ++- .../src/plugins/sinks/defaults/Hive.ts | 13 +++- .../src/plugins/sinks/defaults/Hudi.ts | 12 ++- .../src/plugins/sinks/defaults/Iceberg.ts | 86 +++++++++++++++++++++- .../src/plugins/sinks/defaults/Kafka.ts | 7 +- .../src/plugins/sinks/defaults/Kudu.ts | 9 ++- .../src/plugins/sinks/defaults/MySQL.ts | 8 +- .../src/plugins/sinks/defaults/Oracle.ts | 9 ++- .../src/plugins/sinks/defaults/PostgreSQL.ts | 10 ++- .../src/plugins/sinks/defaults/Pulsar.ts | 7 +- .../src/plugins/sinks/defaults/Redis.ts | 19 ++++- .../src/plugins/sinks/defaults/SQLServer.ts | 12 ++- .../src/plugins/sinks/defaults/StarRocks.ts | 7 +- .../src/plugins/sinks/defaults/TDSQLPostgreSQL.ts | 10 ++- .../plugins/sources/common/SourceDefaultInfo.ts | 30 +++++++- .../src/plugins/sources/defaults/MySQLBinlog.ts | 11 ++- .../src/plugins/sync/common/SyncDefaultInfo.ts | 20 +++++ inlong-dashboard/src/ui/locales/cn.json | 7 +- inlong-dashboard/src/ui/locales/en.json | 6 ++ .../src/ui/pages/SynchronizeDetail/Info/index.tsx | 4 + .../SynchronizeDetail/SyncSink/DetailModal.tsx | 16 +++- .../ui/pages/SynchronizeDetail/SyncSink/helper.ts | 47 ++++++++++++ .../ui/pages/SynchronizeDetail/SyncSink/index.tsx | 11 ++- .../SynchronizeDetail/SyncSources/DetailModal.tsx | 12 ++- .../pages/SynchronizeDetail/SyncSources/index.tsx | 11 ++- .../SynchronizeDetail/SyncT/SyncDatabaseCard.tsx | 58 +++++++++++++++ .../src/ui/pages/SynchronizeDetail/SyncT/index.tsx | 39 +++++++--- .../src/ui/pages/SynchronizeDetail/common.d.ts | 1 + 35 files changed, 570 insertions(+), 48 deletions(-) diff --git a/inlong-dashboard/src/plugins/RenderRow.ts b/inlong-dashboard/src/plugins/RenderRow.ts index 591f93f074..3bb38c6f0a 100644 --- a/inlong-dashboard/src/plugins/RenderRow.ts +++ b/inlong-dashboard/src/plugins/RenderRow.ts @@ -24,6 +24,8 @@ export abstract class RenderRow { static FieldList: FieldItemType[] = []; static SyncFieldSet = new Set<string>(); static SyncCreateTableFieldSet = new Set<string>(); + static SyncMoveDbFieldSet = new Set<string>(); + static IngestionFieldSet = new Set<string>(); static FieldDecorator(config: FieldItemType): PropertyDecorator { return (target: any, propertyKey: string) => { @@ -60,6 +62,18 @@ export abstract class RenderRow { }; } + static SyncMoveDbField(): PropertyDecorator { + return (target: any, propertyKey: string) => { + target.constructor.SyncMoveDbFieldSet.add(propertyKey); + }; + } + + static IngestionField(): PropertyDecorator { + return (target: any, propertyKey: string) => { + target.constructor.IngestionFieldSet.add(propertyKey); + }; + } + abstract renderRow(fields?: FieldItemType[]): FieldItemType[]; } diff --git a/inlong-dashboard/src/plugins/sinks/common/SinkDefaultInfo.ts b/inlong-dashboard/src/plugins/sinks/common/SinkDefaultInfo.ts index fb9a1f297f..381da1a309 100644 --- a/inlong-dashboard/src/plugins/sinks/common/SinkDefaultInfo.ts +++ b/inlong-dashboard/src/plugins/sinks/common/SinkDefaultInfo.ts @@ -27,7 +27,17 @@ import { statusList, genStatusTag } from './status'; import { sinks, defaultValue } from '..'; const { I18nMap, I18n } = DataWithBackend; -const { FieldList, FieldDecorator, SyncField, SyncFieldSet, SyncCreateTableFieldSet } = RenderRow; +const { + FieldList, + FieldDecorator, + SyncField, + SyncFieldSet, + SyncMoveDbField, + SyncMoveDbFieldSet, + SyncCreateTableFieldSet, + IngestionField, + IngestionFieldSet, +} = RenderRow; const { ColumnList, ColumnDecorator } = RenderList; export class SinkDefaultInfo implements DataWithBackend, RenderRow, RenderList { @@ -35,7 +45,9 @@ export class SinkDefaultInfo implements DataWithBackend, RenderRow, RenderList { static FieldList = FieldList; static ColumnList = ColumnList; static SyncFieldSet = SyncFieldSet; + static SyncMoveDbFieldSet = SyncMoveDbFieldSet; static SyncCreateTableFieldSet = SyncCreateTableFieldSet; + static IngestionFieldSet = IngestionFieldSet; readonly id: number; @@ -45,6 +57,8 @@ export class SinkDefaultInfo implements DataWithBackend, RenderRow, RenderList { hidden: true, }) @SyncField() + @SyncMoveDbField() + @IngestionField() @I18n('inlongGroupId') readonly inlongGroupId: string; @@ -53,6 +67,8 @@ export class SinkDefaultInfo implements DataWithBackend, RenderRow, RenderList { hidden: true, }) @SyncField() + @SyncMoveDbField() + @IngestionField() @I18n('inlongStreamId') readonly inlongStreamId: string; @@ -78,6 +94,8 @@ export class SinkDefaultInfo implements DataWithBackend, RenderRow, RenderList { render: type => sinks.find(c => c.value === type)?.label || type, }) @SyncField() + @SyncMoveDbField() + @IngestionField() @I18n('meta.Sinks.SinkType') sinkType: string; @@ -98,6 +116,8 @@ export class SinkDefaultInfo implements DataWithBackend, RenderRow, RenderList { }) @ColumnDecorator() @SyncField() + @SyncMoveDbField() + @IngestionField() @I18n('meta.Sinks.SinkName') sinkName: string; @@ -110,6 +130,8 @@ export class SinkDefaultInfo implements DataWithBackend, RenderRow, RenderList { visible: values => Boolean(values.sinkType), }) @SyncField() + @SyncMoveDbField() + @IngestionField() @I18n('meta.Sinks.Description') description: string; @@ -126,14 +148,18 @@ export class SinkDefaultInfo implements DataWithBackend, RenderRow, RenderList { render: text => genStatusTag(text), }) @SyncField() + @SyncMoveDbField() + @IngestionField() @I18n('basic.Status') readonly status: string; @ColumnDecorator() @I18n('basic.Creator') + @IngestionField() readonly creator: string; @ColumnDecorator() + @IngestionField() @I18n('basic.Modifier') readonly modifier: string; @@ -166,17 +192,36 @@ export class SinkDefaultInfo implements DataWithBackend, RenderRow, RenderList { return FieldList.filter(item => SyncCreateTableFieldSet.has(item.name as string)); } + renderSyncAllRow() { + const constructor = this.constructor as typeof SinkDefaultInfo; + const { FieldList, SyncMoveDbFieldSet } = constructor; + return FieldList.filter(item => { + if (item.name === 'sinkType') { + item.props = values => ({ + disabled: Boolean(values.id), + dropdownMatchSelectWidth: false, + options: sinks + .filter(item => item.value === 'ICEBERG') + .map(item => ({ + label: item.label, + value: item.value, + image: loadImage(item.label), + })), + }); + } + return SyncMoveDbFieldSet.has(item.name as string); + }); + } + renderRow() { const constructor = this.constructor as typeof SinkDefaultInfo; - constructor.FieldList.filter(item => { + const { FieldList, IngestionFieldSet } = constructor; + return FieldList.filter(item => { if (item.name === 'tableName' || item.name === 'primaryKey' || item.name === 'database') { item.type = 'input'; } - if (item.name === 'createTableField') { - item.hidden = true; - } + return IngestionFieldSet.has(item.name as string); }); - return constructor.FieldList; } renderList() { diff --git a/inlong-dashboard/src/plugins/sinks/defaults/ClickHouse.ts b/inlong-dashboard/src/plugins/sinks/defaults/ClickHouse.ts index d54792f061..1c7a3ed124 100644 --- a/inlong-dashboard/src/plugins/sinks/defaults/ClickHouse.ts +++ b/inlong-dashboard/src/plugins/sinks/defaults/ClickHouse.ts @@ -28,7 +28,7 @@ import NodeSelect from '@/ui/components/NodeSelect'; import CreateTable from '@/ui/components/CreateTable'; const { I18n } = DataWithBackend; -const { FieldDecorator, SyncField, SyncCreateTableField } = RenderRow; +const { FieldDecorator, SyncField, SyncCreateTableField, IngestionField } = RenderRow; const { ColumnDecorator } = RenderList; const clickHouseTargetTypes = [ @@ -59,6 +59,7 @@ export default class ClickHouseSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.ClickHouse.DbName') dbName: string; @@ -78,6 +79,7 @@ export default class ClickHouseSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.ClickHouse.TableName') tableName: string; @@ -100,6 +102,7 @@ export default class ClickHouseSink ], }), }) + @IngestionField() @I18n('meta.Sinks.EnableCreateResource') enableCreateResource: number; @@ -113,6 +116,7 @@ export default class ClickHouseSink }) @I18n('meta.Sinks.DataNodeName') @SyncField() + @IngestionField() @ColumnDecorator() dataNodeName: string; @@ -129,6 +133,7 @@ export default class ClickHouseSink @I18n('meta.Sinks.ClickHouse.FlushInterval') @SyncCreateTableField() @ColumnDecorator() + @IngestionField() flushInterval: number; @FieldDecorator({ @@ -143,6 +148,7 @@ export default class ClickHouseSink }) @I18n('meta.Sinks.ClickHouse.FlushRecord') @ColumnDecorator() + @IngestionField() @SyncCreateTableField() flushRecord: number; @@ -158,6 +164,7 @@ export default class ClickHouseSink }) @I18n('meta.Sinks.ClickHouse.RetryTimes') @ColumnDecorator() + @IngestionField() @SyncCreateTableField() retryTimes: number; @@ -181,6 +188,7 @@ export default class ClickHouseSink }) @I18n('meta.Sinks.ClickHouse.IsDistributed') @ColumnDecorator() + @IngestionField() @SyncCreateTableField() isDistributed: number; @@ -209,6 +217,7 @@ export default class ClickHouseSink }) @I18n('meta.Sinks.ClickHouse.PartitionStrategy') @ColumnDecorator() + @IngestionField() @SyncCreateTableField() partitionStrategy: string; @@ -222,6 +231,7 @@ export default class ClickHouseSink }) @I18n('meta.Sinks.ClickHouse.PartitionFields') @ColumnDecorator() + @IngestionField() @SyncCreateTableField() partitionFields: string; @@ -249,6 +259,7 @@ export default class ClickHouseSink }) @I18n('meta.Sinks.ClickHouse.Engine') @ColumnDecorator() + @IngestionField() @SyncCreateTableField() engine: string; @@ -260,6 +271,7 @@ export default class ClickHouseSink }) @I18n('meta.Sinks.ClickHouse.OrderBy') @SyncCreateTableField() + @IngestionField() orderBy: string; @FieldDecorator({ @@ -270,6 +282,7 @@ export default class ClickHouseSink }) @I18n('meta.Sinks.ClickHouse.PartitionBy') @ColumnDecorator() + @IngestionField() @SyncCreateTableField() partitionBy: string; @@ -281,6 +294,7 @@ export default class ClickHouseSink }) @I18n('meta.Sinks.ClickHouse.PrimaryKey') @SyncField() + @IngestionField() primaryKey: string; @FieldDecorator({ @@ -292,6 +306,7 @@ export default class ClickHouseSink @I18n('meta.Sinks.ClickHouse.Cluster') @SyncCreateTableField() @ColumnDecorator() + @IngestionField() cluster: string; @FieldDecorator({ @@ -346,6 +361,7 @@ export default class ClickHouseSink }) @I18n('Time To Live') @ColumnDecorator() + @IngestionField() @SyncCreateTableField() ttl: number; @@ -359,6 +375,7 @@ export default class ClickHouseSink upsertByFieldKey: true, }), }) + @IngestionField() sinkFieldList: Record<string, unknown>[]; @FieldDecorator({ diff --git a/inlong-dashboard/src/plugins/sinks/defaults/Cls.ts b/inlong-dashboard/src/plugins/sinks/defaults/Cls.ts index 29168970f5..2025993226 100644 --- a/inlong-dashboard/src/plugins/sinks/defaults/Cls.ts +++ b/inlong-dashboard/src/plugins/sinks/defaults/Cls.ts @@ -27,7 +27,7 @@ import { sourceFields } from '../common/sourceFields'; import NodeSelect from '@/ui/components/NodeSelect'; const { I18n } = DataWithBackend; -const { FieldDecorator, SyncField } = RenderRow; +const { FieldDecorator, SyncField, IngestionField } = RenderRow; const { ColumnDecorator } = RenderList; const targetTypes = ['int', 'long', 'float', 'double', 'string', 'date', 'timestamp'].map(item => ({ @@ -46,6 +46,7 @@ export default class ClsSink extends SinkInfo implements DataWithBackend, Render @ColumnDecorator() @I18n('Topic Name') @SyncField() + @IngestionField() topicName: string; @FieldDecorator({ @@ -58,6 +59,7 @@ export default class ClsSink extends SinkInfo implements DataWithBackend, Render @ColumnDecorator() @I18n('meta.Sinks.Cls.Tag') @SyncField() + @IngestionField() tag: string; @FieldDecorator({ @@ -69,6 +71,7 @@ export default class ClsSink extends SinkInfo implements DataWithBackend, Render }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Cls.Tokenizer') tokenizer: string; @@ -99,6 +102,7 @@ export default class ClsSink extends SinkInfo implements DataWithBackend, Render }) @I18n('meta.Sinks.Cls.StorageDuration') @SyncField() + @IngestionField() storageDuration: number; @FieldDecorator({ @@ -111,6 +115,7 @@ export default class ClsSink extends SinkInfo implements DataWithBackend, Render }) @I18n('meta.Sinks.DataNodeName') @SyncField() + @IngestionField() @ColumnDecorator() dataNodeName: string; diff --git a/inlong-dashboard/src/plugins/sinks/defaults/Doris.ts b/inlong-dashboard/src/plugins/sinks/defaults/Doris.ts index 2879215616..2f0d5362c1 100644 --- a/inlong-dashboard/src/plugins/sinks/defaults/Doris.ts +++ b/inlong-dashboard/src/plugins/sinks/defaults/Doris.ts @@ -26,7 +26,7 @@ import { SinkInfo } from '../common/SinkInfo'; import { sourceFields } from '../common/sourceFields'; const { I18n } = DataWithBackend; -const { FieldDecorator, SyncField } = RenderRow; +const { FieldDecorator, SyncField, IngestionField } = RenderRow; const { ColumnDecorator } = RenderList; const dorisTargetTypes = [ @@ -63,6 +63,7 @@ export default class DorisSink extends SinkInfo implements DataWithBackend, Rend @ColumnDecorator() @I18n('meta.Sinks.Doris.HttpAddress') @SyncField() + @IngestionField() feNodes: string; @FieldDecorator({ @@ -74,6 +75,7 @@ export default class DorisSink extends SinkInfo implements DataWithBackend, Rend }) @I18n('meta.Sinks.Username') @SyncField() + @IngestionField() username: string; @FieldDecorator({ @@ -85,6 +87,7 @@ export default class DorisSink extends SinkInfo implements DataWithBackend, Rend }) @I18n('meta.Sinks.Password') @SyncField() + @IngestionField() password: string; @FieldDecorator({ @@ -97,6 +100,7 @@ export default class DorisSink extends SinkInfo implements DataWithBackend, Rend @ColumnDecorator() @I18n('meta.Sinks.Doris.TableIdentifier') @SyncField() + @IngestionField() tableIdentifier: string; @FieldDecorator({ @@ -108,6 +112,7 @@ export default class DorisSink extends SinkInfo implements DataWithBackend, Rend }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Doris.LabelPrefix') labelPrefix: string; @@ -120,6 +125,7 @@ export default class DorisSink extends SinkInfo implements DataWithBackend, Rend }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Doris.PrimaryKey') primaryKey: string; @@ -143,6 +149,7 @@ export default class DorisSink extends SinkInfo implements DataWithBackend, Rend }) @I18n('meta.Sinks.Doris.SinkMultipleEnable') @SyncField() + @IngestionField() sinkMultipleEnable: boolean; @FieldDecorator({ @@ -155,6 +162,7 @@ export default class DorisSink extends SinkInfo implements DataWithBackend, Rend @ColumnDecorator() @I18n('meta.Sinks.Doris.SinkMultipleFormat') @SyncField() + @IngestionField() sinkMultipleFormat: string; @FieldDecorator({ @@ -166,6 +174,7 @@ export default class DorisSink extends SinkInfo implements DataWithBackend, Rend }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Doris.DatabasePattern') databasePattern: string; @@ -178,6 +187,7 @@ export default class DorisSink extends SinkInfo implements DataWithBackend, Rend }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Doris.TablePattern') tablePattern: string; @@ -191,6 +201,7 @@ export default class DorisSink extends SinkInfo implements DataWithBackend, Rend upsertByFieldKey: true, }), }) + @IngestionField() sinkFieldList: Record<string, unknown>[]; } diff --git a/inlong-dashboard/src/plugins/sinks/defaults/Elasticsearch.ts b/inlong-dashboard/src/plugins/sinks/defaults/Elasticsearch.ts index 468f7ffcbb..71d0dfa65c 100644 --- a/inlong-dashboard/src/plugins/sinks/defaults/Elasticsearch.ts +++ b/inlong-dashboard/src/plugins/sinks/defaults/Elasticsearch.ts @@ -28,7 +28,7 @@ import NodeSelect from '@/ui/components/NodeSelect'; import CreateTable from '@/ui/components/CreateTable'; const { I18n } = DataWithBackend; -const { FieldDecorator, SyncField, SyncCreateTableField } = RenderRow; +const { FieldDecorator, SyncField, SyncCreateTableField, IngestionField } = RenderRow; const { ColumnDecorator } = RenderList; const esTypes = [ @@ -63,6 +63,7 @@ export default class ElasticsearchSink }) @I18n('meta.Sinks.DataNodeName') @SyncField() + @IngestionField() dataNodeName: string; @FieldDecorator({ @@ -98,6 +99,7 @@ export default class ElasticsearchSink }, }) @I18n('meta.Sinks.ES.Index') + @IngestionField() index: string; @FieldDecorator({ @@ -109,6 +111,7 @@ export default class ElasticsearchSink }), }) @I18n('meta.Sinks.ES.Index') + @IngestionField() indexNamePattern: string; @FieldDecorator({ @@ -121,6 +124,7 @@ export default class ElasticsearchSink upsertByFieldKey: true, }), }) + @IngestionField() sinkFieldList: Record<string, unknown>[]; } diff --git a/inlong-dashboard/src/plugins/sinks/defaults/Greenplum.ts b/inlong-dashboard/src/plugins/sinks/defaults/Greenplum.ts index c071fb16cc..9debfcb4fa 100644 --- a/inlong-dashboard/src/plugins/sinks/defaults/Greenplum.ts +++ b/inlong-dashboard/src/plugins/sinks/defaults/Greenplum.ts @@ -25,7 +25,7 @@ import { SinkInfo } from '../common/SinkInfo'; import CreateTable from '@/ui/components/CreateTable'; const { I18n } = DataWithBackend; -const { FieldDecorator, SyncField, SyncCreateTableField } = RenderRow; +const { FieldDecorator, SyncField, SyncCreateTableField, IngestionField } = RenderRow; const { ColumnDecorator } = RenderList; const fieldTypesConf = { @@ -78,6 +78,7 @@ export default class GreenplumSink @ColumnDecorator() @I18n('JDBC URL') @SyncField() + @IngestionField() jdbcUrl: string; @FieldDecorator({ @@ -96,6 +97,7 @@ export default class GreenplumSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Greenplum.TableName') tableName: string; @@ -108,6 +110,7 @@ export default class GreenplumSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Greenplum.PrimaryKey') primaryKey: string; @@ -130,6 +133,7 @@ export default class GreenplumSink ], }), }) + @IngestionField() @I18n('meta.Sinks.EnableCreateResource') enableCreateResource: number; @@ -142,6 +146,7 @@ export default class GreenplumSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Username') username: string; @@ -154,6 +159,7 @@ export default class GreenplumSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Password') password: string; @@ -167,6 +173,7 @@ export default class GreenplumSink upsertByFieldKey: true, }), }) + @IngestionField() sinkFieldList: Record<string, unknown>[]; @FieldDecorator({ diff --git a/inlong-dashboard/src/plugins/sinks/defaults/HBase.ts b/inlong-dashboard/src/plugins/sinks/defaults/HBase.ts index 3d943b19c5..52bd9242e7 100644 --- a/inlong-dashboard/src/plugins/sinks/defaults/HBase.ts +++ b/inlong-dashboard/src/plugins/sinks/defaults/HBase.ts @@ -24,7 +24,7 @@ import { SinkInfo } from '../common/SinkInfo'; import { sourceFields } from '../common/sourceFields'; const { I18n } = DataWithBackend; -const { FieldDecorator, SyncField } = RenderRow; +const { FieldDecorator, SyncField, IngestionField } = RenderRow; const { ColumnDecorator } = RenderList; const hbaseFieldTypes = [ @@ -52,6 +52,7 @@ export default class HBaseSink extends SinkInfo implements DataWithBackend, Rend }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.HBase.Namespace') namespace: string; @@ -64,6 +65,7 @@ export default class HBaseSink extends SinkInfo implements DataWithBackend, Rend }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.HBase.TableName') tableName: string; @@ -76,6 +78,7 @@ export default class HBaseSink extends SinkInfo implements DataWithBackend, Rend }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.HBase.RowKey') rowKey: string; @@ -89,6 +92,7 @@ export default class HBaseSink extends SinkInfo implements DataWithBackend, Rend }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.HBase.ZkQuorum') zkQuorum: string; @@ -102,6 +106,7 @@ export default class HBaseSink extends SinkInfo implements DataWithBackend, Rend }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.HBase.ZkNodeParent') zkNodeParent: string; @@ -116,6 +121,7 @@ export default class HBaseSink extends SinkInfo implements DataWithBackend, Rend }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.HBase.BufferFlushMaxSize') bufferFlushMaxSize: number; @@ -130,6 +136,7 @@ export default class HBaseSink extends SinkInfo implements DataWithBackend, Rend }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.HBase.BufferFlushMaxRows') bufferFlushMaxRows: number; @@ -145,6 +152,7 @@ export default class HBaseSink extends SinkInfo implements DataWithBackend, Rend }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.HBase.BufferFlushInterval') bufferFlushInterval: number; @@ -158,6 +166,7 @@ export default class HBaseSink extends SinkInfo implements DataWithBackend, Rend upsertKey: 'fieldName', }), }) + @IngestionField() sinkFieldList: Record<string, unknown>[]; } diff --git a/inlong-dashboard/src/plugins/sinks/defaults/Hive.ts b/inlong-dashboard/src/plugins/sinks/defaults/Hive.ts index 7bc6a149e5..a09c4899fa 100644 --- a/inlong-dashboard/src/plugins/sinks/defaults/Hive.ts +++ b/inlong-dashboard/src/plugins/sinks/defaults/Hive.ts @@ -28,7 +28,7 @@ import NodeSelect from '@/ui/components/NodeSelect'; import CreateTable from '@/ui/components/CreateTable'; const { I18n } = DataWithBackend; -const { FieldDecorator, SyncField, SyncCreateTableField } = RenderRow; +const { FieldDecorator, SyncField, SyncCreateTableField, IngestionField } = RenderRow; const { ColumnDecorator } = RenderList; const hiveFieldTypes = [ @@ -63,6 +63,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Hive.DbName') dbName: string; @@ -82,6 +83,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Hive.TableName') tableName: string; @@ -104,6 +106,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende ], }), }) + @IngestionField() @I18n('meta.Sinks.EnableCreateResource') enableCreateResource: number; @@ -116,6 +119,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende }) @I18n('meta.Sinks.Username') @SyncField() + @IngestionField() username: string; @FieldDecorator({ @@ -127,6 +131,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende }) @I18n('meta.Sinks.Password') @SyncField() + @IngestionField() password: string; @FieldDecorator({ @@ -139,6 +144,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende }) @I18n('meta.Sinks.DataNodeName') @SyncField() + @IngestionField() dataNodeName: string; @FieldDecorator({ @@ -177,6 +183,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende }) @I18n('meta.Sinks.Hive.FileFormat') @SyncCreateTableField() + @IngestionField() fileFormat: string; @FieldDecorator({ @@ -199,6 +206,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende }) @I18n('meta.Sinks.Hive.DataEncoding') @SyncCreateTableField() + @IngestionField() dataEncoding: string; @FieldDecorator({ @@ -252,6 +260,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende }) @I18n('meta.Sinks.Hive.DataSeparator') @SyncCreateTableField() + @IngestionField() dataSeparator: string; @FieldDecorator({ @@ -264,6 +273,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende upsertByFieldKey: true, }), }) + @IngestionField() sinkFieldList: Record<string, unknown>[]; @FieldDecorator({ @@ -325,6 +335,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende }) @I18n('meta.Sinks.Hive.PartitionFieldList') @SyncField() + @IngestionField() partitionFieldList: Record<string, unknown>[]; } diff --git a/inlong-dashboard/src/plugins/sinks/defaults/Hudi.ts b/inlong-dashboard/src/plugins/sinks/defaults/Hudi.ts index ae66a218a0..b83758d644 100644 --- a/inlong-dashboard/src/plugins/sinks/defaults/Hudi.ts +++ b/inlong-dashboard/src/plugins/sinks/defaults/Hudi.ts @@ -28,7 +28,7 @@ import NodeSelect from '@/ui/components/NodeSelect'; import CreateTable from '@/ui/components/CreateTable'; const { I18n } = DataWithBackend; -const { FieldDecorator, SyncField, SyncCreateTableField } = RenderRow; +const { FieldDecorator, SyncField, SyncCreateTableField, IngestionField } = RenderRow; const { ColumnDecorator } = RenderList; const hudiFieldTypes = [ @@ -117,6 +117,7 @@ export default class HudiSink extends SinkInfo implements DataWithBackend, Rende }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Hudi.DbName') dbName: string; @@ -137,6 +138,7 @@ export default class HudiSink extends SinkInfo implements DataWithBackend, Rende @ColumnDecorator() @I18n('meta.Sinks.Hudi.TableName') @SyncField() + @IngestionField() tableName: string; @FieldDecorator({ @@ -158,6 +160,7 @@ export default class HudiSink extends SinkInfo implements DataWithBackend, Rende ], }), }) + @IngestionField() @I18n('meta.Sinks.EnableCreateResource') enableCreateResource: number; @@ -171,6 +174,7 @@ export default class HudiSink extends SinkInfo implements DataWithBackend, Rende }) @I18n('meta.Sinks.DataNodeName') @SyncField() + @IngestionField() dataNodeName: string; @FieldDecorator({ @@ -198,6 +202,7 @@ export default class HudiSink extends SinkInfo implements DataWithBackend, Rende @ColumnDecorator() @I18n('meta.Sinks.Hudi.FileFormat') @SyncField() + @IngestionField() fileFormat: string; @FieldDecorator({ @@ -227,6 +232,7 @@ export default class HudiSink extends SinkInfo implements DataWithBackend, Rende }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Hudi.ExtList') extList: string; @@ -251,6 +257,7 @@ export default class HudiSink extends SinkInfo implements DataWithBackend, Rende }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Hudi.DataConsistency') dataConsistency: string; @@ -264,6 +271,7 @@ export default class HudiSink extends SinkInfo implements DataWithBackend, Rende columns: getFieldListColumns(values), }), }) + @IngestionField() sinkFieldList: Record<string, unknown>[]; @FieldDecorator({ @@ -291,6 +299,7 @@ export default class HudiSink extends SinkInfo implements DataWithBackend, Rende }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Hudi.PrimaryKey') primaryKey: string; @@ -304,6 +313,7 @@ export default class HudiSink extends SinkInfo implements DataWithBackend, Rende }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Hudi.PartitionKey') partitionKey: string; } diff --git a/inlong-dashboard/src/plugins/sinks/defaults/Iceberg.ts b/inlong-dashboard/src/plugins/sinks/defaults/Iceberg.ts index 83fb8f7bfc..4fdd600d16 100644 --- a/inlong-dashboard/src/plugins/sinks/defaults/Iceberg.ts +++ b/inlong-dashboard/src/plugins/sinks/defaults/Iceberg.ts @@ -28,7 +28,8 @@ import NodeSelect from '@/ui/components/NodeSelect'; import CreateTable from '@/ui/components/CreateTable'; const { I18n } = DataWithBackend; -const { FieldDecorator, SyncField, SyncCreateTableField } = RenderRow; +const { FieldDecorator, SyncField, SyncMoveDbField, SyncCreateTableField, IngestionField } = + RenderRow; const { ColumnDecorator } = RenderList; const icebergFieldTypes = [ @@ -111,6 +112,8 @@ export default class IcebergSink extends SinkInfo implements DataWithBackend, RenderRow, RenderList { + readonly id: number; + @FieldDecorator({ type: 'input', rules: [{ required: true }], @@ -120,6 +123,7 @@ export default class IcebergSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Iceberg.DbName') dbName: string; @@ -139,9 +143,81 @@ export default class IcebergSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Iceberg.TableName') tableName: string; + @FieldDecorator({ + type: 'radiobutton', + initialValue: '${database}', + rules: [{ required: true }], + props: values => ({ + size: 'middle', + disabled: [110].includes(values?.status), + options: [ + { + label: i18n.t('meta.Sinks.Iceberg.Options.DBSameName'), + value: '${database}', + disabled: Boolean(values.id), + }, + { + label: i18n.t('meta.Sinks.Iceberg.Options.Customize'), + value: 'false', + disabled: Boolean(values.id), + }, + ], + }), + suffix: { + type: 'input', + name: 'databasePattern', + visible: values => + values.backupDatabase === 'false' || + (values.id !== undefined && values.databasePattern !== '${database}'), + props: values => ({ + style: { width: 100 }, + disabled: [110].includes(values?.status), + }), + }, + }) + @SyncMoveDbField() + @I18n('meta.Sinks.Iceberg.DatabasePattern') + backupDatabase: string; + + @FieldDecorator({ + type: 'radiobutton', + initialValue: '${table}', + rules: [{ required: true }], + props: values => ({ + size: 'middle', + options: [ + { + label: i18n.t('meta.Sinks.Iceberg.Options.TableSameName'), + value: '${table}', + disabled: Boolean(values.id), + }, + { + label: i18n.t('meta.Sinks.Iceberg.Options.Customize'), + value: 'false', + disabled: Boolean(values.id), + }, + ], + }), + suffix: { + type: 'input', + name: 'tablePattern', + visible: values => + values.backupTable === 'false' || + (values.id !== undefined && values.tablePattern !== '${table}'), + props: values => ({ + style: { width: 100 }, + disabled: [110].includes(values?.status), + }), + }, + }) + @SyncMoveDbField() + @I18n('meta.Sinks.Iceberg.TablePattern') + backupTable: string; + @FieldDecorator({ type: 'radio', rules: [{ required: true }], @@ -161,6 +237,7 @@ export default class IcebergSink ], }), }) + @IngestionField() @I18n('meta.Sinks.EnableCreateResource') enableCreateResource: number; @@ -174,6 +251,8 @@ export default class IcebergSink }) @I18n('meta.Sinks.DataNodeName') @SyncField() + @IngestionField() + @SyncMoveDbField() dataNodeName: string; @FieldDecorator({ @@ -200,6 +279,7 @@ export default class IcebergSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Iceberg.FileFormat') fileFormat: string; @@ -222,6 +302,7 @@ export default class IcebergSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Iceberg.AppendMode') appendMode: string; @@ -250,6 +331,7 @@ export default class IcebergSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Iceberg.ExtList') extList: string; @@ -274,6 +356,7 @@ export default class IcebergSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Iceberg.DataConsistency') dataConsistency: string; @@ -287,6 +370,7 @@ export default class IcebergSink upsertByFieldKey: true, }), }) + @IngestionField() sinkFieldList: Record<string, unknown>[]; @FieldDecorator({ diff --git a/inlong-dashboard/src/plugins/sinks/defaults/Kafka.ts b/inlong-dashboard/src/plugins/sinks/defaults/Kafka.ts index 9b5f5fca17..26242e99ef 100644 --- a/inlong-dashboard/src/plugins/sinks/defaults/Kafka.ts +++ b/inlong-dashboard/src/plugins/sinks/defaults/Kafka.ts @@ -23,7 +23,7 @@ import { RenderList } from '@/plugins/RenderList'; import { SinkInfo } from '../common/SinkInfo'; const { I18n } = DataWithBackend; -const { FieldDecorator, SyncField } = RenderRow; +const { FieldDecorator, SyncField, IngestionField } = RenderRow; const { ColumnDecorator } = RenderList; export default class KafkaSink extends SinkInfo implements DataWithBackend, RenderRow, RenderList { @@ -38,6 +38,7 @@ export default class KafkaSink extends SinkInfo implements DataWithBackend, Rend @ColumnDecorator() @I18n('meta.Sinks.Kafka.Server') @SyncField() + @IngestionField() bootstrapServers: string; @FieldDecorator({ @@ -50,6 +51,7 @@ export default class KafkaSink extends SinkInfo implements DataWithBackend, Rend @ColumnDecorator() @I18n('Topic') @SyncField() + @IngestionField() topicName: string; @FieldDecorator({ @@ -77,6 +79,7 @@ export default class KafkaSink extends SinkInfo implements DataWithBackend, Rend @ColumnDecorator() @I18n('meta.Sinks.Kafka.SerializationType') @SyncField() + @IngestionField() serializationType: string; @FieldDecorator({ @@ -91,6 +94,7 @@ export default class KafkaSink extends SinkInfo implements DataWithBackend, Rend }) @I18n('meta.Sinks.Kafka.PartitionNum') @SyncField() + @IngestionField() partitionNum: number; @FieldDecorator({ @@ -117,5 +121,6 @@ export default class KafkaSink extends SinkInfo implements DataWithBackend, Rend }) @I18n('meta.Sinks.Kafka.AutoOffsetReset') @SyncField() + @IngestionField() autoOffsetReset: string; } diff --git a/inlong-dashboard/src/plugins/sinks/defaults/Kudu.ts b/inlong-dashboard/src/plugins/sinks/defaults/Kudu.ts index 544b72924d..49a7085aaa 100644 --- a/inlong-dashboard/src/plugins/sinks/defaults/Kudu.ts +++ b/inlong-dashboard/src/plugins/sinks/defaults/Kudu.ts @@ -28,7 +28,7 @@ import NodeSelect from '@/ui/components/NodeSelect'; import CreateTable from '@/ui/components/CreateTable'; const { I18n } = DataWithBackend; -const { FieldDecorator, SyncField, SyncCreateTableField } = RenderRow; +const { FieldDecorator, SyncField, SyncCreateTableField, IngestionField } = RenderRow; const { ColumnDecorator } = RenderList; const kuduFieldTypes = [ @@ -84,6 +84,7 @@ export default class KuduSink extends SinkInfo implements DataWithBackend, Rende }) @I18n('meta.Sinks.DataNodeName') @SyncField() + @IngestionField() dataNodeName: string; @FieldDecorator({ @@ -103,6 +104,7 @@ export default class KuduSink extends SinkInfo implements DataWithBackend, Rende @ColumnDecorator() @I18n('meta.Sinks.Kudu.TableName') @SyncField() + @IngestionField() tableName: string; @FieldDecorator({ @@ -124,6 +126,7 @@ export default class KuduSink extends SinkInfo implements DataWithBackend, Rende ], }), }) + @IngestionField() @I18n('meta.Sinks.EnableCreateResource') enableCreateResource: number; @@ -139,6 +142,7 @@ export default class KuduSink extends SinkInfo implements DataWithBackend, Rende @ColumnDecorator() @I18n('meta.Sinks.Kudu.buckets') @SyncField() + @IngestionField() buckets: number; @FieldDecorator({ @@ -168,6 +172,7 @@ export default class KuduSink extends SinkInfo implements DataWithBackend, Rende }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Kudu.ExtList') extList: string; @@ -192,6 +197,7 @@ export default class KuduSink extends SinkInfo implements DataWithBackend, Rende }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Kudu.DataConsistency') dataConsistency: string; @@ -205,6 +211,7 @@ export default class KuduSink extends SinkInfo implements DataWithBackend, Rende upsertByFieldKey: true, }), }) + @IngestionField() sinkFieldList: Record<string, unknown>[]; @FieldDecorator({ diff --git a/inlong-dashboard/src/plugins/sinks/defaults/MySQL.ts b/inlong-dashboard/src/plugins/sinks/defaults/MySQL.ts index 95a18ffdd9..d81dc52de7 100644 --- a/inlong-dashboard/src/plugins/sinks/defaults/MySQL.ts +++ b/inlong-dashboard/src/plugins/sinks/defaults/MySQL.ts @@ -26,7 +26,7 @@ import NodeSelect from '@/ui/components/NodeSelect'; import CreateTable from '@/ui/components/CreateTable'; const { I18n } = DataWithBackend; -const { FieldDecorator, SyncField, SyncCreateTableField } = RenderRow; +const { FieldDecorator, SyncField, SyncCreateTableField, IngestionField } = RenderRow; const { ColumnDecorator } = RenderList; const fieldTypesConf = { @@ -75,6 +75,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende @ColumnDecorator() @I18n('meta.Sinks.MySQL.DatabaseName') @SyncField() + @IngestionField() databaseName: string; @FieldDecorator({ @@ -94,6 +95,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende @ColumnDecorator() @I18n('meta.Sinks.MySQL.TableName') @SyncField() + @IngestionField() tableName: string; @FieldDecorator({ @@ -106,6 +108,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende @ColumnDecorator() @I18n('meta.Sinks.MySQL.PrimaryKey') @SyncField() + @IngestionField() primaryKey: string; @FieldDecorator({ @@ -127,6 +130,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende ], }), }) + @IngestionField() @I18n('meta.Sinks.EnableCreateResource') enableCreateResource: number; @@ -139,6 +143,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende }), }) @SyncField() + @IngestionField() @I18n('meta.Sinks.DataNodeName') dataNodeName: string; @@ -152,6 +157,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende upsertByFieldKey: true, }), }) + @IngestionField() sinkFieldList: Record<string, unknown>[]; @FieldDecorator({ diff --git a/inlong-dashboard/src/plugins/sinks/defaults/Oracle.ts b/inlong-dashboard/src/plugins/sinks/defaults/Oracle.ts index d932d7e58c..9f4808bed3 100644 --- a/inlong-dashboard/src/plugins/sinks/defaults/Oracle.ts +++ b/inlong-dashboard/src/plugins/sinks/defaults/Oracle.ts @@ -25,7 +25,7 @@ import EditableTable from '@/ui/components/EditableTable'; import CreateTable from '@/ui/components/CreateTable'; const { I18n } = DataWithBackend; -const { FieldDecorator, SyncField, SyncCreateTableField } = RenderRow; +const { FieldDecorator, SyncField, SyncCreateTableField, IngestionField } = RenderRow; const { ColumnDecorator } = RenderList; const fieldTypesConf = { @@ -71,6 +71,7 @@ export default class OracleSink extends SinkInfo implements DataWithBackend, Ren @ColumnDecorator() @I18n('JDBC URL') @SyncField() + @IngestionField() jdbcUrl: string; @FieldDecorator({ @@ -89,6 +90,7 @@ export default class OracleSink extends SinkInfo implements DataWithBackend, Ren }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Oracle.TableName') tableName: string; @@ -102,6 +104,7 @@ export default class OracleSink extends SinkInfo implements DataWithBackend, Ren @ColumnDecorator() @I18n('meta.Sinks.Oracle.PrimaryKey') @SyncField() + @IngestionField() primaryKey: string; @FieldDecorator({ @@ -123,6 +126,7 @@ export default class OracleSink extends SinkInfo implements DataWithBackend, Ren ], }), }) + @IngestionField() @I18n('meta.Sinks.EnableCreateResource') enableCreateResource: number; @@ -136,6 +140,7 @@ export default class OracleSink extends SinkInfo implements DataWithBackend, Ren @ColumnDecorator() @I18n('meta.Sinks.Username') @SyncField() + @IngestionField() username: string; @FieldDecorator({ @@ -147,6 +152,7 @@ export default class OracleSink extends SinkInfo implements DataWithBackend, Ren }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Password') password: string; @@ -160,6 +166,7 @@ export default class OracleSink extends SinkInfo implements DataWithBackend, Ren upsertByFieldKey: true, }), }) + @IngestionField() sinkFieldList: Record<string, unknown>[]; @FieldDecorator({ diff --git a/inlong-dashboard/src/plugins/sinks/defaults/PostgreSQL.ts b/inlong-dashboard/src/plugins/sinks/defaults/PostgreSQL.ts index 2e65caa5c7..7cf8db7a4e 100644 --- a/inlong-dashboard/src/plugins/sinks/defaults/PostgreSQL.ts +++ b/inlong-dashboard/src/plugins/sinks/defaults/PostgreSQL.ts @@ -25,7 +25,7 @@ import { sourceFields } from '../common/sourceFields'; import CreateTable from '@/ui/components/CreateTable'; const { I18n } = DataWithBackend; -const { FieldDecorator, SyncField, SyncCreateTableField } = RenderRow; +const { FieldDecorator, SyncField, SyncCreateTableField, IngestionField } = RenderRow; const { ColumnDecorator } = RenderList; const fieldTypesConf = { @@ -74,6 +74,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('JDBC URL') jdbcUrl: string; @@ -86,6 +87,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.PostgreSQL.DbName') dbName: string; @@ -105,6 +107,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.PostgreSQL.TableName') tableName: string; @@ -117,6 +120,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.PostgreSQL.PrimaryKey') primaryKey: string; @@ -139,6 +143,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende ], }), }) + @IngestionField() @I18n('meta.Sinks.EnableCreateResource') enableCreateResource: number; @@ -151,6 +156,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Username') username: string; @@ -163,6 +169,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Password') password: string; @@ -176,6 +183,7 @@ export default class HiveSink extends SinkInfo implements DataWithBackend, Rende upsertByFieldKey: true, }), }) + @IngestionField() sinkFieldList: Record<string, unknown>[]; @FieldDecorator({ diff --git a/inlong-dashboard/src/plugins/sinks/defaults/Pulsar.ts b/inlong-dashboard/src/plugins/sinks/defaults/Pulsar.ts index f2e00cdcab..e13b1f4e6a 100644 --- a/inlong-dashboard/src/plugins/sinks/defaults/Pulsar.ts +++ b/inlong-dashboard/src/plugins/sinks/defaults/Pulsar.ts @@ -24,7 +24,7 @@ import { SinkInfo } from '../common/SinkInfo'; import NodeSelect from '@/ui/components/NodeSelect'; const { I18n } = DataWithBackend; -const { FieldDecorator, SyncField } = RenderRow; +const { FieldDecorator, SyncField, IngestionField } = RenderRow; const { ColumnDecorator } = RenderList; export default class PulsarSink extends SinkInfo implements DataWithBackend, RenderRow, RenderList { @@ -37,6 +37,7 @@ export default class PulsarSink extends SinkInfo implements DataWithBackend, Ren }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Pulsar.Tenant') pulsarTenant: string; @@ -49,6 +50,7 @@ export default class PulsarSink extends SinkInfo implements DataWithBackend, Ren }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Pulsar.Namespace') namespace: string; @@ -61,6 +63,7 @@ export default class PulsarSink extends SinkInfo implements DataWithBackend, Ren }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('Topic') topic: string; @@ -77,6 +80,7 @@ export default class PulsarSink extends SinkInfo implements DataWithBackend, Ren }) @I18n('meta.Sinks.Pulsar.PartitionNum') @ColumnDecorator() + @IngestionField() partitionNum: number; @FieldDecorator({ @@ -89,6 +93,7 @@ export default class PulsarSink extends SinkInfo implements DataWithBackend, Ren }) @I18n('meta.Sinks.DataNodeName') @SyncField() + @IngestionField() @ColumnDecorator() dataNodeName: string; } diff --git a/inlong-dashboard/src/plugins/sinks/defaults/Redis.ts b/inlong-dashboard/src/plugins/sinks/defaults/Redis.ts index d3344ebd85..ad8d1fd365 100644 --- a/inlong-dashboard/src/plugins/sinks/defaults/Redis.ts +++ b/inlong-dashboard/src/plugins/sinks/defaults/Redis.ts @@ -28,7 +28,7 @@ import NodeSelect from '@/ui/components/NodeSelect'; import CreateTable from '@/ui/components/CreateTable'; const { I18n } = DataWithBackend; -const { FieldDecorator, SyncField, SyncCreateTableField } = RenderRow; +const { FieldDecorator, SyncField, SyncCreateTableField, IngestionField } = RenderRow; const { ColumnDecorator } = RenderList; const redisTargetTypes = [ @@ -79,6 +79,7 @@ export default class RedisSink extends SinkInfo implements DataWithBackend, Rend }), }) @SyncField() + @IngestionField() @I18n('meta.Sinks.DataNodeName') dataNodeName: string; @@ -106,6 +107,7 @@ export default class RedisSink extends SinkInfo implements DataWithBackend, Rend }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Redis.DataType') dataType: string; @@ -119,6 +121,7 @@ export default class RedisSink extends SinkInfo implements DataWithBackend, Rend }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Redis.SchemaMapMode') schemaMapMode: string; @@ -150,6 +153,7 @@ export default class RedisSink extends SinkInfo implements DataWithBackend, Rend rules: [{ required: true }], }) @SyncField() + @IngestionField() @I18n('meta.Sinks.Redis.FormatDataType') formatDataType: string; @@ -173,6 +177,7 @@ export default class RedisSink extends SinkInfo implements DataWithBackend, Rend }), }) @SyncField() + @IngestionField() @I18n('meta.Sinks.Redis.FormatIgnoreParseError') formatIgnoreParseError: boolean; @@ -196,6 +201,7 @@ export default class RedisSink extends SinkInfo implements DataWithBackend, Rend rules: [{ required: true }], }) @SyncField() + @IngestionField() @I18n('meta.Sinks.Redis.FormatDataEncoding') formatDataEncoding: string; @@ -249,6 +255,7 @@ export default class RedisSink extends SinkInfo implements DataWithBackend, Rend ], }) @SyncField() + @IngestionField() @I18n('meta.Sinks.Redis.FormatDataSeparator') formatDataSeparator: string; @@ -269,6 +276,7 @@ export default class RedisSink extends SinkInfo implements DataWithBackend, Rend }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.Redis.Database') database: number; @@ -283,6 +291,7 @@ export default class RedisSink extends SinkInfo implements DataWithBackend, Rend suffix: i18n.t('meta.Sinks.Redis.TtlUnit'), }) @SyncField() + @IngestionField() @I18n('meta.Sinks.Redis.Ttl') ttl: number; @@ -296,6 +305,7 @@ export default class RedisSink extends SinkInfo implements DataWithBackend, Rend upsertByFieldKey: true, }), }) + @IngestionField() sinkFieldList: Record<string, unknown>[]; @FieldDecorator({ @@ -339,6 +349,7 @@ export default class RedisSink extends SinkInfo implements DataWithBackend, Rend }), }) @SyncField() + @IngestionField() @I18n('meta.Sinks.Redis.ExtList') properties: string; @@ -353,6 +364,7 @@ export default class RedisSink extends SinkInfo implements DataWithBackend, Rend suffix: i18n.t('meta.Sinks.Redis.TimeoutUnit'), }) @SyncField() + @IngestionField() @I18n('meta.Sinks.Redis.Timeout') timeout: number; @@ -367,6 +379,7 @@ export default class RedisSink extends SinkInfo implements DataWithBackend, Rend suffix: i18n.t('meta.Sinks.Redis.SoTimeoutUnit'), }) @SyncField() + @IngestionField() @I18n('meta.Sinks.Redis.SoTimeout') soTimeout: number; @@ -380,6 +393,7 @@ export default class RedisSink extends SinkInfo implements DataWithBackend, Rend }), }) @SyncField() + @IngestionField() @I18n('meta.Sinks.Redis.MaxTotal') maxTotal: number; @@ -393,6 +407,7 @@ export default class RedisSink extends SinkInfo implements DataWithBackend, Rend }), }) @SyncField() + @IngestionField() @I18n('meta.Sinks.Redis.MaxIdle') maxIdle: number; @@ -406,6 +421,7 @@ export default class RedisSink extends SinkInfo implements DataWithBackend, Rend }), }) @SyncField() + @IngestionField() @I18n('meta.Sinks.Redis.MinIdle') minIdle: number; @@ -420,6 +436,7 @@ export default class RedisSink extends SinkInfo implements DataWithBackend, Rend }), }) @SyncField() + @IngestionField() @I18n('meta.Sinks.Redis.MaxRetries') maxRetries: number; } diff --git a/inlong-dashboard/src/plugins/sinks/defaults/SQLServer.ts b/inlong-dashboard/src/plugins/sinks/defaults/SQLServer.ts index 93f6780246..5f774fa963 100644 --- a/inlong-dashboard/src/plugins/sinks/defaults/SQLServer.ts +++ b/inlong-dashboard/src/plugins/sinks/defaults/SQLServer.ts @@ -25,7 +25,7 @@ import { sourceFields } from '../common/sourceFields'; import CreateTable from '@/ui/components/CreateTable'; const { I18n } = DataWithBackend; -const { FieldDecorator, SyncField, SyncCreateTableField } = RenderRow; +const { FieldDecorator, SyncField, SyncCreateTableField, IngestionField } = RenderRow; const { ColumnDecorator } = RenderList; const fieldTypesConf = { @@ -78,6 +78,7 @@ export default class SqlServerSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('JDBC URL') jdbcUrl: string; @@ -90,6 +91,7 @@ export default class SqlServerSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.SQLServer.SchemaName') schemaName: string; @@ -103,6 +105,7 @@ export default class SqlServerSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.SQLServer.ServerTimezone') serverTimezone: string; @@ -122,6 +125,7 @@ export default class SqlServerSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.SQLServer.TableName') tableName: string; @@ -134,6 +138,7 @@ export default class SqlServerSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.SQLServer.PrimaryKey') primaryKey: string; @@ -156,6 +161,7 @@ export default class SqlServerSink ], }), }) + @IngestionField() @I18n('meta.Sinks.EnableCreateResource') enableCreateResource: number; @@ -178,6 +184,7 @@ export default class SqlServerSink }), }) @SyncField() + @IngestionField() @I18n('meta.Sinks.SQLServer.AllMigration') allMigration: boolean; @@ -189,6 +196,7 @@ export default class SqlServerSink }), }) @SyncField() + @IngestionField() @I18n('meta.Sinks.Username') username: string; @@ -200,6 +208,7 @@ export default class SqlServerSink }), }) @SyncField() + @IngestionField() @I18n('meta.Sinks.Password') password: string; @@ -213,6 +222,7 @@ export default class SqlServerSink upsertByFieldKey: true, }), }) + @IngestionField() sinkFieldList: Record<string, unknown>[]; @FieldDecorator({ diff --git a/inlong-dashboard/src/plugins/sinks/defaults/StarRocks.ts b/inlong-dashboard/src/plugins/sinks/defaults/StarRocks.ts index 42c96db88e..f86a24d15a 100644 --- a/inlong-dashboard/src/plugins/sinks/defaults/StarRocks.ts +++ b/inlong-dashboard/src/plugins/sinks/defaults/StarRocks.ts @@ -26,7 +26,7 @@ import NodeSelect from '@/ui/components/NodeSelect'; import CreateTable from '@/ui/components/CreateTable'; const { I18n } = DataWithBackend; -const { FieldDecorator, SyncField, SyncCreateTableField } = RenderRow; +const { FieldDecorator, SyncField, SyncCreateTableField, IngestionField } = RenderRow; const { ColumnDecorator } = RenderList; const fieldTypesConf = { @@ -71,6 +71,7 @@ export default class StarRocksSink }), }) @SyncField() + @IngestionField() @I18n('meta.Sinks.DataNodeName') dataNodeName: string; @@ -83,6 +84,7 @@ export default class StarRocksSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.StarRocks.DatabaseName') databaseName: string; @@ -102,6 +104,7 @@ export default class StarRocksSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.StarRocks.TableName') tableName: string; @@ -113,6 +116,7 @@ export default class StarRocksSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.StarRocks.PrimaryKey') primaryKey: string; @@ -126,6 +130,7 @@ export default class StarRocksSink upsertByFieldKey: true, }), }) + @IngestionField() sinkFieldList: Record<string, unknown>[]; @FieldDecorator({ diff --git a/inlong-dashboard/src/plugins/sinks/defaults/TDSQLPostgreSQL.ts b/inlong-dashboard/src/plugins/sinks/defaults/TDSQLPostgreSQL.ts index 5d87bb3f1f..93c692422a 100644 --- a/inlong-dashboard/src/plugins/sinks/defaults/TDSQLPostgreSQL.ts +++ b/inlong-dashboard/src/plugins/sinks/defaults/TDSQLPostgreSQL.ts @@ -25,7 +25,7 @@ import { SinkInfo } from '../common/SinkInfo'; import CreateTable from '@/ui/components/CreateTable'; const { I18n } = DataWithBackend; -const { FieldDecorator, SyncField, SyncCreateTableField } = RenderRow; +const { FieldDecorator, SyncField, SyncCreateTableField, IngestionField } = RenderRow; const { ColumnDecorator } = RenderList; const tdsqlPostgreSQLFieldTypes = [ @@ -71,6 +71,7 @@ export default class TDSQLPostgreSQLSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('JDBC URL') jdbcUrl: string; @@ -83,6 +84,7 @@ export default class TDSQLPostgreSQLSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.TDSQLPostgreSQL.SchemaName') schemaName: string; @@ -102,6 +104,7 @@ export default class TDSQLPostgreSQLSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.TDSQLPostgreSQL.TableName') tableName: string; @@ -114,6 +117,7 @@ export default class TDSQLPostgreSQLSink }) @ColumnDecorator() @SyncField() + @IngestionField() @I18n('meta.Sinks.TDSQLPostgreSQL.PrimaryKey') primaryKey: string; @@ -136,6 +140,7 @@ export default class TDSQLPostgreSQLSink ], }), }) + @IngestionField() @I18n('meta.Sinks.EnableCreateResource') enableCreateResource: number; @@ -147,6 +152,7 @@ export default class TDSQLPostgreSQLSink }), }) @SyncField() + @IngestionField() @I18n('meta.Sinks.Username') username: string; @@ -158,6 +164,7 @@ export default class TDSQLPostgreSQLSink }), }) @SyncField() + @IngestionField() @I18n('meta.Sinks.Password') password: string; @@ -171,6 +178,7 @@ export default class TDSQLPostgreSQLSink upsertByFieldKey: true, }), }) + @IngestionField() sinkFieldList: Record<string, unknown>[]; @FieldDecorator({ diff --git a/inlong-dashboard/src/plugins/sources/common/SourceDefaultInfo.ts b/inlong-dashboard/src/plugins/sources/common/SourceDefaultInfo.ts index 2535baf95b..b06f4795ec 100644 --- a/inlong-dashboard/src/plugins/sources/common/SourceDefaultInfo.ts +++ b/inlong-dashboard/src/plugins/sources/common/SourceDefaultInfo.ts @@ -27,7 +27,8 @@ import { sources, defaultValue } from '..'; import i18n from '@/i18n'; const { I18nMap, I18n } = DataWithBackend; -const { FieldList, FieldDecorator, SyncField, SyncFieldSet } = RenderRow; +const { FieldList, FieldDecorator, SyncField, SyncFieldSet, SyncMoveDbField, SyncMoveDbFieldSet } = + RenderRow; const { ColumnList, ColumnDecorator } = RenderList; export class SourceDefaultInfo implements DataWithBackend, RenderRow, RenderList { @@ -35,6 +36,7 @@ export class SourceDefaultInfo implements DataWithBackend, RenderRow, RenderList static FieldList = FieldList; static ColumnList = ColumnList; static SyncFieldSet = SyncFieldSet; + static SyncMoveDbFieldSet = SyncMoveDbFieldSet; readonly id: number; @@ -44,6 +46,7 @@ export class SourceDefaultInfo implements DataWithBackend, RenderRow, RenderList hidden: true, }) @SyncField() + @SyncMoveDbField() @I18n('inlongGroupId') readonly inlongGroupId: string; @@ -52,6 +55,7 @@ export class SourceDefaultInfo implements DataWithBackend, RenderRow, RenderList hidden: true, }) @SyncField() + @SyncMoveDbField() @I18n('inlongStreamId') readonly inlongStreamId: string; @@ -75,6 +79,7 @@ export class SourceDefaultInfo implements DataWithBackend, RenderRow, RenderList render: type => sources.find(c => c.value === type)?.label || type, }) @SyncField() + @SyncMoveDbField() @I18n('meta.Sources.Type') sourceType: string; @@ -95,6 +100,7 @@ export class SourceDefaultInfo implements DataWithBackend, RenderRow, RenderList }) @ColumnDecorator() @SyncField() + @SyncMoveDbField() @I18n('meta.Sources.Name') sourceName: string; @@ -111,6 +117,7 @@ export class SourceDefaultInfo implements DataWithBackend, RenderRow, RenderList render: text => genStatusTag(text), }) @SyncField() + @SyncMoveDbField() @I18n('basic.Status') readonly status: string; @@ -151,6 +158,27 @@ export class SourceDefaultInfo implements DataWithBackend, RenderRow, RenderList }); } + renderSyncEnableRow() { + const constructor = this.constructor as typeof SourceDefaultInfo; + const { FieldList, SyncMoveDbFieldSet } = constructor; + return FieldList.filter(item => { + if (item.name === 'sourceType') { + item.props = values => ({ + disabled: Boolean(values.id), + dropdownMatchSelectWidth: false, + options: sources + .filter(item => item.value === 'MYSQL_BINLOG') + .map(item => ({ + label: item.label, + value: item.value, + image: loadImage(item.label), + })), + }); + } + return SyncMoveDbFieldSet.has(item.name as string); + }); + } + renderRow() { const constructor = this.constructor as typeof SourceDefaultInfo; constructor.FieldList.map(item => { diff --git a/inlong-dashboard/src/plugins/sources/defaults/MySQLBinlog.ts b/inlong-dashboard/src/plugins/sources/defaults/MySQLBinlog.ts index 8c3793edb0..e37ad2539a 100644 --- a/inlong-dashboard/src/plugins/sources/defaults/MySQLBinlog.ts +++ b/inlong-dashboard/src/plugins/sources/defaults/MySQLBinlog.ts @@ -24,7 +24,7 @@ import i18n from '@/i18n'; import { SourceInfo } from '../common/SourceInfo'; const { I18n } = DataWithBackend; -const { FieldDecorator, SyncField } = RenderRow; +const { FieldDecorator, SyncField, SyncMoveDbField } = RenderRow; const { ColumnDecorator } = RenderList; export default class TubeMqSource @@ -40,6 +40,7 @@ export default class TubeMqSource }) @SyncField() @ColumnDecorator() + @SyncMoveDbField() @I18n('meta.Sources.Db.Server') hostname: string; @@ -55,6 +56,7 @@ export default class TubeMqSource }) @SyncField() @ColumnDecorator() + @SyncMoveDbField() @I18n('meta.Sources.Db.Port') port: number; @@ -66,6 +68,7 @@ export default class TubeMqSource }), }) @SyncField() + @SyncMoveDbField() @I18n('meta.Sources.Db.User') user: string; @@ -77,6 +80,7 @@ export default class TubeMqSource }), }) @SyncField() + @SyncMoveDbField() @I18n('meta.Sources.Db.Password') password: string; @@ -135,7 +139,6 @@ export default class TubeMqSource ], }), }) - @SyncField() @I18n('meta.Sources.Db.AllMigration') allMigration: boolean; @@ -158,6 +161,7 @@ export default class TubeMqSource }), }) @SyncField() + @SyncMoveDbField() @I18n('meta.Sources.Db.ReadMode') onlyIncremental: boolean; @@ -170,6 +174,7 @@ export default class TubeMqSource }), }) @SyncField() + @SyncMoveDbField() @I18n('meta.Sources.Db.DatabaseWhiteList') databaseWhiteList: string; @@ -180,9 +185,9 @@ export default class TubeMqSource props: values => ({ disabled: values?.status === 101, }), - visible: values => !values?.allMigration, }) @SyncField() + @SyncMoveDbField() @I18n('meta.Sources.Db.TableWhiteList') tableWhiteList: boolean; } diff --git a/inlong-dashboard/src/plugins/sync/common/SyncDefaultInfo.ts b/inlong-dashboard/src/plugins/sync/common/SyncDefaultInfo.ts index 6423e9ffb0..a32c750d81 100644 --- a/inlong-dashboard/src/plugins/sync/common/SyncDefaultInfo.ts +++ b/inlong-dashboard/src/plugins/sync/common/SyncDefaultInfo.ts @@ -102,6 +102,26 @@ export class SyncDefaultInfo implements DataWithBackend, RenderRow, RenderList { @I18n('meta.Group.InlongGroupOwners') inCharges: string; + @FieldDecorator({ + type: 'radio', + initialValue: false, + rules: [{ required: true }], + props: { + options: [ + { + label: i18n.t('meta.Consume.Yes'), + value: true, + }, + { + label: i18n.t('meta.Consume.No'), + value: false, + }, + ], + }, + }) + @I18n('components.Synchronize.SinkMultipleEnable') + sinkMultipleEnable: boolean; + @FieldDecorator({ type: 'textarea', props: { diff --git a/inlong-dashboard/src/ui/locales/cn.json b/inlong-dashboard/src/ui/locales/cn.json index c35005a163..eb1a426f47 100644 --- a/inlong-dashboard/src/ui/locales/cn.json +++ b/inlong-dashboard/src/ui/locales/cn.json @@ -205,7 +205,11 @@ "meta.Sinks.Iceberg.Description": "表描述", "meta.Sinks.Iceberg.ExtList": "属性", "meta.Sinks.Iceberg.DataConsistency": "数据一致性", - "meta.Sinks.Iceberg.PartitionStrategy": "分区策略", + "meta.Sinks.Iceberg.DatabasePattern": "库匹配策略", + "meta.Sinks.Iceberg.TablePattern": "表匹配策略", + "meta.Sinks.Iceberg.Options.DBSameName": "与来源库同名", + "meta.Sinks.Iceberg.Options.TableSameName": "与来源表同名", + "meta.Sinks.Iceberg.Options.Customize": "自定义", "meta.Sinks.Hudi.DbName": "DB 名称", "meta.Sinks.Hudi.TableName": "表名称", "meta.Sinks.Hudi.Warehouse": "仓库路径", @@ -815,6 +819,7 @@ "pages.SynchronizeDetail.Transform.Type.Field": "字段", "pages.SynchronizeDetail.Transform.Type.CustomValue": "自定义值", "pages.SynchronizeDetail.Transform.ComparisonValue": "比较值", + "components.Synchronize.SinkMultipleEnable": "整库迁移", "components.FieldList.Source": "源字段", "components.FieldList.Sink": "目标字段", "components.FieldList.CreateSource": "新建源字段", diff --git a/inlong-dashboard/src/ui/locales/en.json b/inlong-dashboard/src/ui/locales/en.json index 9853526fe1..f32c06445b 100644 --- a/inlong-dashboard/src/ui/locales/en.json +++ b/inlong-dashboard/src/ui/locales/en.json @@ -206,6 +206,11 @@ "meta.Sinks.Iceberg.ExtList": "Ext list", "meta.Sinks.Iceberg.DataConsistency": "Data consistency", "meta.Sinks.Iceberg.PartitionStrategy": "Partition strategy", + "meta.Sinks.Iceberg.DatabasePattern": "Database name pattern", + "meta.Sinks.Iceberg.TablePattern": "Table name pattern", + "meta.Sinks.Iceberg.Options.DBSameName": "Same as source database", + "meta.Sinks.Iceberg.Options.TableSameName": "Same as source table", + "meta.Sinks.Iceberg.Options.Customize": "Customize", "meta.Sinks.Hudi.DbName": "Db name", "meta.Sinks.Hudi.TableName": "Table name", "meta.Sinks.Hudi.Warehouse": "Warehouse", @@ -818,6 +823,7 @@ "pages.SynchronizeDetail.Transform.Type.Field": "Field", "pages.SynchronizeDetail.Transform.Type.CustomValue": "Custom value", "pages.SynchronizeDetail.Transform.ComparisonValue": "Comparison value", + "components.Synchronize.SinkMultipleEnable": "Full database migration", "components.FieldList.AddField": "Add field", "pages.Tenant.config.Description": "Description", "pages.Tenant.config.Name": "Tenant name", diff --git a/inlong-dashboard/src/ui/pages/SynchronizeDetail/Info/index.tsx b/inlong-dashboard/src/ui/pages/SynchronizeDetail/Info/index.tsx index 2bceedd3cc..5673ac1ced 100644 --- a/inlong-dashboard/src/ui/pages/SynchronizeDetail/Info/index.tsx +++ b/inlong-dashboard/src/ui/pages/SynchronizeDetail/Info/index.tsx @@ -72,6 +72,9 @@ const Comp = ({ inlongGroupId, inlongStreamId, readonly, isCreate }: Props, ref) }), { manual: true, + onSuccess: result => { + form.setFieldValue('sinkMultipleEnable', result.sinkMultipleEnable); + }, }, ); const { data: streamData, run: getDataStream } = useRequest( @@ -108,6 +111,7 @@ const Comp = ({ inlongGroupId, inlongStreamId, readonly, isCreate }: Props, ref) inlongStreamId: values.inlongStreamId, name: values.streamName, fieldList: streamDetail?.fieldList, + sinkMultipleEnable: values.sinkMultipleEnable, }; if (streamData !== undefined) { submitDataStream['version'] = streamData?.list[0].version; diff --git a/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncSink/DetailModal.tsx b/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncSink/DetailModal.tsx index bf11190df4..1e1f583810 100644 --- a/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncSink/DetailModal.tsx +++ b/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncSink/DetailModal.tsx @@ -26,6 +26,7 @@ import EditableTable from '@/ui/components/EditableTable'; import FormGenerator, { useForm } from '@/ui/components/FormGenerator'; import { useLoadMeta, SinkMetaType } from '@/plugins'; import request from '@/core/utils/request'; +import { dataToForm, paramReplace } from './helper'; import { State } from '@/core/stores'; import { useLocalStorage } from '@/core/utils/localStorage'; import { dataToMap } from '../SyncT/helper'; @@ -36,6 +37,7 @@ export interface DetailModalProps extends ModalProps { defaultType?: string; // (True operation, save and adjust interface) Need to upload when editing id?: string; + sinkMultipleEnable?: boolean; // others onOk?: (values) => void; } @@ -45,6 +47,7 @@ const Comp: React.FC<DetailModalProps> = ({ inlongStreamId, defaultType, id, + sinkMultipleEnable, ...modalProps }) => { const [form] = useForm(); @@ -76,7 +79,7 @@ const Comp: React.FC<DetailModalProps> = ({ formatResult: result => new Entity()?.parse(result) || result, onSuccess: result => { setSinkType(result.sinkType); - form.setFieldsValue(result); + form.setFieldsValue(dataToForm(result.sinkType, result)); }, }, ); @@ -99,7 +102,9 @@ const Comp: React.FC<DetailModalProps> = ({ const formContent = useMemo(() => { if (Entity) { - const row = new Entity().renderSyncRow(); + const row = sinkMultipleEnable + ? new Entity().renderSyncAllRow() + : new Entity().renderSyncRow(); return row.map(item => ({ ...item, col: item.name === 'sinkType' || item.type === EditableTable ? 24 : 12, @@ -111,7 +116,10 @@ const Comp: React.FC<DetailModalProps> = ({ const onOk = async (startProcess = false) => { const values = await form.validateFields(); - const submitData = new Entity()?.stringify(values) || values; + const replaceValues = paramReplace(values.sinkType, values); + const submitData = sinkMultipleEnable + ? new Entity()?.stringify(replaceValues) || replaceValues + : new Entity()?.stringify(values) || values; const isUpdate = Boolean(id); const createData = getLocalStorage('createTableData'); if (submitData?.properties !== undefined && submitData?.properties.length !== 0) { @@ -163,7 +171,7 @@ const Comp: React.FC<DetailModalProps> = ({ > <Spin spinning={loading || pluginLoading}> <FormGenerator - labelCol={{ flex: '0 0 200px' }} + labelCol={{ flex: '0 0 170px' }} wrapperCol={{ flex: '1' }} col={12} content={formContent} diff --git a/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncSink/helper.ts b/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncSink/helper.ts new file mode 100644 index 0000000000..5421816eb2 --- /dev/null +++ b/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncSink/helper.ts @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const paramReplace = (sinkType, values) => { + const replaceValues = values; + if (sinkType === 'ICEBERG') { + if (values.backupDatabase === '${database}') { + replaceValues.databasePattern = values.backupDatabase; + } + if (values.backupTable === '${table}') { + replaceValues.tablePattern = values.backupTable; + } + } + replaceValues.sinkMultipleFormat = 'canal'; + replaceValues.sinkMultipleEnable = true; + replaceValues.enableCreateResource = 0; + return replaceValues; +}; + +export const dataToForm = (sinkType, data) => { + const sinkData = data; + if (sinkType === 'ICEBERG') { + if (data.databasePattern !== '${database}') { + sinkData.backupDatabase = 'false'; + } + if (data.tablePattern !== '${table}') { + sinkData.backupTable = 'false'; + } + } + return sinkData; +}; diff --git a/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncSink/index.tsx b/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncSink/index.tsx index cdb06da937..9e7c243630 100644 --- a/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncSink/index.tsx +++ b/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncSink/index.tsx @@ -41,7 +41,7 @@ interface Props extends CommonInterface { inlongStreamId: string; } -const Comp = ({ inlongGroupId, inlongStreamId, readonly }: Props, ref) => { +const Comp = ({ inlongGroupId, inlongStreamId, sinkMultipleEnable, readonly }: Props, ref) => { const [mode, setMode] = useState('list'); const { defaultValue } = useDefaultMeta('sink'); @@ -138,7 +138,13 @@ const Comp = ({ inlongGroupId, inlongStreamId, readonly }: Props, ref) => { }, [Entity]); const entityFields = useMemo(() => { - return Entity ? new Entity().renderSyncRow() : []; + return sinkMultipleEnable + ? Entity + ? new Entity().renderSyncAllRow() + : [] + : Entity + ? new Entity().renderSyncRow() + : []; }, [Entity]); const getFilterFormContent = useCallback( @@ -276,6 +282,7 @@ const Comp = ({ inlongGroupId, inlongStreamId, readonly }: Props, ref) => { inlongGroupId={inlongGroupId} inlongStreamId={inlongStreamId} open={createModal.open as boolean} + sinkMultipleEnable={sinkMultipleEnable} onOk={async () => { await getList(); setCreateModal({ open: false }); diff --git a/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncSources/DetailModal.tsx b/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncSources/DetailModal.tsx index d90830cc47..9081175919 100644 --- a/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncSources/DetailModal.tsx +++ b/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncSources/DetailModal.tsx @@ -33,6 +33,7 @@ export interface Props extends ModalProps { inlongStreamId: string; defaultType?: string; sourceType?: string; + sinkMultipleEnable?: boolean; } const Comp: React.FC<Props> = ({ @@ -41,6 +42,7 @@ const Comp: React.FC<Props> = ({ inlongStreamId, defaultType, sourceType, + sinkMultipleEnable, ...modalProps }) => { const [form] = useForm(); @@ -80,6 +82,8 @@ const Comp: React.FC<Props> = ({ return; } + submitData.allMigration = sinkMultipleEnable; + await request({ url: `/source/${isUpdate ? 'update' : 'save'}`, method: 'POST', @@ -108,7 +112,13 @@ const Comp: React.FC<Props> = ({ }, [modalProps.open]); const formContent = useMemo(() => { - return Entity ? new Entity().renderSyncRow() : []; + return sinkMultipleEnable + ? Entity + ? new Entity().renderSyncEnableRow() + : [] + : Entity + ? new Entity().renderSyncRow() + : []; }, [Entity]); return ( diff --git a/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncSources/index.tsx b/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncSources/index.tsx index 6afd8458d7..20ddb402c7 100644 --- a/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncSources/index.tsx +++ b/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncSources/index.tsx @@ -45,7 +45,7 @@ interface Props extends CommonInterface { inlongStreamId: string; } -const Comp = ({ inlongGroupId, inlongStreamId, readonly }: Props, ref) => { +const Comp = ({ inlongGroupId, inlongStreamId, sinkMultipleEnable, readonly }: Props, ref) => { const [mode, setMode] = useState('list'); const { defaultValue } = useDefaultMeta('source'); @@ -181,7 +181,13 @@ const Comp = ({ inlongGroupId, inlongStreamId, readonly }: Props, ref) => { }, [Entity]); const entityFields = useMemo(() => { - return Entity ? new Entity().renderSyncRow() : []; + return sinkMultipleEnable + ? Entity + ? new Entity().renderSyncEnableRow() + : [] + : Entity + ? new Entity().renderSyncRow() + : []; }, [Entity]); const getFilterFormContent = useCallback( @@ -345,6 +351,7 @@ const Comp = ({ inlongGroupId, inlongStreamId, readonly }: Props, ref) => { inlongStreamId={inlongStreamId} sourceType={data?.list[0]?.sourceType} open={createModal.open as boolean} + sinkMultipleEnable={sinkMultipleEnable} onOk={async () => { await getList(); setCreateModal({ open: false }); diff --git a/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncT/SyncDatabaseCard.tsx b/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncT/SyncDatabaseCard.tsx new file mode 100644 index 0000000000..c44e4ca8d2 --- /dev/null +++ b/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncT/SyncDatabaseCard.tsx @@ -0,0 +1,58 @@ +/* + * 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 React from 'react'; +import { Col, Row } from 'antd'; +import { DoubleRightOutlined } from '@ant-design/icons'; +import SyncSources from '../SyncSources'; +import SyncSink from '../SyncSink'; + +export interface Props { + inlongGroupId: string; + inlongStreamId: string; + sinkMultipleEnable?: boolean; +} + +const Comp: React.FC<Props> = ({ inlongGroupId, inlongStreamId, sinkMultipleEnable }) => { + return ( + <> + <Row gutter={60}> + <Col span={12}> + <SyncSources + sinkMultipleEnable={sinkMultipleEnable} + inlongGroupId={inlongGroupId} + inlongStreamId={inlongStreamId} + /> + </Col> + <Col span={12}> + <SyncSink + sinkMultipleEnable={sinkMultipleEnable} + inlongGroupId={inlongGroupId} + inlongStreamId={inlongStreamId} + /> + </Col> + <DoubleRightOutlined + style={{ position: 'absolute', top: '50%', left: 'calc(50% - 7px)' }} + /> + </Row> + </> + ); +}; + +export default Comp; diff --git a/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncT/index.tsx b/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncT/index.tsx index 5be4696798..285e71d2a6 100644 --- a/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncT/index.tsx +++ b/inlong-dashboard/src/ui/pages/SynchronizeDetail/SyncT/index.tsx @@ -19,28 +19,24 @@ import React, { useState, forwardRef, useEffect } from 'react'; import { defaultSize } from '@/configs/pagination'; -import { useRequest, useUpdateEffect } from '@/ui/hooks'; +import { useRequest } from '@/ui/hooks'; import SourceSinkCard from './SourceSinkCard'; +import SyncDatabaseCard from './SyncDatabaseCard'; const Comp = ({ inlongGroupId, readonly, mqType }) => { - const [options, setOptions] = useState({ - pageSize: defaultSize, - pageNum: 1, - }); - const [inlongStreamId, setInlongStreamId] = useState(''); + const [sinkMultipleEnable, setSinkMultipleEnable] = useState(false); const { data, run: getList } = useRequest( { url: '/stream/list', method: 'POST', data: { - ...options, inlongGroupId, }, }, { - refreshDeps: [options], + manual: true, onSuccess: result => { const [item] = result?.list || []; setInlongStreamId(item.inlongStreamId); @@ -48,15 +44,40 @@ const Comp = ({ inlongGroupId, readonly, mqType }) => { }, ); + const { data: streamDetail, run: getStreamDetail } = useRequest( + streamId => ({ + url: `/stream/getBrief`, + params: { + groupId: inlongGroupId, + streamId, + }, + }), + { + manual: true, + onSuccess: result => { + setSinkMultipleEnable(result.sinkMultipleEnable); + }, + }, + ); + useEffect(() => { if (inlongGroupId !== null) { getList(); + getStreamDetail(inlongStreamId); } }, []); return ( <> - <SourceSinkCard inlongGroupId={inlongGroupId} inlongStreamId={inlongStreamId} /> + {sinkMultipleEnable ? ( + <SyncDatabaseCard + sinkMultipleEnable={sinkMultipleEnable} + inlongGroupId={inlongGroupId} + inlongStreamId={inlongStreamId} + /> + ) : ( + <SourceSinkCard inlongGroupId={inlongGroupId} inlongStreamId={inlongStreamId} /> + )} </> ); }; diff --git a/inlong-dashboard/src/ui/pages/SynchronizeDetail/common.d.ts b/inlong-dashboard/src/ui/pages/SynchronizeDetail/common.d.ts index 2fbb8f78d5..f277ad80b9 100644 --- a/inlong-dashboard/src/ui/pages/SynchronizeDetail/common.d.ts +++ b/inlong-dashboard/src/ui/pages/SynchronizeDetail/common.d.ts @@ -22,5 +22,6 @@ export interface CommonInterface { inlongStreamId: string; readonly?: boolean; isCreate?: boolean; + sinkMultipleEnable?: boolean; ref?: React.RefObject<unknown>; }