This is an automated email from the ASF dual-hosted git repository.

benjobs pushed a commit to branch k8s-FE
in repository https://gitbox.apache.org/repos/asf/incubator-streampark.git

commit 8250fb0a3fb05558fdca6df78729960cc8125274
Author: benjobs <[email protected]>
AuthorDate: Sun Jun 23 00:28:32 2024 +0800

    [Improve] job name validator improvement
---
 .../src/locales/lang/en/flink/app.ts               | 12 ++++-
 .../src/locales/lang/zh-CN/flink/app.ts            | 39 +++++++++-------
 .../src/locales/lang/zh-CN/setting/flinkCluster.ts | 14 +++---
 .../flink/app/hooks/useCreateAndEditSchema.ts      | 52 ++++++++++++++--------
 .../src/views/flink/app/hooks/useFlinkRender.tsx   | 40 +++++++++++++++++
 5 files changed, 116 insertions(+), 41 deletions(-)

diff --git 
a/streampark-console/streampark-console-webapp/src/locales/lang/en/flink/app.ts 
b/streampark-console/streampark-console-webapp/src/locales/lang/en/flink/app.ts
index ff29d9980..32aa9b540 100644
--- 
a/streampark-console/streampark-console-webapp/src/locales/lang/en/flink/app.ts
+++ 
b/streampark-console/streampark-console-webapp/src/locales/lang/en/flink/app.ts
@@ -275,8 +275,18 @@ export default {
       'The application name already exists in YARN, cannot be repeated. Please 
check',
     appNameExistsInK8sMessage:
       'The application name already exists in Kubernetes,cannot be repeated. 
Please check',
+    appNameValid: 'The job name is invalid',
+    appNameRole: 'The job name must follow these rules: ',
     appNameNotValid:
       'The application name is invalid, must be (Chinese or English or "-" or 
"_"), two consecutive spaces cannot appear.Please check',
+    K8sSessionClusterIdRole: 'The K8s clusterId must follow the following 
rules:',
+    appNameK8sClusterIdRole:
+      'The current deployment mode is K8s Application mode, and the job name 
will be used as the clusterId in K8s. Therefore, the job name must follow the 
following rules:',
+    appNameK8sClusterIdRoleLength: 'must be no more than 45 characters',
+    appNameK8sClusterIdRoleRegexp:
+      'must only contain lowercase alphanumeric characters and "-",The 
required format is [a-z]([-a-z0-9]*[a-z0-9])',
+    appNameRoleContent:
+      'must be (Chinese or English or "-" or "_"), two consecutive spaces 
cannot appear.Please check',
     flinkClusterIsRequiredMessage: 'Flink Cluster is required',
     flinkSqlIsRequiredMessage: 'Flink SQL is required',
     tagsPlaceholder: 'Please enter tags,if more than one, separate them with 
