You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@inlong.apache.org by do...@apache.org on 2022/09/22 03:52:08 UTC

[inlong] branch master updated: [INLONG-5986][Dashboard] Support fieldType field to set length (#5987)

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 09d66316a [INLONG-5986][Dashboard] Support fieldType field to set length (#5987)
09d66316a is described below

commit 09d66316ae03428db27f83da6d912978c10236eb
Author: Daniel <le...@apache.org>
AuthorDate: Thu Sep 22 11:52:02 2022 +0800

    [INLONG-5986][Dashboard] Support fieldType field to set length (#5987)
---
 .../src/components/EditableTable/index.tsx         | 22 ++++--
 inlong-dashboard/src/metas/sinks/clickhouse.tsx    |  1 -
 inlong-dashboard/src/metas/sinks/mysql.tsx         | 85 ++++++++++++++--------
 3 files changed, 73 insertions(+), 35 deletions(-)

diff --git a/inlong-dashboard/src/components/EditableTable/index.tsx b/inlong-dashboard/src/components/EditableTable/index.tsx
index ee4cc5885..cadfa05ed 100644
--- a/inlong-dashboard/src/components/EditableTable/index.tsx
+++ b/inlong-dashboard/src/components/EditableTable/index.tsx
@@ -52,6 +52,8 @@ export interface ColumnsItemProps {
 }
 
 export interface EditableTableProps {
+  // id comes from FormItem, like name
+  id?: string;
   value?: RowValueType[];
   onChange?: (value: RowValueType[]) => void;
   size?: string;
@@ -92,6 +94,7 @@ const addIdToValues = (values: RowValueType[]): RecordType[] =>
   });
 
 const Comp = ({
+  id,
   value,
   onChange,
   columns,
@@ -101,6 +104,12 @@ const Comp = ({
   canAdd = true,
   size,
 }: EditableTableProps) => {
+  if (!id) {
+    console.error(
+      'The id is lost, which may cause an error in the value of the array. Please check! Has the component library changed?',
+    );
+  }
+
   const { t } = useTranslation();
 
   const [data, setData] = useState<RecordType[]>(
@@ -234,12 +243,15 @@ const Comp = ({
         // Use div to wrap input, select, etc. so that the value and onChange events are not taken over by FormItem
         // So the actual value change must be changed by onChange itself and then exposed to the outer component
         <Form.Item
-          rules={item.rules?.map(item => ({
-            ...item,
-            transform: () => text ?? '',
-          }))}
+          rules={
+            id
+              ? item.rules
+              : item.rules?.map(rule =>
+                  typeof rule === 'function' ? rule : { ...rule, transform: () => text ?? '' },
+                )
+          }
           messageVariables={{ label: item.title }}
-          name={['__proto__', 'editableRow', idx, item.dataIndex]}
+          name={id ? [id, idx, item.dataIndex] : ['__proto__', 'editableRow', idx, item.dataIndex]}
           className={styles.formItem}
         >
           <div>{formCompObj[item.type || 'input']}</div>
diff --git a/inlong-dashboard/src/metas/sinks/clickhouse.tsx b/inlong-dashboard/src/metas/sinks/clickhouse.tsx
index 76623d32f..9d21896ef 100644
--- a/inlong-dashboard/src/metas/sinks/clickhouse.tsx
+++ b/inlong-dashboard/src/metas/sinks/clickhouse.tsx
@@ -93,7 +93,6 @@ export const clickhouse: FieldItemType[] = [
     name: 'password',
     type: 'password',
     label: i18n.t('meta.Sinks.Password'),
-    rules: [{ required: true }],
     props: values => ({
       disabled: [110, 130].includes(values?.status),
     }),
diff --git a/inlong-dashboard/src/metas/sinks/mysql.tsx b/inlong-dashboard/src/metas/sinks/mysql.tsx
index bef4d7220..28f8c48e2 100644
--- a/inlong-dashboard/src/metas/sinks/mysql.tsx
+++ b/inlong-dashboard/src/metas/sinks/mysql.tsx
@@ -20,31 +20,40 @@ import type { FieldItemType } from '@/metas/common';
 import EditableTable from '@/components/EditableTable';
 import { sourceFields } from './common/sourceFields';
 
-const mysqlFieldTypes = [
-  'TINYINT',
-  'SMALLINT',
-  'MEDIUMINT',
-  'INT',
-  'FLOAT',
-  'BIGINT',
-  'DOUBLE',
-  'NUMERIC',
-  'DECIMAL',
-  'BOOLEAN',
-  'DATE',
-  'TIME',
-  'DATETIME',
-  'CHAR',
-  'VARCHAR',
-  'TEXT',
-  'BINARY',
-  'VARBINARY',
-  'BLOB',
-  // 'interval',
-].map(item => ({
-  label: item,
-  value: item,
-}));
+const fieldTypesConf = {
+  TINYINT: (m, d) => (1 <= m && m <= 4 ? '' : '1<=M<=4'),
+  SMALLINT: (m, d) => (1 <= m && m <= 6 ? '' : '1<=M<=6'),
+  MEDIUMINT: (m, d) => (1 <= m && m <= 9 ? '' : '1<=M<=9'),
+  INT: (m, d) => (1 <= m && m <= 11 ? '' : '1<=M<=11'),
+  FLOAT: (m, d) =>
+    1 <= m && m <= 255 && 1 <= d && d <= 30 && d <= m - 2 ? '' : '1<=M<=255,1<=D<=30,D<=M-2',
+  BIGINT: (m, d) => (1 <= m && m <= 20 ? '' : '1<=M<=20'),
+  DOUBLE: (m, d) =>
+    1 <= m && m <= 255 && 1 <= d && d <= 30 && d <= m - 2 ? '' : '1<=M<=255,1<=D<=30,D<=M-2',
+  NUMERIC: (m, d) =>
+    1 <= m && m <= 255 && 1 <= d && d <= 30 && d <= m - 2 ? '' : '1<=M<=255,1<=D<=30,D<=M-2',
+  DECIMAL: (m, d) =>
+    1 <= m && m <= 255 && 1 <= d && d <= 30 && d <= m - 2 ? '' : '1<=M<=255,1<=D<=30,D<=M-2',
+  BOOLEAN: () => '',
+  DATE: () => '',
+  TIME: () => '',
+  DATETIME: () => '',
+  CHAR: (m, d) => (1 <= m && m <= 255 ? '' : '1<=M<=255'),
+  VARCHAR: (m, d) => (1 <= m && m <= 255 ? '' : '1<=M<=255'),
+  TEXT: () => '',
+  BINARY: (m, d) => (1 <= m && m <= 64 ? '' : '1<=M<=64'),
+  VARBINARY: (m, d) => (1 <= m && m <= 64 ? '' : '1<=M<=64'),
+  BLOB: () => '',
+};
+
+const fieldTypes = Object.keys(fieldTypesConf).reduce(
+  (acc, key) =>
+    acc.concat({
+      label: key,
+      value: key,
+    }),
+  [],
+);
 
 export const mysql: FieldItemType[] = [
   {
@@ -148,13 +157,31 @@ const getFieldListColumns = sinkValues => {
     {
       title: `MYSQL${i18n.t('meta.Sinks.MySQL.FieldType')}`,
       dataIndex: 'fieldType',
-      initialValue: mysqlFieldTypes[0].value,
-      type: 'select',
+      initialValue: fieldTypes[0].value,
+      type: 'autocomplete',
       props: (text, record, idx, isNew) => ({
-        options: mysqlFieldTypes,
+        options: fieldTypes,
         disabled: [110, 130].includes(sinkValues?.status as number) && !isNew,
+        allowClear: true,
       }),
-      rules: [{ required: true }],
+      rules: [
+        { required: true },
+        () => ({
+          validator(_, val) {
+            if (val) {
+              const [, type = val, typeLength = ''] = val.match(/^(.+)\((.+)\)$/) || [];
+              if (fieldTypesConf.hasOwnProperty(type)) {
+                const [m = -1, d = -1] = typeLength.split(',');
+                const errMsg = fieldTypesConf[type]?.(m, d);
+                if (typeLength && errMsg) return Promise.reject(new Error(errMsg));
+              } else {
+                return Promise.reject(new Error('FieldType error'));
+              }
+            }
+            return Promise.resolve();
+          },
+        }),
+      ],
     },
     {
       title: i18n.t('meta.Sinks.MySQL.IsMetaField'),