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 b22a3bdca8 [INLONG-10256][DashBoard] Modify the data source IP item of 
the file data source form in the data access module (#10258)
b22a3bdca8 is described below

commit b22a3bdca881d6f47b55bd1f477b772afd844fd9
Author: wohainilaodou <[email protected]>
AuthorDate: Mon May 27 09:36:24 2024 +0800

    [INLONG-10256][DashBoard] Modify the data source IP item of the file data 
source form in the data access module (#10258)
    
    Co-authored-by: v_shuomqiu <v_shuomqiu@tencent>
---
 inlong-dashboard/src/core/utils/pattern.ts         |  2 +
 .../src/plugins/sources/defaults/File.ts           | 32 +++++++++-----
 .../src/ui/components/MultiSelectWithAll/index.tsx | 50 ++++++++++++++++++++++
 inlong-dashboard/src/ui/locales/cn.json            |  3 +-
 inlong-dashboard/src/ui/locales/en.json            |  1 +
 .../pages/GroupDetail/DataSources/DetailModal.tsx  |  2 +
 6 files changed, 79 insertions(+), 11 deletions(-)

diff --git a/inlong-dashboard/src/core/utils/pattern.ts 
b/inlong-dashboard/src/core/utils/pattern.ts
index ab0543d86e..84e5e3985f 100644
--- a/inlong-dashboard/src/core/utils/pattern.ts
+++ b/inlong-dashboard/src/core/utils/pattern.ts
@@ -23,6 +23,8 @@
 // eslint-disable-next-line
 export default {
   ip: 
/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,
+  fileIp:
+    
/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?:,\s*(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]))*$|^All$/,
   url: 
/^https?:\/\/(([a-zA-Z0-9_-])+(\.)?)*(:\d+)?(\/((\.)?(\?)?=?&?[a-zA-Z0-9_-](\?)?)*)*$/i,
   port: 
/^([1-9](\d{0,3}))$|^([1-5]\d{4})$|^(6[0-4]\d{3})$|^(65[0-4]\d{2})$|^(655[0-2]\d)$|^(6553[0-5])$/,
 };
diff --git a/inlong-dashboard/src/plugins/sources/defaults/File.ts 
b/inlong-dashboard/src/plugins/sources/defaults/File.ts
index 9e5107fe24..52835a7e87 100644
--- a/inlong-dashboard/src/plugins/sources/defaults/File.ts
+++ b/inlong-dashboard/src/plugins/sources/defaults/File.ts
@@ -23,6 +23,7 @@ import { RenderList } from '@/plugins/RenderList';
 import i18n from '@/i18n';
 import rulesPattern from '@/core/utils/pattern';
 import { SourceInfo } from '../common/SourceInfo';
+import MultiSelectWithALL, { ALL_OPTION_VALUE } from 
'@/ui/components/MultiSelectWithAll';
 
 const { I18n } = DataWithBackend;
 const { FieldDecorator, IngestionField } = RenderRow;
@@ -82,15 +83,17 @@ export default class PulsarSource
   clusterId: number;
 
   @FieldDecorator({
-    type: 'select',
+    type: MultiSelectWithALL,
+    tooltip: i18n.t('meta.Sources.File.FileIpHelp'),
     rules: [
       {
-        pattern: rulesPattern.ip,
+        pattern: rulesPattern.fileIp,
         message: i18n.t('meta.Sources.File.IpRule'),
         required: true,
       },
     ],
     props: values => ({
+      mode: 'multiple',
       disabled: Boolean(values.id),
       showSearch: true,
       allowClear: true,
@@ -108,12 +111,21 @@ export default class PulsarSource
           },
         }),
         requestParams: {
-          formatResult: result =>
-            result?.list?.map(item => ({
-              ...item,
-              label: item.ip,
-              value: item.ip,
-            })),
+          formatResult: result => {
+            const allOption = {
+              label: ALL_OPTION_VALUE,
+              value: ALL_OPTION_VALUE,
+            };
+            return result?.list
+              ? [
+                  allOption,
+                  ...result.list.map(item => ({
+                    label: item.ip,
+                    value: item.ip,
+                  })),
+                ]
+              : [allOption];
+          },
         },
       },
     }),
@@ -121,7 +133,7 @@ export default class PulsarSource
   @ColumnDecorator()
   @IngestionField()
   @I18n('meta.Sources.File.DataSourceIP')
