Browse Source

update validation and comment

tumao 4 years ago
parent
commit
0177a3ae93

+ 35 - 7
client/src/components/insert/Container.tsx

@@ -56,8 +56,9 @@ const InsertContainer: FC<InsertContentProps> = ({
   const [insertStatus, setInsertStauts] = useState<InsertStatusEnum>(
     InsertStatusEnum.init
   );
-  // TODO: add validation
-  // const [nextDisabled, setNextDisabled] = useState<boolean>(false);
+  const [insertFailMsg, setInsertFailMsg] = useState<string>('');
+
+  const [nextDisabled, setNextDisabled] = useState<boolean>(false);
 
   // selected collection name
   const [collectionValue, setCollectionValue] = useState<string>(
@@ -85,6 +86,26 @@ const InsertContainer: FC<InsertContentProps> = ({
     return csvData.slice(0, end);
   }, [csvData, isContainFieldNames]);
 
+  useEffect(() => {
+    if (activeStep === InsertStepperEnum.import) {
+      /**
+       * 1. must choose collection and partition
+       * 2. must upload a csv file
+       */
+      const selectValid = collectionValue !== '' && partitionValue !== '';
+      const uploadValid = csvData.length > 0;
+      const condition = selectValid && uploadValid;
+      setNextDisabled(!condition);
+    }
+    if (activeStep === InsertStepperEnum.preview) {
+      /**
+       * table heads shouldn't be empty
+       */
+      const headsValid = tableHeads.every(h => h !== '');
+      setNextDisabled(!headsValid);
+    }
+  }, [activeStep, collectionValue, partitionValue, csvData, tableHeads]);
+
   useEffect(() => {
     const heads = isContainFieldNames
       ? previewData[0]
@@ -213,12 +234,19 @@ const InsertContainer: FC<InsertContentProps> = ({
   const handleInsertData = async () => {
     // combine table heads and data
     const tableData = isContainFieldNames ? csvData.slice(1) : csvData;
-
     const data = combineHeadsAndData(tableHeads, tableData);
 
     setInsertStauts(InsertStatusEnum.loading);
-    const res = await handleInsert(collectionValue, partitionValue, data);
-    const status = res ? InsertStatusEnum.success : InsertStatusEnum.error;
+    const { result, msg } = await handleInsert(
+      collectionValue,
+      partitionValue,
+      data
+    );
+
+    if (!result) {
+      setInsertFailMsg(msg);
+    }
+    const status = result ? InsertStatusEnum.success : InsertStatusEnum.error;
     setInsertStauts(status);
   };
 
@@ -288,7 +316,7 @@ const InsertContainer: FC<InsertContentProps> = ({
         );
       // default represents InsertStepperEnum.status
       default:
-        return <InsertStatus status={insertStatus} />;
+        return <InsertStatus status={insertStatus} failMsg={insertFailMsg} />;
     }
   };
 
@@ -300,7 +328,7 @@ const InsertContainer: FC<InsertContentProps> = ({
       cancelLabel={cancel}
       handleCancel={handleBack}
       handleConfirm={handleNext}
-      confirmDisabled={false}
+      confirmDisabled={nextDisabled}
       showActions={showActions}
       showCancel={showCancel}
       // don't show close icon when insert not finish

+ 2 - 1
client/src/components/insert/Status.tsx

@@ -32,7 +32,7 @@ const getStyles = makeStyles((theme: Theme) => ({
   },
 }));
 
-const InsertStatus: FC<InsertStatusProps> = ({ status }) => {
+const InsertStatus: FC<InsertStatusProps> = ({ status, failMsg }) => {
   const { t: insertTrans } = useTranslation('insert');
   const classes = getStyles({ status });
 
@@ -69,6 +69,7 @@ const InsertStatus: FC<InsertStatusProps> = ({ status }) => {
       <Typography variant="h4" className={classes.text}>
         {insertTrans('statusError')}
       </Typography>
+      {failMsg && <Typography className={classes.text}>{failMsg}</Typography>}
     </>
   );
 

+ 2 - 1
client/src/components/insert/Types.ts

@@ -23,7 +23,7 @@ export interface InsertContentProps {
     collectionName: string,
     partitionName: string,
     fieldData: any[]
-  ) => Promise<boolean>;
+  ) => Promise<{ result: boolean; msg: string }>;
 }
 
 export enum InsertStepperEnum {
@@ -71,4 +71,5 @@ export interface InsertPreviewProps {
 
 export interface InsertStatusProps {
   status: InsertStatusEnum;
+  failMsg: string;
 }

+ 1 - 1
client/src/http/Collection.ts

@@ -36,7 +36,7 @@ export class CollectionHttp extends BaseModel implements CollectionView {
   }
 
   static getCollection(name: string) {
-    return super.findAll({
+    return super.search({
       path: `${this.COLLECTIONS_URL}/${name}`,
       params: {},
     });

+ 8 - 3
client/src/pages/collections/Collections.tsx

@@ -143,7 +143,7 @@ const Collections = () => {
     collectionName: string,
     partitionName: string,
     fieldData: any[]
-  ): Promise<boolean> => {
+  ): Promise<{ result: boolean; msg: string }> => {
     const param: InsertDataParam = {
       partition_names: [partitionName],
       fields_data: fieldData,
@@ -153,9 +153,14 @@ const Collections = () => {
       await MilvusHttp.flush(collectionName);
       // update collections
       fetchData();
-      return true;
+      return { result: true, msg: '' };
     } catch (err) {
-      return false;
+      const {
+        response: {
+          data: { message },
+        },
+      } = err;
+      return { result: false, msg: message || '' };
     }
   };
 

+ 8 - 3
client/src/pages/partitions/Partitions.tsx

@@ -190,7 +190,7 @@ const Partitions: FC<{
     collectionName: string,
     partitionName: string,
     fieldData: any[]
-  ): Promise<boolean> => {
+  ): Promise<{ result: boolean; msg: string }> => {
     const param: InsertDataParam = {
       partition_names: [partitionName],
       fields_data: fieldData,
@@ -201,9 +201,14 @@ const Partitions: FC<{
       // update partitions
       fetchPartitions(collectionName);
 
-      return true;
+      return { result: true, msg: '' };
     } catch (err) {
-      return false;
+      const {
+        response: {
+          data: { message },
+        },
+      } = err;
+      return { result: false, msg: message || '' };
     }
   };
 

+ 6 - 0
client/src/utils/Insert.ts

@@ -12,6 +12,12 @@ export const transferCsvArrayToTableData = (data: any[][]) => {
   );
 };
 
+/**
+ * function to replace object key
+ * @param obj e.g. {0: 'name1', 1: 12, 2: 'red'}
+ * @param newKeys e.g. ['name', 'age', 'color']
+ * @returns e.g. {name: 'name1', age: 12, color: 'red'}
+ */
 const replaceKeysByIndex = (obj: any, newKeys: string[]) => {
   const keyValues = Object.keys(obj).map(key => {
     const newKey = newKeys[Number(key)] || key;