Browse Source

update insert

tumao 4 years ago
parent
commit
74f8fc324f

+ 46 - 19
client/src/components/insert/Container.tsx

@@ -28,27 +28,47 @@ const getStyles = makeStyles((theme: Theme) => ({
 
 const InsertContainer: FC<InsertContentProps> = ({
   collections,
-  selectedCollection,
   partitions,
-  selectedPartition,
+
+  /**
+   * every time selected collection change,
+   * we need to call handleSelectedCollectionChange function to update partitions and schema data,
+   */
+  defaultSelectedCollection,
+  handleSelectedCollectionChange,
+
+  defaultSelectedPartition,
+
   schema,
   handleInsert,
 }) => {
   const classes = getStyles();
 
   // props children component needed:
-  const collectionOptions: Option[] = collections.map(c => ({
-    label: c._name,
-    value: c._name,
-  }));
-  const partitionOptions: Option[] = partitions.map(p => ({
-    label: p._name,
-    value: p._name,
-  }));
-  const schemaOptions: Option[] = schema.map(s => ({
-    label: s._fieldName,
-    value: s._fieldId,
-  }));
+  const collectionOptions: Option[] = useMemo(
+    () =>
+      collections.map(c => ({
+        label: c._name,
+        value: c._name,
+      })),
+    [collections]
+  );
+  const partitionOptions: Option[] = useMemo(
+    () =>
+      partitions.map(p => ({
+        label: p._name,
+        value: p._name,
+      })),
+    [partitions]
+  );
+  const schemaOptions: Option[] = useMemo(
+    () =>
+      schema.map(s => ({
+        label: s._fieldName,
+        value: s._fieldId,
+      })),
+    [schema]
+  );
 
   const { t: insertTrans } = useTranslation('insert');
   const { t: btnTrans } = useTranslation('btn');
@@ -62,11 +82,13 @@ const InsertContainer: FC<InsertContentProps> = ({
   // const [nextDisabled, setNextDisabled] = useState<boolean>(false);
 
   // selected collection name
-  const [collectionValue, setCollectionValue] =
-    useState<string>(selectedCollection);
+  const [collectionValue, setCollectionValue] = useState<string>(
+    defaultSelectedCollection
+  );
   // selected partition name
-  const [partitionValue, setPartitionValue] =
-    useState<string>(selectedPartition);
+  const [partitionValue, setPartitionValue] = useState<string>(
+    defaultSelectedPartition
+  );
   // use contain field names yes as default
   const [isContainFieldNames, setIsContainFieldNames] = useState<number>(1);
   // uploaded file name
@@ -143,6 +165,11 @@ const InsertContainer: FC<InsertContentProps> = ({
     setInsertStauts(status);
   };
 
+  const handleCollectionChange = (name: string) => {
+    setCollectionValue(name);
+    handleSelectedCollectionChange && handleSelectedCollectionChange(name);
+  };
+
   const handleNext = () => {
     switch (activeStep) {
       case InsertStepperEnum.import:
@@ -183,7 +210,7 @@ const InsertContainer: FC<InsertContentProps> = ({
             partitionOptions={partitionOptions}
             selectedCollection={collectionValue}
             selectedPartition={partitionValue}
-            handleCollectionChange={setCollectionValue}
+            handleCollectionChange={handleCollectionChange}
             handlePartitionChange={setPartitionValue}
             handleUploadedData={handleUploadedData}
             fileName={fileName}

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

@@ -127,7 +127,8 @@ const InsertImport: FC<InsertImportProps> = ({
             label={collectionTrans('collection')}
             onChange={(e: { target: { value: unknown } }) => {
               const collection = e.target.value;
-              handleCollectionChange(collection as string);
+              handleCollectionChange &&
+                handleCollectionChange(collection as string);
             }}
           />
           <Divider classes={{ root: 'divider' }} />

+ 9 - 3
client/src/components/insert/Types.ts

@@ -5,9 +5,14 @@ import { Option } from '../customSelector/Types';
 
 export interface InsertContentProps {
   collections: CollectionData[];
-  selectedCollection: string;
   partitions: PartitionData[];
-  selectedPartition: string;
+  // insert default selected collection
+  defaultSelectedCollection: string;
+  // optional if collections not selectable
+  handleSelectedCollectionChange?: (name: string) => void;
+
+  // insert default selected partition
+  defaultSelectedPartition: string;
   schema: FieldData[];
   handleInsert: () => Promise<boolean>;
 }
@@ -35,7 +40,8 @@ export interface InsertImportProps {
   selectedPartition: string;
 
   // selectors change methods
-  handleCollectionChange: (collectionName: string) => void;
+  // optional if collection not selectable
+  handleCollectionChange?: (collectionName: string) => void;
   handlePartitionChange: (partitionName: string) => void;
   // handle uploaded data
   handleUploadedData: (data: string) => void;

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

@@ -1,8 +1,9 @@
 import { ChildrenStatusType, StatusEnum } from '../components/status/Types';
-import { CollectionView } from '../pages/collections/Types';
+import { CollectionView, DataType } from '../pages/collections/Types';
 import { IndexState, ShowCollectionsType } from '../types/Milvus';
 import { formatNumber } from '../utils/Common';
 import BaseModel from './BaseModel';
+import { FieldHttp } from './Field';
 
 export class CollectionHttp extends BaseModel implements CollectionView {
   private autoID!: string;
@@ -12,6 +13,16 @@ export class CollectionHttp extends BaseModel implements CollectionView {
   private index_status!: string;
   private id!: string;
   private isLoaded!: boolean;
+  private schema!: {
+    fields: {
+      data_type: DataType;
+      fieldID: string;
+      type_params: { key: string; value: string }[];
+      is_primary_key: true;
+      name: string;
+      description: string;
+    }[];
+  };
 
   static COLLECTIONS_URL = '/collections';
   static COLLECTIONS_INDEX_STATUS_URL = '/collections/indexes/status';
@@ -85,6 +96,10 @@ export class CollectionHttp extends BaseModel implements CollectionView {
     return this.isLoaded === true ? StatusEnum.loaded : StatusEnum.unloaded;
   }
 
+  get _fields() {
+    return this.schema.fields.map(f => new FieldHttp(f));
+  }
+
   get _indexState() {
     switch (this.index_status) {
       case IndexState.InProgress:

+ 62 - 24
client/src/pages/collections/Collections.tsx

@@ -26,6 +26,9 @@ import {
 import Highlighter from 'react-highlight-words';
 import { parseLocationSearch } from '../../utils/Format';
 import InsertContainer from '../../components/insert/Container';
+import { PartitionData } from '../partitions/Types';
+import { FieldData } from '../schema/Types';
+import { PartitionHttp } from '../../http/Partition';
 
 const useStyles = makeStyles((theme: Theme) => ({
   emptyWrapper: {
@@ -88,6 +91,14 @@ const Collections = () => {
   const ReleaseIcon = icons.release;
   const InfoIcon = icons.info;
 
+  /**
+   * insert needed data:
+   * 1. partitions: according to selected collection, always selectable
+   * 2. schema: according to selected collection, used as editable heads options
+   */
+  const [insertPartitions, setInsertPartitions] = useState<PartitionData[]>([]);
+  const [insertSchema, setInsertSchema] = useState<FieldData[]>([]);
+
   const fetchData = useCallback(async () => {
     try {
       const res = await CollectionHttp.getCollections();
@@ -133,6 +144,28 @@ const Collections = () => {
     fetchData();
   }, [fetchData]);
 
+  const handleInsert = useCallback(async (): Promise<boolean> => {
+    return new Promise((resolve, reject) => {});
+  }, []);
+
+  const handleInsertCollectionChange = useCallback(
+    async (name: string) => {
+      const selectCollection = collections.find(c => c._name === name);
+
+      console.log('select collection', selectCollection);
+      if (selectCollection) {
+        const partitions = await PartitionHttp.getPartitions(name);
+        console.log('----- partitions', partitions);
+        setInsertPartitions(partitions);
+
+        const schema = selectCollection._fields || [];
+        console.log('----- schema', schema);
+        setInsertSchema(schema);
+      }
+    },
+    [collections]
+  );
+
   const handleCreateCollection = async (param: CollectionCreateParam) => {
     const data: CollectionCreateParam = JSON.parse(JSON.stringify(param));
     const vectorType = [DataTypeEnum.BinaryVector, DataTypeEnum.FloatVector];
@@ -229,30 +262,35 @@ const Collections = () => {
       },
       icon: 'add',
     },
-    // {
-    //   label: btnTrans('insert'),
-    //   onClick: () => {
-    //     const component = (
-    //       <InsertContainer
-    //         collections={[]}
-    //         selectedCollection={''}
-    //         partitions={[]}
-    //         selectedPartition={''}
-    //         schema={[]}
-    //         handleInsert={() => {}}
-    //       />
-    //     );
-    //     handleInsertDialog(component);
-    //   },
-    //   /**
-    //    * insert validation:
-    //    * 1. At least 1 available collection
-    //    * 2. selected collections quantity shouldn't over 1
-    //    */
-    //   disabled: () =>
-    //     collectionList.length === 0 || selectedCollections.length > 1,
-    //   icon: 'upload',
-    // },
+    {
+      label: btnTrans('insert'),
+      onClick: () => {
+        handleInsertDialog(
+          <InsertContainer
+            collections={collections}
+            defaultSelectedCollection={
+              selectedCollections.length === 1
+                ? selectedCollections[0]._name
+                : ''
+            }
+            handleSelectedCollectionChange={handleInsertCollectionChange}
+            partitions={insertPartitions}
+            // user can't select partition on collection page, so default value is ''
+            defaultSelectedPartition={''}
+            schema={insertSchema}
+            handleInsert={handleInsert}
+          />
+        );
+      },
+      /**
+       * insert validation:
+       * 1. At least 1 available collection
+       * 2. selected collections quantity shouldn't over 1
+       */
+      disabled: () =>
+        collectionList.length === 0 || selectedCollections.length > 1,
+      btnVariant: 'outlined',
+    },
     {
       type: 'iconBtn',
       onClick: () => {

+ 2 - 0
client/src/pages/collections/Types.ts

@@ -1,5 +1,6 @@
 import { Dispatch, ReactElement, SetStateAction } from 'react';
 import { ChildrenStatusType, StatusEnum } from '../../components/status/Types';
+import { FieldData } from '../schema/Types';
 
 export interface CollectionData {
   _name: string;
@@ -8,6 +9,7 @@ export interface CollectionData {
   _rowCount: string;
   _desc: string;
   _indexState: ChildrenStatusType;
+  _fields?: FieldData[];
 }
 
 export interface CollectionView extends CollectionData {