commas(,)',
@@ -296,7 +306,7 @@ export default {
     flinkImagePlaceholder:
       'Please enter the tag of Flink base docker image, such as: 
flink:1.13.0-scala_2.11-java8',
     flinkImageIsRequiredMessage: 'Flink Base Docker Image is required',
-    k8sRestExposedTypePlaceholder: 'kubernetes.rest-service.exposed.type',
+    k8sRestExposedTypePlaceholder: 'Kubernetes Rest-Service Exposed Type',
     hadoopXmlConfigFileTips:
       'Automatically copy configuration files from system environment 
parameters',
     dynamicPropertiesPlaceholder:
diff --git 
a/streampark-console/streampark-console-webapp/src/locales/lang/zh-CN/flink/app.ts
 
b/streampark-console/streampark-console-webapp/src/locales/lang/zh-CN/flink/app.ts
index 2aee8d0cb..a3d55c7fa 100644
--- 
a/streampark-console/streampark-console-webapp/src/locales/lang/zh-CN/flink/app.ts
+++ 
b/streampark-console/streampark-console-webapp/src/locales/lang/zh-CN/flink/app.ts
@@ -47,10 +47,10 @@ export default {
   yarnQueue: 'Yarn队列',
   mavenPom: 'maven pom',
   uploadJar: '上传依赖Jar文件',
-  kubernetesNamespace: 'K8S命名空间',
-  kubernetesClusterId: 'K8S ClusterId',
-  flinkBaseDockerImage: 'Flink基础docker镜像',
-  restServiceExposedType: 'K8S服务对外类型',
+  kubernetesNamespace: 'Kubernetes 命名空间',
+  kubernetesClusterId: 'Kubernetes ClusterId',
+  flinkBaseDockerImage: 'Flink 基础docker镜像',
+  restServiceExposedType: 'Rest-Service Exposed Type',
   resourceFrom: '资源来源',
   uploadJobJar: '上传jar文件',
   selectJobJar: '选择jar文件',
@@ -71,7 +71,7 @@ export default {
   hadoopUser: 'Hadoop User',
   restoreModeTip: 'flink 1.15开始支持restore模式,一般情况下不用设置该参数',
   release: {
-    releaseTitle: '该应用程序的当前启动正在进行中.',
+    releaseTitle: '该作业正在启动中.',
     releaseDesc: '您确定要强制进行另一次构建吗',
     releaseFail: '发布作业失败',
     releasing: '当前作业正在发布中',
@@ -153,11 +153,11 @@ export default {
     errorLog: '错误日志',
     errorSummary: '错误摘要',
     errorStack: '错误堆栈',
-    logTitle: '启动日志 : 应用名称 [ {0} ]',
+    logTitle: '启动日志 : 作业名称 [ {0} ]',
     refreshTime: '上次刷新时间',
     refresh: '刷新',
     start: '启动作业',
-    stop: '停止应用',
+    stop: '停止作业',
     savepoint: '触发 Savepoint',
     recheck: '关联的项目已更新,需要重新发布此作业',
     changed: '作业已更新',
@@ -265,10 +265,19 @@ export default {
     appNamePlaceholder: '请输入作业名称',
     appNameIsRequiredMessage: '作业名称必填',
     appNameNotUniqueMessage: '作业名称必须唯一, 输入的作业名称已经存在',
-    appNameExistsInYarnMessage: '应用程序名称已经在YARN集群中存在,不能重复。请检查',
-    appNameExistsInK8sMessage: '该应用程序名称已经在K8S集群中存在,不能重复。请检查',
+    appNameExistsInYarnMessage: '作业名称已经在YARN集群中存在,不能重复。请检查',
+    appNameExistsInK8sMessage: '该作业名称已经在 Kubernetes 集群中存在,不能重复。请检查',
+    appNameValid: '作业名称不合法',
+    appNameRole: '作业必须遵循以下规则:',
+    K8sSessionClusterIdRole: 'Kubernetes 集群ID必要遵循以下规则:',
+    appNameK8sClusterIdRole:
+      '当前部署模式是 Kubernetes Application 模式,会将作业名称作为 Kubernetes 的 
clusterId,因此作业名称要遵循以下规则:',
+    appNameK8sClusterIdRoleLength: '不应超过 45 个字符',
+    appNameK8sClusterIdRoleRegexp:
+      '只能由小写字母、数字、字符、和"-" 组成,必须满足正则格式 [a-z]([-a-z0-9]*[a-z0-9])',
+    appNameRoleContent: '字符必须是(中文 或 英文 或 "-" 或 "_"),不能出现两个连续的空格',
     appNameNotValid:
-      '应用程序名称无效。字符必须是(中文 或 英文 或 "-" 或 "_"),不能出现两个连续的空格,请检查',
+      '作业名称无效。字符必须是(中文 或 英文 或 "-" 或 "_"),不能出现两个连续的空格,请检查',
     flinkClusterIsRequiredMessage: 'Flink集群必填',
     flinkSqlIsRequiredMessage: 'Flink SQL必填',
     tagsPlaceholder: '请输入标签,如果超过一个,用逗号(,)分隔',
@@ -279,15 +288,15 @@ export default {
     totalMemoryOptionsPlaceholder: '请选择要设置的资源参数',
     tmPlaceholder: '请选择要设置的资源参数',
     yarnQueuePlaceholder: '请输入yarn队列标签名称',
-    descriptionPlaceholder: '请输入此应用程序的描述',
-    kubernetesNamespacePlaceholder: '请输入K8S命名空间, 如: default',
-    kubernetesClusterIdPlaceholder: '请选择K8S ClusterId',
+    descriptionPlaceholder: '请输入此作业的描述',
+    kubernetesNamespacePlaceholder: '请输入 Kubernetes 命名空间, 如: default',
+    kubernetesClusterIdPlaceholder: '请选择 Kubernetes ClusterId',
     kubernetesClusterIdRequire:
       '小写字母、数字、“-”,并且必须以字母数字字符开头和结尾,并且不超过45个字符',
-    kubernetesClusterIdIsRequiredMessage: 'K8S ClusterId必填',
+    kubernetesClusterIdIsRequiredMessage: 'Kubernetes ClusterId 必填',
     flinkImagePlaceholder: 
'请输入Flink基础docker镜像的标签,如:flink:1.13.0-scala_2.11-java8',
     flinkImageIsRequiredMessage: 'Flink基础docker镜像是必填的',
-    k8sRestExposedTypePlaceholder: 'K8S服务对外类型',
+    k8sRestExposedTypePlaceholder: 'Kubernetes Rest-Service Exposed Type',
     hadoopXmlConfigFileTips: '从系统环境参数自动复制配置文件',
     dynamicPropertiesPlaceholder: '$key=$value,如果有多个参数,可以换行输入(-D <arg>)',
   },
diff --git 
a/streampark-console/streampark-console-webapp/src/locales/lang/zh-CN/setting/flinkCluster.ts
 
b/streampark-console/streampark-console-webapp/src/locales/lang/zh-CN/setting/flinkCluster.ts
index 4e926d749..9cfdb9b84 100644
--- 
a/streampark-console/streampark-console-webapp/src/locales/lang/zh-CN/setting/flinkCluster.ts
+++ 
b/streampark-console/streampark-console-webapp/src/locales/lang/zh-CN/setting/flinkCluster.ts
@@ -32,12 +32,12 @@ export default {
     addNew: '全新集群',
     yarnQueue: 'Yarn队列',
     yarnSessionClusterId: 'Yarn Session模式集群ID',
-    k8sNamespace: 'k8s命名空间',
-    k8sClusterId: 'k8s集群ID',
-    serviceAccount: 'k8s命名空间绑定的服务账号',
-    k8sConf: 'k8s环境Kube配置文件',
-    flinkImage: 'Flink基础docker镜像',
-    k8sRestExposedType: 'K8S服务对外类型',
+    k8sNamespace: 'Kubernetes 命名空间',
+    k8sClusterId: 'Kubernetes 集群 ID',
+    serviceAccount: 'Kubernetes  服务账号',
+    k8sConf: 'Kube 配置文件',
+    flinkImage: 'Flink 基础 Docker 镜像',
+    k8sRestExposedType: 'Kubernetes Rest exposed-type',
     resolveOrder: '类加载顺序',
     taskSlots: '任务槽数',
     jmOptions: 'JM内存',
@@ -54,7 +54,7 @@ export default {
     addressNoRemoteMode: '请输入集群地址,例如:http://host:port',
     yarnSessionClusterId: '请输入Yarn Session模式集群ID',
     k8sConf: '示例:~/.kube/config',
-    flinkImage: '请输入Flink基础docker镜像的标签,如:flink:1.13.0-scala_2.11-java8',
+    flinkImage: '请输入 Flink 基础 docker 镜像的标签,如:flink:1.13.0-scala_2.11-java8',
     k8sRestExposedType: 'kubernetes.rest-service.exposed.type',
     resolveOrder: 'classloader.resolve-order',
     taskSlots: '每个TaskManager的插槽数',
diff --git 
a/streampark-console/streampark-console-webapp/src/views/flink/app/hooks/useCreateAndEditSchema.ts
 
b/streampark-console/streampark-console-webapp/src/views/flink/app/hooks/useCreateAndEditSchema.ts
index 25847a28f..d3263d2a1 100644
--- 
a/streampark-console/streampark-console-webapp/src/views/flink/app/hooks/useCreateAndEditSchema.ts
+++ 
b/streampark-console/streampark-console-webapp/src/views/flink/app/hooks/useCreateAndEditSchema.ts
@@ -29,6 +29,7 @@ import {
   renderTotalMemory,
   renderYarnQueue,
   renderFlinkCluster,
+  renderJobName,
 } from './useFlinkRender';
 
 import { fetchCheckName } from '/@/api/flink/app';
@@ -279,26 +280,33 @@ export const useCreateAndEditSchema = (
   });
 
   /* Detect job name field */
-  async function getJobNameCheck(_rule: RuleObject, value: StoreValue) {
+  async function getJobNameCheck(_rule: RuleObject, value: StoreValue, model: 
Recordable) {
     if (value === null || value === undefined || value === '') {
       return 
Promise.reject(t('flink.app.addAppTips.appNameIsRequiredMessage'));
-    } else {
-      const params = { jobName: value };
-      if (edit?.appId) Object.assign(params, { id: edit.appId });
-      const res = await fetchCheckName(params);
-      switch (parseInt(res)) {
-        case 0:
-          return Promise.resolve();
-        case 1:
-          return 
Promise.reject(t('flink.app.addAppTips.appNameNotUniqueMessage'));
-        case 2:
-          return 
Promise.reject(t('flink.app.addAppTips.appNameExistsInYarnMessage'));
-        case 3:
-          return 
Promise.reject(t('flink.app.addAppTips.appNameExistsInK8sMessage'));
-        default:
-          return Promise.reject(t('flink.app.addAppTips.appNameNotValid'));
+    }
+    if (model.executionMode == ExecModeEnum.KUBERNETES_APPLICATION) {
+      const regexp = /^(?=.{1,45}$)[a-z]([-a-z0-9]*[a-z0-9])$/;
+      if (!regexp.test(value)) {
+        return Promise.reject(t('flink.app.addAppTips.appNameValid'));
       }
     }
+    const params = { jobName: value };
+    if (edit?.appId) {
+      Object.assign(params, { id: edit.appId });
+    }
+    const res = await fetchCheckName(params);
+    switch (parseInt(res)) {
+      case 0:
+        return Promise.resolve();
+      case 1:
+        return 
Promise.reject(t('flink.app.addAppTips.appNameNotUniqueMessage'));
+      case 2:
+        return 
Promise.reject(t('flink.app.addAppTips.appNameExistsInYarnMessage'));
+      case 3:
+        return 
Promise.reject(t('flink.app.addAppTips.appNameExistsInK8sMessage'));
+      default:
+        return Promise.reject(t('flink.app.addAppTips.appNameValid'));
+    }
   }
 
   const getFlinkFormOtherSchemas = computed((): FormSchema[] => {
@@ -313,8 +321,16 @@ export const useCreateAndEditSchema = (
         label: t('flink.app.appName'),
         component: 'Input',
         componentProps: { placeholder: 
t('flink.app.addAppTips.appNamePlaceholder') },
-        dynamicRules: () => {
-          return [{ required: true, trigger: 'blur', validator: 
getJobNameCheck }];
+        render: (param) => renderJobName(param),
+        dynamicRules: ({ model }) => {
+          return [
+            {
+              required: true,
+              trigger: 'blur',
+              validator: (rule: RuleObject, value: StoreValue) =>
+                getJobNameCheck(rule, value, model),
+            },
+          ];
         },
       },
       {
diff --git 
a/streampark-console/streampark-console-webapp/src/views/flink/app/hooks/useFlinkRender.tsx
 
b/streampark-console/streampark-console-webapp/src/views/flink/app/hooks/useFlinkRender.tsx
index 45b22f1d5..62975b584 100644
--- 
a/streampark-console/streampark-console-webapp/src/views/flink/app/hooks/useFlinkRender.tsx
+++ 
b/streampark-console/streampark-console-webapp/src/views/flink/app/hooks/useFlinkRender.tsx
@@ -44,6 +44,7 @@ import {
   FailoverStrategyEnum,
   RestoreModeEnum,
   ClusterStateEnum,
+  ExecModeEnum,
 } from '/@/enums/flinkEnum';
 import { useI18n } from '/@/hooks/web/useI18n';
 import { fetchYarnQueueList } from '/@/api/setting/yarnQueue';
@@ -299,6 +300,45 @@ export const renderFlinkCluster = (clusters, { model, 
field }: RenderCallbackPar
   );
 };
 
+export const renderJobName = ({ model, field }: RenderCallbackParams) => {
+  return (
+    <div>
+      <Input
+        name="jobName"
+        placeholder={t('flink.app.addAppTips.appNamePlaceholder')}
+        value={model[field]}
+        onInput={(e: ChangeEvent) => (model[field] = e?.target?.value)}
+      />
+      <p class="conf-desc mt-10px">
+        <span class="note-info">
+          <Tag color="#2db7f5" class="tag-note">
+            {t('flink.app.noteInfo.note')}
+          </Tag>
+          {model.executionMode == ExecModeEnum.KUBERNETES_APPLICATION && (
+            <span>
+              {t('flink.app.addAppTips.appNameK8sClusterIdRole')}
+              <div>
+                <Tag color="orange"> 1.</Tag>
+                {t('flink.app.addAppTips.appNameK8sClusterIdRoleLength')}
+              </div>
+              <div>
+                <Tag color="orange"> 2.</Tag>
+                {t('flink.app.addAppTips.appNameK8sClusterIdRoleRegexp')}
+              </div>
+            </span>
+          )}
+          {model.executionMode != ExecModeEnum.KUBERNETES_APPLICATION && (
+            <span>
+              <span>{t('flink.app.addAppTips.appNameRole')}</span>
+              <span>{t('flink.app.addAppTips.appNameRoleContent')}</span>
+            </span>
+          )}
+        </span>
+      </p>
+    </div>
+  );
+};
+
 /* render memory option */
 export const renderDynamicProperties = ({ model, field }: 
RenderCallbackParams) => {
   return (

Reply via email to