Browse Source

Merge pull request #96 from Tumao727/collection-name-validation

update collection name validation
ryjiang 4 years ago
parent
commit
ba819a7be2

+ 4 - 0
client/src/i18n/cn/collection.ts

@@ -30,6 +30,10 @@ const collectionTrans = {
   dimensionMutipleWarning: 'Dimension should be 8 multiple',
   dimensionMutipleWarning: 'Dimension should be 8 multiple',
   dimensionPositiveWarning: 'Dimension should be positive number',
   dimensionPositiveWarning: 'Dimension should be positive number',
   newBtn: 'add new field',
   newBtn: 'add new field',
+  nameLengthWarning: 'Name length should be less than 256',
+  nameContentWarning: 'Name can only contain numbers, letters, and underscores',
+  nameFirstLetterWarning:
+    'Name first character must be underscore or character(a~z, A~Z)',
 
 
   // load dialog
   // load dialog
   loadTitle: 'Load Collection',
   loadTitle: 'Load Collection',

+ 4 - 0
client/src/i18n/en/collection.ts

@@ -30,6 +30,10 @@ const collectionTrans = {
   dimensionMutipleWarning: 'Dimension should be 8 multiple',
   dimensionMutipleWarning: 'Dimension should be 8 multiple',
   dimensionPositiveWarning: 'Dimension should be positive number',
   dimensionPositiveWarning: 'Dimension should be positive number',
   newBtn: 'add new field',
   newBtn: 'add new field',
+  nameLengthWarning: 'Name length should be less than 256',
+  nameContentWarning: 'Name can only contain numbers, letters, and underscores',
+  nameFirstLetterWarning:
+    'Name first character must be underscore or character(a~z, A~Z)',
 
 
   // load dialog
   // load dialog
   loadTitle: 'Load Collection',
   loadTitle: 'Load Collection',

+ 24 - 0
client/src/pages/collections/Create.tsx

@@ -7,6 +7,7 @@ import { ITextfieldConfig } from '../../components/customInput/Types';
 import { rootContext } from '../../context/Root';
 import { rootContext } from '../../context/Root';
 import { useFormValidation } from '../../hooks/Form';
 import { useFormValidation } from '../../hooks/Form';
 import { formatForm } from '../../utils/Form';
 import { formatForm } from '../../utils/Form';
+import { TypeEnum } from '../../utils/Validation';
 import CreateFields from './CreateFields';
 import CreateFields from './CreateFields';
 import {
 import {
   CollectionCreateParam,
   CollectionCreateParam,
@@ -111,12 +112,35 @@ const CreateCollection: FC<CollectionCreateProps> = ({ handleCreate }) => {
       onChange: (value: string) => handleInputChange('collection_name', value),
       onChange: (value: string) => handleInputChange('collection_name', value),
       variant: 'filled',
       variant: 'filled',
       validations: [
       validations: [
+        // cannot be empty
         {
         {
           rule: 'require',
           rule: 'require',
           errorText: warningTrans('required', {
           errorText: warningTrans('required', {
             name: collectionTrans('name'),
             name: collectionTrans('name'),
           }),
           }),
         },
         },
+        // length <= 255
+        {
+          rule: 'range',
+          extraParam: {
+            max: 255,
+            type: 'string',
+          },
+          errorText: collectionTrans('nameLengthWarning'),
+        },
+        // name can only be combined with letters, number or underscores
+        {
+          rule: 'collectionName',
+          errorText: collectionTrans('nameContentWarning'),
+        },
+        // name can not start with number
+        {
+          rule: 'firstCharacter',
+          extraParam: {
+            invalidTypes: [TypeEnum.number],
+          },
+          errorText: collectionTrans('nameFirstLetterWarning'),
+        },
       ],
       ],
       className: classes.input,
       className: classes.input,
     },
     },

+ 49 - 10
client/src/utils/Validation.ts

@@ -13,7 +13,8 @@ export type ValidType =
   | 'collectionName'
   | 'collectionName'
   | 'dimension'
   | 'dimension'
   | 'multiple'
   | 'multiple'
-  | 'partitionName';
+  | 'partitionName'
+  | 'firstCharacter';
 export interface ICheckMapParam {
 export interface ICheckMapParam {
   value: string;
   value: string;
   extraParam?: IExtraParam;
   extraParam?: IExtraParam;
@@ -30,11 +31,18 @@ export interface IExtraParam {
   // used for dimension
   // used for dimension
   metricType?: MetricType;
   metricType?: MetricType;
   multipleNumber?: number;
   multipleNumber?: number;
+
+  // used for check start item
+  invalidTypes?: TypeEnum[];
 }
 }
 export type CheckMap = {
 export type CheckMap = {
   [key in ValidType]: boolean;
   [key in ValidType]: boolean;
 };
 };
 
 
+export enum TypeEnum {
+  'number' = 'number',
+}
+
 export const checkEmptyValid = (value: string): boolean => {
 export const checkEmptyValid = (value: string): boolean => {
   return value.trim() !== '';
   return value.trim() !== '';
 };
 };
@@ -103,20 +111,47 @@ export const checkIpOrCIDR = (value: string): boolean => {
 };
 };
 
 
 // collection name can only be combined with number, letter or _
 // collection name can only be combined with number, letter or _
-// name max length 255 and can't start with number
 export const checkCollectionName = (value: string): boolean => {
 export const checkCollectionName = (value: string): boolean => {
-  const length = value.length;
-  if (length > 254) {
-    return false;
+  const re = /^[0-9,a-z,A-Z_]+$/;
+  return re.test(value);
+};
+
+/**
+ * check data type
+ * @param type data types, like string, number
+ * @param value
+ * @returns whether value's value is equal to param type
+ */
+export const checkType = (type: TypeEnum, value: string): boolean => {
+  switch (type) {
+    case TypeEnum.number:
+      return !isNaN(Number(value));
+    default:
+      return true;
   }
   }
+};
 
 
-  const start = Number(value[0]);
-  if (!isNaN(start)) {
-    return false;
+/**
+ * check input first character
+ * @param value
+ * @param invalidTypes
+ * @returns whether start letter type not belongs to invalid types
+ */
+export const checkFirstCharacter = (param: {
+  value: string;
+  invalidTypes?: TypeEnum[];
+}): boolean => {
+  const { value, invalidTypes } = param;
+  const start = value[0];
+  const types = invalidTypes || [];
+  for (let type of types) {
+    const result = checkType(type, start);
+    if (result) {
+      return false;
+    }
   }
   }
 
 
-  const re = /^[0-9,a-z,A-Z$_]+$/;
-  return re.test(value);
+  return true;
 };
 };
 
 
 export const checkPartitionName = (value: string): boolean => {
 export const checkPartitionName = (value: string): boolean => {
@@ -176,6 +211,10 @@ export const getCheckResult = (param: ICheckMapParam): boolean => {
       multipleNumber: extraParam?.multipleNumber,
       multipleNumber: extraParam?.multipleNumber,
     }),
     }),
     partitionName: checkPartitionName(value),
     partitionName: checkPartitionName(value),
+    firstCharacter: checkFirstCharacter({
+      value,
+      invalidTypes: extraParam?.invalidTypes,
+    }),
   };
   };
 
 
   return checkMap[rule];
   return checkMap[rule];