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;