-  agentIp: string;
+  agentIp: string[] | string;
 
   @FieldDecorator({
     type: 'input',
@@ -182,7 +194,7 @@ export default class PulsarSource
     initialValue: '0h',
     rules: [
       {
-        pattern: /-?[0-9][mhd]$/,
+        pattern: /-?\d+[mhd]$/,
         required: true,
         message: i18n.t('meta.Sources.File.TimeOffsetRules'),
       },
diff --git a/inlong-dashboard/src/ui/components/MultiSelectWithAll/index.tsx 
b/inlong-dashboard/src/ui/components/MultiSelectWithAll/index.tsx
new file mode 100644
index 0000000000..35b414b29a
--- /dev/null
+++ b/inlong-dashboard/src/ui/components/MultiSelectWithAll/index.tsx
@@ -0,0 +1,50 @@
+/*
+ * 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, { useState, useEffect } from 'react';
+import HighSelect from '@/ui/components/HighSelect';
+
+export const ALL_OPTION_VALUE = 'All';
+const MultiSelectWithALL = props => {
+  const [selectedValues, setSelectedValues] = useState([]);
+
+  const handleSelectChange = (value, option) => {
+    let newSelectedValues = [];
+    if (value[value.length - 1] === ALL_OPTION_VALUE) {
+      newSelectedValues = [ALL_OPTION_VALUE];
+    } else {
+      newSelectedValues = value.filter(item => item !== ALL_OPTION_VALUE);
+    }
+
+    setSelectedValues(newSelectedValues);
+    if (props.onChange) {
+      props.onChange(newSelectedValues);
+    }
+  };
+
+  useEffect(() => {
+    if ('value' in props) {
+      setSelectedValues(props.value || []);
+    }
+  }, [props.value]);
+
+  return <HighSelect {...props} value={selectedValues} 
onChange={handleSelectChange} />;
+};
+
+export default MultiSelectWithALL;
diff --git a/inlong-dashboard/src/ui/locales/cn.json 
b/inlong-dashboard/src/ui/locales/cn.json
index 831ca63cae..0691781f38 100644
--- a/inlong-dashboard/src/ui/locales/cn.json
+++ b/inlong-dashboard/src/ui/locales/cn.json
@@ -32,7 +32,8 @@
   "meta.Sources.File.ClusterName": "集群名称",
   "meta.Sources.File.FilePath": "⽂件路径",
   "meta.Sources.File.FilePathHelp": "必须是绝对路径,支持正则表达式,多个时以逗号分隔,如:/data/.*log",
-  "meta.Sources.File.IpRule": "请输入正确的IP地址",
+  "meta.Sources.File.FileIpHelp": "请选择文件采集节点 IP,若 IP 不固定请选择 All",
+  "meta.Sources.File.IpRule": "请输入正确的 IP 地址",
   "meta.Sources.File.TimeOffset": "时间偏移量",
   "meta.Sources.File.TimeOffsetHelp": 
"从文件的某个时间开始采集,'1m'表示1分钟之后,'-1m'表示1分钟之前,支持m(分钟),h(小时),d(天),空则从当前时间开始采集",
   "meta.Sources.File.TimeOffsetRules": "只能包含数字和字母 m、h、d",
diff --git a/inlong-dashboard/src/ui/locales/en.json 
b/inlong-dashboard/src/ui/locales/en.json
index 5b6aa65056..828b7e7e8f 100644
--- a/inlong-dashboard/src/ui/locales/en.json
+++ b/inlong-dashboard/src/ui/locales/en.json
@@ -32,6 +32,7 @@
   "meta.Sources.File.ClusterName": "Cluster name",
   "meta.Sources.File.FilePath": "File path",
   "meta.Sources.File.FilePathHelp": "Must be an absolute path and support 
regular expressions, such as: /data/.*log",
+  "meta.Sources.File.FileIpHelp": "Please select the file collection node IP. 
If the IP is not fixed, please select All",
   "meta.Sources.File.IpRule": "Please enter the IP address correctly",
   "meta.Sources.File.TimeOffset": "Time offset",
   "meta.Sources.File.TimeOffsetHelp": "The file will be collected from a 
certain time,' 1m' means 1 minute later,' -1m' means 1 minute before, and 
m(minute), h(hour), d(day) are supported. If it is empty, the file will be 
collected from the current time",
diff --git 
a/inlong-dashboard/src/ui/pages/GroupDetail/DataSources/DetailModal.tsx 
b/inlong-dashboard/src/ui/pages/GroupDetail/DataSources/DetailModal.tsx
index 970ccd6106..62af7bcbb7 100644
--- a/inlong-dashboard/src/ui/pages/GroupDetail/DataSources/DetailModal.tsx
+++ b/inlong-dashboard/src/ui/pages/GroupDetail/DataSources/DetailModal.tsx
@@ -25,6 +25,7 @@ import { useRequest, useUpdateEffect } from '@/ui/hooks';
 import { useTranslation } from 'react-i18next';
 import { useDefaultMeta, useLoadMeta, SourceMetaType } from '@/plugins';
 import request from '@/core/utils/request';
+import { ALL_OPTION_VALUE } from '@/ui/components/MultiSelectWithAll';
 
 export interface Props extends ModalProps {
   // When editing, use the ID to call the interface for obtaining details
@@ -67,6 +68,7 @@ const Comp: React.FC<Props> = ({
   const onOk = async () => {
     const values = await form.validateFields();
     const submitData = new Entity()?.stringify(values) || values;
+    submitData.agentIp = submitData.agentIp.join(',');
     const isUpdate = Boolean(id);
     if (isUpdate) {
       submitData.id = id;

Reply via email to